Continue elevators

This commit is contained in:
Miloslav Číž 2019-09-27 03:34:49 +02:00
parent 5c1c54bea2
commit e1b52492ca
3 changed files with 99 additions and 48 deletions

View File

@ -11,4 +11,9 @@
*/ */
#define SFG_PLAYER_MOVE_SPEED 5 #define SFG_PLAYER_MOVE_SPEED 5
/**
How quickly elevators and squeezers move, in RCL_Unit per second.
*/
#define SFG_MOVING_WALL_SPEED 1024
#endif // guard #endif // guard

View File

@ -51,6 +51,11 @@ typedef uint8_t SFG_MapArray[SFG_MAP_SIZE * SFG_MAP_SIZE];
bbbbbb: index into tile dictionary bbbbbb: index into tile dictionary
*/ */
#define SFG_TILE_PROPERTY_NORMAL 0x00
#define SFG_TILE_PROPERTY_ELEVATOR 0x40
#define SFG_TILE_PROPERTY_SQUEEZER 0x80
#define SFG_TILE_PROPERTY_DOOR 0xc0
typedef struct typedef struct
{ {
SFG_MapArray mapArray; SFG_MapArray mapArray;
@ -70,26 +75,20 @@ static inline SFG_TileDefinition SFG_getMapTile
( (
const SFG_Map *map, const SFG_Map *map,
int16_t x, int16_t x,
int16_t y int16_t y,
uint8_t *properties
) )
{ {
if (x < 0 || x >= SFG_MAP_SIZE || y < 0 || y >= SFG_MAP_SIZE) if (x < 0 || x >= SFG_MAP_SIZE || y < 0 || y >= SFG_MAP_SIZE)
{
*properties = SFG_TILE_PROPERTY_NORMAL;
return SFG_OUTSIDE_TILE; return SFG_OUTSIDE_TILE;
}
return map->tileDictionary[map->mapArray[y * SFG_MAP_SIZE + x] & 0x3f]; uint8_t tile = map->mapArray[y * SFG_MAP_SIZE + x];
}
static inline uint8_t SFG_getMapTileProperties *properties = tile & 0xc0;
( return map->tileDictionary[tile & 0x3f];
const SFG_Map *map,
int16_t x,
int16_t y
)
{
if (x < 0 || x >= SFG_MAP_SIZE || y < 0 || y >= SFG_MAP_SIZE)
return 0;
return map->mapArray[y * SFG_MAP_SIZE + x] & 0xc0;
} }
static const SFG_Level SFG_level0 = static const SFG_Level SFG_level0 =
@ -100,7 +99,7 @@ static const SFG_Level SFG_level0 =
.tileDictionary = .tileDictionary =
{ {
SFG_TD(0 ,31,0,0),SFG_TD(15,63,5,0),SFG_TD(28,63,1,0),SFG_TD(6 ,63,6,0), // 0 SFG_TD(0 ,31,0,0),SFG_TD(15,63,5,0),SFG_TD(28,63,1,0),SFG_TD(6 ,63,6,0), // 0
SFG_TD(3 ,31,4,0),SFG_TD(4 ,63,4,0),SFG_TD(5 ,63,4,0),SFG_TD(1 ,10,1,0), // 4 SFG_TD(10,28,4,0),SFG_TD(4 ,63,4,0),SFG_TD(5 ,63,4,0),SFG_TD(1 ,10,1,0), // 4
SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 8 SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 8
SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 12 SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 12
SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 16 SFG_TD(0 ,31,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0),SFG_TD(0 ,63,0,0), // 16
@ -119,6 +118,7 @@ static const SFG_Level SFG_level0 =
.mapArray = .mapArray =
{ {
#define o 0 #define o 0
#define AA (0x04 | SFG_TILE_PROPERTY_ELEVATOR)
1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
@ -126,7 +126,7 @@ static const SFG_Level SFG_level0 =
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,AA,o ,o ,o ,o ,o ,AA,3 ,3 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , 1 ,o ,o ,o ,o ,o ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
@ -184,6 +184,7 @@ static const SFG_Level SFG_level0 =
o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o , o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,o ,
#undef o #undef o
#undef A
} }
} }
}; };

109
main.c
View File

