Handle player motion (arrow keys)

This commit is contained in:
Camden Dixie O'Brien 2024-12-28 11:35:06 +00:00
parent 39e8002caf
commit fad49a7d15
2 changed files with 81 additions and 14 deletions

View File

@ -5,6 +5,7 @@ set_default_target_options(game)
target_include_directories(game PUBLIC include) target_include_directories(game PUBLIC include)
target_link_libraries(game PRIVATE target_link_libraries(game PRIVATE
m
LibXml2::LibXml2 LibXml2::LibXml2
SDL2::SDL2 SDL2::SDL2
SDL2::SDL2main SDL2::SDL2main

View File

@ -8,6 +8,8 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <libxml/parser.h> #include <libxml/parser.h>
#include <math.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#define SCALE 4 #define SCALE 4
@ -32,12 +34,28 @@
#define PIHEIGHT 64 #define PIHEIGHT 64
#define PIANIMLEN 8 #define PIANIMLEN 8
#define WALKSPEED 72 // pixels per second
#define BASEANIMPERIOD 200 #define BASEANIMPERIOD 200
typedef struct {
bool left, right, up, down;
} input_state_t;
typedef struct {
double x, y;
} dvec_t;
static SDL_Window *window; static SDL_Window *window;
static SDL_Renderer *renderer; static SDL_Renderer *renderer;
static unsigned map[MAPWIDTH][MAPHEIGHT]; static unsigned map[MAPWIDTH][MAPHEIGHT];
static SDL_Texture *tstex, *pitex; static SDL_Texture *tstex, *pitex;
static input_state_t input;
static inline double mag(dvec_t v)
{
return sqrt(v.x * v.x + v.y * v.y);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -144,25 +162,77 @@ int main(int argc, char *argv[])
assert(NULL != pitex); assert(NULL != pitex);
int offx = 16, offy = 0; int offx = 16, offy = 0;
const SDL_Rect pdest = { SDL_Rect psrc = { .y = 0, .w = PIWIDTH, .h = PIHEIGHT };
.x = SCALE * 80, SDL_Rect pdest = { .w = SCALE * PIWIDTH, .h = SCALE * PIHEIGHT };
.y = SCALE * 80, dvec_t pvel = { 0, 0 }, ppos = { 80, 80 };
.w = SCALE * PIWIDTH,
.h = SCALE * PIHEIGHT,
};
SDL_Event event; SDL_Event event;
uint64_t prevt = SDL_GetTicks64();
while (1) { while (1) {
// Calculate dt
const uint64_t t = SDL_GetTicks64();
const uint64_t dt = t - prevt;
prevt = t;
// Handle events // Handle events
SDL_PollEvent(&event); SDL_PollEvent(&event);
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_QUIT:
goto quit; goto quit;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_LEFT:
input.left = true;
break;
case SDLK_RIGHT:
input.right = true;
break;
case SDLK_UP:
input.up = true;
break;
case SDLK_DOWN:
input.down = true;
break;
default:
break;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_LEFT:
input.left = false;
break;
case SDLK_RIGHT:
input.right = false;
break;
case SDLK_UP:
input.up = false;
break;
case SDLK_DOWN:
input.down = false;
break;
default:
break;
}
break;
default: default:
break; break;
} }
// Calculate and apply velocity
pvel.x = (input.left ? -1 : 0) + (input.right ? 1 : 0);
pvel.y = (input.up ? -1 : 0) + (input.down ? 1 : 0);
const double pspeed = mag(pvel);
if (pspeed != 0) {
pvel.x *= WALKSPEED / pspeed;
pvel.y *= WALKSPEED / pspeed;
ppos.x += (double)dt / 1000.0 * pvel.x;
ppos.y += (double)dt / 1000.0 * pvel.y;
}
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
// Draw map // Draw map
@ -189,14 +259,10 @@ int main(int argc, char *argv[])
} }
// Draw player // Draw player
const unsigned piframe const unsigned piframe = (t / BASEANIMPERIOD) % PIANIMLEN;
= (SDL_GetTicks64() / BASEANIMPERIOD) % PIANIMLEN; psrc.x = PIWIDTH * piframe;
const SDL_Rect psrc = { pdest.x = SCALE * (int)ppos.x;
.x = PIWIDTH * piframe, pdest.y = SCALE * (int)ppos.y;
.y = 0,
.w = PIWIDTH,
.h = PIHEIGHT,
};
SDL_RenderCopy(renderer, pitex, &psrc, &pdest); SDL_RenderCopy(renderer, pitex, &psrc, &pdest);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);