Tables or Inheritance

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.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Tables or Inheritance

Post by Knaimhe »

I have an element, such as a box2D shape, in a table.
If I send this element to a function, is there any way I could get to the table from that?

I know there's a getBody(), but that's not what I'm looking for.
If there was a getParent() like in RBLX.Lua...

Context: I'm trying to script AI enemies for my game. I can manipulate AI behavior through tables, but I can't get to the health value. Health is stored within the same table as the shape (and the body, and the fixture, etc.).

Alternatively, I can have multiple parallel tables (matrix? probably not, actually) and stick the related values at the same position within each one. For that, I'd need to be able to get the position of an element in the table, if I give a function just the element.
User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Re: Tables or Inheritance

Post by substitute541 »

Roblox Lua... Damn, many people got here from the Love2D Fan Group in ROBLOX...

Anyways, I really don't know about Box2D (I use old fashioned type physics :3)
And what do you mean by "Health is stored within the same table as the shape (and the body, and the fixture, etc.)." ? Can't you do "body.health = 0" ?
Currently designing themes for WordPress.

Sometimes lurks around the forum.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

I've been dealing with similar decisions before.
There are two approaches that you can take:
1.Store a reference from the body or shape to the parent table object:

Code: Select all

shape.parent =
since you can get the body from a shape, it's often preferable to put the reference in the body:

Code: Select all

body.parent =
2.The second approach is much better in my opinion because it de-couples your physics code from the AI and the rendering code. Basically, you set up parallel tables: one containing all the bodies, another table containing all the health data, etc. Both tables are indexed by unique IDs. Therefore, each object in your game is represented by an ID and you pass this ID to functions instead of a table.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

substitute541 wrote:Roblox Lua... Damn, many people got here from the Love2D Fan Group in ROBLOX...

Anyways, I really don't know about Box2D (I use old fashioned type physics :3)
And what do you mean by "Health is stored within the same table as the shape (and the body, and the fixture, etc.)." ? Can't you do "body.health = 0" ?
In Box2D, you cannot make a body a table. A body is an object. Kind'a different from RBLX.Lua, where you can put just about anything inside just about anything else.

The structure here is: (for the 1st technique I mentioned)

Code: Select all

entity = {} --creates a table

entity.body = love.physics.newBody(world, xPos, yPos, "dynamic") --creates a body as an element within the table; a body is an invisible point (on a coordinate plane) with mass and velocity and all that stuff

entity.shape = love.physics.newRectangleShape(width, length) --creates a shape as an element within the table; a shape has area and is used for collisions

entity.fixture = love.physics.newFixture(entity.body, entity.shape, density) --creates a fixture as an element within the table; a fixture attaches a shape to a body

entity.health = 100 --health is a variable within the table and is used to control behavior (mainly alive/dead)
The collisions detector collects fixture data. Fixture data can be used to get to the body. But I still need some kind of method to get from the fixture data or body data to the actual table, where I can then access health.

And I actually got here from a forum thread, not the fan group.


ivan wrote:I've been dealing with similar decisions before.
There are two approaches that you can take:
1.Store a reference from the body or shape to the parent table object:

Code: Select all

shape.parent =
since you can get the body from a shape, it's often preferable to put the reference in the body:

Code: Select all

body.parent =
2.The second approach is much better in my opinion because it de-couples your physics code from the AI and the rendering code. Basically, you set up parallel tables: one containing all the bodies, another table containing all the health data, etc. Both tables are indexed by unique IDs. Therefore, each object in your game is represented by an ID and you pass this ID to functions instead of a table.
For #1:
Impossibru!
To clarify, I'm talking about Love2D, not RBLX.Lua. (Were I to be concerned with the latter, I would have posted on Roblox forums.)
I'm pretty sure ".parent" only works in RBLX.Lua. I tested it out here, to no avail.

For #2:
Yeah, uh... you're pretty much just explaining my original (2nd) plan.
I'm trying to figure out how to get to the ID from the shape/body/fixture.

Another thing: I could use metatables instead of parallel tables. +/-?
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tables or Inheritance

Post by Robin »

Knaimhe wrote:For #2:
Yeah, uh... you're pretty much just explaining my original (2nd) plan.
I'm trying to figure out how to get to the ID from the shape/body/fixture.
Shape:setData and Shape:getData come in handy here.
Knaimhe wrote:Another thing: I could use metatables instead of parallel tables. +/-?
I don't think that applies here. If you explained what you want to do with metatables, I could be more specific.
Help us help you: attach a .love.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

