Hello,
I’m trying to make a 2D platfomer game and i’m running into some problems, mainly with getting the player to move around a game world. I have this code for player movement left right and jumping but its not working how I intended.
function update(self, dt)
--Movement
--Normalizing the direction so that diagonal isn't faster than horizontal/vertical
if vmath.length_sqr(self.input)> 1 then
self.input = vmath.normalize(self.input)
end
-- setting the acceleration to 200 pixels per second in the direction of the player's input
local acceleration = self.input * 200
local dv = acceleration * dt
local v0 = self.velocity
local v1 = self.velocity + dv
local movement = (v0 + v1) * dt * 0.5
local p = go.get_position()
go.set_position(p + movement)
self.velocity = v1 -- So input veolcity next time is the final velocity of the previous time
self.input = vmath.vector3() -- Changes the vector back to 0 for next useage
end
When I press a key the player moves in a direction forever and never stops and when I repeatedly press a key it gets faster. When i hold down a key its like I’ve only pressed it once. I don’t know what to do. Any help would be appreciated.
You can use the action parameter in the input function to find out if the button has been released. Something like this:
function on_input(self, action_id, action)
if action.pressed and action_id == hash("...") then
-- Put code for when a button is pressed here
end
if action.released then
--Put code for when it is released here
end
end
You also could reset the self.input variable every frame, which (I think) would work the same way.
I tried that by adding when the action is released set the self.input variable to 0 and it didn’t change anything, and at the end of the on update I am changing the self.input to 0 anyway
Oops, my apologies, I missed that at the end. But I think I now know what’s causing it…
In every frame after pressing a movement button, self.velocity will be greater than 0. Even if the acceleration is 0, you are always making the movement variable at least equal to:
v0 * dt * 0.5
Since (v0 + v1) would always equal v0 whenever you aren’t pressing a button, the script will constantly be applying the original force every frame.
I think the first code you posted was pretty close, but it was missing one thing: friction to slow down the player once the keys are released.
Maybe give this a try? It seems to work okay with minimal changes to your previous code.
function init(self)
msg.post(".", "acquire_input_focus")
self.input = vmath.vector3(0,0,0)
self.velocity = vmath.vector3(0,0,0)
end
function update(self, dt)
if vmath.length_sqr(self.input)> 1 then
self.input = vmath.normalize(self.input)
end
local acceleration = self.input * 100
local friction = self.velocity/10
self.velocity = self.velocity + acceleration - friction
local movement = self.velocity * dt
go.set_position(go.get_position() + movement)
self.input = vmath.vector3(0,0,0)
end
function on_input(self, action_id, action)
if not action.released then
if action_id == hash("right") then
self.input.x = 1
elseif action_id == hash("left") then
self.input.x = -1
elseif action_id == hash("up") then
self.input.y = 1
elseif action_id == hash("down") then
self.input.y = -1
end
end
end
Due to not being able to find a way I decided to not do acceleration anymore and it works a lot better without giving me a headache, thanks for your help. I may use this in a future project.