From 985338f81460df53528aba1b5efc44665e0b53d2 Mon Sep 17 00:00:00 2001 From: slipyx Date: Sat, 28 Jul 2018 22:17:56 -0400 Subject: [PATCH] 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. --- draw.c | 10 ++++++---- game.c | 2 ++ monster.c | 20 ++++++++++++++------ monster.h | 1 + player.c | 24 ++++++++++++++++++++++-- player.h | 1 + world.c | 36 ++++++++++++++++++++++++++++++++++-- 7 files changed, 80 insertions(+), 14 deletions(-) diff --git a/draw.c b/draw.c index c31e2f7..4d25e3e 100644 --- a/draw.c +++ b/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 ); } } diff --git a/game.c b/game.c index d658b25..4d853c3 100644 --- a/game.c +++ b/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) ); } diff --git a/monster.c b/monster.c index c8b33c9..365bae8 100644 --- a/monster.c +++ b/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; + } + } } diff --git a/monster.h b/monster.h index 0ae73cf..e477943 100644 --- a/monster.h +++ b/monster.h @@ -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 diff --git a/player.c b/player.c index 42d4f9e..4530680 100644 --- a/player.c +++ b/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() { } } } + diff --git a/player.h b/player.h index 26abae6..6095972 100644 --- a/player.h +++ b/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; diff --git a/world.c b/world.c index 3672cd8..c4397d2 100644 --- a/world.c +++ b/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