## To Trigger Animations At Certain Times - help?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
worldaway
Prole
Posts: 44
Joined: Thu Sep 08, 2011 2:22 am

### To Trigger Animations At Certain Times - help?

I have a game, and I want it to work so that when you shoot an enemy, an explosion animation goes off at the position of the enemy (the enemy explodes). But I cant seem to get it right. I am using "AnAL" by the way.

This is the area of my code where I am guessing I have to print something to trigger the animation (in function updateGame):

Code: Select all

		-- check for collision with enemies
for ii,vv in ipairs(enemies) do
if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
--PRINT CODE HERE
-- mark that enemy for removal
table.insert(remEnemy, ii)
-- mark the shot to be removed
table.insert(remShot, i)

end
end

Here is my whole code (above included):

Code: Select all

state = 0 -- 0 = menu, 1 = game, 2 = gameover, 3 = information

function start()

require ("anal")

hero = {}
hero.x = 400
hero.y = 300
hero.width = 5
hero.height = 25
hero.speed = 300
hero.shots = {} -- holds fired shots

enemies = {}

for i=0,6 do
enemy = {}
enemy.width = 40
enemy.height = 30
enemy.x = i * (enemy.width + 60) + 100
enemy.y = enemy.height - 100 + math.random() * 30 * i
table.insert(enemies, enemy)
end

fastEnemies = {}

for i=0,2 do
fastEnemy = {}
fastEnemy.width = 25
fastEnemy.height = 38
fastEnemy.x = i * (fastEnemy.width + 300) + 75
fastEnemy.y = enemy.height - 100
table.insert (fastEnemies, fastEnemy)
end

anim = newAnimation(img, 36, 36, 0.05, 0)
anim:setMode ("once")

scan = newAnimation(scanner, 36, 36, 0.05, 0)
scan:setMode ("loop")

sClock = newAnimation (clockSprite, 36, 36, 0.05, 0)
sClock:setMode ("loop")

state = 1
end

pigman = love.graphics.newImage("Resources/pigman.png")
img = love.graphics.newImage ("Resources/explosion.png")
enemyPic = love.graphics.newImage("Resources/enemy.png")
fEnemyPic = love.graphics.newImage("Resources/fEnemy.png")
backround = love.graphics.newImage ("Resources/backround.png")
info = love.graphics.newImage ("Resources/info.png")
Over = love.graphics.newImage ("Resources/Over.png")
scanner = love.graphics.newImage ("Resources/scannersprite.png")
clockSprite = love.graphics.newImage ("Resources/clock.png")
Music = love.audio.newSource ("Resources/Music.mp3")
woosh = love.audio.newSource ("Resources/woosh.mp3" , "static")
Music:setLooping(Music)
love.audio.play (Music)

end

function gameOver()
state = 2
end

function information()
state = 3
end

function spawnEnemies()

for i=0,6 do
enemy = {}
enemy.width = 40
enemy.height = 30
enemy.x = i * (enemy.width + 60) + 100
enemy.y = enemy.height - 100 + math.random() * 30 * i
table.insert(enemies, enemy)
end

end

function spawnFastEnemies()

for i=0,2 do
fastEnemy = {}
fastEnemy.width = 25
fastEnemy.height = 38
fastEnemy.x = i * (fastEnemy.width + 300) + 75
fastEnemy.y = enemy.height - 100
table.insert (fastEnemies, fastEnemy)
end

end

spawntimer = 3
fSpawntimer = 7
timer = 1
pTimer = 1
score = pTimer

function updateGame(dt)

--spawn enemies every 3 seconds and 7 seconds

spawntimer = spawntimer - dt

if spawntimer <= 0 then
spawnEnemies()
local leftover = math.abs(spawntimer)
spawntimer = 3 - leftover
end

fSpawntimer = fSpawntimer - dt

if fSpawntimer <= 0 then
spawnFastEnemies()
local sLeftover = math.abs(fSpawntimer)
fSpawntimer = 7 - sLeftover
end

timer = timer - dt

if timer <= 0 then
pTimer = pTimer + 1
local tLeftover = math.abs(timer)
timer = 1 - tLeftover
end

if # enemies + # fastEnemies >= 40 then
state = 2
end

--update animations
anim:update(dt)
scan:update(dt)
sClock:update(dt)

--keyboard actions (move hero)

if love.keyboard.isDown("left") then
hero.x = hero.x - hero.speed*dt
elseif love.keyboard.isDown("right") then
hero.x = hero.x + hero.speed*dt
elseif love.keyboard.isDown("up") then
hero.y = hero.y - hero.speed*dt
elseif love.keyboard.isDown("down") then
hero.y = hero.y	+ hero.speed*dt
end

local remEnemy = {}
local remShot = {}
local remFastEnemy = {}

-- update the shots
for i,v in ipairs(hero.shots) do
if v.dir == 1 then
v.y = v.y - dt * 500
elseif v.dir == 2 then
v.x = v.x - dt * 500
else
v.x = v.x + dt * 500
end

