Sign in to follow this  
Ahmad Ridwan Fauzi

Tile-Based Movement Algorithm

Recommended Posts

What is the best algorithm for tile-based movement in 2d game (particularly controlled by keyboard)? I just have these 2 depiction of tile-based movement algorithm in my mind right now. For example I wanna move right by pressing right arrow key:

 

1. When I press and hold the key, the timer starts. For the first I press a key, the player move immediately, but when I hold it for, example, 2 seconds, the player will move two tiles away (Is it efficient?)

2. When I press and hold the key, the player starts to move. When I release the key immediately, the player will move a bit (if the player isn't located exactly next to the tile), move a bit, and then stop at the tile where he collides (but I believe this method requires collision detection which I think it's not efficient enough)

 

Share this post


Link to post
Share on other sites

Moving a character in a tile-based environment is not likely to be a performance problem, so I wouldn't worry about efficiency in this case.. "The best" depends on what you want the behavior to be. Those two options describe different behaviors. Which one do you think makes more sense for your game?

Share this post


Link to post
Share on other sites

Moving a character in a tile-based environment is not likely to be a performance problem, so I wouldn't worry about efficiency in this case.. "The best" depends on what you want the behavior to be. Those two options describe different behaviors. Which one do you think makes more sense for your game?

I'm just wondering to choose the best one that still represents the tile-based movement concept, in case I have a lot of contents in my game so that the game becomes so laggy. thanks for your answer. ;)

Edited by uzzybotak

Share this post


Link to post
Share on other sites

I'm assuming you want the character to slide from tile to tile, instead of moving an entire tile at a time, but not have the player stop in between tiles.

 

What I did was interpolate from tile to tile (centers), but also keep track if the user is still holding any input, and if they are holding input at the end of the interpolation, to go ahead and start a new interpolation to the next tile.

 

You can see it here: http://joshv.itburns.net/MazeWarMulti.html (select multiplayer, and you can either just run around by yourself or add bots)

Edited by ferrous

Share this post


Link to post
Share on other sites

What framework are you working on? I don't think you have to do any collision detection. Let's say your tile's side is 30 pixels. When the players presses the left arrow key, for example, you'll tell the program to move the player spirte 30 px to the left at a rate of x pixels per frame, probably animating the sprite. You do need to raise a flag that the sprite is moving, so that other key presses are ignored.

 

This is my version of the solution, although I'm a terrible programmer, and it might be a little convoluted:

import pygame
from pygame.locals import *

pygame.init()

clock = pygame.time.Clock()
screen = pygame.display.set_mode((800,600))
image = pygame.image.load('logo.png')
imagePos = [330,250]

running = True
movement = False
direction = ''
initialPos = imagePos[0]

def moveImageRight(movement,initialPos):
    if movement == True:
        if imagePos[0] != initialPos + 30:
            imagePos[0] += 3
            return True
    initialPos = imagePos[0]
    return False

def moveImageLeft(movement,initialPos):
    if movement == True:
        if imagePos[0] != initialPos - 30:
            imagePos[0] -= 3
            return True
    initialPos = imagePos[0]
    return False

while running:

    clock.tick(60)

    for event in pygame.event.get():
        if event.type == QUIT:
            running = False

    key = pygame.key.get_pressed()

    if key[K_RIGHT]:
        if movement == False:
            movement = True
            direction = 'right'
            initialPos = imagePos[0]

    if key[K_LEFT]:
        if movement == False:
            movement = True
            direction = 'left'
            initialPos = imagePos[0]

    if direction == 'right' and movement:
        movement = moveImageRight(movement,initialPos)

    if direction == 'left' and movement:
        movement = moveImageLeft(movement,initialPos)

    screen.fill((200,200,200))
    for i in range(30):
        pygame.draw.line(screen,(0,0,0),(30*i,0),(30*i,600),2)
        
    screen.blit(image,tuple(imagePos))
    pygame.display.flip()

pygame.quit()

I drew the lines just to check that the sprite won't move other than 30 pixels to either direction.

Share this post


Link to post
Share on other sites


What I did was interpolate from tile to tile (centers), but also keep track if the user is still holding any input, and if they are holding input at the end of the interpolation, to go ahead and start a new interpolation to the next tile.

 

okay thanks, will note that

 


What framework are you working on? I don't think you have to do any collision detection. Let's say your tile's side is 30 pixels. When the players presses the left arrow key, for example, you'll tell the program to move the player spirte 30 px to the left at a rate of x pixels per frame, probably animating the sprite. You do need to raise a flag that the sprite is moving, so that other key presses are ignored.

 

I'm working on unity right now. thanks. you've been a big help. ;)

Share this post


Link to post
Share on other sites

I'm assuming you want the character to slide from tile to tile, instead of moving an entire tile at a time, but not have the player stop in between tiles.

 

What I did was interpolate from tile to tile (centers), but also keep track if the user is still holding any input, and if they are holding input at the end of the interpolation, to go ahead and start a new interpolation to the next tile.

 

You can see it here: http://joshv.itburns.net/MazeWarMulti.html (select multiplayer, and you can either just run around by yourself or add bots)

 

It should be noted that a new interpolation should only be done if the key is still pressed after the previous interpolation has been completed (that is, the character has actually arrived at his destination point). Otherwise, it might slide too far away from it's intended destination.

 

This might sound trivial and obvious, but I've been bitten by this simple thing before, and it hurts.

Share this post


Link to post
Share on other sites

 

I'm assuming you want the character to slide from tile to tile, instead of moving an entire tile at a time, but not have the player stop in between tiles.

 

What I did was interpolate from tile to tile (centers), but also keep track if the user is still holding any input, and if they are holding input at the end of the interpolation, to go ahead and start a new interpolation to the next tile.

 

You can see it here: http://joshv.itburns.net/MazeWarMulti.html (select multiplayer, and you can either just run around by yourself or add bots)

 

It should be noted that a new interpolation should only be done if the key is still pressed after the previous interpolation has been completed (that is, the character has actually arrived at his destination point). Otherwise, it might slide too far away from it's intended destination.

 

This might sound trivial and obvious, but I've been bitten by this simple thing before, and it hurts.

 

thank you. sure thing as a beginner I have to go to pass the pain you said. ;)

Share this post


Link to post
Share on other sites

Yup, and I agree, if you are doing this kind of movement, you can do it without collision.  With a caveat.  If you have multiple characters all moving, and they can't occupy the same square, you need to take that into account.  I ended up with a system where a character claims the square they are moving to, and holds the claim to the square they currently in, and only relinquishes the claims after the interpolation has ended.  Though I may have fudged it a little, and let someone move in to the previous square a little earlier, as the previous character was mostly out of their starting square.  (And if you use this method, I also suggest letting the player(s) claim squares first, before ai monsters or whatever)

Edited by ferrous

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this