I am trying to build a game like Toki Tori 2 by modifying the platformer tutorial character controls. I want to remove the jump and replace it with climbing on a ledge about the height of the character. How do I start with this?
Also to add a stomp-like move
This is my first game and first time using an engine, so bear with me -__-
Hmm, ok, so if you want to add ladders or something the player can climb then you need to do a couple of different things:
Create game objects with ladder graphics and a collision object with a new collision group “ladder”
You need to add the “ladder” group to the player’s collision object so that it will detect collisions with the ladder
In the player script’s on_message() function you need to check if the player has collided with the “ladder” group when you get a colision response message. When this happens you set a flag on the player script saying that the player is on a ladder.
When the player presses up/down in the on_input() function of the player script you need to check if the “collide with ladder”-flag is set and if that’s the case you move the player up/down
You need to modify the player script so that you don’t apply gravity if the “collide with ladder” flag is set
If you want to make a stomp-like move (I assume jump and press a key to stomp):
Either define a new key to trigger the stomp action or decide if the jump button should also trigger a stomp
Check in on_input() if the player triggered a stomp action and check if the player is jumping (and perhaps moving up but maybe not down)
If the conditions for a stomp has been met then modify gravity so that the player falls down a bit faster and set a stomp flag on the player script.
When you get a collision response in on_message() that indicates if the player has landed then also check if the stomp flag is set. If the stomp flag was set then trigger whatever effect you had in mind (perhaps destroying the ground or damaging enemies)
In my last game (made on GM:S), I did it like this (might miss several points in the list, bear with me):
Every platform piece (square) checks in the begining of the level, if it’s the edge of the whole platform, and if it is - “transform” itself to self’s child object “corner”, which got all the same data, just different name
if the hero’s state is “flying” - which means he’s in the air - then
if hero colliding with “corner”- then
if middle of hero’s sprite higher then the top of the “corner” - then
hero’s state = “pulling up”, and special animation going on, controls are checked if the player wanna jump off the edge.
What’s the best way to do something similar in the Defold?
Can I, for example, in-game spawn some special collision box for edges?
I do believe it’s pretty easy to do everything else due to message system you got here. Like, if colliding with hero, send self position to the hero - and hero will decide, if it’s enough to change his state.
I would do this by collision triggers at the edges that sends messages to the player how they are interacted with. Depending on how diverse they are and what amount of control they require, they can even temporarily take control of the player, like animating the player to a specific position etc. That way it also becomes quite straight-forward if you later decide non-players should be able to use the edges as well.
Ok the first thing I am trying to figure out is just make the character walk left and right.
Note: The numbers are arbitrary for now, as I am trying to set the framework first
this is my intention:
if player on ground =
player can move left
player can move right
if player press left =
player moves = 500
if player press right =
player moves -500
This is my current script:
local max_speed = 100
local gravity = -1500
local input_left = hash(“left”)
local input_right = hash(“right”)
function init(self)
– Add initialization code here
msg.post(".", “acquire_input_focus”)
self.speed = 0
self.ground_contact = false
self.move_input = 0
– Remove this function if not needed
end
function on_input(self, action_id, action)
– Add input-handling code here
if action_id == hash(“left”) then
self.speed = max_speed
elseif action_id == hash(“right”) then
self.speed = -max_speed
end
This is my latest character control. Im learning to build a new character from scratch while taking inspiration from the platformer one.
I think I got the gravity right, but now I am figuring out moving from left and right
local gravity = -1100
local max_speed = 400
local group_geometry = hash("ground")
local input_left = hash("left")
local input_right = hash("right")
function init(self)
-- this tells the engine to send input to on_input() in this script
msg.post(".", "acquire_input_focus")
-- save the starting position
self.position = go.get_position()
-- keep track of movement vector and if there is ground contact
self.velocity = vmath.vector3(0, 0, 0)
self.move_input = 0
self.ground_contact = false
end
function final(self)
-- Return input focus when the object is deleted
msg.post(".", "release_input_focus")
end
function update(self, dt)
local gravity = vmath.vector3(0, gravity, 0)
if not self.ground_contact then
-- Apply gravity if there's no ground contact
self.velocity = self.velocity + gravity
end
-- apply velocity to the player character
go.set_position(go.get_position() + self.velocity * dt)
-- reset volatile state
self.correction = vmath.vector3()
self.ground_contact = false
end
local function handle_geometry_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)
if message_id == hash("contact_point_response") then
-- check if we received a contact point message. One message for each contact point
if message.group == hash("ground") then
handle_geometry_contact(self, message.normal, message.distance)
end
end
end
function on_input(self, action_id, action)
if action_id == input_left then
self.move_input = -action.value
self.direction = -1
elseif action_id == input_right then
self.move_input = action.value
self.direction = 1
end
end