-- mark shots that are not visible for removal
if v.y < 0 then
table.insert(remShot, i)
end

-- check for collision with enemies
for ii,vv in ipairs(enemies) do
if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then

-- mark that enemy for removal
table.insert(remEnemy, ii)
-- mark the shot to be removed
table.insert(remShot, i)

end
end

for ii,vv in ipairs(fastEnemies) do
if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
--anim:draw (100,100)
-- mark that enemy for removal
table.insert(remFastEnemy, ii)
-- mark the shot to be removed
table.insert(remShot, i)

end
end

end

-- remove the marked enemies
for i,v in ipairs(remEnemy) do
table.remove(enemies, v)
end

for i,v in ipairs(remFastEnemy) do
table.remove(fastEnemies, v)
end

for i,v in ipairs(remShot) do
table.remove(hero.shots, v)

end

-- update enemies
for i,v in ipairs(enemies) do
-- fall down slowly
v.y = v.y + 20*dt

end

for i,v in ipairs(fastEnemies) do
-- fall down quickly
v.y = v.y + 75*dt

end

end

function love.mousereleased()
if (state == 0) then
start()
end
end

function love.update(dt)
if (state == 1) then
updateGame(dt)
end
end

function drawGame()
love.graphics.setColor ( 255, 255, 255)
love.graphics.draw(backround)

--draw explosion animation
anim:draw (100, 100)

--draw scanner animation
scan:draw (10, 550)

--draw clock animation
sClock:draw (750, 550)

love.graphics.setColor(225,225,225,225)

love.graphics.rectangle("fill", hero.x, hero.y, hero.width, hero.height)
love.graphics.draw(pigman, hero.x-36, hero.y+5, hero.width/25, hero.height/25)

-- draw heros shots
love.graphics.setColor(255,255,255,255)
for i,v in ipairs(hero.shots) do
love.graphics.rectangle("fill", v.x, v.y, 2, 2)
end

-- draw enemies
for i,v in ipairs(enemies) do
love.graphics.draw(enemyPic, v.x+25, v.y-15, v.width/35, v.height/35)
end

