Heya,
recently I started implementing smooth movement between tiles in my game. I came up with a method that uses lerping to smoothly correct the player's position on one axis, while he is moving on the other. It works pretty well, but I have a pretty stupid question which is more a related to design rather than code (at least that's what I think).
The problem occurs at crossroads with two valid paths like this (red is the actual tile position, blue is the real position):
When the player presses two keys at the same time (in this case up and right) then the character gets stuck in between tiles like in the image above. I already tried a few things like discarding one of the input directions, but haven't found a solution that I like.
Any ideas?
Smooth movement (design question)
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Smooth movement (design question)
I worked on a maze tag kind of game in college that dealt a lot with pacman/bomberman-style arena movement, so it might be relevant here.
These were the basic rules, in case your game wouldn't work the same way:
1. Players could only move straight north, south, easy, west (no diagonal, no height)
2. Levels were straight paths and intersections (like pacman), no "rooms"
3. Game was real-time (not turn-based like Pokemon)
Given that, we ended up with these design rules in the code:
1. Assume the player wants to move over standing still (standing still is OK, just make totally sure that's definitely what the player wants). Ambiguity means "find the best direction," not "stop moving."
2. At an intersection, if a player's intended direction is unclear, assume they want to change directions from their previous movement (which we tracked). For example, holding up-right should tend to zigzag you to the northeast of the level.
3. If direction still can't be decided... CONTROLLER: compare joystick axes; KEYBOARD: whichever direction was most recently pressed gets priority.
4. If direction even still can't be decided, choose arbitrarily (like "favors north and east, north if still need a tiebreaker"). Movement test never got this far.
Hope that's helpful!
EDIT: Hm I think I mighta misread the OP and skipped a step. :0
You should be separating input attempt and actual movement. In between, you should run checks to see where to actually move the character, if at all. If the diagonal is illegal, it shouldn't permit the diagonal movement. You may also want it to check for alternative "close enough" directions to move, like the example I have above, and then move in that direction instead.
These were the basic rules, in case your game wouldn't work the same way:
1. Players could only move straight north, south, easy, west (no diagonal, no height)
2. Levels were straight paths and intersections (like pacman), no "rooms"
3. Game was real-time (not turn-based like Pokemon)
Given that, we ended up with these design rules in the code:
1. Assume the player wants to move over standing still (standing still is OK, just make totally sure that's definitely what the player wants). Ambiguity means "find the best direction," not "stop moving."
2. At an intersection, if a player's intended direction is unclear, assume they want to change directions from their previous movement (which we tracked). For example, holding up-right should tend to zigzag you to the northeast of the level.
3. If direction still can't be decided... CONTROLLER: compare joystick axes; KEYBOARD: whichever direction was most recently pressed gets priority.
4. If direction even still can't be decided, choose arbitrarily (like "favors north and east, north if still need a tiebreaker"). Movement test never got this far.
Hope that's helpful!
EDIT: Hm I think I mighta misread the OP and skipped a step. :0
You should be separating input attempt and actual movement. In between, you should run checks to see where to actually move the character, if at all. If the diagonal is illegal, it shouldn't permit the diagonal movement. You may also want it to check for alternative "close enough" directions to move, like the example I have above, and then move in that direction instead.
Last edited by G-Mang on Wed Sep 03, 2014 6:32 am, edited 1 time in total.
Re: Smooth movement (design question)
The trick is to separate movement in x- and y-direction. First process all the input and calculate the velocity of the player. Then move the player in x-direction only, detect and resolve collisions, then move in y-direction, detect and resolve collision. Here is a nice blog post about this topic (not only relevant for 2d-platformers).rmcode wrote:When the player presses two keys at the same time (in this case up and right) then the character gets stuck in between tiles like in the image above. I already tried a few things like discarding one of the input directions, but haven't found a solution that I like.
Any ideas?
Check out my blog on gamedev
Re: Smooth movement (design question)
Thanks a lot to you both. I'm close to fixing the movement, which means that I'll finally have a version with all the major features in it!
I have a small follow up question though, so I can do it correctly for my next games. Both of you said I should separate input and actual movement.
I currently use an InputManager I wrote for my first game, which basically sets command flags to true or false based on which keys have been pressed. In my player class I check for these commands:
So whenever one of the keys is pressed
is called from the entity class which the player inherits from. That move(...) function is the one doing all the calculations and the actual movement. Is that what you meant?
I have a small follow up question though, so I can do it correctly for my next games. Both of you said I should separate input and actual movement.
I currently use an InputManager I wrote for my first game, which basically sets command flags to true or false based on which keys have been pressed. In my player class I check for these commands:
Code: Select all
local function handleInput()
if InputManager.hasCommand('UP') then
self:move('n');
elseif InputManager.hasCommand('DOWN') then
self:move('s');
elseif InputManager.hasCommand('RIGHT') then
self:move('e');
elseif InputManager.hasCommand('LEFT') then
self:move('w');
end
end
Code: Select all
self:move(...)
Who is online
Users browsing this forum: Bing [Bot], Semrush [Bot] and 12 guests