Page 1 of 1

Layers order

Posted: Tue Feb 23, 2010 3:38 pm
by malkian
I'm just starting my first experience with LOVE, it seems really a nice project!
I've a doubt... how to "move" object between layers... i mean.. "back" and "forth"... :oops:
Any hints?

Re: Layers order

Posted: Tue Feb 23, 2010 3:47 pm
by Robin
There aren't really layers, you just change the order in which you draw images (and text etc):

Code: Select all

function love.draw()
    love.graphics.draw(image1, 10, 10)
    love.graphics.draw(image2, 50, 50)
end
image2 will be drawn on top of image1. To change the order you will want to use tables, instead of using just image1, 10, 10 and image2, 50, 50.

Re: Layers order

Posted: Tue Feb 23, 2010 3:50 pm
by malkian
Mmm if i want to change the order dynamically? I've to redraw all the images?

Re: Layers order

Posted: Tue Feb 23, 2010 4:36 pm
by Robin
Well, all the images are always redrawn every frame. Since this is a game engine, it is assumed it will usually be dynamic anyway. ;)

There are plenty of example games on the forum, pick one or two and read the source code. That will help you understand how this engine works.

Re: Layers order

Posted: Tue Feb 23, 2010 7:10 pm
by malkian
lol it's true XD thank you so much XD

Re: Layers order

Posted: Thu Feb 25, 2010 3:12 am
by Jasoco
I played around with draw order a few weeks ago when I was playing a side-scrolling beat-em-up game (Like TMNT or The Simpsons Arcade) where you could move up or down in the scenery to go in front of or behind another character and figured out the best way for me to achieve a "z-index" was to take every object that needs a z-index, dump it into a new table by y value, while also checking the player's y value and placing it appropriately.. God, that's confusing to read and explain. Here's the code to give an idea...

Code: Select all

function load()
	pi = math.pi
	math.randomseed(os.time())

	monoFont = love.graphics.newImageFont("images/mono.gif", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\"", 1)

	gOff = 200 --Offset of the top edge of the world...

	player = { x = 100, y = 50, hp = 100 }
	enemy = {}
	for i=1,5 do enemy[i] = { x = 100 + (20 * i), y = 120 - (20 * i), hp = 100} end

	objBubble = {}
end

function update(dt)
	if love.keyboard.isDown(love.key_left) then player.x = player.x - (256*dt) end
	if love.keyboard.isDown(love.key_right) then player.x = player.x + (256*dt) end
	if love.keyboard.isDown(love.key_up) then player.y = player.y - (128*dt) end
	if love.keyboard.isDown(love.key_down) then player.y = player.y + (128*dt) end
	if player.y < 0 then player.y = 0 end

	-- When the Update function is called it creates a special table just for all the objects to draw. It then places all the objects and the player into the table based on their Y positions. The player is placed when the time comes, then no more until the next loop. 
	local playerPlaced = false
	objBubble = {}
	for i=0,299 do
		for j, e in ipairs(enemy) do
			if e.y == i then
				if e.x < 800 then
					table.insert(objBubble, {x = e.x, y = e.y, hp = e.hp, name = "Enemy"})
				end
			end
		end
		if math.floor(player.y) == i and playerPlaced == false then
			--This part will place the player where it belongs. Once it's placed, it won't be placed again.
			table.insert(objBubble, {x = player.x, y = player.y, hp = player.hp, name = "Player" })
			playerPlaced = true
		end
	end

	love.timer.sleep(10)
end

function draw()
	love.graphics.setBackgroundColor(255,255,255)

	local data = "FPS: " .. love.timer.getFPS() .. "\n"
	data = data .. table.getn(objBubble) .. "\n"
	for i, e in ipairs(objBubble) do
		love.graphics.setColor(love.graphics.newColor(255-(i*25),0,i*25,255))
		love.graphics.rectangle(love.draw_fill, e.x, e.y-64+gOff, 32, 64)
		data = data .. e.name .. " " .. e.y .. "\n"
	end

	love.graphics.setFont(monoFont)
	love.graphics.setColor(love.graphics.newColor(0,0,0,255))
	love.graphics.draw(data, 11, 11)
end
Though since I created this, I discovered the table.sort() function. I assume that would be a better method than what I used. I created it in the case I ever want to make a TMNT/Simpsons classic Konami-style beat-em-up clone.

Re: Layers order

Posted: Thu Feb 25, 2010 8:02 am
by kikito
table.sort() is really the way to go, in my opinion :)

Re: Layers order

Posted: Thu Feb 25, 2010 9:17 pm
by Jasoco
I would still dump all objects that need to be drawn into a single table, then sort that table by its y values. (With higher Y's coming later than lower Y's. So that lower Y's get drawn first.)

A sample sorting algorithm:

Code: Select all

function sort(T)
	table.sort(T,
		function(first, second)
			return first.var1 < second.var1
		end
	)
end
Where var1 would be the table column to sort by. (In this case, the Y) And T is the table name. i.e. sort(tablename)

So, basically, every frame you need to:
1) Reset a table whose one reason for existing is to hold all the objects by calling tablename = {}.
2) Add all enemies to a table -- table.insert(tablename, {x = whatever, y = whatever, etc...}
3) Add all other stuff to the same table
4) Add the player(s) to the same table -- table.insert(tablename, { x = playerx, y = playery, etc...}
5) Sort the table -- sort(tablename)
6) run through the table using for i,t in ipairs(tablename) to draw all the objects

Should work swimmingly.