Platformer Movement

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.

1 Like

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.

That’s a good point, do you know of any fixes for that?

I would change this line to self.velocity = vmath.vector().

But I wasn’t quite sure what you meant in this comment, and I wouldn’t want to ruin what you are trying to accomplish here.

I’ve just tried that and now the player doesn’t move at all for some reason.

Anyone else got any ideas of how to make a smooth movement? I’ve only got it to work as very jumpy.

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
1 Like

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.

2 Likes