Timed animations attached to images.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

Timed animations attached to images.

Post by Ryne »

Alright. My game world is covered in trees. Now these trees aren't animated, but I'd like to give them the FEEL of being animated.

Image

The animation is a little quick in that example, but you get the idea. So right now I have a small "leaf falling" animation that can just be placed over any of the existing trees, the thing is, I don't want to over-use this animation, I only want it to appear on tree in the scene, every few seconds. So if there are 10 trees on screen, it would randomize among them, but at a relatively slow rate. Probably 1 random tree every 3-5 seconds.

The same goes for that little water splash animation there. Now I'm going to do something embarrassing and post my code, for how I have trees spawning on the map.

First I've got this big Quad for all of the tree graphics:

Code: Select all

	quads = {
		love.graphics.newQuad(0, 0, 16, 16, 64, 128), -- 1 big white
		love.graphics.newQuad(32, 0, 16, 16, 64, 128), -- 2 big green
		love.graphics.newQuad(32, 32, 16, 16, 64, 128), -- 3 big blue
		love.graphics.newQuad(0, 32, 16, 16, 64, 128), -- 4 big orange
		love.graphics.newQuad(0, 16, 16, 16, 64, 128), -- 5 med white
		love.graphics.newQuad(0, 48, 16, 16, 64, 128), -- 6 med orange
		love.graphics.newQuad(32, 48, 16, 16, 64, 128), -- 7 med blue
		love.graphics.newQuad(32, 16, 16, 16, 64, 128), -- 8 med green
		love.graphics.newQuad(16, 0, 16, 16, 64, 128), -- 9 2 white
		love.graphics.newQuad(16, 32, 16, 16, 64, 128), -- 10 2 orange
		love.graphics.newQuad(48, 0, 16, 16, 64, 128), -- 11 2 green
		love.graphics.newQuad(48, 32, 16, 16, 64, 128), -- 12 2 blue
		love.graphics.newQuad(16, 16, 16, 16, 64, 128), -- 13 single white
		love.graphics.newQuad(16, 48, 16, 16, 64, 128), -- 14 single orange
		love.graphics.newQuad(48, 16, 16, 16, 64, 128), -- 15 single green
		love.graphics.newQuad(48, 48, 16, 16, 64, 128), -- 16 single blue
		love.graphics.newQuad(0, 64, 16, 16, 64, 128), -- 17 water well
		love.graphics.newQuad(16, 64, 16, 16, 64, 128), -- 18 empty well
		love.graphics.newQuad(32, 64, 16, 16, 64, 128), -- 19 wide well empty
		love.graphics.newQuad(48, 64, 16, 16, 64, 128), -- 20 wide well concrete
		love.graphics.newQuad(0, 80, 16, 16, 64, 128), -- 21 small well empty
		love.graphics.newQuad(16, 80, 16, 16, 64, 128), -- 22 2 sticks
		love.graphics.newQuad(32, 80, 16, 16, 64, 128), -- 23 1 sm stick
		love.graphics.newQuad(48, 80, 16, 16, 64, 128), -- 24 1 lrg stick
		love.graphics.newQuad(0, 96, 16, 16, 64, 128), -- 25 house marker
		love.graphics.newQuad(0, 96, 16, 16, 64, 128) -- 26 water float marker
	}
And this is my draw code.

Code: Select all

function drawTrees()

	for i = 1, #map do
		for l = 1, #map do
			if map[i][l] ~= 0 then
			love.graphics.drawq(images.tileset, quads[map[i][l]], mapToWorld(l-1, i-2))
			end
		end
	end

end
I know, it's ugly - but I understand it at least - and with my limited programming skills it does the job.

Any ideas guys?
@rynesaur
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: Timed animations attached to images.

Post by Taehl »

