Jump to content
  • Advertisement
Sign in to follow this  
The Pancake House

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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

Thanks for the quick reply!

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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:


000000000000
000000000000
000010000000
000010A00000
000010000000
00B011111100
000000000000
000000000000


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:

000000000000
000000000000
000000000000
000000100000
000000000000
000000000000
000000000000
000000000000


Next step, all tiles around the player are accessable:

000000000000
000000000000
000000200000
000002120000
000000200000
000000000000
000000000000
000000000000


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

000000000000
000000300000
000003230000
000002123000
000003230000
000000000000
000000000000
000000000000


Next step:

000000400000
000004340000
000003234000
000002123400
000003234000
000000000000
000000000000
000000000000


Next step, we get around the wall on top:

000005450000
000054345000
000003234500
000002123450
000003234500
000000000000
000000000000
000000000000


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 this post


Link to post
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 :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!