Skip to content

Commit

Permalink
Static sprites now collide relative to the viewport.
Browse files Browse the repository at this point in the history
  • Loading branch information
AliceLR committed Dec 27, 2023
1 parent e842e7d commit 9b96427
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 6 deletions.
9 changes: 7 additions & 2 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ are a lot of changes, including a large number of crash fixes.
Brief summaries of each section:

General: worlds are decrypted in memory now, MegaZeux 1.x worlds
are now supported, you can have more custom sound effects, and
the 1/8th random movement chance of dragons has been readded.
are now supported, you can have more custom sound effects, the
1/8th random movement chance of dragons has been readded, and
static sprites now collide at their apparent position.

Robotic: new label PLAYERDIED, new counter KEY_PRESSEDn, new
counter DATE_WEEKDAY, new counter SPRn_OFFONEXIT, new viewport
Expand Down Expand Up @@ -74,6 +75,10 @@ GENERAL
could cause it to rarely return a number outside of the
expected range. This unfortunately breaks compatibility for
the RANDOM_SEED# counter.
+ Static sprites now collide as if they are at the position on
the board where they are currently being drawn i.e. relative
to the viewport instead of at their actual X/Y position. This
behavior has also been added to the IF SPRITE AT # # command.
+ Optimized ccheck 3 sprite collision performance by generating
visibility masks for characters directly instead of using an
intermediate render and skipping pixel checks for blank chars.
Expand Down
5 changes: 3 additions & 2 deletions src/run_robot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2313,7 +2313,8 @@ void run_robot(context *ctx, int id, int x, int y)

for(i = check_color; i < MAX_SPRITES; i++)
{
if(sprite_at_xy(mzx_world->sprite_list[i], check_x, check_y))
if(sprite_at_xy(mzx_world, mzx_world->sprite_list[i],
check_x, check_y))
break;
}
if(i == MAX_SPRITES)
Expand All @@ -2331,7 +2332,7 @@ void run_robot(context *ctx, int id, int x, int y)
{
if((unsigned int)check_param < 256)
{
ret = sprite_at_xy(mzx_world->sprite_list[check_param],
ret = sprite_at_xy(mzx_world, mzx_world->sprite_list[check_param],
check_x, check_y);
}
}
Expand Down
31 changes: 30 additions & 1 deletion src/sprite.c
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ static inline struct rect board_rectangle(struct rect r)
);
}

boolean sprite_at_xy(struct sprite *spr, int x, int y)
boolean sprite_at_xy(struct world *mzx_world, struct sprite *spr, int x, int y)
{
struct rect sprite_rect;
struct rect pos_rect;
Expand All @@ -884,6 +884,15 @@ boolean sprite_at_xy(struct sprite *spr, int x, int y)
sprite_rect = sprite_rectangle(spr);
pos_rect = rectangle(x * CHAR_W, y * CHAR_H, CHAR_W, CHAR_H);

// Static sprite collision occurs at its apparent position from 2.93 onward.
if((spr->flags & SPRITE_STATIC) && mzx_world->version >= V293)
{
int screen_x, screen_y;
calculate_xytop(mzx_world, &screen_x, &screen_y);
sprite_rect.x += screen_x * CHAR_W;
sprite_rect.y += screen_y * CHAR_H;
}

if(rectangle_overlap(sprite_rect, pos_rect))
return true;
return false;
Expand Down Expand Up @@ -1126,6 +1135,8 @@ int sprite_colliding_xy(struct world *mzx_world, struct sprite *spr,
struct board *cur_board = mzx_world->current_board;
char *level_id = cur_board->level_id;
int board_width = cur_board->board_width;
int screen_x = 0;
int screen_y = 0;
int bx, by;
int sprite_idx;
int cx, cy;
Expand All @@ -1139,6 +1150,14 @@ int sprite_colliding_xy(struct world *mzx_world, struct sprite *spr,
if(mzx_world->version < V290)
return sprite_colliding_xy_old(mzx_world, spr, x, y);

// Adjust static sprites to match their apparent positions onscreen.
if(mzx_world->version >= V293)
{
calculate_xytop(mzx_world, &screen_x, &screen_y);
screen_x *= CHAR_W;
screen_y *= CHAR_H;
}

board_rect = rectangle(
0,
0,
Expand Down Expand Up @@ -1168,6 +1187,11 @@ int sprite_colliding_xy(struct world *mzx_world, struct sprite *spr,

sprite_rect = sprite_rectangle(&collision_sprite);
col_rect = collision_rectangle(&collision_sprite);
if(spr->flags & SPRITE_STATIC)
{
sprite_rect.x += screen_x;
sprite_rect.y += screen_y;
}
col_rect.x += sprite_rect.x;
col_rect.y += sprite_rect.y;

Expand Down Expand Up @@ -1231,6 +1255,11 @@ int sprite_colliding_xy(struct world *mzx_world, struct sprite *spr,

target_spr_rect = sprite_rectangle(target_spr);
target_col_rect = collision_rectangle(target_spr);
if(target_spr->flags & SPRITE_STATIC)
{
target_spr_rect.x += screen_x;
target_spr_rect.y += screen_y;
}
//debug("sprite #%d a: %d %d %d %d\n",
// target_rect.x, target_rect.y, target_rect.w, target_rect.h);
target_col_rect.x += target_spr_rect.x;
Expand Down
2 changes: 1 addition & 1 deletion src/sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ enum
void plot_sprite(struct world *mzx_world, struct sprite *cur_sprite, int color,
int x, int y);
void draw_sprites(struct world *mzx_world);
boolean sprite_at_xy(struct sprite *cur_sprite, int x, int y);
boolean sprite_at_xy(struct world *mzx_world, struct sprite *cur_sprite, int x, int y);
int sprite_colliding_xy(struct world *mzx_world, struct sprite *check_sprite,
int x, int y);

Expand Down
Binary file added testworlds/2.65/004 Static Sprite Collision.mzx
Binary file not shown.
3 changes: 3 additions & 0 deletions testworlds/2.65/004 Static Sprite Collision.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Title: Static Sprite Collision (2.65)
Author: Alice Rowan
Desc: Pre-2.90 static sprites display relative to the screen but do not collide relative to the screen. This world tests the original collision function from before unbound sprites.
Binary file added testworlds/2.90/016 Static Sprite Collision.mzx
Binary file not shown.
Binary file added testworlds/2.93/012 Static Sprite Collision.mzx
Binary file not shown.

0 comments on commit 9b96427

Please sign in to comment.