Accessible objects and Love

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.
User avatar
Carl
Prole
Posts: 18
Joined: Wed Oct 28, 2009 10:32 pm

Re: Accessible objects and Love

Post by Carl »

Great explanation anjo, really makes sense now. Though how would I go about creating objects at runtime as apposed to having them all created when the game is loaded?

This is my code so far:

Code: Select all

function load()
	ObjectsList = {} -- A global list of all objects inside of the game
		local Block1 = {} -- First object in the list "Block1"
		Block1.x = 100
		Block1.y = 100
		Block1.sprite = love.graphics.newImage("block.png")
		function Block1:draw()
		love.graphics.draw(self.sprite,self.x,self.y)
		end
	
	ObjectsList[1] = Block1
end

function draw()
	for i,v in ipairs(ObjectsList) do
		v:draw()
	end
end
I tried table.insert but that didn't work as I had hoped. (I want to essentially duplicate block1 along with all of its code and name it block2).

Thanks for the help. :D
User avatar
bmelts
Party member
Posts: 380
Joined: Fri Jan 30, 2009 3:16 am
Location: Wiscönsin
Contact:

Re: Accessible objects and Love

Post by bmelts »

Sketchy wrote:Think I need to read up on "ipairs" too, as I don't actually know what that does...
Basically, ipairs will iterate over an array in numerical order.

Code: Select all

for i, v in ipairs(t) do
   -- do stuff
end
If you've programmed in other languages, you might be used to for loops that look like "for (int i = 0; i < j; i++)". Lua has these too, though they look slightly different. They're called numeric for loops. This for loop, on the other hand, is a generic for loop. (You can read about them here and here, respectively.) See the "i, v" part? The ipairs function gives you two variables to work with. The first (i) is the index of the array that it's at. So, it'll start at 1, then increase every loop, until it reaches the end of the array. The second (v) is more interesting: it's the value of the array at index i. v == t[ i ]. If it helps, you can think of ipairs as similar to this:

Code: Select all

for i=1, #t do   -- #t means the size of table t
   local v = t[i]
   -- do stuff
end
It's better to use ipairs, though. (And if you're using tables with non-numerical keys, you need to use pairs, which is like ipairs' older brother. pairs will do the same thing over every element of a table - but in no particular order.)
Carl wrote:Great explanation anjo, really makes sense now. Though how would I go about creating objects at runtime as apposed to having them all created when the game is loaded?
By leveraging the power of the ObjectsList! Let's say the player should create a block every time they click. We'd put the following code in:

Code: Select all

function mousepressed(x, y)
   local Block = {}
   Block.x = x
   Block.y = y
   Block.sprite = love.graphics.newImage("block.png")
   function Block:draw()
      love.graphics.draw(self.sprite, self.x, self.y)
   end
   table.insert(ObjectsList, Block)
end
Next time the game calls its draw() function, when it loops through the contents of ObjectsList, it will find the new Block you put in, and draw it where the person clicked.
Carl wrote:(I want to essentially duplicate block1 along with all of its code and name it block2)
The best way to do that is to create a generator function - a function that returns a new block completely separate from any other block. It might look something like this:

Code: Select all

function newBlock(x, y)
   local block = {}
   block.x = x
   block.y = y
   block.sprite = love.graphics.newImage("block.png")
   function block:draw()
     love.graphics.draw(self.sprite, self.x, self.y)
   end
   return block
end
That way, any time you want to create a block, just call newBlock() with the x and y coordinates. So, for Block1, you'd do something like this:

Code: Select all

local Block1 = newBlock(100, 100)
local Block2 = newBlock(Block1.x, Block1.y)
And the mousepressed() example above could be simplified to:

Code: Select all

function mousepressed(x, y)
   table.insert(ObjectsList, newBlock(x, y))
end
If you want to copy the current state of a block to a new object, that's a bit more annoying, assuming you want them to act separately, so a change in one doesn't affect the other. If that's the case, try this:

Code: Select all

function copy(t)
   local copied = {}
   for k,v in pairs(t) do
     copied[k] = v
   end
   return copied
end
So to create a copy of Block1 called Block2:

Code: Select all

Block1 = newBlock(100, 100)
-- do stuff to Block1
Block2 = copy(Block1)
And you'll end up with a new block that has identical properties to Block1, but can be manipulated separately without affecting the original. The above copy() function isn't perfect, but for simple copying purposes it should suffice.
User avatar
Carl
Prole
Posts: 18
Joined: Wed Oct 28, 2009 10:32 pm

Re: Accessible objects and Love

Post by Carl »

Amazing, exactly what I was after. Thanks a million anjo!
User avatar
Sketchy
Prole
Posts: 5
Joined: Fri Oct 30, 2009 2:54 pm
Location: Cörnwall, UK

Re: Accessible objects and Love

Post by Sketchy »

Thanks again for another very detailed reply.
You even pre-empted my next question, which would have been "What do you use for non-numerical keys?" :)
Post Reply

Who is online

Users browsing this forum: Bing [Bot], darkfrei and 82 guests