From 4e65d9f101f57daeecd245ffedfa1b92153b1971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Tue, 22 Oct 2019 01:34:40 +0200 Subject: [PATCH] Collide with monsters --- constants.h | 8 ++++- main.c | 91 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/constants.h b/constants.h index 28e2f36..3bca003 100644 --- a/constants.h +++ b/constants.h @@ -75,6 +75,12 @@ Distance at which level elements (sprites) collide, in RCL_Unit (1024 per square). */ -#define SFG_ELEMENT_COLLISION_DISTANCE 700 +#define SFG_ELEMENT_COLLISION_DISTANCE 800 + +/** + Distance at which explosion does damage and throws away the player and + monsters, in RCL_Units. +*/ +#define SFG_EXPLOSION_DISTANCE 2048 #endif // guard diff --git a/main.c b/main.c index b54fcc9..a0e0375 100755 --- a/main.c +++ b/main.c @@ -273,6 +273,7 @@ typedef struct } SFG_MonsterRecord; #define SFG_MONSTER_COORD_TO_RCL_UNITS(c) (c * 256) +#define SFG_MONSTER_COORD_TO_SQUARES(c) (c / 4) #define SFG_MONSTER_MASK_STATE 0x0f #define SFG_MONSTER_MASK_TYPE 0xf0 @@ -445,6 +446,12 @@ uint8_t SFG_random() return SFG_currentRandom; } +static inline RCL_Unit + SFG_taxicabDistance(RCL_Unit x0, RCL_Unit y0, RCL_Unit x1, RCL_Unit y1) +{ + return RCL_absVal(x0 - x1) + RCL_absVal(y0 - y1); +} + static inline uint8_t SFG_RCL_unitToZBuffer(RCL_Unit x) { x /= RCL_UNITS_PER_SQUARE; @@ -1155,14 +1162,15 @@ uint8_t SFG_createProjectile(SFG_ProjectileRecord projectile) */ void SFG_pushAway( RCL_Unit pos[3], - RCL_Vector2D center, + RCL_Unit centerX, + RCL_Unit centerY, RCL_Unit preferredDirection, RCL_Unit distance) { RCL_Vector2D fromCenter; - fromCenter.x = pos[0] - center.x; - fromCenter.y = pos[1] - center.y; + fromCenter.x = pos[0] - centerX; + fromCenter.y = pos[1] - centerY; RCL_Unit l = RCL_len(fromCenter); @@ -1197,6 +1205,23 @@ void SFG_pushAway( pos[2] = c.height; } +void SFG_pushPlayerAway(RCL_Unit centerX, RCL_Unit centerY, RCL_Unit distance) +{ + RCL_Unit p[3]; + + p[0] = SFG_player.camera.position.x; + p[1] = SFG_player.camera.position.y; + p[2] = SFG_player.camera.height; + + SFG_pushAway(p,centerX,centerY, + SFG_player.camera.direction - RCL_UNITS_PER_SQUARE / 2, + distance); + + SFG_player.camera.position.x = p[0]; + SFG_player.camera.position.y = p[1]; + SFG_player.camera.height = p[2]; +} + void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z) { SFG_ProjectileRecord explostion; @@ -1215,23 +1240,7 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z) SFG_createProjectile(explostion); -RCL_Unit p[3]; - -p[0] = SFG_player.camera.position.x; -p[1] = SFG_player.camera.position.y; -p[2] = SFG_player.camera.height; - -RCL_Vector2D center; - -center.x = x; -center.y = y; - -SFG_pushAway(p,center, - SFG_player.camera.direction - RCL_UNITS_PER_SQUARE / 2, 2 * RCL_UNITS_PER_SQUARE); - -SFG_player.camera.position.x = p[0]; -SFG_player.camera.position.y = p[1]; -SFG_player.camera.height = p[2]; + SFG_pushPlayerAway(x,y,SFG_EXPLOSION_DISTANCE); } /** @@ -1467,6 +1476,31 @@ SFG_createProjectile(p); SFG_player.squarePosition[1] = SFG_player.camera.position.y / RCL_UNITS_PER_SQUARE; + // handle player collision with level elements: + + for (uint8_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) + { + SFG_MonsterRecord *m = &(SFG_currentLevel.monsterRecords[i]); + + if ( + ((m->stateType & SFG_MONSTER_MASK_STATE) != SFG_MONSTER_STATE_INACTIVE) && + ( + SFG_taxicabDistance( + SFG_player.camera.position.x, + SFG_player.camera.position.y, + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]), + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1])) + <= SFG_ELEMENT_COLLISION_DISTANCE + ) + ) + { + SFG_pushPlayerAway( + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]), + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]), + SFG_ELEMENT_COLLISION_DISTANCE); + } + } + // update projectiles: uint8_t substractFrames = @@ -1516,10 +1550,11 @@ SFG_createProjectile(p); SFG_MONSTER_STATE_INACTIVE) { RCL_Unit distance = - RCL_absVal( - p->position[0] - SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0])) + - RCL_absVal( - p->position[1] - SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1])); + SFG_taxicabDistance( + p->position[0], + p->position[1], + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]), + SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1])); if (distance <= SFG_ELEMENT_COLLISION_DISTANCE) { @@ -1541,10 +1576,10 @@ SFG_createProjectile(p); SFG_currentLevel.levelPointer->elements[ item & ~SFG_ITEM_RECORD_ACTIVE_MASK]; - if ( - (RCL_absVal(p->position[0] - e.coords[0] * RCL_UNITS_PER_SQUARE) + - RCL_absVal(p->position[1] - e.coords[1] * RCL_UNITS_PER_SQUARE)) - <= SFG_ELEMENT_COLLISION_DISTANCE) + if (SFG_taxicabDistance(p->position[0],p->position[1], + e.coords[0] * RCL_UNITS_PER_SQUARE, + e.coords[1] * RCL_UNITS_PER_SQUARE) + <= SFG_ELEMENT_COLLISION_DISTANCE) { eliminate = 1; break;