>

이 게임에서 몇 초마다 소행성을 스폰하려고합니다. 그러나 게임을 실행할 때마다

stack traceback:
      main.lua:277: in function '_listener'
      ?: in function '?'
      ?: in function <?:172>

코드를 옮기려고했지만 도움이되지 않습니다. 교수님이 내 코드를보고 문제가 무엇인지 정확히 알지 못하지만 사용중인 루프에 문제가 있습니다. "createAsteroid"를 포함하는 모든 코드는 다음과 같습니다

수정 :이 질문에 main.lua 파일 전체를 추가했습니다. 이 프로젝트에있는 별도의 파일은 캐릭터와 배경 이미지이며 구성 파일 외에 다른 모든 것은 여기에 있습니다. 여분의 end 를 삭제하려고했습니다.  gameLoop 함수에서 그러나 내가 할 때 기본적으로 end 를 예상한다는 오류가 발생했습니다.  거기 요.


display.setStatusBar( display.HiddenStatusBar )
------------------------------
-- RENDER THE SAMPLE CODE UI
------------------------------
local sampleUI = require( "sampleUI.sampleUI" )
local physics = require( "physics" )
physics.start()
math.randomseed( os.time() )
------------------------------
-- CONFIGURE STAGE
------------------------------
local composer = require( "composer" )
local mainScene = display.newGroup()
display.getCurrentStage():insert( mainScene )
----------------------
-- BEGIN SAMPLE CODE
----------------------
-- Frequently used variables
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local originX = display.screenOriginX
local originY = display.screenOriginY
local width = display.actualContentWidth
local height = display.actualContentHeight
local score = 0
local died = false
local asteroidsTable = {}
local player
local gameLoopTimer
local scoreText
local uiGroup = display.newGroup()    -- Display group for UI objects like the score
-- Load background and character from "background.lua" and "character.lua" respectively
local background = require( "background" )
mainScene:insert( background )
local character = require( "character" )
mainScene:insert( character )

local asteroid = display.newImage( "asteroid.png", 180, -50 )
asteroid.rotation = 5
physics.addBody( asteroid, { density=3.0, friction=0.5, bounce=0.3, radius=25 })

-------------------------
-- BEGIN MOVEMENT LOGIC
-------------------------
-- Movement logic variables
local movementSpeed = 1.5
local moving = false
local moveDirection = "down"
-- Sets if the character should move and updates sprite animation
local function setMoving( state )
    moving = state
    if ( moving ) then
        character:play()
    else
        character:pause()
        character:setFrame(2)
    end
end
-- Sets the direction that the player should move and updates the character's sprite facing
local function setMovementDirection( direction )
    -- Don't change anything if we haven't altered direction
    if ( moveDirection == direction ) then
        return
    end
    -- Update the sprite playback
    moveDirection = direction
    character:setSequence( "walk-" .. direction )
    -- Refresh animation playback, which can pause after changing the sprite sequence
    setMoving( moving )
end
-- Set movement magnitudes
local movementX = 0
local movementY = 0
local function setMovement( x, y )
    local updatedMovement = false
    -- Horizontal movement checks
    if ( movementX ~= x and nil ~= x ) then
        movementX = x
        updatedMovement = true
    end

    -- Abort if nothing is updating
    -- We do this since axis/key events can fire multiple times with the same values
    if ( not updatedMovement ) then
        return
    end
    -- Determine movement direction
    if ( 0 ~= movementX or 0 ~= movementY ) then
        -- Favor horizontal animations over vertical ones
        if ( math.abs( movementX ) >= math.abs( movementY ) ) then
            if ( 0 < movementX ) then
                setMovementDirection( "right" )
            else
                setMovementDirection( "left" )
            end
        else
            if ( 0 < movementY ) then
                setMovementDirection( "down" )
            else
                setMovementDirection( "up" )
            end
        end
    end
    -- Update moving animation/variable
    if ( 0 == movementX and 0 == movementY ) then
        setMoving( false )
    else
        setMoving( true )
    end
end
-- Handle character translation on the screen per frame
local function onFrameEnter()
    if ( 0 ~= movementX ) then
        character.x = character.x + ( movementSpeed * movementX )
        setMoving( true )
    end
    if ( 0 ~= movementY ) then
        character.y = character.y + ( movementSpeed * movementY )
        setMoving( true )
    end