@ -54,6 +54,11 @@ void SFG_init();
#include "raycastlib.h" #include "raycastlib.h"
/**
Step in which walls get higher, in raycastlib units.
*/
#define SFG_WALL_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 4)
RCL_Camera SFG_camera; RCL_Camera SFG_camera;
RCL_RayConstraints SFG_rayConstraints; RCL_RayConstraints SFG_rayConstraints;
@ -68,18 +73,9 @@ struct
const SFG_Map *mapPointer; const SFG_Map *mapPointer;
const SFG_Level *levelPointer; const SFG_Level *levelPointer;
const uint8_t* textures[7]; const uint8_t* textures[7];
uint32_t timeStart;
} SFG_currentLevel; } SFG_currentLevel;
void SFG_setLevel(const SFG_Level *level)
{
SFG_currentLevel.levelPointer = level;
SFG_currentLevel.mapPointer = &(level->map);
for (uint8_t i = 0; i < 7; ++i)
SFG_currentLevel.textures[i] =
SFG_texturesWall[level->map.textureIndices[i]];
}
void SFG_pixelFunc(RCL_PixelInfo *pixel) void SFG_pixelFunc(RCL_PixelInfo *pixel)
{ {
uint8_t color; uint8_t color;
@ -139,27 +135,59 @@ void SFG_pixelFunc(RCL_PixelInfo *pixel)
RCL_Unit SFG_texturesAt(int16_t x, int16_t y) RCL_Unit SFG_texturesAt(int16_t x, int16_t y)
{ {
SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y); uint8_t properties;
SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y,&properties);
return SFG_TILE_FLOOR_TEXTURE(tile) | (SFG_TILE_CEILING_TEXTURE(tile) << 3); return SFG_TILE_FLOOR_TEXTURE(tile) | (SFG_TILE_CEILING_TEXTURE(tile) << 3);
// ^ store both textures (floor and ceiling) in one number // ^ store both textures (floor and ceiling) in one number
} }
RCL_Unit SFG_movingWallHeight
(
RCL_Unit low,
RCL_Unit high,
uint32_t time
)
{
RCL_Unit height = high - low;
RCL_Unit halfHeight = height / 2;
RCL_Unit sinArg =
(time * ((SFG_MOVING_WALL_SPEED * RCL_UNITS_PER_SQUARE) / 1000)) / height;
return
low + halfHeight + (RCL_sinInt(sinArg) * halfHeight) / RCL_UNITS_PER_SQUARE;
}
RCL_Unit SFG_floorHeightAt(int16_t x, int16_t y) RCL_Unit SFG_floorHeightAt(int16_t x, int16_t y)
{ {
SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y); uint8_t properties;
return SFG_TILE_FLOOR_HEIGHT(tile) * (RCL_UNITS_PER_SQUARE / 4); SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y,&properties);
return properties != SFG_TILE_PROPERTY_ELEVATOR ?
SFG_TILE_FLOOR_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP :
SFG_movingWallHeight(
SFG_TILE_FLOOR_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP,
SFG_TILE_CEILING_HEIGHT(tile) * SFG_WALL_HEIGHT_STEP,
SFG_getTimeMs() - SFG_currentLevel.timeStart);
} }
#define SFG_CEILING_MAX_HEIGHT (32 * RCL_UNITS_PER_SQUARE)
RCL_Unit SFG_ceilingHeightAt(int16_t x, int16_t y) RCL_Unit SFG_ceilingHeightAt(int16_t x, int16_t y)
{ {
SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y); uint8_t properties;
SFG_TileDefinition tile = SFG_getMapTile(&(SFG_level0.map),x,y,&properties);
if (properties == SFG_TILE_PROPERTY_ELEVATOR)
return SFG_CEILING_MAX_HEIGHT;
uint8_t height = SFG_TILE_CEILING_HEIGHT(tile); uint8_t height = SFG_TILE_CEILING_HEIGHT(tile);
return height != SFG_TILE_CEILING_MAX_HEIGHT ? return height != SFG_TILE_CEILING_MAX_HEIGHT ?
((SFG_TILE_FLOOR_HEIGHT(tile) + height) * (RCL_UNITS_PER_SQUARE / 4)) : ((SFG_TILE_FLOOR_HEIGHT(tile) + height) * SFG_WALL_HEIGHT_STEP) :
(RCL_UNITS_PER_SQUARE * 32); SFG_CEILING_MAX_HEIGHT;
} }
uint32_t SFG_frame; uint32_t SFG_frame;
@ -196,7 +224,34 @@ void SFG_init()
#define SFG_PLAYER_MOVE_UNITS_PER_FRAME\ #define SFG_PLAYER_MOVE_UNITS_PER_FRAME\
((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) ((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS)
RCL_Vector2D playerDirection; 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_currentLevel.levelPointer = level;
SFG_currentLevel.mapPointer = &(level->map);
for (uint8_t i = 0; i < 7; ++i)
SFG_currentLevel.textures[i] =
SFG_texturesWall[level->map.textureIndices[i]];
SFG_currentLevel.timeStart = SFG_getTimeMs();
SFG_recompurePLayerDirection();
}
/** /**
Performs one game step (logic, physics), happening SFG_MS_PER_FRAME after Performs one game step (logic, physics), happening SFG_MS_PER_FRAME after
@ -218,27 +273,17 @@ void SFG_gameStep()
} }
if (recomputeDirection) if (recomputeDirection)
{ SFG_recompurePLayerDirection();
SFG_camera.direction = RCL_wrap(SFG_camera.direction,RCL_UNITS_PER_SQUARE);
playerDirection = RCL_angleToDirection(SFG_camera.direction);
playerDirection.x = (playerDirection.x * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE;
playerDirection.y = (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;
}
if (SFG_keyPressed(SFG_KEY_UP)) if (SFG_keyPressed(SFG_KEY_UP))
{ {
SFG_camera.position.x += playerDirection.x; SFG_camera.position.x += SFG_playerDirection.x;
SFG_camera.position.y += playerDirection.y; SFG_camera.position.y += SFG_playerDirection.y;
} }
else if (SFG_keyPressed(SFG_KEY_DOWN)) else if (SFG_keyPressed(SFG_KEY_DOWN))
{ {
SFG_camera.position.x -= playerDirection.x; SFG_camera.position.x -= SFG_playerDirection.x;
SFG_camera.position.y -= playerDirection.y; SFG_camera.position.y -= SFG_playerDirection.y;
} }
if (SFG_keyPressed(SFG_KEY_A)) if (SFG_keyPressed(SFG_KEY_A))