Hello all, since the Frogger Challenge I have been hard at work doing some cleanup in my "engine" and adding a few features that were missing from the first challenge. Specifically, I was able to add add in a state machine as well as figured out how to use SFML for poller based input. I decided that I didn't have enough of one type of art to fully flesh out the graphics of a dungeon crawler, they were all a bit mismatched and I decided to forego frankensteining it together, so I went over to Oryx Design Labs and got their Ultimate Fantasy Tileset!
One of my first major hurdles was that I decided I wanted to use tile based movement rather than the free movement that I used in the Frogger Challenge. I'm trying to slightly mimic the kind of motion i see in Sproggiwood and Paper Dungeons Crawler. I visited the forums for a while and ended up coming up with my own flavor of tile based movement that I believe at least is a close match to what I'm seeing in these games. I wanted diagonal movement, but I wanted everything locked to the tiles. and I think I have accomplished that at this time! See Below:
2018-12-24_00-10-03.mp4
This was more of a task than I thought it would be, but here is the code that makes it work, I'm definitely open to some suggestions here!
Firstly, input!
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if(gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->setVelocity(XMFLOAT3{ float(.025) * dt,float(.025) * dt, 0 });
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x + 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y + 1;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->setVelocity(XMFLOAT3{ float(-.025) * dt,float(.025) * dt, 0 });
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x - 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y + 1;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) && sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->setVelocity(XMFLOAT3{ float(.025) * dt,float(-.025) * dt, 0 });
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x + 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y - 1;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) && sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->setVelocity(XMFLOAT3{ float(-.025) * dt,float(-.025) * dt, 0 });
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x - 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y - 1;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->getPhysics()->SetVelocityX(float(.025) * dt);
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x + 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->getPhysics()->SetVelocityX(float(-.025) * dt);
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x - 1;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->getPhysics()->SetVelocityY(float(.025) * dt);
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y + 1;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
if (gameobjects[0]->getPhysics()->inMotion == false)
{
gameobjects[0]->getPhysics()->SetVelocityY(float(-.025) * dt);
gameobjects[0]->nextmapcoords.x = gameobjects[0]->mapcoords.x;
gameobjects[0]->nextmapcoords.y = gameobjects[0]->mapcoords.y - 1;
}
}
So, I had to add some information to my gameobject class. Specifically, map coordinates, and next map coordinates. Then I had to limit my input to only when inmotion is false, which will be false whenever I have successfully locked to a tile. Now, to make all the map coordinates work correctly, I needed to be able to update the next map coordinates and current map coordinates in my game object update loop, using this code:
void Game::UpdateMapPosition(GameObject * object)
{
XMFLOAT3A objectpos = object->getPosition();
int xcount = floor(objectpos.x / map->tileSizeX);
int ycount = floor(objectpos.y / map->tileSizeY);
object->mapcoords.x = xcount;
object->mapcoords.y = ycount;
XMFLOAT3A pos = map->At(xcount, ycount);
if (object->currentDirection == Facing::UP_RIGHT || object->currentDirection == Facing::DOWN_LEFT)
{
if (pos.x == map->At(object->nextmapcoords.x, object->nextmapcoords.y).x)
{
object->getPhysics()->SetVelocityX(0);
}
else if (pos.y == map->At(object->nextmapcoords.x, object->nextmapcoords.y).y)
{
object->getPhysics()->SetVelocityY(0);
}
}
else if (object->currentDirection == Facing::UP_LEFT || object->currentDirection == Facing::DOWN_RIGHT)
{
if (pos.x == map->At(object->nextmapcoords.x, object->nextmapcoords.y).x)
{
object->getPhysics()->SetVelocityX(0);
}
else if (pos.y == map->At(object->nextmapcoords.x, object->nextmapcoords.y).y)
{
object->getPhysics()->SetVelocityY(0);
}
}
else if(object->currentDirection == Facing::RIGHT || object->currentDirection == Facing::LEFT)
{
if (pos.x == map->At(object->nextmapcoords.x, object->nextmapcoords.y).x)
{
object->getPhysics()->SetVelocityX(0);
}
else if (pos.y == map->At(object->nextmapcoords.x, object->nextmapcoords.y).y)
{
object->getPhysics()->SetVelocityY(0);
}
}
else if(object->currentDirection == Facing::UP || object->currentDirection == Facing::DOWN)
{
if (pos.y == map->At(object->nextmapcoords.x, object->nextmapcoords.y).y)
{
object->getPhysics()->SetVelocityY(0);
}
else if (pos.y == map->At(object->nextmapcoords.x, object->nextmapcoords.y).y)
{
object->getPhysics()->SetVelocityY(0);
}
}
}
Again, definitely open to suggestions for cleanup here, this is what I was able to throw together given my current knowledge and understanding. The end result is definitely functional though! The next thing I think I want to do is incorporate the mouse in some kind of way, but I haven't thought up any ideas yet, lets here what you think! There are a few things I like about this setup, and of course a few that I don't like. I think the code is pretty easy to read, and I like that. However, It feels a bit bloated and large for the job its actually accomplishing, definitely some room for some tidying up and optimization.
Anyways I think I've made a good start for the next challenge. What's next? Maybe make some of my objects interactable, like boxes and crates and junk. Loot is, I believe, the biggest part of the requirement, aside from beating the bad guys!
Lol, I should really examine my code before i post it. So many redundant if else statements!