Add explosion object

This commit is contained in:
Lucas S. Vieira 2024-11-12 12:54:10 -03:00
parent 575ebe1712
commit 4909f7d00c
14 changed files with 72 additions and 13 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Before After
Before After

View file

@ -308,6 +308,37 @@ duration = 0
frames = [[144, 72, 32, 8]]
loopback = 0
# ============
[explosion]
[[explosion.animations]]
name = "small"
id = 0
duration = 4
frames = [
[48, 136, 32, 32],
[80, 136, 32, 32],
[112, 136, 32, 32],
[144, 136, 48, 48],
[192, 136, 48, 48],
]
loopback = -1
[[explosion.animations]]
name = "big"
id = 0
duration = 4
frames = [
[48, 136, 32, 32],
[80, 168, 32, 32],
[112, 168, 32, 32],
[144, 136, 48, 48],
[192, 136, 48, 48],
]
loopback = -1
# ============
# Dummy objects
# ============

View file

@ -49,4 +49,5 @@
<tile id="10" type="ring_3v"/>
<tile id="11" type="goal_sign"/>
<tile id="12" type="startpos"/>
<tile id="13" type="explosion"/>
</tileset>

View file

@ -24,6 +24,7 @@ typedef enum {
OBJ_SPRING_RED_DIAGONAL = 0x07,
OBJ_SWITCH = 0x08,
OBJ_GOAL_SIGN = 0x09,
OBJ_EXPLOSION = 0x0a,
} ObjectType;
#define MASK_FLIP_FLIPX 0x1 // Flip on X axis

View file

@ -26,7 +26,7 @@
Locations of common textures on frame buffer:
================================================
Player 1: 320x0; CLUT: 0x480
Common objects: 576x0; CLUT: 0x481
Common objects: 576x0; CLUT: 0x481 (8-bit only)
Level tiles: 448x0; CLUT: 0x482 (if exists)
Level BG0: 448x256; CLUT: 0x483 (4-bit only)
Level BG1: 512x256; CLUT: 0x484 (4-bit only)

View file

@ -60,6 +60,7 @@ load_object_table(const char *filename, ObjectTable *tbl)
// Entry ID, always sequential; discarded for now
uint8_t _id = get_byte(bytes, &b); (void)(_id);
/* printf("Load object 0x%04x\n", _id); */
uint8_t has_fragment = get_byte(bytes, &b);
entry->num_animations = get_short_be(bytes, &b);

View file

@ -272,7 +272,7 @@ begin_render_routine:
// Sprites: 576x0
// CLUT: 0x481
poly->tpage = getTPage(0, 0, 576, 0);
poly->tpage = getTPage(1, 0, 576, 0);
poly->clut = getClut(0, 481);
sort_prim(poly, state->id == OBJ_RING ? OTZ_LAYER_OBJECTS : OTZ_LAYER_PLAYER);

View file

@ -42,6 +42,7 @@ static void _spring_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos,
static void _spring_diagonal_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos, uint8_t is_red);
static void _checkpoint_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos);
static void _spikes_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos);
static void _explosion_update(ObjectState *state, ObjectTableEntry *, VECTOR *);
// Player hitbox information. Calculated once per frame.
static int32_t player_vx, player_vy; // Top left corner of player hitbox
@ -100,6 +101,7 @@ object_update(ObjectState *state, ObjectTableEntry *typedata, VECTOR *pos)
case OBJ_SPRING_RED_DIAGONAL: _spring_diagonal_update(state, typedata, pos, 1); break;
case OBJ_CHECKPOINT: _checkpoint_update(state, typedata, pos); break;
case OBJ_SPIKES: _spikes_update(state, typedata, pos); break;
case OBJ_EXPLOSION: _explosion_update(state, typedata, pos); break;
}
}
@ -247,6 +249,12 @@ _monitor_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
level_score_count += 10;
sound_play_vag(sfx_pop, 0);
// Create explosion effect
PoolObject *explosion = object_pool_create(OBJ_EXPLOSION);
explosion->freepos.vx = (pos->vx << 12);
explosion->freepos.vy = (pos->vy << 12);
explosion->state.anim_state.animation = 0; // Small explosion
// TODO: This should be the behaviour of our monitor particles
switch(((MonitorExtra *)state->extra)->kind) {
case MONITOR_KIND_RING:
@ -495,3 +503,13 @@ _spikes_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
}
}
}
static void
_explosion_update(ObjectState *state, ObjectTableEntry *, VECTOR *)
{
// Explosions are simple particles: their animation is finished?
// If so, destroy.
if(state->anim_state.animation == OBJ_ANIMATION_NO_ANIMATION)
state->props |= OBJ_FLAG_DESTROYED;
}

View file

@ -262,8 +262,8 @@ screen_level_draw(void *d)
/* render_model(&data->ring); */
render_lvl(&leveldata, &map128, &map16, &obj_table_common, camera.pos.vx, camera.pos.vy);
object_pool_render(&obj_table_common, camera.pos.vx, camera.pos.vy);
render_lvl(&leveldata, &map128, &map16, &obj_table_common, camera.pos.vx, camera.pos.vy);
parallax_draw(&data->parallax, &camera);
// Gouraud-shaded cube

View file

@ -26,16 +26,21 @@ class DummyObjectId(Enum):
class ObjectId(Enum):
RING = 0
MONITOR = 1
SPIKES = 2
CHECKPOINT = 3
SPRING_YELLOW = 4
SPRING_RED = 5
SPRING_YELLOW_DIAGONAL = 6
SPRING_RED_DIAGONAL = 7
SWITCH = 8
GOAL_SIGN = 9
RING = 0x00
MONITOR = 0x01
SPIKES = 0x02
CHECKPOINT = 0x03
SPRING_YELLOW = 0x04
SPRING_RED = 0x05
SPRING_YELLOW_DIAGONAL = 0x06
SPRING_RED_DIAGONAL = 0x07
SWITCH = 0x08
GOAL_SIGN = 0x09
# Certain objects simply cannot be placed.
# This happens when the object in question is a particle
# or effect.
EXPLOSION = 0x0a
@staticmethod
def get(name):
@ -50,6 +55,7 @@ class ObjectId(Enum):
"spring_red_diagonal": ObjectId.SPRING_RED_DIAGONAL,
"goal_sign": ObjectId.GOAL_SIGN,
"switch": ObjectId.SWITCH,
"explosion": ObjectId.EXPLOSION,
}
result = switch.get(name.lower())
assert result is not None, f"Unknown common object {name}"

View file

@ -11,6 +11,7 @@ enum CommonId: s8 {
SPRING_RED_DIAGONAL = 7,
GOAL_SIGN = 8,
SWITCH = 9,
EXPLOSION = 10,
};
bitfield FlipMask {