#oop #lua #love2d
Вопрос:
Я заинтересовался Love2D и Lua и решил попробовать.
Поэтому, чтобы ознакомиться как с Lua, так и с Love2D, я закодировал простой пример:
Структура проекта:
demo |-ball.lua |-main.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 gt; love.graphics.getWidth() or self.x - self.ballRadius lt; 0 then self.xSpeed = self.xSpeed * -1 Ball:changeColor() end if self.y self.ballRadiusgt; love.graphics.getHeight() or self.y - self.ballRadius lt; 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 изменились, но сам шар не изменил цвет, любая помощь приветствуется!
Комментарии:
1. не используйте love2d, пожалуйста :-(, вместо этого используйте solar2d или даже лучше gideros, у вас будет тонна вкусностей! хотя это мое личное мнение
2. Внутри
Ball:checkEdges
вызовите функцию какself:changeColor()
вместоBall:changeColor()
3. @EgorSkriptunoff Это была еще одна ошибка, она заработала после изменения этого и функции изменения цвета, спасибо!
Ответ №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
Последнее, что важно.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(...)
( Три точки являются заполнителями для опций )
…чтобы сделать другого (x, y, speedx, speedy, радиус, цвет) независимым ребенком (мячом) от ребенка, который require('ball')
lt;—lt;
Комментарии:
1. Спасибо! после тщательной проверки документации выяснилось, что значения rgb должны быть от 0 до 1, спасибо за ответ!
2. Чем сейчас вы готовы к части ООП.