local input_jump = hash("jump")
function init(self)
msg.post(".","acquire_input_focus")
self.runSpeed = 350
self.curAnim = "idle"
msg.post("#sprite", "play_animation", { id=hash("idle") })
self.speed = vmath.vector3()
msg.post(".", "acquire_input_focus")
self.speed = vmath.vector3(0, 0, 0)
self.correction = vmath.vector3()
self.ground_contact = false
self.move_input = 0
self.anim = nil
self.touch_jump_timer = 0
end
local function update_animations(self)
-- make sure the player character faces the right way
sprite.set_hflip("#sprite", self.move_input < 0)
-- make sure the right animation is playing
if self.ground_contact then
if self.speed.x == 0 then
play_animation(self, anim_idle)
end
end
end
function update(self, dt)
local pos = go.get_position()
if self.speed.y >= -100 then
self.speed.y = self.speed.y - 25
end
if self.speed.x ~= 0 then
pos = pos + self.speed * dt
go.set_position(pos)
if self.curAnim ~= "run" then
msg.post("#sprite", "play_animation", { id=hash("run") })
self.curAnim = "run"
end
end
end
--local function jump(self)
-- if self.contact_point_response then
-- self.speed.y = 300
-- end
--end
function on_input(self, action_id, action, message_id)
if action_id == hash("MOVE_RIGHT") then
self.speed.x = self.runSpeed
sprite.set_hflip("#sprite", false)
end
if action_id == hash("MOVE_LEFT") then
self.speed.x = self.runSpeed * -1
sprite.set_hflip("#sprite", true)
end
if action_id == hash("JUMP") and self.ground_contact then
self.speed.y = self.speed.y + 300
end
end
function on_message(self, message_id, message, sender)
-- Handle collision
if message_id == hash("contact_point_response") then
local newpos = go.get_position() + message.normal * message.distance
go.set_position(newpos)
end
end
this is the code, the problematic section is the movement function and jump, it works fine without self.ground_contact but as soon as that is added the character can no longer jump, i need it there so my character cannot fly. Is there any alternatives or fixes to my code to sort this out?
Just two side notes, not directly related to the issue you are facing.
I would guess that the line
self.speed.y = (self.speed.y - 25)
is used to limit the y velocity. However, in this way, your update code is heavily dependent on the refresh rate. You should avoid using formula for cinematic variables without using dt! I would suggest something similar to
self.speed.y = (1.0 - K*dt) * self.speed.y
where K is a (small!) constant you should adjust to your need. In this way the code is (somehow) independent of the refresh rate since it is using dt.
It is not good to compare floating numbers. Instead of the line
if self.speed.x ~= 0 then
I would advice something like
if math.abs(self.speed.x) > 0.1 then
where 0.1 is a constant you may adjust.
First of all, it’s easier to read your code if you copy and paste it in here. If you highlight it and then hit this button it should look nicely formatted:
Are there parts of your code that haven’t been posted? It looks like self.ground_contact isn’t defined anywhere, which would make it nil. If it’s nil, then you will indeed never be able to jump. Nil is equivalent to false in conditionals, so even if the action_id is hash(“jump”) then the other part of the conditional will still always fail.
What you need is to set self.ground_contact to true whenever you’re in contact with the ground, and false if you’re not.
what im struggling with is how i would do that, im fairly new to defold and cant code in lua although i know other languages, i just dont know if theres a built in command for contact with another collision object or something like that?
I haven’t made a platformer in Defold myself but I suspect a simple way would be to set self.ground_contact to true when the player character collides with the ground. If you jump, you can set self.ground_contact to false. You could also set a timer so that self.ground_contact is set to false x frames after last contact (to handle cases where you’re not on the ground but didn’t jump, e.g. if you walked off a ledge).
function on_message(self, message_id, message, sender)
if message_id == hash("contact_point_response") then
self.ground_contact = true
end
end
function on_input(self, action_id, action, message_id)
if action_id == hash("MOVE_RIGHT") then
self.speed.x = self.runSpeed
sprite.set_hflip("#sprite", false)
end
if action_id == hash("MOVE_LEFT") then
self.speed.x = self.runSpeed * -1
sprite.set_hflip("#sprite", true)
end
if action_id == hash("JUMP") and self.ground_contact == true then
self.speed.y = self.speed.y + 750
self.ground_contact = false
end
end
Ok so i’ve got the change for ground_contact at the top and the jumping code at the bottom, theres nothing wrong with the jump code its just the collision at the top isnt changing the boolean, I know the code for registering the collision is right because it works elsewhere in the code and the boolean change code also works elsewhere in the code so im really not sure where im going wrong here
Code looks fine to me, so that makes me think your collision objects might not be set up properly. I tend to pepper my code with prints to try and gain a clue about what’s going wrong. For example, I might change your on_message to this:
function on_message(self, message_id, message, sender)
print(message_id, sender)
pprint(message)
if message_id == hash("contact_point_response") then
print("ground contact registered")
self.ground_contact = true
end
end
This will only be slightly useful if my suspicion is right, which is that your collision objects aren’t set up correctly. For that, I recommend you review the Group and mask section of the Physics manual.
Figured it out, apparently defold doesnt like multiple functions responding to collisions so i just had to put it all into one function and it worked!!! Thank you very much
I couldnt make multiple function on_message(self, message_id, message, sender) because the second one i made didnt work for some reason so i just kind of assumed it didnt like multiple being there, its probably because of the first one being a collision correction function for a player character messing with the collision recognition