2011-06-14 4 views
7

그래서 저는 OOP 원칙을 사용하는 전통적인 게임 개발에서 왔으며, 내가 한 일을 통해 LUA를 사용하여 이것을 모방 할 수 있다는 것을 알았습니다. 코드 게시 중 일부에서는 디렉터 클래스를 사용하여 new() 함수 등이있는 파일을 만드는 방법을 알았습니다.코로나 LUA 및 OOP 디자인

내가 찾고있는 것은 내 무기를 관리하는 방법입니다. 나는 선수와 상대를 가지고 있으며, 무기 클래스 하나를 가지고 싶다고 말합니다. weapon 캐논. 내가 무슨 짓을하는 것입니다 :

-- private vars here 
local power 
local canonSprite 
local whatever 

local someFunction = function() 
... 
end 

-- Private stuff here 
local weaponCanon = {} 

weaponCanon.fire = function(atX, atY) 
... 
end 

weaponCanon.reset = function() 
... 
end 

return weaponCanon 

그런 다음 내 수준의 코드에서 단순히 수행 코딩 할 때이 잘 작동하고 나에게 "개인"과 "공공"의 정신을 사용할 수 있습니다
local weaponCanon = require("weaponCanon") 
weaponCanon.fire(100, 100) 

내 무기. 문제는 플레이어와 상대방이 캐논을 갖고 싶어하는 경우입니다.

local playerWeapon = require("weaponCanon") 
local opponentWeapon = require("weaponCanon") 

이렇게하면 새 인스턴스 대신 해당 개체가 반환됩니다. 그래서 나는 무기 하나만 가져 간다. 상대방에있는 캐논은 웨폰의 위치에있다. 이것은 분명히 지금 내가 원하거나 필요로하는 것입니다.

우리 게임에는 많은 무기가 있습니다. 상대방 무기 또는 플레이어 무기가 있는지 알려주는 설정이있는 각 파일의 버전이 하나만 있으면 좋을 것입니다. 다른 방법은 각 파일을 복사하고 weaponPlayerCanon과 weaponOpponentCanon을 만드는 것입니다. 그러나 한 파일의 수정을 생각할 때마다 매번 2 개 이상의 파일을 변경해야합니다.

인스턴스를 반환하도록하려면 어떻게해야하며 LUA 파일의 구조는 어떻게해야합니까?

감사 또는 모두가

-d

+0

나는 잘 알고있다 : http://lua-users.org/wiki/LuaModuleFunctionCritiqued이 곳에서 나는 내 디자인을 얻었으나, 내가 뭔가를 간과하지 않으면 정말 내 문제를 해결하지 못한다. –

+0

내가 놓친 부분은 데이터와 논리가 필요하다는 것입니다.따라서 화재 기능에 대한 매개 변수로 제공 할 무기에 대한 설정을 포함하는 "테이블"을 제공하는 새 기능이 필요하므로 건을 전달한 테이블의 전원 값이 감소합니다. PIL의 15 장은 올바른 방향으로 당신을 설정해야합니다. http://www.lua.org/pil/15.html –

+0

여기서 한 것은 결국 어쨌든 테스트 할 계획 이었기 때문에 저를 구해 주셔서 감사합니다. 문제. – jhocking

답변

5

도움이 당신이 소스 파일과 클래스를 모델링하려고하는 것 같아요. 즉, 모든 상태를 공유하지 않는 한 해당 클래스의 새 인스턴스를 만드는 기능도 있어야합니다. (안된)의 라인을 따라

뭔가 : (또한 테스트되지 않은)

local WeaponCannon = {} 
WeaponCannon.__index = WeaponCannon 
function WeaponCannon:new() 
    return setmetatable({}, self) 
end 

function WeaponCannon:fire(x, y) 
    -- Do something via the self reference and arguments (x, y) 
end 

return WeaponCannon 

그리고 당신의 호출 코드 :

require('WeaponCannon') 
local playerWeapon = WeaponCannon:new() 
local opponentWeapon = WeaponCannon:new() 
+0

모든 답장을 보내 주셔서 감사합니다. 나는 모든 것이 훌륭한 해결책이라고 생각합니다.이 하나만으로도 제가하고 싶은 것을 이끌었습니다. –

+0

이봐 요,이 예제에서는 어떻게 private 변수/함수가 있습니까? 아니면 라이브러리를 사용하지 않으면 존재하지 않습니까? –

+0

상태가없는 유틸리티 함수는 소스 파일에 넣고 반환하지 않습니다. 테이블에 표시되지 않는 모든 로컬 변수도 비공개입니다. 예제로서'function f() local a = 5; return {getA = function() end, setA = function (new_a) a = new_a end} end'를 반환합니다. 지역 변수'a'는'getA'와'setA'를 통해서만 나타납니다. – ponzao

0

방금 ​​글로벌의 무리가 여기 - 어떤 물체가 없습니다 데이터. 인스턴스를 만들 필요가 있습니다. 나중에에 상속을 필요로 시작하는 경우

function NewWeapon(arg) 
    return { 
     fire = function(self, atX, atY) 
      print(self.var) 
     end, 
     var = arg, 
    } 
end 

NewWeapon(3):fire(1, 2) 
NewWeapon(7):fire(3, 5) 
7

