Implement terrain collisions
This commit is contained in:
parent
f17530af4a
commit
c24cd75360
56
app/main.c
56
app/main.c
@ -34,11 +34,17 @@
|
|||||||
#define PWIDTH 48
|
#define PWIDTH 48
|
||||||
#define PHEIGHT 64
|
#define PHEIGHT 64
|
||||||
#define PANIMLEN 8
|
#define PANIMLEN 8
|
||||||
|
#define PFBWIDTH 12
|
||||||
|
#define PFBHEIGHT 6
|
||||||
|
#define PFBOFFX -6
|
||||||
|
#define PFBOFFY 6
|
||||||
|
|
||||||
#define WALKSPEED 72 // pixels per second
|
#define WALKSPEED 72 // pixels per second
|
||||||
|
|
||||||
#define BASEANIMPERIOD 100
|
#define BASEANIMPERIOD 100
|
||||||
|
|
||||||
|
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPRITE_DIR_DOWN = 0,
|
SPRITE_DIR_DOWN = 0,
|
||||||
SPRITE_DIR_LEFT_DOWN = 1,
|
SPRITE_DIR_LEFT_DOWN = 1,
|
||||||
@ -61,12 +67,34 @@ static SDL_Renderer *renderer;
|
|||||||
static unsigned map[MAPWIDTH][MAPHEIGHT];
|
static unsigned map[MAPWIDTH][MAPHEIGHT];
|
||||||
static SDL_Texture *tstex, *pidle, *pwalk, *ptex;
|
static SDL_Texture *tstex, *pidle, *pwalk, *ptex;
|
||||||
static input_state_t input;
|
static input_state_t input;
|
||||||
|
static dvec_t vpos = { 512, 0 };
|
||||||
|
static const unsigned passable[] = { 118, 178 };
|
||||||
|
|
||||||
static inline double mag(dvec_t v)
|
static inline double mag(dvec_t v)
|
||||||
{
|
{
|
||||||
return sqrt(v.x * v.x + v.y * v.y);
|
return sqrt(v.x * v.x + v.y * v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned tileat(double x, double y)
|
||||||
|
{
|
||||||
|
const unsigned row = (unsigned)floor(x / TILESIZE) + MAPSHIFTX;
|
||||||
|
const unsigned col = (unsigned)floor(y / TILESIZE) + MAPSHIFTY;
|
||||||
|
if (row >= MAPWIDTH || col >= MAPHEIGHT)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return map[row][col];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool tilepassable(int x, int y)
|
||||||
|
{
|
||||||
|
const unsigned id = tileat(x, y);
|
||||||
|
for (unsigned i = 0; i < NELEMS(passable); ++i) {
|
||||||
|
if (passable[i] == id)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char path[MAX_PATH_LEN];
|
char path[MAX_PATH_LEN];
|
||||||
@ -176,8 +204,7 @@ int main(int argc, char *argv[])
|
|||||||
pwalk = IMG_LoadTexture(renderer, path);
|
pwalk = IMG_LoadTexture(renderer, path);
|
||||||
assert(NULL != pwalk);
|
assert(NULL != pwalk);
|
||||||
|
|
||||||
// Initialize view and player
|
// Initialize player
|
||||||
dvec_t vpos = { 512, 0 };
|
|
||||||
SDL_Rect psrc = { .y = 0, .w = PWIDTH, .h = PHEIGHT };
|
SDL_Rect psrc = { .y = 0, .w = PWIDTH, .h = PHEIGHT };
|
||||||
SDL_Rect pdest = { .w = SCALE * PWIDTH, .h = SCALE * PHEIGHT };
|
SDL_Rect pdest = { .w = SCALE * PWIDTH, .h = SCALE * PHEIGHT };
|
||||||
dvec_t pvel = { 0, 0 }, ppos = { 640, 96 };
|
dvec_t pvel = { 0, 0 }, ppos = { 640, 96 };
|
||||||
@ -247,8 +274,21 @@ int main(int argc, char *argv[])
|
|||||||
if (pspeed != 0) {
|
if (pspeed != 0) {
|
||||||
pvel.x *= WALKSPEED / pspeed;
|
pvel.x *= WALKSPEED / pspeed;
|
||||||
pvel.y *= WALKSPEED / pspeed;
|
pvel.y *= WALKSPEED / pspeed;
|
||||||
ppos.x += (double)dt / 1000.0 * pvel.x;
|
|
||||||
ppos.y += (double)dt / 1000.0 * pvel.y;
|
// Check for terrain collision, update position if none
|
||||||
|
const double nextx = ppos.x + (double)dt / 1000.0 * pvel.x;
|
||||||
|
const double nexty = ppos.y + (double)dt / 1000.0 * pvel.y;
|
||||||
|
const dvec_t pfb
|
||||||
|
= { .x = nextx + PFBOFFX, .y = nexty + PFBOFFY };
|
||||||
|
bool valid = true;
|
||||||
|
valid &= tilepassable(pfb.x, pfb.y);
|
||||||
|
valid &= tilepassable(pfb.x + PFBWIDTH, pfb.y);
|
||||||
|
valid &= tilepassable(pfb.x, pfb.y + PFBHEIGHT);
|
||||||
|
valid &= tilepassable(pfb.x + PFBWIDTH, pfb.y + PFBHEIGHT);
|
||||||
|
if (valid) {
|
||||||
|
ppos.x = nextx;
|
||||||
|
ppos.y = nexty;
|
||||||
|
}
|
||||||
|
|
||||||
// Update direction
|
// Update direction
|
||||||
if (pvel.y >= 0) {
|
if (pvel.y >= 0) {
|
||||||
@ -267,7 +307,6 @@ int main(int argc, char *argv[])
|
|||||||
pdir = SPRITE_DIR_UP;
|
pdir = SPRITE_DIR_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set walkikng texture
|
|
||||||
ptex = pwalk;
|
ptex = pwalk;
|
||||||
} else {
|
} else {
|
||||||
ptex = pidle;
|
ptex = pidle;
|
||||||
@ -290,11 +329,7 @@ int main(int argc, char *argv[])
|
|||||||
const int starty = TILESIZE * floor(vpos.y / TILESIZE);
|
const int starty = TILESIZE * floor(vpos.y / TILESIZE);
|
||||||
for (int y = starty; y < vpos.y + VIEWHEIGHT; y += TILESIZE) {
|
for (int y = starty; y < vpos.y + VIEWHEIGHT; y += TILESIZE) {
|
||||||
for (int x = startx; x < vpos.x + VIEWWIDTH; x += TILESIZE) {
|
for (int x = startx; x < vpos.x + VIEWWIDTH; x += TILESIZE) {
|
||||||
const unsigned row = x / TILESIZE + MAPSHIFTX;
|
const unsigned tileid = tileat(x, y);
|
||||||
const unsigned col = y / TILESIZE + MAPSHIFTY;
|
|
||||||
if (row >= MAPWIDTH || col >= MAPHEIGHT)
|
|
||||||
continue;
|
|
||||||
const unsigned tileid = map[row][col];
|
|
||||||
if (0 == tileid)
|
if (0 == tileid)
|
||||||
continue;
|
continue;
|
||||||
const SDL_Rect src = {
|
const SDL_Rect src = {
|
||||||
@ -320,6 +355,7 @@ int main(int argc, char *argv[])
|
|||||||
pdest.x = SCALE * (int)(ppos.x - vpos.x - PWIDTH / 2);
|
pdest.x = SCALE * (int)(ppos.x - vpos.x - PWIDTH / 2);
|
||||||
pdest.y = SCALE * (int)(ppos.y - vpos.y - PHEIGHT / 2);
|
pdest.y = SCALE * (int)(ppos.y - vpos.y - PHEIGHT / 2);
|
||||||
SDL_RenderCopy(renderer, ptex, &psrc, &pdest);
|
SDL_RenderCopy(renderer, ptex, &psrc, &pdest);
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user