1
\$\begingroup\$

I've just started getting into game development, SDL in particular, so please go easy on me. I'm struggling to understand why my player's position isn't chaning when I press the left arrow button.

main.cpp

#include <iostream>
#include "SDL2/SDL.h"
#include "SDL2/SDL_image.h"

typedef struct
{
  float x, y;
  SDL_Texture *sprite;
} Player;

int processEvents(SDL_Window *window, Player *player) {
    SDL_Event event;
    int done = 0;
    while(SDL_PollEvent(&event)) {
        switch(event.type) {
            case SDL_WINDOWEVENT_CLOSE: {
                if(window) {
                    SDL_DestroyWindow(window);
                    window = NULL;
                    done = 1;
                }
            }
            break;
            case SDL_QUIT: {
                done = 1;
            }
            break;
        }
    }

    const Uint8 *keyState = SDL_GetKeyboardState(NULL);
    if( keyState[SDL_SCANCODE_LEFT] ) {
      player->x = 120;
    }
    return done;
}

void render(SDL_Renderer *renderer, Player *player) {
    SDL_RenderClear(renderer);

    SDL_Rect playerRect;
    playerRect.x = 0;
    playerRect.y = 0;
    playerRect.w = 32;
    playerRect.h = 32;
    SDL_RenderCopy(renderer, player->sprite, NULL, &playerRect);
    SDL_RenderPresent(renderer);
}

void update(Player *player) {
     player->x += 10;
}

int main( int argc, char *args[] ) {
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_Event event;

    Player player;
    player.x = 50;
    player.y = 0;

    SDL_Init(SDL_INIT_EVERYTHING);
    window = SDL_CreateWindow("Dungeon", 100 , 100, 640, 480, SDL_WINDOW_SHOWN);
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    player.sprite = IMG_LoadTexture(renderer, "assets/player.png");

    int done = 0;
    while( !done ) {
        done = processEvents(window, &player);
        update(&player);
        render(renderer, &player);
    }
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    SDL_Quit;
    return 0;
}

Any help would be much appreciated.

Thanks :)

\$\endgroup\$
1
  • \$\begingroup\$ processEvents sets the player's x-position to the same value each frame, instead of incrementing it like update does. Either processEvents or update should handle player movement. Lastly, the dstRect (playerRect) for SDL_RenderCopy needs to use player->x and player->y to position on the window. The dstRect width and height you have are fine, but be aware that if the srcRect (player.sprite) width and height differ from that of the dstRect then SDL_RenderCopy will scale the player.sprite. \$\endgroup\$
    – TOM__
    Feb 26, 2017 at 9:56

1 Answer 1

1
\$\begingroup\$

Okay, so there are a number of things I want to comment on, however first of all, in your render function, you are never actually setting the position of the drawn rectangle to the position of the player:

SDL_Rect playerRect;
playerRect.x = player->x;
playerRect.y = player->y;
playerRect.w = player->x + 32;
playerRect.h = player->y + 32;

I can only assume the update function you had was not working either?


If this doesn't work, it may be to do with how the keyboard data is being fetched. I've only personally used the SDL_GetKeyState(..) function.

You can use it in a very similar way, but it definitely works well:

Uint8* keystate = SDL_GetKeyState(0);
if (keystate[SDLK_LEFT]) {
     player->x = 120;
}

As a personal design preference, I would also put the keyboard processing in the update function rather than the processEvents as you are polling the keyboard rather than waiting for incoming keypress events. (Though there is no difference in doing this, just organisation).


I understand this is a test project, however I feel it would be more productive for you to experiment and learn in a game engine environment rather than jumping straight into C++. I am only making assumptions of your experience from the code you have provided, however speaking from my own personal experience, it can be counter-productive to try and create games in C++ from the get go, simply because you will run into a lot of brick walls if you aren't all that experienced with the language. From another point of view, other engines can teach you strong skills in design patterns and program structure which do become increasingly important later on.

I would also say that pure SDL is pretty bad for game development. It is a reasonable "raw" rendering setup that is quick and easy to get setup, however is does not really provide many utility functions that aid in game development. I'd recommend SFML over SDL for this sort of thing, especially because it is a little bit more intuitive as well if you are focused on taking the C++ route. (SFML does a good job of abstracting away alot of the complexity)

\$\endgroup\$
1
  • \$\begingroup\$ + 1 for advice and SFML is pretty great for beginners. Love2D might also be worth a look. It is Lua bound to SDL and theres a few games made with it and its portable to mobile devices. \$\endgroup\$
    – Gambit
    Mar 1, 2017 at 3:45

You must log in to answer this question.