物理在lua中不起作用

时间:2014-03-19 03:43:21

标签: lua corona

这个代码创造了一个大炮和3个气球,大炮应该射出一颗能够摧毁气球的子弹以及文字。在这个过程中,大炮应该旋转,当我从屏幕上释放我的手指时,它会射击。由于某些原因,它没有响应,炮弹不旋转也没有射击子弹。

local score = 0
local scoreText
local scoreForLevelComplete
local background
local infoBar
local restartBtn
local cannon
local levelNum
local cannonCharge = {}
local shot = {}
local cannonBall
local impulse = 0
local balloons = {}
local cannonCharge = {}
local shot = {}


function scene:createScene(event)
    local group = self.view

    background = display.newImage( "bkg_clouds.png")
    group:insert(background)
    background.x = 230
    background.y = 195

    scoreText = display.newText( "0", 0, 0, native.systemFont, 32 )
    scoreText:setFillColor( 0,0, 0 )
    scoreText.x = 87
    scoreText.y = 28
    group:insert( scoreText ) 

    questionText = display.newText('a', display.contentCenterX, display.contentWidth/4, native.systemFont, 40)
    group:insert(questionText)

    infoBar = display.newImage ("infoBar.png")
    group:insert(infoBar)
    infoBar.x = 10
    infoBar.y = 25

    restartBtn = display.newImage ("restartBtn.png")
    group:insert(restartBtn)
    restartBtn.x = 470
    restartBtn.y = 300

    cannon = display.newImage ("cannon.png")
    group:insert(cannon)
    cannon.x = 10
    cannon.y = 270

    cannon.anchorX = 0.5
    cannon.anchorY = 0.5
    restartBtn.isVisible = true

    local balloon = display.newImage ('balloon_fat_red.png', 495, 125)
    group:insert(balloon)
    balloon = display.newImage ('balloon_fat_red.png', 495, 175)
    group:insert(balloon)
    balloon = display.newImage ('balloon_fat_red.png', 495, 225)
    group:insert(balloon)

    local balloonText1 = display.newText('\227\129\130', 495, 125)
    balloonText1:setFillColor( 1,1, 0 )
    local balloonText2 = display.newText('\227\129\132', 495, 170)
    balloonText2:setFillColor( 1,1, 0 )
    local balloonText3 = display.newText('\227\129\134', 495, 225)
    balloonText3:setFillColor( 1,1, 0 )

    balloon.name = 'balloon'
    physics.addBody(balloon)
    balloon.bodyType = 'static'
    table.insert(balloons, balloon)      

    group:insert(balloonText1)
    group:insert(balloonText2)
    group:insert(balloonText3)


    function ballCollision(e)
       if (e.other.name == 'balloon') then
            scene.updateScore()
            e.target:removeSelf() 
            print ('remove balloon text')
            e.other:removeSelf()
            audio.play(pop)
        end
    end

    function cannonCharge:touch(e)
        if(e.phase == 'began') then
            impulse = 0
            cannon.isVisible = true
            Runtime:addEventListener('enterFrame', charge)
        end
    end

    function charge()
        local degreesPerFrame = 0.5
        cannon.rotation = cannon.rotation - degreesPerFrame 
        impulse=impulse-0.2

        if(cannon.rotation < -46) then
            cannon.rotation = -46
            impulse = -3.2
        end
    end

    function shot:touch(e)
        if(e.phase == 'ended') then
            Runtime:removeEventListener('enterFrame', charge)
            cannon.isVisible = true
            cannon.rotation = 0

            cannonBall = display.newImage('cannon ball.png', 84, 220)
            physics.addBody(cannonBall, {density = 1, friction = 0, bounce = 0})
            group:insert(cannonBall)

            -- Shoot cannon ball
            cannonBall:applyLinearImpulse(3, impulse, cannonBall.x, cannonBall.y )

            --Collision listener
            cannonBall:addEventListener ('collision', ballCollision)
        end
    end
end

这是我的entercene功能

function scene:enterScene( event )
    local group = self.view
    background:addEventListener('touch', cannonCharge)
    background:addEventListener('touch', shot) 