end
Runtime:addEventListener( "enterFrame", onFrameEnter )

---------------------------
-- BEGIN INPUT CODE: TOUCH
---------------------------
local padGraphic, padButtonUp, padButtonDown, padButtonLeft, padButtonRight
-- Determine if we have a joystick connected or not
local inputDevices = system.getInputDevices()
local function getHasJoystick()
    for i = 1, #inputDevices do
        if ( "joystick" == inputDevices[i].type ) then
            return true
        end
    end
    return false
end
local hasJoystick = getHasJoystick()
-- If we don't have any controllers found, create a virtual D-pad controller
if ( not hasJoystick ) then
    -- Called when one of the virtual D-pad buttons are used
    local function onTouchEvent( event )
        local phase = event.phase
        local targetID = event.target.id
        if ( "began" == phase or "moved" == phase ) then
            if ( "up" == targetID ) then
                setMovement( 0, -1 )
            elseif ( "down" == targetID ) then
                setMovement( 0, 1 )
            elseif ( "left" == targetID ) then
                setMovement( -1, 0 )
            elseif ( "right" == targetID ) then
                setMovement( 1, 0 )
            elseif ( "padGraphic" == targetID ) then
                setMovement( 0, 0 )
            end
        elseif ( "ended" == phase or "cancelled"  == phase ) then
            -- An alternative to checking for "cancelled" is to set focus on the control
            -- However, we don't want an incoming phone call to bug out input
            if ( "up" == targetID or "down" == targetID ) then
                setMovement( nil, 0 )
            elseif ( "left" == targetID or "right" == targetID ) then
                setMovement( 0, nil )
            end
        end
        return true
    end
-- Display score
scoreText = display.newText( uiGroup, "Score: " .. score, 400, 40, native.systemFont, 36 )
-- Hide the status bar
display.setStatusBar( display.HiddenStatusBar )

local function updateText()
    scoreText.text = "Score: " .. score
end

local function createAsteroid()
    local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 )
    table.insert( asteroidsTable, newAsteroid )
    physics.addBody( newAsteroid, "dynamic", { radius=25, bounce=0.8 } )
    newAsteroid.myName = "asteroid"
    local whereFrom = math.random( 3 )
    if ( whereFrom == 1 ) then
         -- From the left
        newAsteroid.x = -60
        newAsteroid.y = math.random( 500 )
        newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) )
        elseif ( whereFrom == 2 ) then
        -- From the top
        newAsteroid.x = math.random( display.contentWidth )
        newAsteroid.y = -60
        newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) )
    elseif ( whereFrom == 3 ) then
        -- From the right
        newAsteroid.x = display.contentWidth + 60
        newAsteroid.y = math.random( 500 )
        newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) )
    end
        newAsteroid:applyTorque( math.random( -6,6 ) )
end
        -- Create the visuals for the on-screen D-pad
    local padSize = 200
    padGraphic = display.newImageRect( mainScene, "pad.png", padSize, padSize )
    padGraphic.x = originX + padSize/2 - 40
    padGraphic.y = height + originY - padSize/2 + 40
    padGraphic.alpha = 0.35
    padGraphic.id = "padGraphic"
    padGraphic:addEventListener( "touch", onTouchEvent )
    -- Creates one of the invisible virtual D-pad buttons
    local function createPadButton( buttonID, offsetX, offsetY )
        local btn = display.newRect( mainScene, padGraphic.x+offsetX, padGraphic.y+offsetY, padSize/5, padSize/5 )
        btn:addEventListener( "touch", onTouchEvent )
        btn.id = buttonID
        btn.isVisible = false
        btn.isHitTestable = true
        return btn
    end
    -- Create buttons for handling the D-pad input
    padButtonUp = createPadButton( "up", 0, padSize/-5 )
    padButtonDown = createPadButton( "down", 0, padSize/5 )
    padButtonLeft = createPadButton( "left", padSize/-5, 0 )
    padButtonRight = createPadButton( "right", padSize/5, 0 )
end
-----------------
--  GAME LOOP  --
-----------------
local function gameLoop()
    -- Create new asteroid
    createAsteroid()
    -- Remove asteroids which have drifted off screen
    for i = #asteroidsTable, 1, -1 do
        local thisAsteroid = asteroidsTable[i]
        if ( thisAsteroid.x < -100 or
             thisAsteroid.x > display.contentWidth + 100 or
             thisAsteroid.y < -100 or
             thisAsteroid.y > display.contentHeight + 100 )
        then
            display.remove( thisAsteroid )
            table.remove( asteroidsTable, i )
        end
        end
