sprite: path: morcus.gif size: [16, 32] # Geometria de col·lisió. `size` és la caixa contra murs/sarcs; # `hit_size`, la caixa contra altres actors (més petita); `height`, # l'alçada que un salt ha de superar per passar per damunt. collision: size: 16 base_size: 16 hit_size: 8 height: 12 animations: # Les variants `*_west` reaprofiten els frames de l'est i declaren # `flip_h: true` perquè el motor d'animació apliqui el flip al sprite — # el codi del joc no toca mai `flip_` directament. stand_south: { frames: [0] } stand_north: { frames: [4] } stand_east: { frames: [8] } stand_west: { frames: [8], flip_h: true } jump_south: { frames: [12] } jump_north: { frames: [13] } jump_east: { frames: [14] } jump_west: { frames: [14], flip_h: true } stun_south: { frames: [16] } stun_north: { frames: [17] } stun_east: { frames: [18] } stun_west: { frames: [18], flip_h: true } walk_south: { frames: [0, 1, 2, 3], frame_ms: 100 } walk_north: { frames: [4, 5, 6, 7], frame_ms: 100 } walk_east: { frames: [8, 9, 10, 11], frame_ms: 100 } walk_west: { frames: [8, 9, 10, 11], frame_ms: 100, flip_h: true } hurt_south: { frames: [0, 1, 2, 3], frame_ms: 100 } hurt_north: { frames: [4, 5, 6, 7], frame_ms: 100 } hurt_east: { frames: [8, 9, 10, 11], frame_ms: 100 } hurt_west: { frames: [8, 9, 10, 11], frame_ms: 100, flip_h: true } attack_south: { frames: [20, 21, 22, 23], frame_ms: 50 } attack_north: { frames: [24, 25, 26, 27], frame_ms: 50 } attack_east: { frames: [28, 29, 30, 31], frame_ms: 50 } attack_west: { frames: [28, 29, 30, 31], frame_ms: 50, flip_h: true } recover_south: { frames: [23] } recover_north: { frames: [27] } recover_east: { frames: [31] } recover_west: { frames: [31], flip_h: true } # Animació de mort: 3 voltes horàries començant pel sud (south → # west → north → east, repetit 3×). Reaprofita els frames stand_*; el # west és l'east amb `flip_h: true` declarat per-frame (mapping form, # no hereta del nivell d'anim). `frame_ms` per-frame creix linealment # per donar la sensació de desaccelerar fins a aturar-se. `loop: false` # → es queda al darrer frame i marca completed. death_spinning: frames: - 0 - { index: 8, flip_h: true } - 4 - 8 - 0 - { index: 8, flip_h: true } - 4 - 8 - 0 - { index: 8, flip_h: true } - 4 - 8 frame_ms: [60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280] loop: false # Mort per caiguda a un agujero (DeathCause::HOLE). `loop: false` perquè # `animationIsCompleted()` dispari el respawn timer determinísticament. death_hole: frames: [15] frame_ms: 60 loop: false # Inèrcia de frenada en soltar la direcció. `threshold_ms` filtra # tocs curts (passets d'un tile sense rellisquera). inertia: brake_time_ms: 150 threshold_ms: 300 # Gir de 180°: durant `duration_ms` el facing es fixa a la direcció # intermèdia indicada (purament visual). turn: duration_ms: 80 transitions: west_to_east: south east_to_west: north north_to_south: east south_to_north: west # Salt vertical (px de z, no toca la posició al món). # `shadow_y_offset`: puja la sombra per compensar la franja # transparent sota els peus del sprite. jump: impulse: 200 gravity: 600 landing_stun_ms: 400 shadow_y_offset: 3 sound: jump.wav land_sound: land.wav # Projecció post-impacte: surt cap a la direcció amb més recorregut # lliure i frena fins a 0 en `brake_time_ms`. hurt: speed: 120 brake_time_ms: 500 sound: hurt.wav # Atac amb làtigo. `range_tiles` és la longitud abans de retallar # contra murs/sarcs; `cooldown_ms` allarga ATTACKING amb una # recuperació en què la hitbox ja no fa dany. whip: range_tiles: 3 swing_ms: 200 cooldown_ms: 200 damage: 1 sound: whip.wav # Mort + respawn. `respawn_delay_ms` és la pausa entre la fi de # `death_spinning` i la reaparició al spawn. `lives` és el comptador # inicial d'intents (estil Mario): cada respawn el decrementa en 1, pot # anar a negatius (no hi ha game over). death: respawn_delay_ms: 500 lives: 3