2017-03-14 10 views
0

オブジェクトモジュール内にリスナー関数を置くことは可能ですか?オブジェクト内のCorona SDK Listener関数

私は表示オブジェクトを実装するCloudクラスを持っています。今、クラスはイメージを作成するだけです。私はそれ自身のリスナーイベントを担当したいので、私が生成したオブジェクトごとにaddEventListenerを呼び出す必要はありません。

私はいくつかのバリエーションを試しましたが、いつもリスナー機能をnilとして終了します。また、addEventListener関数がメインで呼び出されるように分割しようとしました。

オブジェクトのリスナー機能がサポートされていないと感じ始めました。多分私はこれに間違ったアプローチを取っていますか?私は実現可能なことを求めているのですか?そしてもしそうなら、私は何が間違っているのですか?

-- 
-- Cloud.lua 
-- 

local Cloud = {} 
local mtaCloud = { __index = cloud } -- metatable 

local display = require "display" 

-- DOESN'T WORK 
function Cloud.scroll(event) 
    img.y = img.y - img.scrollSpeed 
    if (img.y + img.contentWidth) < 0 then 
    img.x = 0 
    img:translate(math.random(1,_W), 1800 ) 
    end 
end 

function Cloud.New(strImage, intHeight, intWidth, intScrollSpeed) 

    local image = display.newImageRect(strImage, intWidth, intHeight) 
    image.anchorX = 0; image.anchorY = 0.5; 
    image.x = _W/2; image.y = _H/2; 
    image.scrollSpeed = 10 
    image.enterFrame = scroll 
    Runtime:addEventListener("enterFrame", scroll) 

    local newCloud = { 

    img = image 

    } 

return setmetatable(newCloud, mtaCloud) 

end 

return Cloud 

-- main.lua (simplified) 
local cloud = require "object.cloud" 

function scene:create(event) 
    local group = self.view 
    cloud = cloud.New("img/cloud.png", 230, 140) 
    group:insert(cloud.img) 
end 

答えて

0

はい、あなたがChapter 16 of Programming in Luaで議論通常のオブジェクト指向プログラミングの意味でのオブジェクトを意味している場合、オブジェクトにリスナーを設定することが可能です。 selfの参照を正しく取得することが重要です。私はこの答えで動作する実装を含んでいます。

私はあなたがたDisplayObject上でこれを行うことができますかどうかわからないんだけど、それはあなたがあなたの例ではやっていたものではありませんどちらか(DisplayObjectが表newCloudであるあなたのコンストラクタCloud.New()、によって返されるものあなたのimageではありません)。

これは確かにうまくいく方法です。あなたのCloud.luaはこのような何かが必要です(私はテストのために、このスクラッチ実装でShapeObjectsを使用しましたが、あなたは、あなたの画像アセットを使用するように変更を行います):

-- Cloud.lua 

local Cloud = {} 

function Cloud:scroll() 

    self.img.x = self.img.x + self.scrollSpeed 
    if self.img.x >= display.contentWidth + self.img.contentWidth then 
     self.img.x = - self.img.contentWidth 
    end 

end 

function Cloud:enterFrame(event) 
    self:scroll() 
end 

function Cloud:new(intHeight, intWidth, intScrollSpeed) 

    local aCloud = {} 

    local img = display.newRect(0, 0, intWidth, intHeight) 
    img:setFillColor(1) 

    aCloud.img = img 
    aCloud.scrollSpeed = intScrollSpeed 
    aCloud.id = id 

    setmetatable(aCloud, self) 
    self.__index = self 

    Runtime:addEventListener("enterFrame", aCloud) 

    return aCloud 

end 

return Cloud 

お知らせsetmetatableと​​機能でself.__index = self。これが鍵です。私は「ドット表記」のためのシンタックスシュガーである関数定義における「コロン記法」(例えば。Cloud:new(...))を使用しました

は、あなたが使用している関数の最初の引数はself(例えば。Cloud.new(self, ...))です。

また、オブジェクト(テーブル)リスナー(関数ではありません)を使用しています。各enterFrameイベントで、ランタイムはオブジェクトに存在する(つまり、指定されたテーブルに存在する)場合、enterFrame()関数を呼び出します。

local cloud = require("objects.Cloud") 

local maxScrollRate = 4 
local cloud1 = cloud:new(100, 50, 1 + math.random(maxScrollRate) ) 
cloud1.img.x = 200 
cloud1.img.y = 200 
sceneGroup:insert(cloud1.img) 

local cloud2 = cloud:new(100, 50, 1 + math.random(maxScrollRate)) 
cloud2.img.x = 100 
cloud2.img.y = 400 
sceneGroup:insert(cloud2.img) 

役に立てば幸い:「Cloud.lua」という名前のファイルを想定し

があなたのsceneで、プロジェクトのサブディレクトリの「オブジェクト」で発見され、あなたのようなものを持っているでしょう。

関連する問題