end
timer.performWithDelay(1000, gameLoop, 0)
--------------------------------------------------
-- BEGIN INPUT CODE: KEYBOARD & BASIC CONTROLLER
--------------------------------------------------
-- Detect if a joystick axis is being used
local joystickInUse = false
-- Keyboard input configuration
local keyUp = "up"
local keyDown = "down"
local keyLeft = "left"
local keyRight = "right"
-- Called when a key event has been received
local function onKeyEvent( event )
    local keyName = event.keyName
    local phase = event.phase
    -- Handle movement keys events; update movement logic variables
    if ( not joystickInUse ) then
        if ( "down" == phase ) then
            if ( keyUp == keyName ) then
                setMovement( nil, -1 )
            elseif ( keyDown == keyName ) then
                setMovement( nil, 1 )
            elseif ( keyLeft == keyName ) then
                setMovement( -1, nil )
            elseif ( keyRight == keyName ) then
                setMovement( 1, nil )
            end
        elseif ( "up" == phase ) then
            if ( keyUp == keyName ) then
                setMovement( nil, 0 )
            elseif ( keyDown == keyName ) then
                setMovement( nil, 0 )
            elseif ( keyLeft == keyName ) then
                setMovement( 0, nil )
            elseif ( keyRight == keyName ) then
                setMovement( 0, nil )
            end
        end
    end
    return false
end
Runtime:addEventListener( "key", onKeyEvent )

------------------------------------------
-- BEGIN INPUT CODE: ADVANCED CONTROLLER
------------------------------------------
-- We only support advanced controllers when one is detected
if ( getHasJoystick ) then
    -- Detect axis event updates
    local function onAxisEvent( event )
        local value = event.normalizedValue
        local axis = event.axis.type
        local descriptor = event.axis.descriptor
        -- We only care about "x" and "y" input events
        -- However, touch-screen events can fire these as well so we filter them out
        if ( ( "x" ~= axis and "y" ~= axis ) or ( string.find( descriptor, "Joystick" ) == nil ) ) then
            return
        end
        -- Detect zero movement at a certain cutoff so we don't get the character moving very, very slowly
        if ( math.abs(value) < 0.15 ) then
            value = 0
        end
        -- Based on which axis type we are dealing with, set movement variables
        if ( "x" == axis ) then
            setMovement( value, nil )
        elseif ( "y" == axis ) then
            setMovement( nil, value )
        end
        -- Some devices will send both up/down/left/right keys and the axis value
        -- We let our code know that we are using a joystick value so they do not conflict
        if ( 0 ~= value ) then
            joystickInUse = true
        else
            joystickInUse = false
        end
    end
    Runtime:addEventListener( "axis", onAxisEvent )
end
local function onCollision( event )
        if ( ( obj1.myName == "player" and obj2.myName == "asteroid" ) or
                 ( obj1.myName == "asteroid" and obj2.myName == "player" ) )
        then
            display.remove( player )
                else
                    ship.alpha = 0
                    timer.performWithDelay( 1000, restoreShip )
                end
            end
Runtime:addEventListener( "collision", onCollision )


  • 답변 # 1

    main.lua 파일에서 277 행으로 이동

    createAsteroid() 함수 호출을 찾을 수 있습니다 . 이 범위 내에서 createAsteroid  정의되어 있지 않습니다.

    그래서 createAsteroid 에 대한 정의를 찾을 수 있는지 봅시다  이 파일에서.

    218 행 : local function createAsteroid()  ...

    함수 호출이 해당 기능의 범위 내에 있는지 확인하십시오 ...

    아니요! 함수 호출이 해당 명령문 외부에있는 동안 if 문 안에 있습니다. createAsteroid 로   gameLoop 내부에서 알 수없는 경우  따라서 호출되지 않을 수 있습니다.

    적절한 들여 쓰기가 있으면 이러한 범위 문제를 찾는 것이 매우 쉽습니다!

  • 이전 hyperledger fabric - 수정 후 체인 코드를 업그레이드하는 방법은 무엇입니까?
  • 다음 Java에서 객체 배열 만들기