Player movement

This commit is contained in:
Miloslav Číž 2019-10-01 20:25:21 +02:00
parent 17f4da5714
commit be55322fe8
2 changed files with 96 additions and 46 deletions

View File

@ -4,12 +4,18 @@
/**
How quickly player turns left/right, in degrees per second.
*/
#define SFG_PLAYER_TURN_SPEED 180
#define SFG_PLAYER_TURN_SPEED 210
/**
How quickly player moves, in squares per second.
*/
#define SFG_PLAYER_MOVE_SPEED 5
#define SFG_PLAYER_MOVE_SPEED 10
/**
Gravity acceleration in squares / (second^2).
*/
#define SFG_GRAVITY_ACCELERATION 30
/**
How quickly elevators and squeezers move, in RCL_Unit per second.

132
main.c
View File

@ -62,13 +62,20 @@ void SFG_init();
#define SFG_PLAYER_TURN_UNITS_PER_FRAME\
((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS))
// TODO: ^ if zero, set to 1?
#define SFG_PLAYER_MOVE_UNITS_PER_FRAME\
((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS)
#define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME\
((SFG_GRAVITY_ACCELERATION * RCL_UNITS_PER_SQUARE) / (SFG_FPS * SFG_FPS))
#define RCL_PIXEL_FUNCTION SFG_pixelFunc
#define RCL_TEXTURE_VERTICAL_STRETCH 0
#define RCL_CAMERA_COLL_HEIGHT_BELOW 800
#define RCL_CAMERA_COLL_HEIGHT_ABOVE 100
#include "raycastlib.h"
/**
@ -79,12 +86,45 @@ void SFG_init();
#define SFG_CEILING_MAX_HEIGHT\
(16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 )
RCL_Camera SFG_camera;
RCL_RayConstraints SFG_rayConstraints;
uint8_t SFG_backgroundScaleMap[SFG_RESOLUTION_Y];
int8_t SFG_backgroundScaleMap[SFG_RESOLUTION_Y];
uint16_t SFG_backgroundScroll;
struct
{
RCL_Camera camera;
RCL_Vector2D direction;
RCL_Unit verticalSpeed;
} SFG_player;
void SFG_recompurePLayerDirection()
{
SFG_player.camera.direction = RCL_wrap(SFG_player.camera.direction,RCL_UNITS_PER_SQUARE);
SFG_player.direction = RCL_angleToDirection(SFG_player.camera.direction);
SFG_player.direction.x = (SFG_player.direction.x * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE;
SFG_player.direction.y = (SFG_player.direction.y * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE;
SFG_backgroundScroll =
((SFG_player.camera.direction * 8) * SFG_RESOLUTION_Y) / RCL_UNITS_PER_SQUARE;
}
void SFG_initPlayer()
{
RCL_initCamera(&SFG_player.camera);
SFG_player.camera.resolution.x = SFG_RESOLUTION_X / SFG_RAYCASTING_SUBSAMPLE;
SFG_player.camera.resolution.y = SFG_RESOLUTION_Y;
SFG_player.camera.height = RCL_UNITS_PER_SQUARE * 12;
SFG_player.camera.position.x = RCL_UNITS_PER_SQUARE * 15;
SFG_player.camera.position.y = RCL_UNITS_PER_SQUARE * 8;
SFG_recompurePLayerDirection();
SFG_player.verticalSpeed = 0;
}
RCL_RayConstraints SFG_rayConstraints;
/**
Stores the current level and helper precomputed vaues for better performance.
*/
@ -256,21 +296,6 @@ RCL_Unit SFG_ceilingHeightAt(int16_t x, int16_t y)
uint32_t SFG_frame;
uint32_t SFG_lastFrameTimeMs;
RCL_Vector2D SFG_playerDirection;
void SFG_recompurePLayerDirection()
{
SFG_camera.direction = RCL_wrap(SFG_camera.direction,RCL_UNITS_PER_SQUARE);
SFG_playerDirection = RCL_angleToDirection(SFG_camera.direction);
SFG_playerDirection.x = (SFG_playerDirection.x * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE;
SFG_playerDirection.y = (SFG_playerDirection.y * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE;
SFG_backgroundScroll =
((SFG_camera.direction * 8) * SFG_RESOLUTION_Y) / RCL_UNITS_PER_SQUARE;
}
void SFG_setLevel(const SFG_Level *level)
{
SFG_LOG("setting and initializing level");
@ -286,7 +311,7 @@ void SFG_setLevel(const SFG_Level *level)
SFG_currentLevel.timeStart = SFG_getTimeMs();
SFG_recompurePLayerDirection();
SFG_initPlayer();
}
void SFG_init()
@ -296,15 +321,8 @@ void SFG_init()
SFG_frame = 0;
SFG_lastFrameTimeMs = 0;
RCL_initCamera(&SFG_camera);
RCL_initRayConstraints(&SFG_rayConstraints);
SFG_camera.resolution.x = SFG_RESOLUTION_X / SFG_RAYCASTING_SUBSAMPLE;
SFG_camera.resolution.y = SFG_RESOLUTION_Y;
SFG_camera.height = RCL_UNITS_PER_SQUARE;
SFG_camera.position.x = RCL_UNITS_PER_SQUARE * 5;
SFG_camera.position.y = RCL_UNITS_PER_SQUARE * 5;
SFG_rayConstraints.maxHits = SFG_RAYCASTING_MAX_HITS;
SFG_rayConstraints.maxSteps = SFG_RAYCASTING_MAX_STEPS;
@ -324,35 +342,61 @@ void SFG_gameStep()
{
int8_t recomputeDirection = 0;
if (SFG_keyPressed(SFG_KEY_LEFT))
RCL_Vector2D moveOffset;
moveOffset.x = 0;
moveOffset.y = 0;
if (SFG_keyPressed(SFG_KEY_A))
{
SFG_camera.direction -= SFG_PLAYER_TURN_UNITS_PER_FRAME;
recomputeDirection = 1;
if (SFG_keyPressed(SFG_KEY_LEFT))
{
moveOffset.x = -1 * SFG_player.direction.y;
moveOffset.y = SFG_player.direction.x;
}
else if (SFG_keyPressed(SFG_KEY_RIGHT))
{
moveOffset.x = SFG_player.direction.y;
moveOffset.y = -1 * SFG_player.direction.x;
}
}
else if (SFG_keyPressed(SFG_KEY_RIGHT))
else
{
SFG_camera.direction += SFG_PLAYER_TURN_UNITS_PER_FRAME;
recomputeDirection = 1;
if (SFG_keyPressed(SFG_KEY_LEFT))
{
SFG_player.camera.direction -= SFG_PLAYER_TURN_UNITS_PER_FRAME;
recomputeDirection = 1;
}
else if (SFG_keyPressed(SFG_KEY_RIGHT))
{
SFG_player.camera.direction += SFG_PLAYER_TURN_UNITS_PER_FRAME;
recomputeDirection = 1;
}
if (recomputeDirection)
SFG_recompurePLayerDirection();
}
if (recomputeDirection)
SFG_recompurePLayerDirection();
SFG_player.verticalSpeed -= SFG_GRAVITY_SPEED_INCREASE_PER_FRAME;
if (SFG_keyPressed(SFG_KEY_UP))
{
SFG_camera.position.x += SFG_playerDirection.x * 5;
SFG_camera.position.y += SFG_playerDirection.y * 5;
moveOffset.x += SFG_player.direction.x;
moveOffset.y += SFG_player.direction.y;
}
else if (SFG_keyPressed(SFG_KEY_DOWN))
{
SFG_camera.position.x -= SFG_playerDirection.x;
SFG_camera.position.y -= SFG_playerDirection.y;
moveOffset.x -= SFG_player.direction.x;
moveOffset.y -= SFG_player.direction.y;
}
if (SFG_keyPressed(SFG_KEY_A))
SFG_camera.height += SFG_PLAYER_MOVE_UNITS_PER_FRAME;
else if (SFG_keyPressed(SFG_KEY_B))
SFG_camera.height -= SFG_PLAYER_MOVE_UNITS_PER_FRAME;
RCL_Unit previousHeight = SFG_player.camera.height;
RCL_moveCameraWithCollision(&(SFG_player.camera),moveOffset,
SFG_player.verticalSpeed,SFG_floorHeightAt,SFG_ceilingHeightAt,1,1);
SFG_player.verticalSpeed =
RCL_min(0,SFG_player.camera.height - previousHeight);
}
void SFG_mainLoopBody()
@ -377,7 +421,7 @@ void SFG_mainLoopBody()
}
// render noly once
RCL_renderComplex(SFG_camera,SFG_floorHeightAt,SFG_ceilingHeightAt,SFG_texturesAt,SFG_rayConstraints);
RCL_renderComplex(SFG_player.camera,SFG_floorHeightAt,SFG_ceilingHeightAt,SFG_texturesAt,SFG_rayConstraints);
SFG_lastFrameTimeMs = timeNow;
}