Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Tile-based RPG woes.

This thread is locked; no one can reply to it. rss feed Print
Tile-based RPG woes.
Taiko Keiji
Member #8,307
February 2007
avatar

I'm creating a tile-based RPG, it's 16*16 and I originally had it so that the caracter moved two pixels every time the D*pad was pressed. but I ran into a few problems with that,namely walking through items because it hadn't registered that the character was over it yet. But I was wondering if anyone had any sugestions as to how I can get the carachter to still move in this way but move over 1 tile. Just turn on your gameboy and pop in pokemon, you'll understand what I mean.

Life could be better, machines could program themselves.

Taiko Keiji-
http://lostotaku.net

OICW
Member #4,069
November 2003
avatar

It's simple, character x and y position would represent map indicies instead of real coordinates.

[My website][CppReference][Pixelate][Allegators worldwide][Who's online]
"Final Fantasy XIV, I feel that anything I could say will be repeating myself, so I'm just gonna express my feelings with a strangled noise from the back of my throat. Graaarghhhh..." - Yahtzee
"Uhm... this is a.cc. Did you honestly think this thread WOULDN'T be derailed and ruined?" - BAF
"You can discuss it, you can dislike it, you can disagree with it, but that's all what you can do with it"

bamccaig
Member #7,536
July 2006
avatar

You just need to know how many pixels a tile is... Then you move in whatever direction that many pixels. You can either hard code it or get it directly from your BITMAP if a tile is exactly sized.

1int main(void)
2{
3 int intStep, x, y;
4 BITMAP *objTileBitmap = NULL;
5 
6...
7 
8 objTileBitmap = load_bitmap("tile.bmp", NULL);
9 
10...
11 
12 intStep = objTileBitmap->w; // or ->h or hard code it
13 
14...
15 
16 while(!keys[KEY_ESC])
17 {
18 // Check input. Depending on which direction they input you increment
19 // or decrement x or y by intStep, which is the width or height of a
20 //tile.
21...
22 }
23 
24...
25 
26 return 0;
27}

Keep in mind it's easier and cleaner if your character BITMAP is size of a tile also, even if there is magic pink whitespace around the outside.

Keep in mind this was a very messy example. I usually use objects to represent game objects so it's easier to keep track of relationships, etc.

1class PLAYER
2{
3private:
4 int mintX, mintY;
5 int mintStep;
6...
7 
8public:
9 
10...
11 
12 void MoveRight(void)
13 {
14 mintX += mintStep;
15 }
16 
17...
18 
19};

int main(void)
{
    PLAYER *objPlayer = new PLAYER();

...

        if(keys[KEY_RIGHT])
        {
            objPlayer.MoveRight();
        }

...

    return 0;
}

Taiko Keiji
Member #8,307
February 2007
avatar

Yes but I dont want it to be so jerky, I dont want it to "jump" from one tile to the next. It should look like he's walking to the next tile.

Life could be better, machines could program themselves.

Taiko Keiji-
http://lostotaku.net

OICW
Member #4,069
November 2003
avatar

Oh, but you didn't say that.

[My website][CppReference][Pixelate][Allegators worldwide][Who's online]
"Final Fantasy XIV, I feel that anything I could say will be repeating myself, so I'm just gonna express my feelings with a strangled noise from the back of my throat. Graaarghhhh..." - Yahtzee
"Uhm... this is a.cc. Did you honestly think this thread WOULDN'T be derailed and ruined?" - BAF
"You can discuss it, you can dislike it, you can disagree with it, but that's all what you can do with it"

ngiacomelli
Member #5,114
October 2004

I imagine the easiest way to do it would be to calculate the distance (in pixels) to the next tile. Once you've got that, just make the player move x pixels in a series of small increments.

Figure out which tile the player is currently on (the map coordinates). Then, if the player were moving right, figure out the map coordinates for the tile to the right of the player (x+1). Get the actual pixel location for that tile. Subtract the players location from that value, to give you the distance. Then simply move the player in small increments, to cover that distance.

bamccaig
Member #7,536
July 2006
avatar

For this you'll need to keep track of what he's doing so in each frame you can animate and move him a bit. When he reaches the next tile you unset a variable so he stops walking.

Taiko Keiji said:

But I was wondering if anyone had any sugestions as to how I can get the carachter to still move in this way but move over 1 tile.

What did you mean then? If he's still walking normally what does it matter if the map is tile based or not? Unless you mean detecting which tile he's on...

Taiko Keiji
Member #8,307
February 2007
avatar

I couldn't figure out a way for him to move 16 pixels across the screen when a button was pressed, I wanted him to walk over to the next tile when you press the key much like in pokemon when to little character moves.
I found a way to do it also. It's just like you said. Keep track of his screen coordinates then edit his map coordinates and move him only if his screen position isn't equal to his map position.

Life could be better, machines could program themselves.

Taiko Keiji-
http://lostotaku.net

Kibiz0r
Member #6,203
September 2005
avatar

If you switch your engine to something like that described in Game Coding Complete, this is easy. Basically, you should set up your actions as cooperative multitasking.

Make an interface class called Process that will add itself to a list of Processes that will be run every iteration of the loop. This makes it easy to derive from the class and implement a MoveCharacterProcess class that locks movement input while it's running and moves the character from tile to tile.

That's a neat and clean way of doing it, however it may force you to change the way you think about engine design. Regardless, you should buy that book I mentioned because it's a great resource. It's being republished again soon since demand has gotten high enough for another round of books.

bamccaig
Member #7,536
July 2006
avatar

If you know the distance he is supposed to travel you should also be able to just set a destination distance and decrement from it every frame. Or, for example, knowing the distance of a tile and the distance covered in a "footstep" (i.e. one frame) you can determine the number of footsteps required and track the distance remaining:

1...
2 
3int *intAxis;
4int intDirection;
5 
6...
7 
8// Determine which axis you are moving and which direction on that axis.
9switch(true)
10{
11case mblnUp:
12 intAxis = &mintY;
13 intDirection = -1;
14 break;
15case mblnLeft:
16 intAxis = &mintX;
17 intDirection = -1;
18 break;
19case mblnRight:
20 intAxis = &mintX;
21 intDirection = 1;
22 break;
23case mblnDown:
24 intAxis = &mintY;
25 intDirection = 1;
26 break;
27}
28 
29...
30 
31if(mintRemainingFootsteps > 0)
32{
33 /*
34 * Increment/decrement x or y every frame. intAxis should point to
35 * x or y, depending on which axis you are moving.
36 */
37 *intAxis += (intDirection * mintFootstep);
38 
39 // Subtract a footstep every frame.
40 mintRemainingFootsteps--;
41}
42 
43...

I don't really have time to run over that... But I think it should work if it's clear enough to understand...

Taiko Keiji
Member #8,307
February 2007
avatar

That's basically what I did.

1if(!Moving)//this tells it to only take keypresses if it isn't transitioning from
2 //one tile to the next.
3{
4 if(key[KEY_UP])
5 {
6 Direction=Up;
7 //so long as the next tile isn't blocked.
8 MapPosy--;
9 Moving=true;
10 }
11 if(key[KEY_LEFT])
12 {
13 Direction=Left;
14 //same thing
15 MapPosx--;
16 Moving=true;
17 }
18 //you get it by now
19}
20if(Moving)
21{
22 if(ScreenPosx>MapPosx)
23 ScreenPosx--;
24 if(ScreenPosx<MapPosx)
25 ScreenPosx++;
26 if(ScreenPosy>MapPosy)
27 ScreenPosy--;
28 if(ScreenPosy<MapPosy)
29 ScreenPosy++;
30 if(anim!=AnimationTiemr)
31 {
32 CurFrame++;
33 if(CurFrame>=NumFrames)
34 Reset_Frame();
35 anim=AnimationTimer;
36 }
37 if(ScreenPosx==MapPosx&&ScreenPosy==MapPosy)
38 Moving=false;
39}
40GameEngine1.Draw_Screen(buffer);
41//goes back to the main game loop.

obviously this isn't the actual code but it works the same way.

Life could be better, machines could program themselves.

Taiko Keiji-
http://lostotaku.net

Go to: