middleclass & extras: middleclass 3.0 is out!

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by BlackBulletIV »

Well I remember having trouble somewhere with them, possibly in plain Lua. But, they don't provide any benefit and can cause problems some times, so I wouldn't use them.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by bartbes »

Yeah, they are only in there for legacy support and it only works in love, I guess we should take them out sometime..
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: middleclass & middleclass-extras: OOP for LUA

Post by Kadoba »

Noooooo... :(
LuaWeaver
Party member
Posts: 183
Joined: Wed Mar 02, 2011 11:15 pm
Location: Ohio, USA

Re: middleclass & middleclass-extras: OOP for LUA

Post by LuaWeaver »

Wait a minute---
wait.

I understand OOP now :3. Everything is just a table with "children" that can have things other then "children" such as functions and values and even subclasses mixed in with those and those can have subclasses and those...

*dies*
"your actions cause me to infer your ego is the size of three houses" -finley
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by BlackBulletIV »

I'm not completely sure whether what you're thinking of is OOP (are you just trying to give the impression of confusion?), but yes, OOP is a very abstract concept, usually being rather hard to wrap your head around.
LuaWeaver
Party member
Posts: 183
Joined: Wed Mar 02, 2011 11:15 pm
Location: Ohio, USA

Re: middleclass & middleclass-extras: OOP for LUA

Post by LuaWeaver »

BlackBulletIV wrote:I'm not completely sure whether what you're thinking of is OOP (are you just trying to give the impression of confusion?), but yes, OOP is a very abstract concept, usually being rather hard to wrap your head around.
Yes, difficult. I only now understand. Table in tables in tables. Sorry about the wording, I'm used to Roblox OOP.
"your actions cause me to infer your ego is the size of three houses" -finley
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by Robin »

LuaWeaver wrote:Table in tables in tables.
No, that's Inception. :P
Help us help you: attach a .love.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by BlackBulletIV »

LuaWeaver wrote:Table in tables in tables.
In Lua it would be metatables actually.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by Jasoco »

Robin wrote:
LuaWeaver wrote:Table in tables in tables.
No, that's Inception. :P
No, that's Xzibit.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by kikito »

LuaWeaver wrote:Wait a minute---
wait.

I understand OOP now :3. Everything is just a table with "children" that can have things other then "children" such as functions and values and even subclasses mixed in with those and those can have subclasses and those...

*dies*
It's a bit more complex than that ... and more simple too.

OOP has two main concepts: classes and instances.

Classes are just a bunch of properties - mostly functions.

When you create a class, you do it because you need a way to represent "common properties shared by a bundh of elements in your game". Those "elements", are usually the "instances" of the class. The "properties" are usually functions.

For example, if you are going to create a game with lots of balls bouncing around. A first approach using simple tables (no oop) could be this one:

Code: Select all

function love.load()
  ball1 = { x=100, y=100 }
  ball2 = { x=200, y=100 }
  ball3 = { x=300, y=100 }
end

function love.draw()
  love.graphics.circle('line', ball1.x, ball1.y, 100)
  love.graphics.circle('line', ball2.x, ball1.y, 100)
  love.graphics.circle('line', ball3.x, ball1.y, 100)
end
Imagine that now you want to have a different radius for each ball. You could do it like this:

Code: Select all

function love.load()
  ball1 = { x=100, y=100, radius = 10 }
  ball2 = { x=200, y=100, radius = 20 }
  ball3 = { x=300, y=100, radius = 30 }
end

function love.draw()
  love.graphics.circle('line', ball1.x, ball1.y, ball1.radius)
  love.graphics.circle('line', ball2.x, ball1.y, ball2.radius)
  love.graphics.circle('line', ball3.x, ball1.y, ball3.radius)
end

Creating balls starts getting complicated when start needing more properties. For example, a color. It makes sense to have a createBall function so you don't have to type that much. And you will probably want a "drawBall" function too:

Code: Select all

function createBall(x,y,radius,color)
  return {x=x, y=y, radius=radius, color=color}
end
function drawBall(ball)
  love.graphics.setcolor(unpack(ball.color))
  love.graphics.circle('line', ball.x, ball.y, ball.radius)
end

function love.load()
  ball1 = createBall(100, 100, 10, { 255,   0,   0 })
  ball2 = createBall(200, 100, 20, {   0, 255,   0 })
  ball3 = createBall(300, 100, 30, {   0,  0, 255 })
end

function love.draw()
  drawBall(ball1)
  drawBall(ball2)
  drawBall(ball3)
end
Remember what I told you about classes? They are thought to "group together" common properties (functions) of elements.

Look at createBall and drawBall. Don't they seem to be somehow "shared" by ball1, ball2 and ball3?

If we were to use OOP with this program, ball1, ball2 and ball3 would be instances of a class; and usually that class would be called Ball. createBall and drawBall would be methods of Ball; Since drawBall is going to be part of Ball, we can simply call it "Ball:draw" (instead of "Ball:drawBall"). For implementation reasons, createBall will get transformed into a method called "initialize" - that's just how it should be called in middleclass. Also, inside those methods, the "ball" parameter will be replaced by a parameter called "self". Let me show you:

Code: Select all

require 'middleclass'

Ball = class('Ball')

function Ball:initialize(x, y, radius, color) -- this was createBall
  self.x, self.y, self.radius, self.color = x, y, radius, color
end

function Ball:draw() -- this was drawball
  love.graphics.setcolor(unpack(self.color))
  love.graphics.circle('line', self.x, self.y, self.radius)
end

function love.load()
  ball1 = Ball:new(100, 100, 10, { 255,   0,   0 })
  ball2 = Ball:new(200, 100, 20, {   0, 255,   0 })
  ball3 = Ball:new(300, 100, 30, {   0,  0, 255 })
end

function love.draw()
  ball1:draw()
  ball2:draw()
  ball3:draw()
end
It doesn't look like much. But there are several things going on here. First, the amount of global variables used has been reduced. That is always good. Second, ball1:draw(...) works. That's because ball1, ball2, and ball3 are built so that they "know how to ask" their class (Ball) for its methods. If you add another method to Ball (for example, Ball:update), and it will also be shared by ball1, ball2, and ball3.

So that's the first part of OOP, in a very simple way: common functions go into a class, and specifics (like the x coordinate or the color) go into the instances. The instances "ask their class for help" when needed.

But that is not all.

A class can have a "superclasses" (a "father", if you want) and "subclasses" (the "children"). (A class could have no parents or children though).

When a class A is a subclass of class B, it's also common to say that is "inherits" from B. And the process of creating a subclass is often called "inheritance".

When the instances of class A find a method they don't know, they ask A. If A doesn't know about that method, it asks B!. That continues until no superclasses are left (nil is returned on that case).

This is very useful to organize the common functions into "groups and subgroups". This is not so easy to implement with regular non-oop tables and functions, and I'm not going to attempt it. For an example of inheritance, see the Person and AgedPerson example in the middleclass wiki.

The typical example: You could have a class called "Enemy" with one single method, called "damagePlayer", and then a subclass of Enemy called "Orc" that contained an orc-specific "Orc:draw()" method, and yet another subclass of Orc called MegaOrc that modified the damagePlayer method and increased the damage.

In middleclass, classes can only have 1 superclass, but they can have as many subclasses as needed. Every class generated has a superclass called Object, which provides some boilerplate methods. Object is the only class that doesn't have a superclass.

Finally, I'd also want to point out that the fact that classes and instances are tables on middleclass is just an implementation detail; other OOP implementations could use other stuff (for example Userdata). The important thing is not how OOP is implemented, but how it behaves.

Sorry for the long post. I hope it helps.
Last edited by kikito on Wed Jun 29, 2011 11:55 am, edited 1 time in total.
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: No registered users and 210 guests