My player can't go left. Why? [SOLVED}

I should start by saying, I am really new to defold, and this in general, so the fix is probably super basic. But essentially, I am making a 2d platformer, the code is based on this defold tutorial: Platformer Defold tutorial. The only changes i made was to some names, as to line up with other defined parts, (obstacle β†’ ground for example). The issue im having is whilst the player can move right, and jump, the player cannot move left, the code seems to allow for it, so i am not sure what im missing.

Thanks in advance,

Solved! thank you to everyone who replied, turned out to be a really simple mistake i made.

Share the project in a zip file and someone will take a look. Impossible to tell otherwise

Do you have input bindings for buttons/input to move left?

Are you checking the right action in on_input()? Add a print(action_id) at the top of the on_input function to check that you receive the action.

Add a breakpoint at the top of on_input and step through the code using the debugger:

Does the code take the path you expect it to? If not, why? Check the values that you are evaluating in your code using the debugger.

2 Likes

Copy and paste your code here and we can check it out for you. No screenshots, just text.

Like this
2 Likes

Apologies for late reply, been really busy, this is the entire player script, as i said, its essentially just a marginally edited version of the code from that tutorial, thanks in advance

-- player.script

-- these are the tweaks for the mechanics, feel free to change them for a different feeling
-- the acceleration to move right/left
local move_acceleration = 3500
-- acceleration factor to use when air-borne
local air_acceleration_factor = 0.8
-- max speed right/left
local max_speed = 450
-- gravity pulling the player down in pixel units
local gravity = -1000
-- take-off speed when jumping in pixel units
local jump_takeoff_speed = 550
-- time within a double tap must occur to be considered a jump (only used for mouse/touch controls)
local touch_jump_timeout = 0.2

-- pre-hashing ids improves performance
local msg_contact_point_response = hash("contact_point_response")
local msg_animation_done = hash("animation_done")
local group_obstacle = hash("Ground")
local input_left = hash("Left")
local input_right = hash("Right")
local input_jump = hash("Jump")
local input_touch = hash("Touch")
local anim_run = hash("Idle")
local anim_idle = hash("Idle")
local anim_jump = hash("Idle")
local anim_fall = hash("Idle")

function init(self)
	-- this lets us handle input in this script
	msg.post(".", "acquire_input_focus")

	-- initial player velocity
	self.velocity = vmath.vector3(0, 0, 0)
	-- support variable to keep track of collisions and separation
	self.correction = vmath.vector3()
	-- if the player stands on ground or not
	self.ground_contact = false
	-- movement input in the range [-1,1]
	self.move_input = 0
	-- the currently playing animation
	self.anim = nil
	-- timer that controls the jump-window when using mouse/touch
	self.touch_jump_timer = 0
end

local function play_animation(self, anim)
	-- only play animations which are not already playing
	if self.anim ~= anim then
		-- tell the sprite to play the animation
		sprite.play_flipbook("#Player", anim)
		-- remember which animation is playing
		self.anim = anim
	end
end

local function update_animations(self)
	-- make sure the player character faces the right way
	sprite.set_hflip("#Player", self.move_input < 0)
	-- make sure the right animation is playing
	if self.ground_contact then
		if self.velocity.x == 0 then
			play_animation(self, anim_idle)
		else
			play_animation(self, anim_run)
		end
	else
		if self.velocity.y > 0 then
			play_animation(self, anim_jump)
		else
			play_animation(self, anim_fall)
		end
	end
end