for i,v in ipairs(fastEnemies) do
love.graphics.draw(fEnemyPic, v.x+20, v.y-15, v.width/38, v.height/38)
end
love.graphics.setColor (0, 0, 0)
love.graphics.print(# enemies + # fastEnemies, 20, 560)
love.graphics.print (pTimer, 762, 560)

love.graphics.setColor (255, 255, 255)
love.graphics.print("Beta 1.2 ", 10, 10)

score = pTimer

end

end

function drawInformation()
love.graphics.draw (info)
end

function drawGameOver()
love.graphics.draw (Over)
love.graphics.print ("Score:", 340, 350)
love.graphics.print (score, 410, 350)
end

function love.draw()
if (state == 0) then drawMenu() end
if (state == 1) then drawGame() end
if (state == 2) then drawGameOver() end
if (state == 3) then drawInformation() end
end

function love.keyreleased(key)
if key == "w" then
shoot(1)  love.audio.play (woosh)
elseif key == "d" then
shoot(3)  love.audio.play (woosh)
elseif key == "a" then
shoot(2)  love.audio.play (woosh)
elseif key == "i" then
state = 3
elseif key == "m" and state == 2 or state == 3 then
state = 0
pTimer = 0
end
end

function shoot(dir)

local shot = {}
shot.x = hero.x+hero.width/2
shot.y = hero.y
shot.dir = dir
table.insert(hero.shots, shot)

end

function CheckCollision(box1x, box1y, box1w, box1h, box2x, box2y, box2w, box2h)
if box1x > box2x + box2w - 1 or -- Is box1 on the right side of box2?
box1y > box2y + box2h - 1 or -- Is box1 under box2?
box2x > box1x + box1w - 1 or -- Is box2 on the right side of box1?
box2y > box1y + box1h - 1    -- Is b2 under b1?
then
return false                -- No collision. Yay!
else

return true                 -- Yes collision. Ouch!
end
end
Sorry for my code being so messy :\

UPDATE:

So I figured out how to trigger the animation when the bullet hits the enemy, but now I can't figure out how to make the explosion trigger in the appropriate place.

I tried (in function drawGame):

Code: Select all

anim:draw (enemy.x, enemy.y)

But that only applies to the last enemy in the row. I need a way for all of the enemies to be included.
Thanks.

thanks.
Last edited by worldaway on Wed May 30, 2012 12:04 am, edited 3 times in total.

worldaway
Prole
Posts: 44
Joined: Thu Sep 08, 2011 2:22 am

### Re: To Trigger Animations At Certain Times

Puzzlem00n
Party member
Posts: 171
Joined: Fri Apr 06, 2012 8:49 pm
Contact:

### Re: To Trigger Animations At Certain Times

Well, I don't have time to fully answer your question, but seeing that you're desperate for an answer, I'll give you some of my ideas. I think you should somehow put all the explosions x and y (from vv.x and vv.y) in a table and draw them on the screen from that. A problem with that, though, is that you'd need different instances of the explosion animation, which I'm not even sure Lua can do without some workarounds (I think instances are only an OOP thing.)
Also, as a tip to condense the code, I think you should probably somehow make the enemies and fastEnemies the same thing, except with a speed parameter. That way, you don't have to copy-paste code for both all over the thing, like how you have two collision checking loops and two spawning loops.
I LÖVE, therefore I am.

worldaway
Prole
Posts: 44
Joined: Thu Sep 08, 2011 2:22 am

### Re: To Trigger Animations At Certain Times

So I figured out how to trigger the animation when the bullet hits the enemy, but now I can't figure out how to make the explosion trigger in the appropriate place.

I tried (in function drawGame):

Code: Select all

anim:draw (enemy.x, enemy.y)
But that only applies to the last enemy in the row. I need a way for all of the enemies to be included.
Thanks.

Puzzlem00n
Party member
Posts: 171
Joined: Fri Apr 06, 2012 8:49 pm
Contact:

### Re: To Trigger Animations At Certain Times - help?

Maybe something like:

Code: Select all

for q,r in ipairs(enemies) do
anim:draw(r.x, r.y)
end

Or of that nature? I still can barely follow all your code. You may need to change it for whatever property the ones just shot have.
I LÖVE, therefore I am.

worldaway
Prole
Posts: 44
Joined: Thu Sep 08, 2011 2:22 am

### Re: To Trigger Animations At Certain Times - help?

Puzzlem00n wrote:Maybe something like:

Code: Select all

for q,r in ipairs(enemies) do
anim:draw(r.x, r.y)
end

Or of that nature? I still can barely follow all your code. You may need to change it for whatever property the ones just shot have.
Yah, I was thinking of that kind of thing, but It wouldn't work. I used

Code: Select all

for i,v in ipairs (enemies) do
anim:draw (v.x, v.y)
end

Didn't give me an error, just nothing happens.

Yeah my code is super messy, but this game is almost done so I just want to finish it, and hopefully be more organized on my next project.

Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Contact:

### Re: To Trigger Animations At Certain Times - help?

I didn't tried, but it might work...Create different animations for each ennemies.
No, that won't be really costly, cause internally, AnAl stores for each animation, a single reference to an image already loaded once in memory, and a set of quads. Basically, if your ennemies share the same tileset, I guess, just load it once, then store a new animation inside each ennemy table:

Code: Select all

local tileset = love.graphics.newImage(...)
local N_ENNEMY = ... --the very number of ennemies needed
local ennemies = {}
for i=1,N_ENNEMY do
ennemies[i] = {}
-- .. defines ennemies properties
ennemies[i].animOnCollision = newAnimation(...)
ennemies[i].animOnCollision:setMode("once")
end

Then trigging these animations shouldn't be hard:

Code: Select all

for i,ennemy in ipairs(ennemies) do
if CheckCollision(ennemy,bullet) then
--Mark him for later removal
ennemy:animOnCollision:draw(ennemy.x,ennemy.y)
end
end
As I said, untested, but might work.I never used AnAL but, as the code is cleary written and very straightforward to figure out, I have a general idea on how it works.

tsturzl
Party member
Posts: 161
Joined: Fri Apr 08, 2011 3:24 am

### Re: To Trigger Animations At Certain Times - help?

You're code is objective, but in a seemingly weird way... Your objects should have there own methods so inside each object is the code to control that object. Usually I give objects there own init(load), update, and draw functions. This organizes your code and later on can prevent a mess of oddly named variables in the same scope.

Bullets could just be rectangles that are collidible. You should have an enemy object, in that object you should have an AnAL object for your base animation of your enemy. Upon destruction of the enemy simply replace the AnAL object with another AnAL object(possibly reuse the object) that represents the explosion animation, which respectively uses your objects x and y coordinates, thus spawning in the same place. You should then remove the enemy object after the animation time has elapsed. This is a simple calculation, animation speed * frames=animation time.

You should also have an object for your player, where you keep a table of the bullets. You may want to even make an object for the bullets, so you dont put bullet code inside of your player object.

Let me just say this. If you're going to code objectively, code objectively. If you're going to code procedurally, code procedurally. Don't mix styles, it makes a mess.

coke905
Citizen
Posts: 52
Joined: Tue Jun 05, 2012 1:46 am

### Re: To Trigger Animations At Certain Times - help?

K honestly I'm just starting love and I find c++ and allegro incredibly easy. I'm able to create an animation within 5 minutes in c ++ and allegro. But now I see all these people asking for help including me. I like love and I'm planning on sticking with it. Anyone know how I cud do basic character animation. It's one sheet and sprites are 32 x 32. I heard quads can do it so quad tutorial wud be extremely nice thanks

Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm