Объектно-ориентированное программирование в Love2D(Lua)

#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() этим ?

вот снимок демо-версии:

1

функция сработала, и значения цвета 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. Чем сейчас вы готовы к части ООП.