Jill Endless Run

Looks about right. You will probably have to play with coefficients to make it feel right too.

Normalization sets vector length to 1 without changing it’s direction.

In first case, it’s used to get direction of attraction and multiply by calculated power of attraction. In second - to limit top speed of attracted items to 200 pixels/sec.

Thanks for the explanation!

Following your suggestion, at the beginnig I was thinking on implementing the code on the coin factory script like:

function on_message(self, message_id, message, sender)
    if message_id == hash("magnet_trigger") then
        local player_pos = go.get_world_position(self.player_obj_id)
        local r = player_pos - go.get_world_position()
        local d = vmath.length(r)
        self.velocity = self.velocity + vmath.normalize(r) * pow2(1000 / (d + 60)) * self.buff
    else...
    ...
end

function update(self, dt)
    self.velocity = self.velocity * (1 / (1 + 0.2*dt))
    if vmath.length(self.velocity) > 200 then
        self.velocity = vmath.normalize(self.velocity) * 200
    end 
    go.set_position(go.get_position() + self.velocity * dt)
end

But then, if the player jumps or falls after the vector has been set, the coin will end up somewhere else, right?

So I’m thinking that what you said about putting both functionalities in the update function would be better, so the coin can follow the player wherever he/she moves, like:

function on_message(self, message_id, message, sender)
    if message_id == hash("magnet_trigger") then
        self.follow_player = true
    else...
    ...
end

function update(self, dt)
    ...
    if self.follow_player then
        -- get player position every loop, so we can follow him/her ;P
        local player_pos = go.get_world_position(self.player_obj_id)
        -- get direction of attraction and multiply by calculated power of attraction
        local r = player_pos - go.get_world_position()
        local d = vmath.length(r) -- distance in pixels between coin and player??
        -- (Here I don't know if I am performing twice the same operation 
        -- or if I can get rid of one of the following lines...)
        self.velocity = self.velocity + vmath.normalize(r) * pow2(1000 / (d + 60)) * self.buff 
        self.velocity = self.velocity * (1 / (1 + 0.2*dt))
        -- limit top speed of attracted item to 200 pixels/sec.
        if vmath.length(self.velocity) > 200 then
            self.velocity = vmath.normalize(self.velocity) * 200
        end 
        -- apply vector and fly towards player
        go.set_position(go.get_position() + self.velocity * dt)
    end
end

I’ll try this as soon as I get to my computer :thumbsup:

Ok, according to the Defold reference, we can get another object’s id by calling:

local id = go.get_id("/my_sub_collection/my_instance") -- absolute path

That means that I don’t need to store the player’s id from the beginning, I can get it when the magnet collision triggers:

function on_message(self, message_id, message, sender)
    if message_id == hash("magnet_trigger") then
        self.follow_player = true
        self.player_obj_id = go.get_id("/my_sub_collection/main_player_instance") -- get the id here
    else...
    ...
end

I hope it works!

You do not necessarily need the id to get the position. You can also use the url directly. Most (all?) of the go.functions accept hash|string|url for the optional id parameter.

Excellent!

Thanks @britzl! I will try that ASAP!

Ok, that worked…

But the coin animation not… :thinking:

Here’s my take on a coin magnet power-up. Perhaps it can give you some inspiration:

HTML: http://britzl.github.io/publicexamples/coin_magnet/index.html
Code: https://github.com/britzl/publicexamples/tree/master/examples/coin_magnet

1 Like

Wow, thank you @britzl!

It certainly gives me some inspiration!

I will use part of your “coin attraction animation”:

local coin_pos = go.get_position(coin)
local delta = player_pos - coin_pos
go.set_position(coin_pos + delta * 5 * dt, coin)

By the way, nice little game! Defold is excellent for this kind of quick developments :wink::thumbsup:

Thanks! I created it just for you :slight_smile: The code was written this morning over the course of an hour or so (and yes, it shows how much you can do with Defold in a short period of time). I’ve decided to put a little bit more effort into new examples now that my examples page is listed among the tutorials.

Thank you very much, I truly appreciate it :relaxed: :thumbsup:

And keep up the good work! :muscle:

(I am really glad I did overcome the initial hesitation and decided to start this Dev Diary, because you can feel the support of other forum members, and when you are being helped you want to keep working to show appreciation for the time and effort someone else took to help you and it encourages you to do your best :grin: )

2 Likes

Ok, I believe I found my problem, remember that I am using the getting started tutorial, and in that tutorial coins are children of the platform, so when I set the position of the coin to follow the player, it goes to the other side…

According to Defold go reference:

go.set_position(position, [id])

The position is relative to the parent (if any). The global world position cannot be manually set.

Hmmmm… :thinking:

Ok, so, can you “detach” the coin from the platform using set_parent and keep the world transform when the coin is collected?

Hi @britzl I’ll try detaching as you suggest :slight_smile:

But I’m a little confused about ‘keep_world_transform’, reading the Defold reference it says:
“if the world transform of the instance should be preserved when changing spaces…” :confused:

Which means that… if I set it to 1 it will remain in its world position? :thinking:

I will try using :

msg.post(".", "set_parent", {keep_world_transform = 1 })

…and see what happens :relaxed:

Success! :muscle:

The “detaching” was the first step, but still it was not working completely right… :confused:

But by looking in the Getting Started Tutorial, you can see that the coins are animated when created, so I tried:

go.cancel_animations(go.get_id(), "position.y")

And that was it! :thumbsup:

I am going to rebuild and reupload for you to see the magnet working now.

Thank you very much! :grin:

1 Like

Ok,

It’s been reuploaded, the magnet works on all coins but I still need to implement the magnet attracting the diamonds.

Question:
Should the magnet also attract other power-ups? or only coins and gems? :thinking:

By the way, in the coin factory script, the magnet code in the upload function ended up as:

        local player_pos = go.get_position("level/player")
        local coin_pos = go.get_position()
        go.set_position( coin_pos + (player_pos - coin_pos) * 5 * dt )

In case somebody wants to implement it also in their getting started tutorial :wink:
Thanks to @baturinsky and @britzl :thumbsup:

2 Likes

Excellent! I’m happy to hear that you got it working!

Thanks! :grinning:

One small step forward in a long road to go :stuck_out_tongue_winking_eye:

Hello Everybody!

I just uploaded an update to the game, it has a new feature that allows you to grab the ledge of a platform when you miss by an “inch” to land on it.

It also has a parkour move when you are running and find an obstacle.

Any more suggestions? :grinning:

p.s. I’ll report the URL here, so you don’t have to find it above:
http://alethos.xyz/jill_run/

Nice, the ledge grab works quite well! But it really slows you down so you’ll almost end up outside the left edge of the screen unless you pay attention.

Yes!

That’s the cost :smiling_imp:

Use it wisely! :grin:

Did you find the “kong” when running?