Hi,
I'm still quite a newb when it comes to C++ (or programming in general) and SFML so this is a project more for my personal learning and interest than anything else.
I've been stumped for a while now on how to implement a way to properly determine the possible movements in a turn-based grid game.
At first, I've implemented possible movements to be something like this:
Basically what happens is that when you click the banana button (just testing for now), the possible grids you can click on to move to gets filled with the colour yellow. After you click on one of those grids, the grids will stop showing and the sprite on the left will move to that grid (always x first, then y; I don't intend to make diagonal movements possible for now; also note that the sprite on the right doesn't do anything other than occupy a grid at the moment). Once the sprite finishes the movement, the banana button will appear again.
I threw in a check so that you cannot move to a grid already occupied by another entity and thought it was fine until I realised that while you cannot move to an occupied grid, you can still move
through them:
However, before I start working on trying to make it so it moves around the occupied grids instead of right through them, I needed to make sure the possible grid movement being shown is correct. There shouldn't be a yellow grid on the right of the non-moving stick entity since it would take more than 3 grids to get there (that is if you dont move
through him or diagonally).
I've been stumped on this for a long time, tried multiple different ways to implement this logic but I cannot come up with anything that works properly or consistently. I've tried to write nests and nests of IF statements instead of using loops , but it got way too messy to manage and I feel that there has to be an easier way.
Eventually, I've stripped it all down to movement in a straight line. If the grid is blocked, further grids beyond no longer gets shown:
This works fine, but obviously I want to also display grids beyond just a straight line. What would be a simple solution to implement this logic?
For reference, below are my current code for implementing the grids. I apologise in advance if they lack clarity, since I'm still quite a newb and may adopt practices and conventions that are not optimal. However, I've inserted comments and tried to explain what I did.
#include "TurnBasedBattle.hpp"
void TurnBasedBattle::drawGrid()
{
if (displayMoveGrid)
{
std::string tGridKey = gridMap[playerDrawList[0]->gridPosition].id; //player's current grid id
int tGridX = gridMap[playerDrawList[0]->gridPosition].getGridPositionX(); //grab player's artificial grid x-coordinate 1~14
int tGridY = gridMap[playerDrawList[0]->gridPosition].getGridPositionY(); //grab player's artificial grid y-coordinate 1~9
//std::cout<<"Position: "<<tGridX << ","<<tGridY<<std::endl;
int movePoints = 5;
int gridWidth = 14;
int gridHeight = 9;
int northLimit = movePoints;
int eastLimit = movePoints;
int southLimit = movePoints;
int westLimit = movePoints;
/***To make sure you do not move off the Gridboard***/
while ((tGridY - northLimit) < 1) --northLimit;
while ((tGridX + eastLimit) > gridWidth) --eastLimit;
while ((tGridY + southLimit) > gridHeight) --southLimit;
while ((tGridX - westLimit) < 1) --westLimit;
showPossibleGridMoves(eastLimit, "east");
showPossibleGridMoves(westLimit, "west");
showPossibleGridMoves(southLimit, "south");
showPossibleGridMoves(northLimit, "north");
}
}
void TurnBasedBattle::showPossibleGridMoves
(int & ref_dirLimit, std::string ref_dir)
{
GridStatus * ptr_gridstatus;
ptr_gridstatus = &gridMap[playerDrawList[0]->gridPosition]; //pointing to the the grid the player is on
for (int i = 0; i < ref_dirLimit; ++i) //ref_dirLimit is the number of movement in that direction possible
{
/**
* grabDir() allows access to grids next to the grid itself (north/east/south/west)
* every GridStatus contains pointers to north/east/south/west of the grid itself
* with nullptr assigned when there is no grid in that direction
**/
if (ptr_gridstatus->grabDir(ref_dir)->isBlocked() == false) //if not blocked, show next grid;
{
ptr_gridstatus = ptr_gridstatus->grabDir(ref_dir);
showGrid(*ptr_gridstatus);
}
}
}
void TurnBasedBattle::showGrid(GridStatus & ref_gridstatus)
{
ptr_mainWindow->draw(ref_gridstatus.mark);
mouse_position = sf::Mouse::getPosition(*ptr_mainWindow);
if (ref_gridstatus.checkMouse(mouse_position)) //if clicked
{
displayMoveGrid = false; //stops showing the display grids
gridMap[playerDrawList[0]->gridPosition].clear(); //gridPosition no longer occupied by player
//change the player's new gridPosition so that he gets moved in another cpp file...
playerDrawList[0]->gridPosition = ref_gridstatus.id;
}
}
Thanks for anyone who can help me this.
-Sine