Added death for monsters and player on collision with each other as well as bullet collision. Added dead timer with explosion sprite drawing. Reverted monsters drawing with center origin. Added player lives functionality. Added hardcoded monster start for level 4.
This commit is contained in:
parent
cf8d944a80
commit
985338f814
10
draw.c
10
draw.c
|
@ -40,7 +40,9 @@ void Draw_Player( SDL_Renderer* r ) {
|
|||
}
|
||||
// jump tile
|
||||
else if ( gs->ps.do_jump || !gs->ps.on_ground )
|
||||
til = gs->ps.last_dir >= 0 ? 67 : 68;
|
||||
til = gs->ps.last_dir >= 0 ? 67 : 68;
|
||||
// dead
|
||||
if ( gs->ps.dead_timer ) til = 129;
|
||||
|
||||
// render
|
||||
// grounded debug
|
||||
|
@ -75,10 +77,10 @@ void Draw_Monsters( SDL_Renderer* r ) {
|
|||
for ( int i = 0; i < sizeof(gs->ms) / sizeof(gs->ms[0]); ++i ) {
|
||||
monster_state_t* m = &gs->ms[i];
|
||||
if ( m->type ) {
|
||||
dst.x = m->px - gs->view_x * TILE_SIZE - 12;
|
||||
dst.y = TILE_SIZE + m->py - 10;
|
||||
dst.x = m->px - gs->view_x * TILE_SIZE;// - 12;
|
||||
dst.y = TILE_SIZE + m->py;// - 10;
|
||||
dst.w = 24; dst.h = 20;
|
||||
til = m->type;
|
||||
til = m->dead_timer ? 129 : m->type;
|
||||
SDL_RenderCopy( r, g_assets->tile_tx[til], NULL, &dst );
|
||||
}
|
||||
}
|
||||
|
|
2
game.c
2
game.c
|
@ -14,6 +14,8 @@ static void G_Init() {
|
|||
|
||||
// clean player state
|
||||
memset( &gs->ps, 0, sizeof(player_state_t) );
|
||||
// 3 lives per game
|
||||
gs->ps.lives = 255;
|
||||
// clean monster states
|
||||
memset( gs->ms, 0, sizeof(gs->ms) );
|
||||
}
|
||||
|
|
20
monster.c
20
monster.c
|
@ -6,7 +6,7 @@ extern game_state_t* gs;
|
|||
void M_Move() {
|
||||
for ( int i = 0; i < sizeof(gs->ms) / sizeof(gs->ms[0]); ++i ) {
|
||||
monster_state_t* m = &gs->ms[i];
|
||||
if ( m->type ) {
|
||||
if ( m->type && !m->dead_timer ) {
|
||||
if ( !m->npx && !m->npy ) {
|
||||
m->npx = gs->levels[gs->current_level].path[m->path_index];
|
||||
m->npy = gs->levels[gs->current_level].path[m->path_index + 1];
|
||||
|
@ -34,13 +34,14 @@ void M_Fire() {
|
|||
if ( !gs->mbullet_px && !gs->mbullet_py ) {
|
||||
for ( int i = 0; i < sizeof(gs->ms) / sizeof(gs->ms[0]); ++i ) {
|
||||
monster_state_t* m = &gs->ms[i];
|
||||
if ( m->type && W_IsVisible( m->px ) && W_IsClear( m->px, m->py, 0 ) ) {
|
||||
// assumed size of 24x20
|
||||
if ( m->type && !m->dead_timer && W_IsVisible( m->px ) && W_IsClear( m->px+12, m->py+10, 0 ) ) {
|
||||
gs->mbullet_dir = gs->ps.px < m->px ? -1 : 1;
|
||||
if ( gs->mbullet_dir == 1 )
|
||||
gs->mbullet_px = m->px;
|
||||
gs->mbullet_px = m->px + 18;
|
||||
if ( gs->mbullet_dir == -1 )
|
||||
gs->mbullet_px = m->px - 20;
|
||||
gs->mbullet_py = m->py;// + 8;
|
||||
gs->mbullet_px = m->px - 10;
|
||||
gs->mbullet_py = m->py + 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +51,14 @@ void M_UpdateBullet() {
|
|||
if ( !gs->mbullet_px || !gs->mbullet_py ) return;
|
||||
if ( !W_IsClear( gs->mbullet_px, gs->mbullet_py, 0 ) || !W_IsVisible( gs->mbullet_px ) )
|
||||
gs->mbullet_px = gs->mbullet_py = 0;
|
||||
if ( gs->mbullet_px )
|
||||
if ( gs->mbullet_px ) {
|
||||
gs->mbullet_px += gs->mbullet_dir * 4;
|
||||
uint8_t tx = gs->mbullet_px / TILE_SIZE;
|
||||
uint8_t ty = gs->mbullet_py / TILE_SIZE;
|
||||
if ( tx == gs->ps.tx && ty == gs->ps.ty && !gs->ps.dead_timer ) {
|
||||
gs->mbullet_px = gs->mbullet_py = 0;
|
||||
gs->ps.dead_timer = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
typedef struct {
|
||||
uint8_t type; // type and tile index
|
||||
uint8_t dead_timer;
|
||||
uint8_t path_index; // current point in path
|
||||
uint8_t tx, ty; // tile pos
|
||||
int16_t px, py; // pixel pos
|
||||
|
|
24
player.c
24
player.c
|
@ -26,6 +26,7 @@ void P_Spawn() {
|
|||
gs->ps.do_fire = 0;
|
||||
gs->ps.do_jetpack = 0;
|
||||
gs->ps.do_up = 0; gs->ps.do_down = 0;
|
||||
gs->ps.dead_timer = 0;
|
||||
|
||||
// hardcoded player starts
|
||||
switch ( gs->current_level ) {
|
||||
|
@ -69,6 +70,7 @@ void P_PickupItem() {
|
|||
|
||||
// update collision point clear flags
|
||||
void P_UpdateCollision() {
|
||||
if ( gs->ps.dead_timer ) return;
|
||||
// 8 points of collision; relative to top left of tile 56 neutral frame (20x16)
|
||||
// 0, 1 = top left, top right
|
||||
gs->ps.col_point[0] = W_IsClear( gs->ps.px + 4, gs->ps.py - 0, 1 );
|
||||
|
@ -91,20 +93,35 @@ void P_UpdateBullet() {
|
|||
// skip if no bullet in world
|
||||
if ( !gs->ps.bullet_px || !gs->ps.bullet_py ) return;
|
||||
|
||||
gs->ps.bullet_px += gs->ps.bullet_dir * 4;
|
||||
|
||||
// collision
|
||||
if ( !W_IsClear( gs->ps.bullet_px, gs->ps.bullet_py, 0 ) )
|
||||
gs->ps.bullet_px = gs->ps.bullet_py = 0;
|
||||
|
||||
// off-screen
|
||||
uint8_t tx = gs->ps.bullet_px / TILE_SIZE;
|
||||
uint8_t ty = gs->ps.bullet_py / TILE_SIZE;
|
||||
if ( tx - gs->view_x < 0 || tx - gs->view_x > 20 )
|
||||
gs->ps.bullet_px = gs->ps.bullet_py = 0;
|
||||
|
||||
if ( gs->ps.bullet_px ) {
|
||||
gs->ps.bullet_px += gs->ps.bullet_dir * 4;
|
||||
|
||||
for ( int i = 0; i < sizeof(gs->ms) / sizeof(gs->ms[0]); ++i ) {
|
||||
monster_state_t* m = &gs->ms[i];
|
||||
if ( m->type && !m->dead_timer ) {
|
||||
if ( (ty == m->ty || ty == m->ty + 1) && (tx == m->tx || tx == m->tx + 1) ) {
|
||||
gs->ps.bullet_px = gs->ps.bullet_py = 0;
|
||||
m->dead_timer = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validate input whose try flags were set
|
||||
void P_VerifyInput() {
|
||||
// no input when dead
|
||||
if ( gs->ps.dead_timer ) return;
|
||||
// right; col points 2, 3
|
||||
if ( gs->ps.try_right && gs->ps.col_point[2] && gs->ps.col_point[3] ) {
|
||||
gs->ps.do_right = 1;
|
||||
|
@ -145,6 +162,7 @@ void P_VerifyInput() {
|
|||
|
||||
// apply validated player movement
|
||||
void P_Move() {
|
||||
if ( gs->ps.dead_timer ) return;
|
||||
// update player's tile pos
|
||||
// sample x towards the center
|
||||
gs->ps.tx = (gs->ps.px + TILE_SIZE / 2) / TILE_SIZE;
|
||||
|
@ -208,6 +226,7 @@ void P_Move() {
|
|||
|
||||
// apply gravity to player
|
||||
void P_ApplyGravity() {
|
||||
if ( gs->ps.dead_timer ) return;
|
||||
if ( !gs->ps.do_jump && !gs->ps.on_ground && !gs->ps.do_jetpack ) {
|
||||
// check below sprite
|
||||
if ( W_IsClear( gs->ps.px + 4, gs->ps.py + 17, 0 ) && W_IsClear( gs->ps.px + 10, gs->ps.py + 17, 0 ) )
|
||||
|
@ -221,3 +240,4 @@ void P_ApplyGravity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
player.h
1
player.h
|
@ -29,6 +29,7 @@ typedef struct {
|
|||
uint8_t do_up, do_down;
|
||||
|
||||
uint8_t jump_timer;
|
||||
uint8_t dead_timer;
|
||||
// pickup tile pos
|
||||
uint8_t check_pickup_x;
|
||||
uint8_t check_pickup_y;
|
||||
|
|
36
world.c
36
world.c
|
@ -23,6 +23,11 @@ void W_StartLevel() {
|
|||
gs->ms[1].px = 59 * TILE_SIZE;
|
||||
gs->ms[1].py = 4 * TILE_SIZE;
|
||||
} break;
|
||||
case 3: { // level 4, one monster
|
||||
gs->ms[0].type = 93;
|
||||
gs->ms[0].px = 32 * TILE_SIZE;
|
||||
gs->ms[0].py = 2 * TILE_SIZE;
|
||||
} break;
|
||||
}
|
||||
|
||||
// reset items
|
||||
|
@ -35,6 +40,7 @@ void W_StartLevel() {
|
|||
// hard reset current level from original data
|
||||
void W_ResetLevel() {
|
||||
Util_GetLevel( gs->current_level, &gs->levels[gs->current_level] );
|
||||
gs->ps.lives = 255;
|
||||
W_StartLevel();
|
||||
}
|
||||
|
||||
|
@ -58,7 +64,7 @@ uint8_t W_IsClear( int16_t px, int16_t py, uint8_t is_player ) {
|
|||
if ( til >= 29 && til <= 30 ) return 0;
|
||||
|
||||
// player collision functionality
|
||||
if ( is_player ) {
|
||||
if ( is_player && !gs->ps.dead_timer ) {
|
||||
// adjusted tile collision
|
||||
SDL_Rect colbox;
|
||||
colbox.x = (tx - gs->view_x) * TILE_SIZE + 2;
|
||||
|
@ -71,7 +77,8 @@ uint8_t W_IsClear( int16_t px, int16_t py, uint8_t is_player ) {
|
|||
if ( til == 6 || til == 25 || til == 36 ) {
|
||||
if ( SDL_PointInRect( &colpt, &colbox ) ) {
|
||||
//return 0;
|
||||
P_Spawn();
|
||||
//P_Spawn();
|
||||
gs->ps.dead_timer = 30;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +123,31 @@ void W_Update() {
|
|||
gs->ps.check_door = 0;
|
||||
}
|
||||
}
|
||||
// update dead timers
|
||||
if ( gs->ps.dead_timer ) {
|
||||
gs->ps.dead_timer--;
|
||||
if ( !gs->ps.dead_timer ) {
|
||||
if ( gs->ps.lives ) {
|
||||
gs->ps.lives--;
|
||||
P_Spawn();
|
||||
} else gs->quit = 1;
|
||||
}
|
||||
}
|
||||
// monsters
|
||||
for ( int i = 0; i < sizeof(gs->ms) / sizeof(gs->ms[0]); ++i ) {
|
||||
monster_state_t* m = &gs->ms[i];
|
||||
if ( m->type ) {
|
||||
if ( m->dead_timer ) {
|
||||
m->dead_timer--;
|
||||
if ( !m->dead_timer ) { m->type = 0; }
|
||||
} else { // player and monster collision
|
||||
if ( m->tx == gs->ps.tx && m->ty == gs->ps.ty ) {
|
||||
m->dead_timer = 30;
|
||||
gs->ps.dead_timer = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update game view based on set scroll values
|
||||
|
|
Loading…
Reference in New Issue