as you can see, the player stops midair and not exactly on top of the tile. I approached this in two ways with SDL_HasIntersection() and also with lazy foo’s collision method but in both cases it stops about 100px above and to the side of the tile. How can I fix this ?
Here’s Game.cpp file:
#include "Game.h"
SDL_Window* gWindow = nullptr;
SDL_Renderer* gRenderer = nullptr;
SDL_Rect dest{};
// HORIZONTAL
float speedX = 2.0f;
float rt_runStr = 8.5f;
float lt_runStr = 8.5f;
float maxX = 15.5f;
// VERTICAL
float speedY = 0.0f;
float gravity = 2.2f;
float jumpStr = 12.2f;
// flags
int rightK = 0;
int leftK = 0;
int up = 0;
int collision = 1;
Entity* player = nullptr;
Tile* newT = nullptr;
//Entity* tile = nullptr;
void Game::init(const char* title ,int x, int y, int w, int h, int flags) {
if (SDL_Init(SDL_INIT_EVERYTHING) == 0) {
// create window
gWindow = SDL_CreateWindow(title, x, y, w, h, flags);
if (gWindow != NULL) {
// create renderer
gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
isRunning = true;
}
else {
isRunning = false;
}
}
else {
isRunning = false;
}
player = new Entity;
player->loadTexture("assets/doux_00.png");
newT = new Tile;
newT->loadImg("assets/grass_tile.png");
//tile = new Entity;
}
void Game::handleEvent() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
isRunning = false;
break;
}
}
}
void Game::update() {
if (SDL_GetKeyboardState(0)[SDL_GetScancodeFromKey(SDLK_d)]) {
rightK = 1;
}
else {
rightK = 0;
}
if (SDL_GetKeyboardState(0)[SDL_GetScancodeFromKey(SDLK_a)]) {
leftK = 1;
}
else {
leftK = 0;
}
if (SDL_GetKeyboardState(0)[SDL_GetScancodeFromKey(SDLK_SPACE)]) {
up = 1;
}
else {
up = 0;
}
if (up == 1) {
gravity = 0;
}
if (rightK == 1) {
lt_runStr = 0.0f;
rt_runStr += 0.6f;
}
if (leftK == 1) {
rt_runStr = 0.0f;
lt_runStr += 0.6f;
}
if (rt_runStr >= maxX) {
rt_runStr = maxX;
lt_runStr = 0.0f;
}
if (lt_runStr >= maxX) {
lt_runStr = maxX;
rt_runStr = 0.0f;
}
/*if (SDL_HasIntersection(player->getRect(), tile->getTile())) {
collision = 0;
}
else {
collision = 1;
}
if (collision == 0) {
gravity = 0;
}*/
if (newT->isColliding(dest)) {
collision = 0;
}
else {
collision = 1;
}
if (collision == 0) {
gravity = 0;
}
speedX += (rightK * rt_runStr) - (leftK * lt_runStr);
gravity += 0.6f;
speedY += (collision * gravity) - (up * jumpStr);
}
void Game::render() {
SDL_RenderClear(gRenderer);
// ------------------------------------------
player->drawTexture(250, 200);
newT->drawTile(250, 350);
//tile->drawTile(250, 300, 150, 30);
// ------------------------------------------
SDL_SetRenderDrawColor(gRenderer, 67, 70, 75, 1);
SDL_RenderPresent(gRenderer);
}
void Game::clean() {
delete player;
//delete tile;
SDL_DestroyWindow(gWindow);
SDL_DestroyRenderer(gRenderer);
SDL_Quit();
}
Here’s Tile.cpp:
#include "Tile.h"
void Tile::loadImg(const char* path) {
texture = IMG_LoadTexture(gRenderer, path);
}
void Tile::drawTile(int x, int y) {
src.x = 0;
src.y = 0;
src.w = 32;
src.h = 32;
dest.x = x;
dest.y = y;
dest.w = src.w;
dest.h = src.h;
SDL_RenderCopy(gRenderer, texture, &src, &dest);
}
bool Tile::isColliding(SDL_Rect player) {
int right, right2;
int left, left2;
int top, top2;
int bottom, bottom2;
right = dest.x + dest.w;
left = dest.x;
top = dest.y;
bottom = dest.y + dest.h;
right2 = player.x + player.w;
left2 = player.x;
top2 = player.y;
bottom2 = player.y + player.h;
if (bottom2 == top) {
return true;
}
else {
return false;
}
}