당신은 아마 더 깊이 메타 테이블을 사용해야합니다 (즉 LaserCannon는 무기의 서브 클래스입니다).

"Lua 위에 oop"할 수있는 라이브러리가 많이 있습니다. 내가 middleclass의 저자 해요

http://lua-users.org/wiki/ObjectOrientedProgramming

: 당신은 여기에 아주 좋은 목록을 볼 수 있습니다.내 lib에, 당신은 같이해야 할 것이다 :

local Weapon = class('Weapon') 

function Weapon:initialize(a,b,c) 
    self.x,self.y,self.z = a,b,c 
end 

function Weapon:fire(x,y) 
... 
end 
LaserCannon 구현하기 쉬울 것이다

- 당신은 그냥 클래스에 두 번째 매개 변수를 전달합니다

local LaserCannon = class('LaserCannon', Weapon) 

function LaserCannon:initialize(a,b,c,d) 
    self.w = d 
    Weapon.initialize(self, a,b,c) -- superclass' constructor 
end 

function LaserCannon:foo() 
... 
end 

당신이처럼 사용할 수 있습니다 :

require 'middleclass' -- so you can use "class" 
LaserCannon = require 'laser_cannon' 

local playerWeapon = LaserCannon:new() -- a laser 
local opponentWeapon = Weapon:new() -- a regular generic weapon 

opponentWeapon:fire(100,200) -- typical use 
playerWeapon:fire(100, 200) -- LaserCannon inherits fire from Weapon 
playerWeapon:foo() -- LaserCannon-exclusive 

이것은 중급 클래스로, 내가 만든 이래로 내가 선호하는 클래스입니다. 앞서 언급 한 페이지의 다른 라이브러리는 비슷한 기능을 제공합니다.

+0

나는 당신의 도서관을보고 많은 것을 좋아합니다. 나는 곧 그 것으로 바꿀 수있다. 나는 몇 가지 테스트를 해왔지만 커다란 문제에 직면 해있다. 나는 코로나 SDK에 이것을 사용하고 onCollision 함수를 호출해야 할 상황에 처하게되었습니다. 일반적으로 내가 할 단지 것 : self.canonBall.collision = onWeaponCollision self.canonBall을 : 그러나하여 addEventListener ("충돌", self.canonBall)를 onWeaponCollision가 작동하지 않습니다. 라이브러리에서이 작업을 수행 할 수있는 방법이 있습니까? 자세히 알아보기 : http://stackoverflow.com/questions/6363671/middleclass-problems –

+1

이 질문에 대답했습니다. :) – kikito

1

무기 개체에 대한 새 테이블을 만들지 만 새 변수를 만들지 않습니다. 모듈 상단에 선언 된 변수는 본질적으로 정적 변수입니다 (즉, 클래스의 모든 인스턴스가 공유하는 변수). 테이블에 객체를 생성해야하는 객체에 고유 한 변수를 만들려면

때로 믿을 수

function new() 
    local weaponCannon = {} 
    weaponCannon.power = 10 
end 


덧붙여, 두 가지 : 한 번만 객체를 생성

weaponCannon = {} 
weaponCannon.power = 10 

어쨌든, 당신은 테이블을 생성하는 "생성자"기능이 필요합니다 귀하의 답변과 직접 관련이 없지만 귀하의 코드에 매우 유용한 수정 사항이 될 수 있습니다. 먼저이 방법 내부의 "자기"키워드를 사용할 수 있도록하는 방법으로 함수를 호출하는 마침표 대신 콜론을 사용하여, 해제, 뭔가 같은 : 다음

function weaponCannon:fire() 
    --this is only a test 
    print(self.power) 
end 

local playerWeapon = require("weaponCanon") 
playerWeapon:fire() 

둘째,

weaponCannon = display.newImage("cannon.png") 
weaponCannon.power = 10 

참고가 메타 t을 설정할 수 없습니다 : 당신은 실제로 오히려 빈 테이블을 만들 필요하고 그 빈 테이블로 표시 객체를 고집보다 테이블로 표시 객체를 사용할 수 있습니다 그러나 당신이 이것을한다면. 이 접근 방식이 더 논리적으로 보이고 메타 테이블을 직접 사용하지 않는 것을 선호하지만 이는 귀하의 요청입니다.

0

나는 폰자의 대답을 좋아한다.

local WeaponCannon = {} 

function WeaponCannon:new() 
    local instance = {} 
    setmetatable(instance, {__index = WeaponCannon}) 
    -- setup your new instance here 
    return instance 
end 

function WeaponCannon:fire(x, y) 
    -- Do something via the self reference and arguments (x, y) 
end 

return WeaponCannon 

그리고 당신의 호출 코드에 :하지만 그것을 바꿀 것

내가 변경 한 무엇
local WeaponCanon = require('WeaponCannon') 
local playerWeapon = WeaponCannon:new() 
local opponentWeapon = WeaponCannon:new() 

:

  • 가 설치를 허용하는 로컬 인스턴스 변수를 생성하여 반환하기 전에
  • 메타 테이블을보다 간단하게 설정하는 방법
  • 클래스에 변수를 사용합니다. whe n 코드를 호출