Continue element collisions

This commit is contained in:
Miloslav Číž 2019-10-22 14:27:56 +02:00
parent 7841c518b2
commit 4452396ad2
3 changed files with 79 additions and 27 deletions

View File

@ -77,6 +77,12 @@
*/ */
#define SFG_ELEMENT_COLLISION_DISTANCE 800 #define SFG_ELEMENT_COLLISION_DISTANCE 800
/**
Height, in RCL_Units, at which collisions happen with level elements
(sprites).
*/
#define SFG_ELEMENT_COLLISION_HEIGHT 1024
/** /**
Distance at which explosion does damage and throws away the player and Distance at which explosion does damage and throws away the player and
monsters, in RCL_Units. monsters, in RCL_Units.

View File

@ -236,7 +236,7 @@ SFG_PROGRAM_MEMORY SFG_Level SFG_level0 =
10, // floorColor 10, // floorColor
32, // ceilingColor 32, // ceilingColor
{ // elements { // elements
{SFG_LEVEL_ELEMENT_BARREL, {9, 1}}, {SFG_LEVEL_ELEMENT_BARREL, {13, 3}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 1}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 13}},
{SFG_LEVEL_ELEMENT_BARREL, {12, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {15, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {12, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {15, 4}},
{SFG_LEVEL_ELEMENT_BARREL, {24, 10}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_BARREL, {24, 10}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_BARREL, {13, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {12, 6}}, {SFG_LEVEL_ELEMENT_BARREL, {13, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {12, 6}},

98
main.c
View File

@ -1291,6 +1291,29 @@ static inline const SFG_LevelElement *SFG_getActiveItemElement(uint8_t index)
~SFG_ITEM_RECORD_ACTIVE_MASK]); ~SFG_ITEM_RECORD_ACTIVE_MASK]);
} }
static inline uint8_t SFG_elementCollides(
RCL_Unit pointX,
RCL_Unit pointY,
RCL_Unit pointZ,
RCL_Unit elementX,
RCL_Unit elementY,
RCL_Unit elementHeight,
RCL_Unit heightMargin,
RCL_Unit widthMargin
)
{
return
(
SFG_taxicabDistance(pointX,pointY,elementX,elementY)
<= (SFG_ELEMENT_COLLISION_DISTANCE + widthMargin)
)
&&
(
(pointZ - heightMargin - elementHeight)
<= SFG_ELEMENT_COLLISION_HEIGHT
);
}
/** /**
Performs one game step (logic, physics), happening SFG_MS_PER_FRAME after Performs one game step (logic, physics), happening SFG_MS_PER_FRAME after
previous frame. previous frame.
@ -1507,15 +1530,19 @@ SFG_createProjectile(p);
mPos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]); mPos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]);
if ( if (
((m->stateType & SFG_MONSTER_MASK_STATE) != SFG_MONSTER_STATE_INACTIVE) && SFG_elementCollides(
( SFG_player.camera.position.x,
SFG_taxicabDistance( SFG_player.camera.position.y,
SFG_player.camera.position.x, SFG_player.camera.height,
SFG_player.camera.position.y, mPos.x,
mPos.x,mPos.y) mPos.y,
<= SFG_ELEMENT_COLLISION_DISTANCE + RCL_CAMERA_COLL_RADIUS SFG_floorHeightAt(
) SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]),
) SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])),
RCL_CAMERA_COLL_RADIUS / 2,
RCL_CAMERA_COLL_HEIGHT_BELOW
)
)
{ {
moveOffset = SFG_resolveCollisionWithElement( moveOffset = SFG_resolveCollisionWithElement(
SFG_player.camera.position,moveOffset,mPos); SFG_player.camera.position,moveOffset,mPos);
@ -1533,11 +1560,18 @@ SFG_createProjectile(p);
ePos.x = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]); ePos.x = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]);
ePos.y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]); ePos.y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]);
if (SFG_taxicabDistance( if (
SFG_player.camera.position.x, SFG_elementCollides(
SFG_player.camera.position.y, SFG_player.camera.position.x,
ePos.x,ePos.y) SFG_player.camera.position.y,
<= (SFG_ELEMENT_COLLISION_DISTANCE + RCL_CAMERA_COLL_RADIUS)) SFG_player.camera.height,
ePos.x,
ePos.y,
SFG_floorHeightAt(e->coords[0],e->coords[1]),
RCL_CAMERA_COLL_RADIUS / 2,
RCL_CAMERA_COLL_HEIGHT_BELOW
)
)
{ {
moveOffset = SFG_resolveCollisionWithElement( moveOffset = SFG_resolveCollisionWithElement(
SFG_player.camera.position,moveOffset,ePos); SFG_player.camera.position,moveOffset,ePos);
@ -1622,14 +1656,19 @@ SFG_createProjectile(p);
if ((m->stateType & SFG_MONSTER_MASK_STATE) != if ((m->stateType & SFG_MONSTER_MASK_STATE) !=
SFG_MONSTER_STATE_INACTIVE) SFG_MONSTER_STATE_INACTIVE)
{ {
RCL_Unit distance = if (
SFG_taxicabDistance( SFG_elementCollides(
p->position[0], p->position[0],
p->position[1], p->position[1],
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]), p->position[2],
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[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) SFG_floorHeightAt(
SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]),
SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])),
0,
0)
)
{ {
eliminate = 1; eliminate = 1;
break; break;
@ -1644,10 +1683,17 @@ SFG_createProjectile(p);
if (e != 0) if (e != 0)
{ {
if (SFG_taxicabDistance(p->position[0],p->position[1], if (
e->coords[0] * RCL_UNITS_PER_SQUARE, SFG_elementCollides(
e->coords[1] * RCL_UNITS_PER_SQUARE) p->position[0],
<= SFG_ELEMENT_COLLISION_DISTANCE) p->position[1],
p->position[2],
SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]),
SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]),
SFG_floorHeightAt(e->coords[0],e->coords[1]),
0,
0)
)
{ {
eliminate = 1; eliminate = 1;
break; break;