end

2 个答案:

答案 0 :(得分:1)

我知道Corona文档说调用addEventListener('event', listener)时监听器可以是一个表对象,但我从未见过或使用过它。在已发布的代码中,createScene中定义的函数没有任何优势,因为它们是全局的,并且您已经拥有一堆或模块局部变量。尝试拉出听众并使其成为常规功能:

local canon
...
local cannonCharge = function(event)
    if event.phase == 'began' then
        impulse = 0
        cannon.isVisible = true
        Runtime:addEventListener('enterFrame', charge)
    end
end

local shot = function(event)
    ...
end

local function charge()
    ...
end

... other local functions ...

function scene:createScene(event)
    ...
end

此外,确认通过在每个内部打印内容来调用您的触摸侦听器。

最后,最重要的是,您只将最后一个气球添加到物理中,因此子弹只能与该气球发生碰撞。与创建每个气球后必须添加group:insert(balloon)的方式相同,每次插入组后都应该physics.addBody(balloon, ...)。所以这样做:

local balloon1 = display.newImage ('balloon_fat_red.png', 495, 125)
local balloon2 = display.newImage ('balloon_fat_red.png', 495, 175)
local balloon3 = display.newImage ('balloon_fat_red.png', 495, 225)

group:insert(balloon1)
group:insert(balloon2)
group:insert(balloon3)

physics.addBody(balloon1)
physics.addBody(balloon2)
physics.addBody(balloon3)

balloon1.bodyType = 'static'
balloon2.bodyType = 'static'
balloon3.bodyType = 'static'

table.insert(balloons, balloon1)      
table.insert(balloons, balloon2)      
table.insert(balloons, balloon3)      

那里有很多代码重复,添加更多气球需要更改许多行,因此您可以将重复的代码分解为函数:

local function createBalloon(x, y)
    local balloon = display.newImage ('balloon_fat_red.png', x, y)
    group:insert(balloon)
    physics.addBody(balloon)
    balloon.bodyType = 'static'
    table.insert(balloons, balloon)      
end

createBalloon(495, 125)
createBalloon(495, 175)
createBalloon(495, 225)

这样做的好处是,如果你需要更多气球,你就不会忘记任何设置,并且任何新设置都放在createBallon中,所以所有气球都有相同的配置(x,y等功能参数除外)。

更新:确定碰撞处理程序中的哪个气球

取决于你需要知道哪个气球。例如,如果它是因为气球1给出了10分而3分给了30分,那么有更好的方法:你可以将你的字段添加到对象,就像你可以balloon1.points = 10,balloon2.points = 30等(你会把它作为createBalloon的函数参数)并且在碰撞处理程序中只使用score = score + e.other.points。你应该只需要使用Local Collision Handling,因为只需要知道炮弹何时与气球发生碰撞。要确定e.other是否为气球,最简单的方法是在创建气球时添加属性:

local function createBalloon(x, y, balloonText)
    local balloon = ...
    ...
    balloon.isBalloon = true -- only balloon objects will have this
    balloon.label = balloonText
end

关于上述内容的注意事项:另一个自定义属性是label,因为您要删除碰撞处理程序中的气球文本,最简单的方法是为其提供属性。但是,不要在碰撞处理程序中删除碰撞中涉及的对象,如that document中所述,使用延迟删除。所以你的处理程序变成了

function ballCollision(e)
   if e.other.isBalloon then
        scene.updateScore(e.other.points)

        timer.performWithDelay(1, e.target.removeSelf, e.target) 
        timer.performWithDelay(1, e.other.removeSelf,  e.target) 

        e.other.label:removeSelf() -- this is ok: not involved in collision
        audio.play(pop)
    end
end

答案 1 :(得分:0)

您已将气球声明为数组并使用气球  作为变量,同时为它们分配图像。因此,您需要声明3个单独的气球对象,如气球文本,或者如果您正在使用数组,那么您需要声明这样。

for i=1,3 do
  balloon[i] = display.newImage ('balloon_fat_red.png', 495, 225)
  group:insert(balloon[i])
end

因此,它将识别您要拍摄的气球。