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:
slipyx 2018-07-28 22:17:56 -04:00
parent cf8d944a80
commit 985338f814
7 changed files with 80 additions and 14 deletions

10
draw.c
View File

@ -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
View File

@ -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) );
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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() {
}
}
}

View File

@ -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
View File

@ -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