Urgent Player Movement Help

Hey, I am currently building a game for some school work (for Wednesday!) and I have run into a problem. I can’t get the player to move. I just cant work out why it won’t move. When I click to drag it around the screen in the simulator it just crashes with an error ‘compare to nil’ I am trying to get the player to move around in the boundaries of the screen by being dragged around by the player. 

Here is my code:

[lua]

local background

local timeLastEnemy = 0

local player

local topside

local bottomside

local enemy

local diffValue = 3000

local score = 0

local scoreText

    – create a grey rectangle as the backdrop

    local background = display.newRect( 0, 0, screenW, screenH )

    background:setFillColor( 24,64,64 )

    

– Load and position the player

player = display.newImage(“crate.png” , 60 , 60)

player.y = display.contentCenterY

player.x = display.contentHeight - player.contentHeight

–physics.addBody(player, “kinematic”, {bounce = 0})

physics.addBody(player, “static”, {density = 2.0, friction = 0.5, bounce=0.3})

player.name = “player”

– Listen to collisions

player.collision = onCollision

player:addEventListener(“collision”, player)

–gameLayer:insert(player)

function scene:createScene( event )

    local group = self.view

    

local topside = display.newImageRect( “crate.png”, 500, 0 )

topside.x = 250

topside.y = -1

physics.addBody(topside, {friction=0.5})

topside.bodyType = “static”

topside.myName = “topside”

local bottomside = display.newImageRect( “crate.png”, 500, 0 )

bottomside.x = 250

bottomside.y = 320

physics.addBody(bottomside, {friction=0.5})

bottomside.bodyType = “static”

bottomside.myName = “bottomside”

local timeLastEnemy = 0

function loop ( event ) 

    if event.time - timeLastEnemy >= math.random(diffValue, 5000) then

    – make a enemy (off-screen), position it, and rotate slightly

    local enemy = display.newImageRect( “crate.png”, 30, 30 )

    enemy.x, enemy.y = 550, math.random(20, 300)

    enemy.rotation = math.random (-90, 90)

    

                timeLastEnemy = event.time

diffValue = diffValue - 5

print(diffValue)

    

    – add physics to the enemy

    physics.addBody( enemy, { density=1.0, friction=0.3, bounce=0.3 } )

    

    

    – all display objects must be inserted into group

–  gameLayer:insert(player)

–    group:insert( background )

–    group:insert( crate )

 end

end

local function playerMovement(event)

    

    – Only move to the screen boundaries

    if event.x >= halfPlayerWidth and event.x <= display.contentWidth - halfPlayerWidth then

        – Update player x axis

        player.x = event.x

        

            if event.y >= halfPlayerWidth and event.y <= display.contentWidth - halfPlayerWidth then

        – Update player y axis

        player.y = event.y

end

    end

end

– Player will listen to touches

player:addEventListener(“touch”, playerMovement)

    

– Called immediately after scene has moved onscreen:

function scene:enterScene( event )

    local group = self.view

    

    physics.start()

    physics.setGravity( -1, 0 )

    

end

Runtime:addEventListener(“enterFrame”, loop)

end

– Called when scene is about to move offscreen:

function scene:exitScene( event )

    local group = self.view

    

    physics.stop()

    

end

– If scene’s view is removed, scene:destroyScene() will be called just prior to:

function scene:destroyScene( event )

    local group = self.view

    

    package.loaded[physics] = nil

    physics = nil

end

[/lua]

I am just using place holder images at the moment while I work it all out. I managed to get collision working and the spawn rate gradually increases throughout the game. Once I get the player movement sorted I am going to have it so when an enemy gets past the player it will end the game.

Thanks

EDIT:

I managed to solve this issue (see below) but it has left me with another. I am unsure how to restrict it to just the screen boundaries. Any idea how to do this?

here is the code I adjusted to solve the movement problem

[lua]

     local function playerMovement(event)

        player.x = event.x 

        player.y = event.y

    end

[/lua] and then I have to put the listener in the game loop. :) 

Can you post more of the error message like the entire stack trace?

oh I managed to solve it. The error was that I was calling the function in the wrong place. I didn’t realise but I had placed the function after the listener outside the loop basically. It was causing the listener to look for something that wasn’t there, so every time I touched the player I was getting an error for nil value because there was nothing there. It was a simple formatting error but it look me ages to work it out.

As regards the movement restriction I simply took it out because it didn’t work at all. I think I will just have to create static physics boundaries and hope that the player can’t push past them. 

Unfortunately, using the player.x=event.x (along with Y) approach, the player can push past them. You’d be better off with a clamp function:

[lua]

local function clamp(value, low, high)

    if value<low then

        return value

    elseif value>high then

        return high

    else

        return value

    end

end

[/lua]

And then using something like this:

[lua]

player.x=clamp(event.x, 150, display.contentWidth-150)

player.y=clamp(event.y, 150, display.contentHeight-150)

[/lua]

That will give you a margin of 150 on all sides.

Hope this helps :slight_smile:

C

Thank you so much. 

Also just on another note, is there a way in invert the x axis? At the moment I am firing a bullet (code below) but it is spawning and going to the left of the screen, when I want it to go to the right. I am away its the transition.to code and originally it was going vertically (y axis) rather then horizontally, but now its going in the wrong direction!

[lua]

function shootButton:touch(event)

                local bullet = display.newImage(“crate.png” , 10 , 10)

            bullet.x = player.x - halfPlayerWidth

            bullet.y = player.y 

        

            – Kinematic, so it doesn’t react to gravity.

            physics.addBody(bullet, “kinematic”, {bounce = 0})

            bullet.name = “bullet”

            

            – Listen to collisions, so we may know when it hits an enemy.

            bullet.collision = onCollision

            bullet:addEventListener(“collision”, bullet)

                    

            transition.to(bullet, {time = 1000, x = -bullet.contentHeight})

                                            

end

[/lua]

First of all, if the only reason you’re using “kinematic” is so that it doesn’t react to gravity, there’s a better way: the “gravityScale” parameter. (or at least I think it’s gravityScale - might be something else, though).

Second of all, the way to reverse x is by just not putting the minus symbol in front of “bullet.contentHeight”. Right now you’re transitioning to the negative of the bullet’s height.

C

Oh ok thank you very much. I can’t seem to quite get the clamp function working but I am going to keep trying. 

I have the bullet firing now. All I can’t seem to get working that I have left now is scoring on bullet hit and removal of that enemy when hit. 

I haven’t actually worked out how im going to end the game but I am thinking I will have some sort of lives system. When 3 enemies get past the player I will have a marker, when they hit this it will destroy the block and -1 from the life value, then have an if statement looking for when life drops below 1. At which point it will say game over and display your score on screen. 

I Developed My First Game “Unending Pursue” In Corona SDK. And Uploaded It Into Google
Market. Dear Members It Would Be Your Most Kindness If You Check That.

Here Is The Link:

https://play.google.com/store/apps/details?id=rt.games.unendingpursue
 

Ok so I am nearly done, Hooray!

I am now down to one last problem. I can’t end the game. I want it so when the timer runs out (yes I had to change the design of the game slightly) or your score drops to 0 it shows the game over screen

[lua]

    function gameover (event)

     if event.time = 0 or event.score = 0 then

      local gameoverText = display.newText(“Game Over!”, 0, 0, “HelveticaNeue”, 35)

        gameoverText:setTextColor(255, 255, 255)

        gameoverText.x = display.contentCenterX

        gameoverText.y = display.contentCenterY

        gameLayer:insert(gameoverText)

        end

end

[/lua]

This the code I have at the moment, but it brings up an error

Anyone got any ideas what the problem is? I can’t work out what is wrong.

Can you post more of the error message like the entire stack trace?

oh I managed to solve it. The error was that I was calling the function in the wrong place. I didn’t realise but I had placed the function after the listener outside the loop basically. It was causing the listener to look for something that wasn’t there, so every time I touched the player I was getting an error for nil value because there was nothing there. It was a simple formatting error but it look me ages to work it out.

As regards the movement restriction I simply took it out because it didn’t work at all. I think I will just have to create static physics boundaries and hope that the player can’t push past them. 

Unfortunately, using the player.x=event.x (along with Y) approach, the player can push past them. You’d be better off with a clamp function:

[lua]

local function clamp(value, low, high)

    if value<low then

        return value

    elseif value>high then

        return high

    else

        return value

    end

end

[/lua]

And then using something like this:

[lua]

player.x=clamp(event.x, 150, display.contentWidth-150)

player.y=clamp(event.y, 150, display.contentHeight-150)

[/lua]

That will give you a margin of 150 on all sides.

Hope this helps :slight_smile:

C

Thank you so much. 

Also just on another note, is there a way in invert the x axis? At the moment I am firing a bullet (code below) but it is spawning and going to the left of the screen, when I want it to go to the right. I am away its the transition.to code and originally it was going vertically (y axis) rather then horizontally, but now its going in the wrong direction!

[lua]

function shootButton:touch(event)

                local bullet = display.newImage(“crate.png” , 10 , 10)

            bullet.x = player.x - halfPlayerWidth

            bullet.y = player.y 

        

            – Kinematic, so it doesn’t react to gravity.

            physics.addBody(bullet, “kinematic”, {bounce = 0})

            bullet.name = “bullet”

            

            – Listen to collisions, so we may know when it hits an enemy.

            bullet.collision = onCollision

            bullet:addEventListener(“collision”, bullet)

                    

            transition.to(bullet, {time = 1000, x = -bullet.contentHeight})

                                            

end

[/lua]

First of all, if the only reason you’re using “kinematic” is so that it doesn’t react to gravity, there’s a better way: the “gravityScale” parameter. (or at least I think it’s gravityScale - might be something else, though).

Second of all, the way to reverse x is by just not putting the minus symbol in front of “bullet.contentHeight”. Right now you’re transitioning to the negative of the bullet’s height.

C

Oh ok thank you very much. I can’t seem to quite get the clamp function working but I am going to keep trying. 

I have the bullet firing now. All I can’t seem to get working that I have left now is scoring on bullet hit and removal of that enemy when hit. 

I haven’t actually worked out how im going to end the game but I am thinking I will have some sort of lives system. When 3 enemies get past the player I will have a marker, when they hit this it will destroy the block and -1 from the life value, then have an if statement looking for when life drops below 1. At which point it will say game over and display your score on screen. 

I Developed My First Game “Unending Pursue” In Corona SDK. And Uploaded It Into Google
Market. Dear Members It Would Be Your Most Kindness If You Check That.

Here Is The Link:

https://play.google.com/store/apps/details?id=rt.games.unendingpursue
 

Ok so I am nearly done, Hooray!

I am now down to one last problem. I can’t end the game. I want it so when the timer runs out (yes I had to change the design of the game slightly) or your score drops to 0 it shows the game over screen

[lua]

    function gameover (event)

     if event.time = 0 or event.score = 0 then

      local gameoverText = display.newText(“Game Over!”, 0, 0, “HelveticaNeue”, 35)

        gameoverText:setTextColor(255, 255, 255)

        gameoverText.x = display.contentCenterX

        gameoverText.y = display.contentCenterY

        gameLayer:insert(gameoverText)

        end

end

[/lua]

This the code I have at the moment, but it brings up an error

Anyone got any ideas what the problem is? I can’t work out what is wrong.