Asteroids 13.5: So, tween.
I looked up tween and my tween example and it seems like just the thing. Let’s find out.
Long story short, the tween
function varies named members of a table, over a time interval. Our Splat
, as a class instance, is a table. Therefore we should be able to use tween
quite nicely to scale our splat.
Here it is as it stands:
-- Splat
-- RJ 20200521
local Splats = {}
local Vecs = {
vec2(-2,0), vec2(-2,-2), vec2(2,-2), vec2(3,1), vec2(2,-1), vec2(0,2), vec2(1,3), vec2(-1,3), vec2(-4,-1), vec2(-3,1)
}
function drawSplats()
for k, splat in pairs(Splats) do
splat:draw()
end
end
Splat = class()
function Splat:init(pos)
self.pos = pos
Splats[self] = self
self.size = 1
end
function Splat:draw()
pushStyle()
pushMatrix()
translate(self.pos.x, self.pos.y)
fill(255)
scale(2)
local s = self.size
for i,v in ipairs(Vecs) do
ellipse(s*v.x, s*v.y, 2)
end
popMatrix()
popStyle()
self.size = self.size * (1 + DeltaTime)
if self.size > 5 then Splats[self] = nil end
end
Our current scaling runs for four seconds (from 1 to 5) and scales the splat from 2 to 10, because it’s at scale 2 already. I’ll remove the scale
call, start size
at 2, and run it up to 10, in 4 seconds, with a tween
.
If this works. Here goes. Oh, before I start, the tween can have a “callback” function when it’s done. I think I know how I’ll use that but let’s do it in two steps. First time, I expect the splat will expand and then stay on the screen, because I’m removing the if that kills it.
function Splat:init(pos)
self.pos = pos
Splats[self] = self
self.size = 2
tween(4, self, {size=10}, tween.easing.linear)
end
function Splat:draw()
pushStyle()
pushMatrix()
translate(self.pos.x, self.pos.y)
fill(255)
local s = self.size
for i,v in ipairs(Vecs) do
ellipse(s*v.x, s*v.y, 2)
end
popMatrix()
popStyle()
end
Notice that in the draw
function, I don’t adjust s, I just use it. And in the init
, I call tween. Here’s what the parameters mean:
- 4, time: the time in seconds for the tween to run
- self, table: the table to be modified
- {size=10} target: a table of target values
- tween.easing.linear, easing: an arcane incantation saying that the variables should change linearly. There are other options.
And just as I expected, the explosions grow and just stay there when done:
Now I mentioned that you can have a “callback” when a tween ends, so we’ll add a function that causes a Splat to die when that happens:
function Splat:init(pos)
local die = function()
Splats[self] = nil
end
self.pos = pos
Splats[self] = self
self.size = 2
tween(4, self, {size=10}, tween.easing.linear, die)
end
The function die
is local to the init
, and as such, its reference to self
refers to the specific instance being created. Each Splat gets its own private die
function. When that function is called at the end of the tween, it nils the entry in the Splats
table, so that Splat is never drawn again.
And it works as advertised:
Summing Up
Well, I called this number 13.5 because that’s all I intended to do this evening. It’s a pretty simple thing, this tween, but it gave us a simpler way to animate our explosion and erase it when it’s over.
A good argument for reading the documents and checking out the example projects!
See you next time!