I am working on a grid based game in c++. I am using this project to learn c++ syntax and get stronger with some programming concepts in general so fairly beginner level programmer here. The problem I am having is with player movement and detection of the walls. Its probably something pretty obvious that I am missing but I have been staring at the code for hours so probably overlooking something. The map is built using an array by dividing the pixels on the screen into 8x8 squares. each one of those elements in the array are given a value based on what tile should be built in that part of the map. Currently the player cant move therefor the collision is being detected even though the player is not hitting a wall.
*** edited the code again - the player can now move. but then eventually there is a collision no where near the wall and then it crashes
void Game::playerMove()
{
//set the hspd and vspd based on the keys being pressed
hspd = ((wnd.kbd.KeyIsPressed(VK_RIGHT)) - (wnd.kbd.KeyIsPressed(VK_LEFT)));
vspd = ((wnd.kbd.KeyIsPressed(VK_DOWN)) - (wnd.kbd.KeyIsPressed(VK_UP)));
//check for collision horizontally
if (gridCollision(pX + hspd, pY))
{
hspd = 0;
}
//move horizontally
pX += hspd;
//check for collision vertically
if (gridCollision(pX, pY + vspd))
{
vspd = 0;
}
//move vertically
pY += vspd;
}
bool Game::gridCollision(int x, int y)
{
int xx = x;
int yy = y;
//remember the position
int curX = x;
int curY = y;
pX = xx;
pY = yy;
//Collisions within the grid.
//The players 'map' position/bounding box tile position
int rgtBbox = mapXpos(pX + 8);
int leftBbox = mapXpos(pX);
int botBbox = mapYpos(pY + 8);
int topBbox = mapYpos(pY);
//Check for collision in the map tiles.
bool x_collision = ((map[rgtBbox][topBbox] != floor) || (map[leftBbox][topBbox]) != floor);
pX = curX;
bool y_collision = ((map[rgtBbox][botBbox] != floor) || (map[rgtBbox][topBbox]) != floor);
pY = curY;
return x_collision || y_collision;
}
int Game::mapXpos(int x)
{
int mapXval = 0;
for (int i = x; i < 8; i -= 8)
{
mapXval += 1;
}
return mapXval;
}
int Game::mapYpos(int y)
{
int mapYval = 0;
for (int i = y; i < 8; i -= 8)
{
mapYval += 1;
}
return mapYval;
}
there is only something off with the collision detection when moving the player.
fyi the map builder is working great so far. It builds a room where the player starts and generates more rooms off of that room if there is enough space to build it.
IT DOES THE THING.
there is a small off by one pixel error right now but that's okay. Here is the solution:
void Game::playerMove()
{
getInput();
//set the hspd and vspd based on the keys being pressed
hspd = rightKey - leftKey;
vspd = downKey - upKey;
//check for collision horizontally
if (gridCollision(pX + hspd, pY))
{
while (!gridCollision(pX + signFunc(hspd), pY))
{
pX += signFunc(hspd);
}
hspd = 0;
}
//move horizontally
pX += hspd;
//check for collision vertically
if (gridCollision(pX, pY + vspd))
{
while (!gridCollision(pX, pY + signFunc(vspd)))
{
pY += signFunc(vspd);
}
vspd = 0;
}
//move vertically
pY += vspd;
//Catch OutofBounds
if (pX < 0)
{
pX = 1;
}
else if (pX > ((mapWidth * tileWidth) - 8))
{
pX = (mapWidth * tileWidth) - 8;
}
if (pY < 0)
{
pY = 1;
}
else if (pY > ((mapHeight * tileHeight) - 8))
{
pY = (mapHeight * tileHeight) - 8;
}
}
bool Game::gridCollision(int x, int y)
{
//Collisions within the grid.
//The players 'map' position/bounding box tile position
int rgtBbox = mapXpos(x + 8);
int leftBbox = mapXpos(x);
int botBbox = mapYpos(y + 8);
int topBbox = mapYpos(y);
//Check for collision in the map tiles.
bool x_collision = ((map[rgtBbox][topBbox] != floor) || (map[leftBbox][topBbox]) != floor);
bool y_collision = ((map[rgtBbox][botBbox] != floor) || (map[rgtBbox][topBbox]) != floor);
return x_collision || y_collision;
}
int Game::mapXpos(int x)
{
int mapXval = 0;
for (int i = x; i > 8; i -= 8)
{
mapXval += 1;
}
return mapXval;
}
int Game::mapYpos(int y)
{
int mapYval = 0;
for (int i = y; i > 8; i -= 8)
{
mapYval += 1;
}
return mapYval;
}
int Game::signFunc(int a)
{
if (a > 0)
{
return 1;
}
else if (a < 0)
{
return -1;
}
else
{
return 0;
}
}
void Game::getInput()
{
if (wnd.kbd.KeyIsPressed(VK_RIGHT))
{
rightKey = 1;
}
else
{
rightKey = 0;
}
if (wnd.kbd.KeyIsPressed(VK_LEFT))
{
leftKey = 1;
}
else
{
leftKey = 0;
}
if (wnd.kbd.KeyIsPressed(VK_UP))
{
upKey = 1;
}
else
{
upKey = 0;
}
if (wnd.kbd.KeyIsPressed(VK_DOWN))
{
downKey = 1;
}
else
{
downKey = 0;
}
}