Hi, I’m new here, sorry in advance. I’m starting with SDL and game development as a whole and decided to open random Youtube tutorial and create my first game (Sokoban) in C++ using SDL. I have a big issue though. Player has no movement. I’ve looked, compared code and I can’t see where the problem lies. Can anyone help?
player.h:
#pragma once
#include “game.h”
struct vec2 {
int x;
int y;
};
class Player {
public:
Player(class Game* g);
void move(int x, int y);
void draw(SDL_Renderer* renderer);
private:
vec2 pos;
SDL_Texture* texture;
SDL_Rect posRect, spriteRect;
class Game* game;
};
player.cpp:
#include “player.h”
Player::Player(Game* g) {
game = g;
texture = game->loadtexture(“textures/player.png”);
pos.x = 0;
pos.y = 0;
posRect = { pos.x, pos.y, TILE_SIZE, TILE_SIZE };
spriteRect = { 0, 0, TILE_SIZE, TILE_SIZE };
}
void Player::move(int x, int y) {
int newPlayerX = pos.x + x;
int newPlayerY = pos.y + y;
if (game->hitwall(newPlayerX, newPlayerY)) {
return;
}
pos.x = newPlayerX;
pos.y = newPlayerY;
posRect.x = pos.x * TILE_SIZE;
posRect.y = pos.y * TILE_SIZE;
}
void Player::draw(SDL_Renderer* renderer) {
SDL_RenderCopy(renderer, texture, &spriteRect, &posRect);
}
game.h:
#pragma once
#include “utils.h”
#include “level_manager.h”
#include “player.h”
class Game {
public:
bool init();
void gameloop();
void shutdown();
SDL_Texture* loadtexture(string path);
bool hitwall(int x, int y);
private:
void handleevents();
void update();
void draw();
bool isrunning = true;
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Texture* wall_tex = nullptr;
SDL_Texture* ground_tex = nullptr;
class level_manager* levelmanager;
class Player* player;
};
game.cpp:
#include “game.h”
bool Game::init() {
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) {
cout << "SDL failed to initialize: " << SDL_GetError() << endl;
return false;
}
if (IMG_Init(IMG_INIT_PNG) == 0) {
cout << "SDL_Image failed to initialize: " << IMG_GetError() << endl;
return false;
}
window = SDL_CreateWindow("Sokoban", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
if(!window) {
cout << "Window failed to initialize: " << SDL_GetError() << endl;
return false;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(!renderer) {
cout << "Renderer failed to initialize: " << SDL_GetError() << endl;
return false;
}
levelmanager = new level_manager();
levelmanager->loadlevel("levels/sokoban_lvl_test.txt");
wall_tex = loadtexture("textures/wall.png");
ground_tex = loadtexture("textures/ground.png");
player = new Player(this);
for (int i = 0; i < TILE_ROWS; i++) {
for (int j = 0; j < TILE_COLS; j++) {
if (levelmanager->levelmap[j][i] == 'p') {
player->move(j, i);
}
}
}
return true;
}
void Game::gameloop() {
while(isrunning) {
handleevents();
update();
draw();
}
}
void Game::handleevents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
isrunning = false;
}
}
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
player->move(1, 0);
break;
case SDLK_LEFT:
player->move(-1, 0);
break;
case SDLK_DOWN:
player->move(0, 1);
break;
case SDLK_UP:
player->move(0, -1);
break;
default:
break;
}
}
const Uint8* keystates = SDL_GetKeyboardState(NULL);
if (keystates[SDL_SCANCODE_ESCAPE]) {
isrunning = false;
}
}
void Game::update() {
}
void Game::draw() {
SDL_SetRenderDrawColor(renderer, 40, 40, 40, 255);
SDL_RenderClear(renderer);
for(int i = 0; i < TILE_ROWS; i++) {
for(int j = 0; j < TILE_COLS; j++) {
SDL_Rect rect = { j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE, TILE_SIZE };
if(levelmanager->levelmap[j][i] == 'x') {
SDL_RenderCopy(renderer, wall_tex, NULL, &rect);
} else {
SDL_RenderCopy(renderer, ground_tex, NULL, &rect);
}
//SDL_RenderFillRect(renderer, &rect);
}
}
player->draw(renderer);
SDL_RenderPresent(renderer);
}
void Game::shutdown() {
SDL_DestroyTexture(wall_tex);
SDL_DestroyTexture(ground_tex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
}
SDL_Texture* Game::loadtexture(string path) {
SDL_Surface* temp_s = IMG_Load(path.c_str());
if (temp_s == NULL) {
cout << "Failed to load surface: " << IMG_GetError() << endl;
}
SDL_Texture* newtex = SDL_CreateTextureFromSurface(renderer, temp_s);
if (newtex == NULL) {
cout << "Failed to conver the texture: " << SDL_GetError() << endl;
}
SDL_FreeSurface(temp_s);
return newtex;
}
bool Game::hitwall(int x, int y) {
return levelmanager->levelmap[x][y] == ‘x’;
}
Of course there is more code, like utils or levelmanager but this is those above are the only files where player is ever mentioned. Any help would be great