Edit My game updating too fast was exactly the problem. I now have a target variable called FPS. At the end of my loop I check the time, if the game is updating faster than my desired rate, I sleep for the extra time
I’m trying to get a rectangle to move when I press the “WASD” keys. I handle the movement code using a Movement struct to capture when keys are down or up, the functions handleKeyDown
, handleKeyUp
, and handleInput
. I’ve got the movement kind of working. If I use the keys “A”, or “W” it works, until I hit the end of the screen, then it gets stuck. If I try to move with the keys “D” or “S” the rectangle doesn’t move. I’m stumped as to why it’s only partially working
#include <stdio.h>
#include <SDL2/SDL.h>
#include <stdbool.h>
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
struct Movement {
bool up;
bool down;
bool left;
bool right;
};
struct Movement movement = {false, false, false, false};
void handleKeyDown(SDL_KeyboardEvent *event)
{
if (event->repeat == 0)
{
if (event->keysym.scancode == SDL_SCANCODE_W)
{
movement.up = true;
}
if (event->keysym.scancode == SDL_SCANCODE_S)
{
movement.down = true;
}
if (event->keysym.scancode == SDL_SCANCODE_A)
{
movement.left = true;
}
if (event->keysym.scancode == SDL_SCANCODE_D)
{
movement.right = true;
}
}
}
void handleKeyUp(SDL_KeyboardEvent *event)
{
if (event->repeat == 0)
{
if (event->keysym.scancode == SDL_SCANCODE_W)
{
movement.up = false;
}
if (event->keysym.scancode == SDL_SCANCODE_S)
{
movement.down = false;
}
if (event->keysym.scancode == SDL_SCANCODE_A)
{
movement.left = false;
}
if (event->keysym.scancode == SDL_SCANCODE_D)
{
movement.right = false;
}
}
}
void handleInput(void){
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
exit(0);
break;
case SDL_KEYDOWN:
handleKeyDown(&event.key);
break;
case SDL_KEYUP:
handleKeyUp(&event.key);
break;
default:
break;
}
}
}
int main() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
SDL_Window *window = SDL_CreateWindow("First Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, 0);
if (!window) {
printf("Failed to open %d x %d window: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_GetError());
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
printf("Failed to create renderer: %s\n", SDL_GetError());
exit(1);
}
// Rectangle properties
SDL_Rect player = {100, 100, 200, 100}; // x, y, width, height
double speed = 300.0; // Speed of movement in pixels per second
bool running = true;
double currentTime;
double lastTime = (double) SDL_GetTicks64();
// Event loop
while (running) {
currentTime = (double) SDL_GetTicks();
double deltaTime = (currentTime - lastTime) / 1000.0; // Delta time in seconds
lastTime = currentTime;
handleInput();
if (movement.up) {
player.y -= speed * deltaTime;
}
if (movement.down) {
player.y += speed * deltaTime;
}
if (movement.right) {
player.x += speed * deltaTime;
}
if (movement.left) {
player.x -= speed * deltaTime;
}
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
// Draw the rectangle
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // Red
SDL_RenderFillRect(renderer, &player);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}