One quick-but-dirty way to do it is (I'm assuming you have code for doing the animation already. AnAL or something), add to your drawing code a check for if it's a tree, and and if math.random(9000)==1, then do the animation instead of the regular drawing.

Code: Select all

function drawTrees()
	for i = 1, #map do
		for l = 1, #map do
			local tile = map[i][l]
			if tile ~= 0 then
				if tile <= 16 and math.random(9000) == 1 then
					StartAnimation(tile)	-- however you do your animations
				else
					love.graphics.drawq(images.tileset, quads[map[i][l]], mapToWorld(l-1, i-2))
				end
			end
		end
	end
end
There are other ways to do this, some of which may be better, but this would be the quickest.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Timed animations attached to images.

Post by Jasoco »

Each tree, house, chicken, person, well, whatever should be an object with its own update and draw functions. You'd put the timing and calculating in the update function. And when placing the trees, give only one tree the ability to animate a leaf and the rest have it disabled.

Is what I would do.

Plus as objects you could sort them by Y and then draw it with depth and proper overlapping.
User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

Re: Timed animations attached to images.

Post by Ryne »

Taehl wrote:One quick-but-dirty way to do it is (I'm assuming you have code for doing the animation already. AnAL or something), add to your drawing code a check for if it's a tree, and and if math.random(9000)==1, then do the animation instead of the regular drawing.

Code: Select all

function drawTrees()
	for i = 1, #map do
		for l = 1, #map do
			local tile = map[i][l]
			if tile ~= 0 then
				if tile <= 16 and math.random(9000) == 1 then
					StartAnimation(tile)	-- however you do your animations
				else
					love.graphics.drawq(images.tileset, quads[map[i][l]], mapToWorld(l-1, i-2))
				end
			end
		end
	end
end
There are other ways to do this, some of which may be better, but this would be the quickest.
will try this once I get into the animations, thanks!

Jasoco wrote:Each tree, house, chicken, person, well, whatever should be an object with its own update and draw functions. You'd put the timing and calculating in the update function. And when placing the trees, give only one tree the ability to animate a leaf and the rest have it disabled.

Is what I would do.

Plus as objects you could sort them by Y and then draw it with depth and proper overlapping.
I was thinking of having a "tree spawn" function to add any trees to a "trees" table as it's own thing, then a "draw trees" function to draw them. Is that what you mean by it's "own" object?
@rynesaur
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Timed animations attached to images.

Post by Jasoco »

Example Pseudocode. This is how I personally make "objects"

Code: Select all

object = {}
  
--WHERE ID IS A RANDOM NUMBER OR UNIQUE IDENTIFIER
local id = math.random(10000,99999) --To make sure you don't have the same ID twice make the number range bigger or use some hash creation algorithm
object[id] = tree:create( { x = 100, y = 100, type = 3, id = id } )

Code: Select all

switchSet = {}

function tree:create(v)
  local instance = {}
  setmetatable(instance, {__index = self})
  instance:reset(v)
  return instance
end

function tree:reset(v)
  v = v or {}
  self.x = v.x
  self.y = v.y
  self.id = v.id --ID would be passed into the function when the tree is created. It would be equivalent to the table index for your tree object for easy reference
  self.type = v.type or math.random(1,5) --Choose a random type for the appearance if no number is specified
  self.leaf = v.leaf or false --If leaf is not true, then there is no leaf
  self.leaftimer = math.random(5,30) --Where the numbers are how often you'd want the animation to play
end

function tree:update(dt)
  self.leaftimer = self.leaftimer - dt
  if self.leaftimer <= 0 then
    --ANIMATION INITIALIZATION GOES HERE
    self.leaftimer = math.random(5,30) --Where the numbers are how often you'd want the animation to play
  end
end

function tree:draw()
  --DRAW THE TREE OF WHATEVER TYPE IT IS
  --DRAW THE ANIMATION OF A LEAF IF IT IS CURRENTLY ACTIVE
end
Then in the main game code:

Code: Select all

for i, o in pairs(object) do
  o:update(dt)
end

for i, o in pairs(object) do
  o:draw()
end
Remember this is just pseudocode and doesn't take into account sorting by the Y value for creating a layered feel. It's just to get an idea. If you use sorting, you'd have to add every object, player and actor into a new "Drawable" table, sort the drawable table by Y and then run through the drawable table drawing everything from top to bottom. I've done it many times including with my shelved Adventure Engine project.
User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

Re: Timed animations attached to images.

Post by Ryne »

ahh, I was thinking something like this.

Code: Select all

trees = {}

function spawnTrees(x,y,w,h)

	table.insert(trees, {x=x, y=y, w=w, h=h})

end

function drawTrees()

	for i=1, #trees do			 
		trees[i].anim:draw(trees[i].x, trees[i].y)
	end

end
then probably write some code to remove the trees from the table if they aren't on screen or something.

I guess your way is probably better, though I think I'll try it my way since I understand it fully. I think when I'm finished I might get a few people to help me clean everything up. It's sure to get ugly.
@rynesaur
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Timed animations attached to images.

Post by Robin »

Why the random id, Jasoco? Why not simply count from 1? That would give no collisions, and be more efficient as well.
Help us help you: attach a .love.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Timed animations attached to images.

Post by Jasoco »

It's just the way I roll, Robin. The way I roll.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 76 guests