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.
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
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
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.
Thanks! I created it just for you 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.
(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 )
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.
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…”
Which means that… if I set it to 1 it will remain in its world position?
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.