What am I doing wrong here?

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
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: What am I doing wrong here?

Post by kikito »

^^

I'm glad it worked nicely for you!

Object orientation is a nice evolution from functions + tables, but it's still no silver bullet. The same way it is sometimes difficult to divide the code into functions, it is also difficult to group data and functions into classes. Please post in the forum when you hit these difficulties (you will).
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: What am I doing wrong here?

Post by Robin »

+1 to everything nevon just said.
kikito wrote:but it's still no silver bullet.
Coming from you that shocks me greatly. :P

Also, this is not about OO specifically, but it's a tool. And in the world of games, it's a very natural and useful tool 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: What am I doing wrong here?

Post by Jasoco »

Using this information I was able to come up with a sample enemy prototype framework to use in my future and current games..

Code: Select all

enemyPrototype = {}

enemyPrototype.goomba = {}
function enemyPrototype.goomba:new(x,y)
  local enemyInstance = {}
  setmetatable(enemyInstance, {__index = self})
  enemyInstance:reset(x,y)
  return enemyInstance
end
function enemyPrototype.goomba:reset(x,y)
  self.x = x
  self.y = y
end
function enemyPrototype.goomba:update(dt)
  self.x = self.x + math.cos(time)
  self.y = self.y + math.sin(time)
end
function enemyPrototype.goomba:draw()
  gr.setColor(100,50,10)
  gr.circle("fill", self.x, self.y, 8)
end

enemyPrototype.koopa = {}
function enemyPrototype.koopa:new(x,y)
  local enemyInstance = {}
  setmetatable(enemyInstance, {__index = self})
  enemyInstance:reset(x,y)
  return enemyInstance
end
function enemyPrototype.koopa:reset(x,y)
  self.x = x
  self.y = y
end
function enemyPrototype.koopa:update(dt)
  self.x = self.x + math.cos(time)
  self.y = self.y + math.sin(time)
end
function enemyPrototype.koopa:draw()
  gr.setColor(0,255,0)
  gr.circle("fill", self.x, self.y, 8)
end
Koopa and Goomba are used as examples. It's just an example for future use.
If I want to make say, a new Goomba, I call enemy[id] = enemyPrototype.goomba:new(x,y)

Another question would be about checking for collisions with each other. How would I go about that the best way? Have to iterate over the table of enemies and check all of them against the current one. But how would I know which is the current self without passing the table id into the update function first so I know which one is the current one so as not to check against itself?
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: What am I doing wrong here?

Post by miko »

Jasoco wrote: Another question would be about checking for collisions with each other. How would I go about that the best way? Have to iterate over the table of enemies and check all of them against the current one. But how would I know which is the current self without passing the table id into the update function first so I know which one is the current one so as not to check against itself?

Code: Select all

function ...:update(dt)
...
for id,e in pairs(enemy) do
  if e~=self then
      checkCollision(self, e)
  end
end
That would be "brute force" approach (ie. check every combination), and is not efficient (but could be good enough for small number of objects).
Note that you would check A against B and B against A - so half of those checks would be reduntant (if A collides with B, then B collides with A).
You could checkfor collisions only for those objects which have just changed their position (if some of them are not moving).
You could check for collisions between neighbours only, if you could tell which of them are close to each other (for example, google for "quad tree").
Finally, you need to define a collision. That could be collisions between points (the easiest), rectangles ("bounding boxes"), circles, or more complicated shapes. In practice, using rectangles or circles is good enough.
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: What am I doing wrong here?

Post by BlackBulletIV »

nevon wrote:That said, I find it amazing that you were able to create your adventure game engine without knowing OOP. That must have been hell.
Here, here! Coding anything that's not small without OOP is a nightmare for me.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: What am I doing wrong here?

Post by kikito »

Jasoco wrote:Using this information I was able to come up with a sample enemy prototype framework to use in my future and current games.. (...)
Well, I prefer classes to prototypes, but I'll keep an eye on your evolution there. It's certainly a less beaten path than classic object orientation.
Jasoco wrote:Another question would be about checking for collisions with each other. How would I go about that the best way? Have to iterate over the table of enemies and check all of them against the current one. But how would I know which is the current self without passing the table id into the update function first so I know which one is the current one so as not to check against itself?
There are lots of approaches here. The simplest approach is certainly comparing every enemy with every other enemy, on each iteration.

The simplest way avoid "comparing against self" is doing exactly that: if (other ~= current) then ....

The brute force approach is good enough when the number of objects being compared is more or less low. It increases its cost exponentially with each new object that you add. If you are going to have lots of entities simultaneously, you will probably want to trim down the number of comparisons that you do.

One approach is dividing the "space" into sections. You divide the screen into, say, 16 rectangular sections. Then, whenever you update the coordinates of each enemy, you also update the section on which that enemy is. And when you need to check for collisions, you only compare with the enemies on that section (there are special conditions for enemies "in between" sections).

Another approach is having a "hard map". A hard map is a 2d array representing your screen, usually at a smaller resolution. At the begining of each frame, the hardmap cells are reset to a "blank" state, for example the number 0. Then, on the update function, every enemy "draws itself" on the hard map. This is, it changes some 0s to 1s. Collision detection then is a matter of looking at the hardmap and checking for a 1. This method is the fastest but also the one with lowest resolution; there are occasions in which 2 entities draw a "1" on the hardmap but they don't really collide; they are just close. This is why this method is better for tile-based games, specially if movement is done tile-by-tile, and not incrementally.
Last edited by kikito on Sat Apr 16, 2011 11:57 pm, edited 2 times in total.
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: What am I doing wrong here?

Post by Robin »

kikito wrote:The
I think you miss something there.
Help us help you: attach a .love.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: What am I doing wrong here?

Post by kikito »

It was a leftover from my edits. I've removed it now, thanks! (I also fixed incorrectly closed quotes)
When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: What am I doing wrong here?

Post by Jasoco »

Here's a question.

How's come I can do this:

Code: Select all

enemySet.goomba = {}

function enemySet.goomba:setup(v)
  ...
end
But I can't do this:

Code: Select all

enemySet["goomba"] = {}

function enemySet["goomba"]:setup(v)
  ...
end
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: What am I doing wrong here?

Post by bartbes »

Not.. sure.., I know you can work around and do this, though:

Code: Select all

enemySet["goomba"].setup = function(self, v)
or:

Code: Select all

local goomba = enemySet["goomba"]
function goomba:setup(v)
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 220 guests