10 changed files with 249 additions and 0 deletions
@ -0,0 +1,80 @@
|
||||
# Bomb and Explosion Sprites |
||||
sprites_ascii = { |
||||
"bomb_3": [ |
||||
" ## ", |
||||
" #### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" #### ", |
||||
" " |
||||
], |
||||
"bomb_2": [ |
||||
" ", |
||||
" ## ", |
||||
" #### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" #### ", |
||||
" ", |
||||
" " |
||||
], |
||||
"bomb_1": [ |
||||
" ", |
||||
" ", |
||||
" ## ", |
||||
" #### ", |
||||
" #### ", |
||||
" ## ", |
||||
" ", |
||||
" " |
||||
], |
||||
"exp_center": [ |
||||
"## ##", |
||||
"# # # #", |
||||
" #### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" #### ", |
||||
"# # # #", |
||||
"## ##" |
||||
], |
||||
"exp_horiz": [ |
||||
" ", |
||||
" ", |
||||
"########", |
||||
" ###### ", |
||||
" ###### ", |
||||
"########", |
||||
" ", |
||||
" " |
||||
], |
||||
"exp_vert": [ |
||||
" #### ", |
||||
" #### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" ###### ", |
||||
" #### ", |
||||
" #### " |
||||
] |
||||
} |
||||
|
||||
print("const unsigned char BombSpriteData[] = {") |
||||
for name, data in sprites_ascii.items(): |
||||
print(f" // {name}") |
||||
bytes_arr = [] |
||||
for row in data: |
||||
lb = 0 |
||||
hb = 0 |
||||
for x, char in enumerate(row): |
||||
if char == '#': |
||||
lb |= (1 << (7 - x)) |
||||
hb |= (1 << (7 - x)) |
||||
bytes_arr.append(lb) |
||||
bytes_arr.append(hb) |
||||
hex_str = ", ".join([f"0x{b:02X}" for b in bytes_arr]) |
||||
print(f" {hex_str},") |
||||
print("};") |
||||
@ -0,0 +1,109 @@
|
||||
#include "bomb.h" |
||||
#include "maze.h" |
||||
#include "rat.h" |
||||
#include "music.h" |
||||
#include <gb/gb.h> |
||||
|
||||
extern const unsigned char BombSpriteData[]; |
||||
|
||||
#define BOMB_STATE_INACTIVE 0 |
||||
#define BOMB_STATE_TICKING 1 |
||||
#define BOMB_STATE_EXPLODING 2 |
||||
|
||||
typedef struct { |
||||
uint8_t state; |
||||
uint8_t x; |
||||
uint8_t y; |
||||
uint16_t timer; |
||||
} Bomb; |
||||
|
||||
static Bomb bomb; |
||||
|
||||
void init_bombs(void) { |
||||
bomb.state = BOMB_STATE_INACTIVE; |
||||
set_sprite_data(5, 6, BombSpriteData); |
||||
for(uint8_t i = 34; i <= 38; i++) { |
||||
move_sprite(i, 0, 0); |
||||
} |
||||
} |
||||
|
||||
void drop_bomb(uint8_t x, uint8_t y) { |
||||
if (bomb.state == BOMB_STATE_INACTIVE) { |
||||
bomb.state = BOMB_STATE_TICKING; |
||||
bomb.x = x; |
||||
bomb.y = y; |
||||
bomb.timer = 180; // 3 seconds
|
||||
play_sfx_plop(); // Generic drop sound
|
||||
} |
||||
} |
||||
|
||||
static void hide_explosion() { |
||||
for(uint8_t i = 34; i <= 38; i++) { |
||||
move_sprite(i, 0, 0); |
||||
} |
||||
} |
||||
|
||||
static void do_explosion_damage(uint8_t ex, uint8_t ey) { |
||||
kill_rats_at(ex, ey); |
||||
} |
||||
|
||||
void update_bombs(void) { |
||||
if (bomb.state == BOMB_STATE_TICKING) { |
||||
bomb.timer--; |
||||
|
||||
uint8_t px = bomb.x * 8 + 12; |
||||
uint8_t py = bomb.y * 8 + 20; |
||||
|
||||
if (bomb.timer > 120) { |
||||
set_sprite_tile(38, 5); // bomb_3
|
||||
} else if (bomb.timer > 60) { |
||||
set_sprite_tile(38, 6); // bomb_2
|
||||
} else { |
||||
if (bomb.timer & 4) { |
||||
set_sprite_tile(38, 7); // bomb_1
|
||||
} else { |
||||
set_sprite_tile(38, 5); |
||||
} |
||||
} |
||||
|
||||
move_sprite(38, px, py); |
||||
|
||||
if (bomb.timer == 0) { |
||||
bomb.state = BOMB_STATE_EXPLODING; |
||||
bomb.timer = 30; // 0.5s explosion
|
||||
|
||||
play_sfx_explosion(); |
||||
|
||||
set_sprite_tile(38, 8); |
||||
move_sprite(38, px, py); |
||||
do_explosion_damage(bomb.x, bomb.y); |
||||
|
||||
if (bomb.y > 0 && maze[bomb.y - 1][bomb.x] == 0) { |
||||
set_sprite_tile(34, 10); |
||||
move_sprite(34, px, py - 8); |
||||
do_explosion_damage(bomb.x, bomb.y - 1); |
||||
} |
||||
if (bomb.y < MAZE_HEIGHT - 1 && maze[bomb.y + 1][bomb.x] == 0) { |
||||
set_sprite_tile(35, 10); |
||||
move_sprite(35, px, py + 8); |
||||
do_explosion_damage(bomb.x, bomb.y + 1); |
||||
} |
||||
if (bomb.x > 0 && maze[bomb.y][bomb.x - 1] == 0) { |
||||
set_sprite_tile(36, 9); |
||||
move_sprite(36, px - 8, py); |
||||
do_explosion_damage(bomb.x - 1, bomb.y); |
||||
} |
||||
if (bomb.x < MAZE_WIDTH - 1 && maze[bomb.y][bomb.x + 1] == 0) { |
||||
set_sprite_tile(37, 9); |
||||
move_sprite(37, px + 8, py); |
||||
do_explosion_damage(bomb.x + 1, bomb.y); |
||||
} |
||||
} |
||||
} else if (bomb.state == BOMB_STATE_EXPLODING) { |
||||
bomb.timer--; |
||||
if (bomb.timer == 0) { |
||||
bomb.state = BOMB_STATE_INACTIVE; |
||||
hide_explosion(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
|
||||
#ifndef BOMB_H |
||||
#define BOMB_H |
||||
|
||||
#include <stdint.h> |
||||
|
||||
void init_bombs(void); |
||||
void drop_bomb(uint8_t x, uint8_t y); |
||||
void update_bombs(void); |
||||
|
||||
#endif |
||||
@ -0,0 +1,14 @@
|
||||
const unsigned char BombSpriteData[] = { |
||||
// bomb_3
|
||||
0x18, 0x18, 0x3C, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x3C, 0x3C, 0x00, 0x00, |
||||
// bomb_2
|
||||
0x00, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, |
||||
// bomb_1
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, |
||||
// exp_center
|
||||
0xC3, 0xC3, 0xA5, 0xA5, 0x3C, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x3C, 0x3C, 0xA5, 0xA5, 0xC3, 0xC3, |
||||
// exp_horiz
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, |
||||
// exp_vert
|
||||
0x3C, 0x3C, 0x3C, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x3C, 0x3C, 0x3C, 0x3C, |
||||
}; |
||||
Loading…
Reference in new issue