Love2D(Lua)中的面向对象编程

Posted

技术标签:

【中文标题】Love2D(Lua)中的面向对象编程【英文标题】:Object-Oriented Programming in Love2D(Lua) 【发布时间】:2022-01-05 11:23:55 【问题描述】:

我对 Love2D 和 Lua 很感兴趣,并决定尝试一下。

所以为了熟悉 Lua 和 Love2D,我编写了一个简单的示例:

项目结构:

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

所以基本上它只是一个在碰到边缘时弹跳的球。 除了function Ball:changeColor(),一切似乎都很好 我希望球每次碰到边缘时都会改变颜色,但这不起作用。function changeColor() 有问题吗?

这是演示的快照:

函数确实触发了,rgb 颜色值确实改变了,但球本身没有改变颜色,感谢任何帮助!

【问题讨论】:

请不要使用love2d :-(,改用solar2d 甚至更好的gideros,你会有很多好东西!不过这是我个人的看法 Ball:checkEdges 内调用函数为self:changeColor() 而不是Ball:changeColor() @EgorSkriptunoff 那又是一个错误,在改变这个和 changeColor 函数后让它工作了,谢谢! 【参考方案1】:

最大的错误是颜色定义本身。 颜色范围从 0(零)到 1。 所以改变...

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:changeColor() 
    self.r = love.math.random()
    self.g = love.math.random()
    self.b = love.math.random()
    print('color: ' .. self.r .. ' ' .. self.g .. ' ' .. self.b)
end

它应该比打印出来...

color: 0.064632309279245 0.45080402957018 0.39887099192605

面向对象编程

您使用Ball:new() 分配了一个球,但在进一步的代码中您不使用ball 分配的方法。 为了给方法球作为参数,使用:。 我给你一个更正的版本来说明我的意思。 我的彩球在这里被命名为cball ;-)

-- main.lua
require "ball"

function love.load()
    x = love.graphics.getWidth() / 2
    y = love.graphics.getHeight() / 2
    cball = Ball:new(x, y, 27, 27, 200, 0, 0, 0)
end

-- When object is assigned you reach the desired function with the :
-- So use it...
function love.update(dt) 
    cball:move() -- Use assigned method with cball as first argument
    cball:checkEdges() -- Same here
end

-- Checking if key is released avoids repeating keys ;-)
function love.keyreleased(key)
    if key == 'escape' or key == 'q' then 
        love.event.quit()
    end
    if key == 'r' then
        love.event.quit('restart')
    end
end

function love.draw()
    love.graphics.setBackgroundColor(.125, .125, .25)
    cball:show() -- Same here
end

最后一件事是 ball.lua 并不是真正为 Lua 设计的。 你的球 Lua 什么也没返回。 因此,第二个要求与第一个要求不同。 一个好的设计的例子......

-- ball.lua start with...
local Ball = 
    x = 0,
    y = 0,
    xSpeed = 0,
    ySpeed = 0,
    ballRadius = 0,
    r = 1,
    g = 0,
    b = 0

-- Than all function/method defining for Ball and last line do
return Ball

之后,它每次都正确加载(首先从文件加载,然后从package.loaded.ball加载)。 此外,您可以直接做的设计事实...

-- Ball = require('ball')
function love.load()
    x = love.graphics.getWidth() / 2
    y = love.graphics.getHeight() / 2
    cball = require('ball'):new(x, y, 27, 27, 20, 0, 0, 0)
end

作为副作用,您在new() 中提供的选项会全部生效。 另一个副作用是你可以在...之后做...

cball=require('ball'):new(...)

...一个...

newball=cball:new(...)

(三个点是选项的占位符) ...从require('ball')

【讨论】:

谢谢!仔细查看文档,发现rgb值必须是0到1,谢谢解答! 比你现在准备好 OOP 部分了。

以上是关于Love2D(Lua)中的面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章

Lua 面向对象

Lua面向对象编程

Lua面向对象编程

lua 面向对象

lua 面向对象编程类机制实现

cocos2d-Lua02Lua面向对象