Robin wrote:
Knaimhe wrote:For #2:
Yeah, uh... you're pretty much just explaining my original (2nd) plan.
I'm trying to figure out how to get to the ID from the shape/body/fixture.
Shape:setData and Shape:getData come in handy here.
Knaimhe wrote:Another thing: I could use metatables instead of parallel tables. +/-?
I don't think that applies here. If you explained what you want to do with metatables, I could be more specific.
Shape:setData and Shape:getData were removed in Love 0.8.
I'm currently using the Love 0.8 equivalent, Fixture:set/getUserData.

I think I should go over both of my plans again.

My goal is to write a function that, when given an element in a table, can find the element's position in the table. Note that all of these elements are called the same exact thing.
In context: I'm trying to program multiple instances of AI enemies. These enemies are represented by shapes attached to bodies (This is just Box2D stuff.), but they also have a health value. The collision detector (bullet hits enemy) returns the fixtures of colliding objects. From the fixtures, I can get to the shapes and the bodies. But the problem is that I can't get to the health from anywhere.

Strategy 1 (Metatables):
I could create a table for each instance of an AI enemy. Within this table, there would be a body, a shape, a fixture, (Again, just Box2D stuff.) and a health value. Each enemy would have its own table, but then each enemy-table would be placed into another table. This would be the metatable. From that metatable, I could access individual tables and the contents thereof.

Strategy 2 (Matrices):
This "matrix" would really be more like a series of tables, placed parallel to each other. One table contains all the bodies, another all the shapes, etc. "Parallel" means that corresponding items (corresponding bodies, shapes, fixtures, and health values) would be placed in the same position across multiple tables.

But the individual plans aren't really relevant. What's important is the method to get to the position in the table from a given element within the table.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

Knaimhe wrote:For #1:
Impossibru!
To clarify, I'm talking about Love2D, not RBLX.Lua. (Were I to be concerned with the latter, I would have posted on Roblox forums.)
I'm pretty sure ".parent" only works in RBLX.Lua. I tested it out here, to no avail.
You can store the .parent reference yourself right after creating the shape.
Knaimhe wrote:For #2:
Yeah, uh... you're pretty much just explaining my original (2nd) plan.
I'm trying to figure out how to get to the ID from the shape/body/fixture.
All of your shapes are stored in a table, right? You can just iterate the shapes table and find the appropriate key ID.
Or you can have another table for reverse lookup where the key is a shape and the value is an ID.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

ivan wrote:
Knaimhe wrote:For #1:
Impossibru!
To clarify, I'm talking about Love2D, not RBLX.Lua. (Were I to be concerned with the latter, I would have posted on Roblox forums.)
I'm pretty sure ".parent" only works in RBLX.Lua. I tested it out here, to no avail.
You can store the .parent reference yourself right after creating the shape.
Knaimhe wrote:For #2:
Yeah, uh... you're pretty much just explaining my original (2nd) plan.
I'm trying to figure out how to get to the ID from the shape/body/fixture.
All of your shapes are stored in a table, right? You can just iterate the shapes table and find the appropriate key ID.
Or you can have another table for reverse lookup where the key is a shape and the value is an ID.
Interesting thought, but I don't think I can store a .parent within a body or shape or fixture.
How would I even go about it?
"objects.body.parent = ..." doesn't work, because the body can't be indexed.

Key... key ID? I don't quite understand.
A search method which traverses the table wouldn't work, because all of the instances of AI enemies have the same name.
I hadn't really thought about a reverse table, but I figure that's vulnerable to the same problem.

When an enemy dies, I plan to destroy its components and clear them from the table, so that's another reason I'd need its position in the table.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

Knaimhe wrote:Interesting thought, but I don't think I can store a .parent within a body or shape or fixture.
How would I even go about it?
"objects.body.parent = ..." doesn't work, because the body can't be indexed.
Somebody with more experience with Love2D would have to confirm, but I'm pretty sure bodies and shapes are userdata objects so I don't see why this wouldn't work.
Knaimhe wrote:Key... key ID? I don't quite understand.
A search method which traverses the table wouldn't work, because all of the instances of AI enemies have the same name.
I hadn't really thought about a reverse table, but I figure that's vulnerable to the same problem.
What do you mean by the "same name"?
If you use the shape/body itself as a key in the table you should be fine.
Lua will use the object's reference as a key and no 2 objects will have the same reference.
Just search the table for an object with the same reference.
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: Tables or Inheritance

Post by miko »

ivan wrote:Or you can have another table for reverse lookup where the key is a shape and the value is an ID.
This of course this can be the same table, as long as there are no collisions between the shape and its parent (if those are userdata vs tables, there will never be a collision)
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests