This commit is contained in:
Miloslav Číž 2020-07-29 21:19:53 +02:00
parent 1ec1d91a63
commit eaa683ecf3
2 changed files with 51 additions and 18 deletions

BIN
assets/levelC.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -26,7 +26,7 @@
author: Miloslav "drummyfish" Ciz author: Miloslav "drummyfish" Ciz
license: CC0 1.0 license: CC0 1.0
version: 0.906 version: 0.907
*/ */
#include <stdint.h> #include <stdint.h>
@ -1857,7 +1857,7 @@ void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset,
else\ else\
dir##Collides = floorHeightFunc(s1,s2) > RCL_CAMERA_COLL_STEP_HEIGHT; dir##Collides = floorHeightFunc(s1,s2) > RCL_CAMERA_COLL_STEP_HEIGHT;
// check a collision against non-diagonal square // check collision against non-diagonal square
#define collCheckOrtho(dir,dir2,s1,s2,x)\ #define collCheckOrtho(dir,dir2,s1,s2,x)\
if (dir##SquareNew != dir##Square)\ if (dir##SquareNew != dir##Square)\
{\ {\
@ -1882,39 +1882,72 @@ void RCL_moveCameraWithCollision(RCL_Camera *camera, RCL_Vector2D planeOffset,
int8_t yCollides = 0; int8_t yCollides = 0;
collCheckOrtho(y,x,xSquare,ySquareNew,0) collCheckOrtho(y,x,xSquare,ySquareNew,0)
#define collHandle(dir)\ if (xCollides || yCollides)
if (dir##Collides)\
cornerNew.dir = (dir##Square) * RCL_UNITS_PER_SQUARE +\
RCL_UNITS_PER_SQUARE / 2 + dir##Dir * (RCL_UNITS_PER_SQUARE / 2) -\
dir##Dir;\
if (!xCollides && !yCollides) /* if non-diagonal collision happend, corner
collision can't happen */
{ {
if (xSquare != xSquareNew && ySquare != ySquareNew) // corner? if (movesInPlane)
{
#define collHandle(dir)\
if (dir##Collides)\
cornerNew.dir = (dir##Square) * RCL_UNITS_PER_SQUARE +\
RCL_UNITS_PER_SQUARE / 2 + dir##Dir * (RCL_UNITS_PER_SQUARE / 2) -\
dir##Dir;\
collHandle(x)
collHandle(y)
#undef collHandle
}
else
{
/* Player collides without moving in the plane; this can happen e.g. on
elevators due to vertical only movement. This code can get executed
when force == 1. */
RCL_Vector2D squarePos;
RCL_Vector2D newPos;
squarePos.x = xSquare * RCL_UNITS_PER_SQUARE;
squarePos.y = ySquare * RCL_UNITS_PER_SQUARE;
newPos.x =
RCL_max(squarePos.x + RCL_CAMERA_COLL_RADIUS + 1,
RCL_min(squarePos.x + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1,
camera->position.x));
newPos.y =
RCL_max(squarePos.y + RCL_CAMERA_COLL_RADIUS + 1,
RCL_min(squarePos.y + RCL_UNITS_PER_SQUARE - RCL_CAMERA_COLL_RADIUS - 1,
camera->position.y));
cornerNew.x = corner.x + (newPos.x - camera->position.x);
cornerNew.y = corner.y + (newPos.y - camera->position.y);
}
}
else
{
/* If no non-diagonal collision is detected, a diagonal/corner collision
can still happen, check it here. */
if (xSquare != xSquareNew && ySquare != ySquareNew)
{ {
int8_t xyCollides = 0; int8_t xyCollides = 0;
collCheck(xy,xSquareNew,ySquareNew) collCheck(xy,xSquareNew,ySquareNew)
if (xyCollides) if (xyCollides)
{ {
// normally should slide, but let's KISS // normally should slide, but let's KISS and simply stop any movement
cornerNew = corner; cornerNew = corner;
} }
} }
} }
collHandle(x)
collHandle(y)
#undef collCheck #undef collCheck
#undef collHandle
camera->position.x = cornerNew.x - xDir * RCL_CAMERA_COLL_RADIUS; camera->position.x = cornerNew.x - xDir * RCL_CAMERA_COLL_RADIUS;
camera->position.y = cornerNew.y - yDir * RCL_CAMERA_COLL_RADIUS; camera->position.y = cornerNew.y - yDir * RCL_CAMERA_COLL_RADIUS;
} }
if (computeHeight && (movesInPlane || heightOffset != 0 || force)) if (computeHeight && (movesInPlane || (heightOffset != 0) || force))
{ {
camera->height += heightOffset; camera->height += heightOffset;