Character Controls like Toki Tori 2

Hi

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:

  1. Create game objects with ladder graphics and a collision object with a new collision group “ladder”
  2. You need to add the “ladder” group to the player’s collision object so that it will detect collisions with the ladder
  3. 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.
  4. 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
  5. 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):

  1. Either define a new key to trigger the stomp action or decide if the jump button should also trigger a stomp
  2. 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)
  3. 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.
  4. 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)

Read more about the physics system in Defold here: http://www.defold.com/manuals/physics/ And about how to handle input here: http://www.defold.com/manuals/input/

2 Likes

Partly question, partly solution to the topic -

In my last game (made on GM:S), I did it like this (might miss several points in the list, bear with me):

  1. 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
  2. if the hero’s state is “flying” - which means he’s in the air - then
  3. if hero colliding with “corner”- then
  4. if middle of hero’s sprite higher then the top of the “corner” - then
  5. 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.

Thanks! I think I know where to start. I will give it a shot!

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.

1 Like

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

end

Is your movement code not working? You probably want to take inspiration from the platformer tutorial.

1 Like

Can you show us the function update(self, dt) codeblock?

1 Like

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