2d turn-based tile movement

This topic is 4515 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Now, im definately sure that this is probably a simple equation, but ive never been very good with nested loops. What I want to do is this: think back to games like Shining Force or Vandal Hearts, on the players turn they select a unit and up pops a highlighted portion of the map that the player can move within. So far im going for a simple highlight, ive got an array constructs itself and returns to the main form and writes into a label. But so far it creates a box, which I dont want. Ill show you what I want below. 0,0,0,0,0,0,0,0,0,0 0,0,0,0,3,0,0,0,0,0 0,0,0,3,2,3,0,0,0,0 0,0,3,2,1,2,3,0,0,0 0,3,2,1,X,1,2,3,0,0 0,0,3,2,1,2,3,0,0,0 0,0,0,3,2,3,0,0,0,0 0,0,0,0,3,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0 Say I have a 10 by 10 array, X is the current X,Y position of the selected Character. If his movement is 1 then he can move as far as the positions marked "1", if his movement is 2 then he can move as far as the positions marked "2" etc. Any help or points in the right direction here would be greatly appreciated :)

Share on other sites
Since your character can't move diagonally, you probably want what is sometimes called the 'Manhattan distance', that is, the sum of the displacements along the Cardinal axes of the space in question.

Here's some pseudocode that applies this to your situation. I'll assume that the grid is indexed as [x][y], and I'm going to ignore range-checking (you can add that yourself easily enough):
void HighlightCells(int x, int y, int distance){    for (int i = x - distance; i <= x + distance; ++i) {        for (int j = y - distance; j <= y + distance; ++j) {            if (abs(x-i) + abs(y-j) <= distance) {                cells[j].hightlighted = true;            }        }    }}
That should do what you want (assuming I didn't mess anything up).

Share on other sites
if (abs(x-i) + abs(y-j) <= distance)

So ^THATS^ what I was mising , i knew it was simple.

It isnt the entire solution but it is a step in the right direction, ill muck around with it and see if I can straighten it out, that general code returns this (X = 3, Y = 3, Distance = 3) (where "2" is where the user can move to and "X" is where the player started):

0,0,0,2,2,2,2,0,0,0
0,0,2,2,2,2,2,0,0,0
0,2,2,2,2,2,2,0,0,0
2,2,2,X,2,2,2,0,0,0
2,2,2,2,2,2,2,0,0,0
2,2,2,2,2,2,2,0,0,0
2,2,2,2,2,2,2,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0

Share on other sites
Okay ive got most of it working, its just the bottom-right corner thats beeing a nuisance.

This is the code that im using (posX = X Position, posY = Y Position, Mo = Movement, all integers)

(posX = 3, posY = 3, Mo = 3)

0,0,0,2,0,0,0,0,0,0
0,0,2,2,2,0,0,0,0,0
0,2,2,2,2,2,0,0,0,0
2,2,2,X,2,2,2,0,0,0
0,2,2,2,2,2,2,0,0,0
0,0,2,2,2,2,2,0,0,0
0,0,0,2,2,2,2,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0

This code returns that array above, what am I missing?

int[,] arrMove = new int[11,11];

for(int i = (posX - Mo); i <= (posX + Mo); i++)
{
for(int j = (posY - Mo); j <= (posY + Mo); j++)
{
if((posX - i) + (posY - j) <= Mo & (posX + i) - (posY + j) <= Mo)
{
if((posX + j) - (posY + i) <= Mo & (posX - j) + (posY - i) <= Mo)
{
arrMove[i,j] = 2;
}
}
}
}
arrMove[XLoc, YLoc] = 7;//Show Starting Point
return arrMove;

*Edit* Sorry for the lack of tabbing but for some reason both normal spaces and tab-spacers seem to not work...

Share on other sites
You should try it with absolute value, like in my earlier example. I didn't try to figure out what your code would do, but it seems unlikely that it would produce the correct results.

For proper formatting of code you can use [ source ][ /source ], or < pre >< /pre > for small snippets (remove the spaces from the tags).

Share on other sites
Your method is ok if you don't have any obstacles or walls in your map. Once you add those you can't use it anymore, since you suddenly might be able to walk through a wall.

The method i usually use is kind of recursive. You create a second array the same size of the map. Init this distance array to zero. Set the current location of your player to 1.

Now iterate max_walkable_distance times over the array. If an array spot equals the current iteration value check all four connecting tiles if they're walkable for the player. If they are, set the connecting tile value one higher than the current spot. Only do this if the connecting tile has not already a value set.

This method basically walks all possible tiles starting from the current player and will nicely walk around walls.

Some clarification, imagine the main map:

000000000000000000000000000010000000000010A0000000001000000000B011111100000000000000000000000000

Let A be the current player, B be his wanted target position and 1 be unwalkable tiles.

Now lets look at the distance array which will build step by step here:

Start out with the start location:
000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000

Next step, all tiles around the player are accessable:
000000000000000000000000000000200000000002120000000000200000000000000000000000000000000000000000

Next step, we hit the first wall to the left and down:
000000000000000000300000000003230000000002123000000003230000000000000000000000000000000000000000

Next step:
000000400000000004340000000003234000000002123400000003234000000000000000000000000000000000000000

Next step, we get around the wall on top:
000005450000000054345000000003234500000002123450000003234500000000000000000000000000000000000000

Of course you stop the iteration once you reach the players max walk count.

And yes, this method is fast enough, unless you use a 1024x1024 map. And even then probably.

Share on other sites
Well I do have a terrain array (Walls, switches, etc), a player array, and this was the selection/movement/attacking array, depending on what action was selected would determine which tiles needed to be highlighted, if you get what im saying.

Now that I think of it, that method will be easier than drawing the array, THEN having to code which tiles are unreachable/unwalkable. Ill work on it and if ive got any problems (I most probably will lol) ill post back here.

Thanks for the nudge in the right direction here Endurion, its been fun and frustrating getting my feet wet in these kinds of calculations :)

1. 1
2. 2
3. 3
4. 4
frob
11
5. 5

• 12
• 16
• 13
• 20
• 12
• Forum Statistics

• Total Topics
632175
• Total Posts
3004584

×