function update(self, dt)
	-- determine the target speed based on input
	local target_speed = self.move_input * max_speed
	-- calculate the difference between our current speed and the target speed
	local speed_diff = target_speed - self.velocity.x
	-- the complete acceleration to integrate over this frame
	local acceleration = vmath.vector3(0, gravity, 0)
	if speed_diff ~= 0 then
		-- set the acceleration to work in the direction of the difference
		if speed_diff < 0 then
			acceleration.x = -move_acceleration
		else
			acceleration.x = move_acceleration
		end
		-- decrease the acceleration when air-borne to give a slower feel
		if not self.ground_contact then
			acceleration.x = air_acceleration_factor * acceleration.x
		end
	end
	-- calculate the velocity change this frame (dv is short for delta-velocity)
	local dv = acceleration * dt
	-- check if dv exceeds the intended speed difference, clamp it in that case
	if math.abs(dv.x) > math.abs(speed_diff) then
		dv.x = speed_diff
	end
	-- save the current velocity for later use
	-- (self.velocity, which right now is the velocity used the previous frame)
	local v0 = self.velocity
	-- calculate the new velocity by adding the velocity change
	self.velocity = self.velocity + dv
	-- calculate the translation this frame by integrating the velocity
	local dp = (v0 + self.velocity) * dt * 0.5
	-- apply it to the player character
	go.set_position(go.get_position() + dp)

	-- update the jump timer
	if self.touch_jump_timer > 0 then
		self.touch_jump_timer = self.touch_jump_timer - dt
	end

	update_animations(self)

	-- reset volatile state
	self.correction = vmath.vector3()
	self.move_input = 0
	self.ground_contact = false

end

local function handle_obstacle_contact(self, normal, distance)
	-- project the correction vector onto the contact normal
	-- (the correction vector is the 0-vector for the first contact point)
	local proj = vmath.dot(self.correction, normal)
	-- calculate the compensation we need to make for this contact point
	local comp = (distance - proj) * normal
	-- add it to the correction vector
	self.correction = self.correction + comp
	-- apply the compensation to the player character
	go.set_position(go.get_position() + comp)
	-- check if the normal points enough up to consider the player standing on the ground
	-- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
	if normal.y > 0.7 then
		self.ground_contact = true
	end
	-- project the velocity onto the normal
	proj = vmath.dot(self.velocity, normal)
	-- if the projection is negative, it means that some of the velocity points towards the contact point
	if proj < 0 then
		-- remove that component in that case
		self.velocity = self.velocity - proj * normal
	end
end

function on_message(self, message_id, message, sender)
	-- check if we received a contact point message
	if message_id == msg_contact_point_response then
		-- check that the object is something we consider an obstacle
		if message.group == group_obstacle then
			handle_obstacle_contact(self, message.normal, message.distance)
		end
	end
end

local function jump(self)
	-- only allow jump from ground
	-- (extend this with a counter to do things like double-jumps)
	if self.ground_contact then
		-- set take-off speed
		self.velocity.y = jump_takeoff_speed
		-- play animation
		play_animation(self, anim_jump)
	end
end

local function abort_jump(self)
	-- cut the jump short if we are still going up
	if self.velocity.y > 0 then
		-- scale down the upwards speed
		self.velocity.y = self.velocity.y * 0.5
	end
end

function on_input(self, action_id, action)
	if action_id == input_left then
		self.move_input = action.value
	elseif action_id == input_right then
		self.move_input = action.value
	elseif action_id == input_jump then
		if action.pressed then
			jump(self)
		elseif action.released then
			abort_jump(self)
		end
	elseif action_id == input_touch then
		-- move towards the touch-point
		local diff = action.x - go.get_position().x
		-- only give input when far away (more than 10 pixels)
		if math.abs(diff) > 10 then
			-- slow down when less than 100 pixels away
			self.move_input = diff / 100
			-- clamp input to [-1,1]
			self.move_input = math.min(1, math.max(-1, self.move_input))
		end
		if action.released then
			-- start timing the last release to see if we are about to jump
			self.touch_jump_timer = touch_jump_timeout
		elseif action.pressed then
			-- jump on double tap
			if self.touch_jump_timer > 0 then
				jump(self)
			end
		end
	end
end

nevermind, fixed it, thanks regardless

image

7 Likes

It’s hard to read the code like this. Is it possible for you to upload the entire project as a .zip file so we can have a look?

What I noticed from taking a quick look is that you removed the - from self.move_input = -action.value which can be found in:

function on_input(self, action_id, action)
    if action_id == input_left then
        self.move_input = -action.value

EDIT: Ah, @COCO beat me to it! :grinning_face_with_smiling_eyes:

4 Likes

ah i see, that worked, thanks!

1 Like

yep thats all i needed, thanks!

1 Like