Tile-Based Movement Algorithm

Started by
7 comments, last by ferrous 9 years, 10 months ago

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)

Thanks for your attention

Advertisement

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?

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. ;)

Thanks for your attention

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)

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.

Starting out in game programming? Me too! Check out my blog, written by a newbie, for the newbies. http://myowngamejourney.blogspot.mx/

Also, if you don't mind a 5 seconds ad, here's a great free ebook for beginners on the subject of pygame: http://bit.ly/19Bem2q


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. ;)

Thanks for your attention

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.

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. ;)

Thanks for your attention

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)

This topic is closed to new replies.

Advertisement