Object-Oriented Programming in Love2D(Lua)

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
river2056
Prole
Posts: 1
Joined: Sun Nov 28, 2021 5:05 am

Object-Oriented Programming in Love2D(Lua)

Post by river2056 »

I got interested in Love2D and Lua and decided to give it a try.

So in order to get familiar both with Lua and Love2D, I code out an easy sample:

Project Struture:
demo
|-ball.lua
|-main.lua

ball.lua
```
Ball = {
x = 0,
y = 0,
xSpeed = 0,
ySpeed = 0,
ballRadius = 0,
r = 0,
g = 0,
b = 0
}

function Ball:new(x, y, xSpeed, ySpeed, ballRadius, r, g, b)
t = {
x = x,
y = y,
xSpeed = xSpeed,
ySpeed = ySpeed,
ballRadius = ballRadius,
r = r,
g = g,
b = b
}
setmetatable(t, self)
self.__index = self
return t
end

function Ball:move()
self.x = self.x + self.xSpeed
self.y = self.y + self.ySpeed
end

function Ball:changeColor()
self.r = love.math.random(0, 255)
self.g = love.math.random(0, 255)
self.b = love.math.random(0, 255)
print('color: ' .. self.r .. ' ' .. self.g .. ' ' .. self.b)
end

function Ball:checkEdges()
if self.x + self.ballRadius > love.graphics.getWidth() or self.x - self.ballRadius < 0 then
self.xSpeed = self.xSpeed * -1
Ball:changeColor()
end
if self.y + self.ballRadius> love.graphics.getHeight() or self.y - self.ballRadius < 0 then
self.ySpeed = self.ySpeed * -1
Ball:changeColor()
end
end

function Ball:show()
love.graphics.setColor(self.r, self.g, self.b)
love.graphics.ellipse('fill', self.x, self.y, self.ballRadius)
end
```

main.lua
```
require "ball"
local ball = nil
local x, y

function love.load()
x = love.graphics.getWidth() / 2
y = love.graphics.getHeight() / 2
ball = Ball:new(x, y, 2, 3.5, 20, 255, 255, 255)
end

function love.update(dt)
Ball.move(ball)
Ball.checkEdges(ball)
end

function love.keypressed(key)
if key == 'escape' then
love.event.quit()
end
end

function love.draw()
love.graphics.setBackgroundColor(0, 0, 0)
Ball.show(ball)
end
```

so basically it's just a ball bouncing around when it hits the edges.
Everything seems fine except for the function Ball:changeColor()
I want the ball to change color everytime it hits the edges, but this isn't working. is it something wrong with the function changeColor() ?

here's a snapshot of the demo:
Image

the function did trigger and the rgb color values did change, but the ball itself didn't change color, any help is appreciated!
MrFariator
Party member
Posts: 548
Joined: Wed Oct 05, 2016 11:53 am

Re: Object-Oriented Programming in Love2D(Lua)

Post by MrFariator »

phpBB forums use [code]...[/code] tags for code, for future reference.

Anyway, the problem seems to be with how you're calling the changeColor function:

Code: Select all

function Ball:checkEdges()
  if self.x + self.ballRadius > love.graphics.getWidth() or self.x - self.ballRadius < 0 then
    self.xSpeed = self.xSpeed * -1
    Ball:changeColor()
  end
  if self.y + self.ballRadius> love.graphics.getHeight() or self.y - self.ballRadius < 0 then
    self.ySpeed = self.ySpeed * -1
    Ball:changeColor()
  end
end
You're calling the changeColor function on the class Ball, as opposed to your instance of the class. As such, your class' rgb fields get changed, which doesn't affect the instance, because they use different tables for looking the rgb values up. All you have to do is change the function calls to:

Code: Select all

self:changeColor()
And it should work. Also, keep in mind that in newer versions of LÖVE, love.graphics.setColor uses the range [0,1], as opposed to [0,255] as it did previously. So if the ball still remains white after fixing the function call, you could change the contents of your changeColor function:

Code: Select all

function Ball:changeColor()
  self.r = love.math.random() -- returns a number in range [0,1] if no arguments are given
  self.g = love.math.random()
  self.b = love.math.random()
  print('color:', self.r, self.g, self.b) -- you can save some processing power by not doing any string concatenation here, like so 
end
On another note, those places where you write something like

Code: Select all

Ball.move(ball)
they could be changed to

Code: Select all

ball:move()
Both lines achieve the same goal, but this way it becomes clearer what's an instance, and what's a class. Of course, that's when you use more distinguishable names than "Ball" and "ball". It also helps in the case if you use some state machine, and the "move" function that the instance holds a reference to changes.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests