Preventing a character from jumping

Hi guys, first of all, I just want to state that I love Corona since I started it last week, and I been reading a lot of tutorials and responses to this forum and see how helpful everyone in here is!

What I am wondering about is, in my game, I have a character jumping forward when you click or touch. My question is, how do I prevent him from jumping again until he lands on the ground? Thus preventing double/triple jumping.

I hope my question is clear enough! :slight_smile: [import]uid: 203940 topic_id: 36157 reply_id: 336157[/import]

Hi @siddigie1234,
Welcome to Corona! Your question is very clear, and it’s answered in my recent tutorial here:

http://www.coronalabs.com/blog/2013/02/19/more-physics-tricks-explained/

Best regards,
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143624[/import]

Thank you very much! I will go over the tutorial and if I have any questions, I hope you don’t mind if I ask you! [import]uid: 203940 topic_id: 36157 reply_id: 143632[/import]

Hi Brent, for some reason, the code as it stands is breaking my code.

Can you tell me what I am doing wrong please?

These are the blocks of code I changed to yours

  
local spriteInstance = display.newSprite( imageSheet, sequencedata )  
  
spriteInstance.myName="unicorn"  
spriteInstance.x = 40  
spriteInstance.y = 200  
spriteInstance:scale(0.5,0.5)  
  
physics.addBody( spriteInstance, "dynamic", { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )  
isSensor=true  
spriteInstance.canJump = 0  
spriteInstance.isFixedRotation = true  
  
local function onScreenTouch( event )  
  
 if (event.phase == "began" spriteInstance.canJump \> 0) then  
 -- make character jump forward  
 swapSequence("jump")  
 spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )  
  
 end  
  
 if event.phase == "moved" then  
 swapSequence("dash")  
 spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )  
 --timer.performWithDelay(2900, swapSequence("run" ))  
 end  
  
 if event.phase == "ended" then  
 swapSequence("run")  
 end  
  
  
  
end  
   
Runtime:addEventListener( "touch", onScreenTouch )  
  
function charCollide( self,event )  
  
 if ( event.selfElement == 2 and event.other.objType == "ground" ) then  
 if ( event.phase == "began" ) then  
 self.canJump = self.canJump+1  
 elseif ( event.phase == "ended" ) then  
 self.canJump = self.canJump-1  
 end  
 end  
end  
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( "collision", spriteInstance)  

Please lemme know what I am doing wrong! :-/ [import]uid: 203940 topic_id: 36157 reply_id: 143736[/import]

Hello,
I notice a few things immediately:

  1. If you scale a sprite, the image part will scale but the physics body won’t scale with it. If you need to see the actual bodies as they are interacting, turn on “hybrid” physics view. Also, please note that if you put physics objects into different display groups, you must keep those display groups “aligned” with each other (in other words, do not shift them around or try to move a display group for reasons of moving physical objects within it). That is a common mistake, and it will break the collision positional sensing.
physics.setDrawMode( "hybrid" )
  1. It looks like you removed the “foot sensor” body part from the unicorn. Was this intentional?

  2. There’s a syntax error in the following line… you need an and between the two cases. Also, you should bundle the phase checking into one “if > elseif > else > end” routine, versus three separate "if > then > end " routines.

if (event.phase == "began" spriteInstance.canJump \> 0) then

should be…

if (event.phase == "began" and spriteInstance.canJump \> 0) then

[import]uid: 200026 topic_id: 36157 reply_id: 143768[/import]

Hi Brent, thanks for the help. In regards the foot sensor, I took it out the body because for some reason, it broke the code when I tried to reload it in Corona. I have done everything you said, however, it is breaking.

Maybe it will be easier if I paste the whole code of what I am doing here. I am learning lua and corona by trying to remake robot unicorn attack game. I only want him to double jump and no more. Here is the entire code, and apologies for the inconvenience!

[code]

display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()

–physics.setDrawMode( “hybrid” ) – shows collision engine outlines only–

–collision filters

local landCollisionFilter = { categoryBits = 1, maskBits = 6 }
local rockCollisionFilter = { categoryBits = 2, maskBits = 7 }
local unicornCollisionFilter = { categoryBits = 4, maskBits = 3 }

local beepSound = audio.loadSound( “…/images/beep.wav” )

local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")
local background = display.newImage( “…/images/mainBg.jpg”)
background.x= 760
background.y= 150
background.xScale= 4
background.yScale= 4

local background2 = display.newImage( “…/images/mainBg.jpg”)
background2.x= 2800
background2.y= 150
background2.xScale= 4
background2.yScale= 4

local backgroundfar = display.newImage("…/images/cloudsBg.png")
backgroundfar.x = 480
backgroundfar.y = 100

local backgroundnear1 = display.newImage("…/images/cloudsBg.png")
backgroundnear1.x = 240
backgroundnear1.y = 80

local backgroundnear2 = display.newImage("…/images/cloudsBg.png")
backgroundnear2.x = 760
backgroundnear2.y = 80

local ground = display.newImage( “…/images/ground.png” )
ground.x, ground.y = 0, 310
ground.myName=“land”
ground.objType = “ground”

local ground1 = display.newImage( “…/images/ground.png” )
ground1.x, ground1.y = 479, 310
ground1.myName=“land”
ground.objType = “ground”

physics.addBody( ground, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
physics.addBody( ground1, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
– Prevent the unicorn from going too high off screen

–local ceiling = display.newRect(0, 0, display.contentWidth, 1)
–physics.addBody(ceiling, “static”, { bounce = 0.1} )
– physics for the rocks

local rock = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock.x, rock.y = 450, 0
rock:scale (0.8,0.8)
rock.myName=“rock”

local rock1 = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock1.x, rock1.y = 900, 0
rock1:scale (0.8, 0.8)
rock1.myName=“rock”

physics.addBody( rock, { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )
physics.addBody( rock1 , { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )

local beepSound = audio.loadSound( “…/images/beep.wav” )
local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")

–the update function will control most everything that happens in our game
–this will be called every frame(30 frames per second in our case, which is the Corona SDK default)
-----------physics for the land

acc=1

function updateBackgrounds()
–far background movement
backgroundfar.x = backgroundfar.x - (.5)
–near background movement
backgroundnear1.x = backgroundnear1.x - (3)
–if the sprite has moved off the screen move it back to the
–other side so it will move back on
background.x = background.x - (.2)
background2.x = background2.x - (.2)
if(backgroundnear1.x < -239) then
backgroundnear1.x = 760
end

backgroundnear2.x = backgroundnear2.x - (3)

if(backgroundnear2.x < -239) then
backgroundnear2.x = 760
end

if background.x < -1061 then
background.x=3011
end
if background2.x < -1061 then
background2.x=3011
end
if ground.x < -245 then
ground.x=740
end
if ground1.x < -245 then
ground1.x=740
end
if rock.x < -50 then
rock.x=440
end
if rock1.x < -50 then
rock1.x=400
end

ground.x=ground.x-(math.min(acc,8))
ground1.x=ground1.x-(math.min(acc,8))
rock.x=rock.x-(math.min(acc,25))
rock1.x=rock1.x-(math.min(acc,25))
acc= acc+(0.01)

end

local function update( event )
–updateBackgrounds will call a function made specifically to handle the background movement
updateBackgrounds()

– tried perform with Delay here , caused a recurring runtime error
end

–this is how we call the update function, make sure that this line comes after the
–actual function or it will not be able to find it
–timer.performWithDelay(how often it will run in milliseconds, function to call,
–how many times to call(-1 means forever))
timer.performWithDelay(1, update, -1)

local options =
{
frames = require(“ss”).frames
}

–load the sprite

local imageSheet = graphics.newImageSheet( “ss.png”, options )

– load the sets of sprite sequences

local sequencedata= {

{ name=“dash”, start=1, count=14, time=300 },
{ name=“jump”, frames={30,29,28,27,26,25,24,23,22,21,20,19,18,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31}, loopCount=1, time=1000 },
{ name=“land”, start=31, count=26, time=2500 },
{name=“run”, frames={88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59}, time=600 },
{ name=“trail”, start=89, count=10, time=1000 },

}
local spriteInstance = display.newSprite( imageSheet, sequencedata )

spriteInstance.myName=“unicorn”
spriteInstance.x = 40
spriteInstance.y = 200
spriteInstance:scale(0.5,0.5)

physics.addBody( spriteInstance, “dynamic”, { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )
isSensor=true
spriteInstance.canJump = 0
spriteInstance.isFixedRotation = true
local function swapSequence(sequence)

spriteInstance:setSequence(sequence)
spriteInstance:play(sequence)

end

local function onScreenTouch( event )

if (event.phase == “began” spriteInstance.canJump > 0) then
– make character jump forward
swapSequence(“jump”)
spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )

else

if event.phase == “moved” then
swapSequence(“dash”)
spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )
–timer.performWithDelay(2900, swapSequence(“run” ))
else

if

event.phase == “ended” then
swapSequence(“run”)
end

end
Runtime:addEventListener( “touch”, onScreenTouch )

local gameover =display.newImage("…/images/gameover.png")
gameover.x=240
gameover.y=160
gameover.alpha=0

function remove()

spriteInstance:applyForce( 0, -3000, spriteInstance.x, spriteInstance.y )

transition.to(gameover, {delay=1000,time=1000, alpha=1})
timer.performWithDelay(1000, endGame)
end

function endGame()

spriteInstance:removeSelf()
rock:removeSelf()
rock1:removeSelf()
ground:removeSelf()
ground1:removeSelf()
background:removeSelf()
background2:removeSelf()
backgroundfar:removeSelf()
backgroundnear1:removeSelf()
backgroundnear2:removeSelf()

end

function charCollide( self,event )

if ( event.selfElement == 2 and event.other.objType == “ground” ) then
if ( event.phase == “began” ) then
self.canJump = self.canJump+1
elseif ( event.phase == “ended” ) then
self.canJump = self.canJump-1
end
end
end
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( “collision”, spriteInstance)
rock.collision = onLocalCollision
rock:addEventListener( “collision”, rock )

rock1.collision = onLocalCollision
rock1:addEventListener( “collision”, rock1 )

spriteInstance.collision = onLocalCollision
spriteInstance:addEventListener( “collision”, spriteInstance )
local cover = display.newImage("…/images/cover1.png")
cover.x = 240
cover.y = 160

function cover:tap( event )
transition.to(cover, {delay=0,time=500, alpha=0})

audio.play( beepSound )
audio.play( bgmusic )
end

cover:addEventListener( “tap”, cover )

–function onLocalCollision( self, event )
– if ( event.phase == “began” ) then

– if (self.myName=“rock” && event.other.myName=“unicorn” )
– timer.performWithDelay(2900, remove)
– elseif (self.myName=“unicorn” && event.other.myName=“rock” )
– timer.performWithDelay(2900, remove)
– end

–end
–end

–function collisionHandler(event)
– if(event.phase==“began” ) then
– if (event.object1.myName==“unicorn” and event.object2.myName==“rock”)
– remove()
– end

– end
–end

–Runtime:addEventListener(“postCollision”,collisonHandler)
[/code] [import]uid: 203940 topic_id: 36157 reply_id: 143783[/import]

Hi @siddigie1234,
While I and the community would like to help figure out the issue, it’s better if you give smaller elements of code, specific error messages, a description of the problem occurring, etc. Most of us just don’t have time to look through a big page of code and figure out what’s going on.

If you can narrow this down to something specific, I or somebody can probably help further.

Thanks!
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143995[/import]

Hi @siddigie1234,
Welcome to Corona! Your question is very clear, and it’s answered in my recent tutorial here:

http://www.coronalabs.com/blog/2013/02/19/more-physics-tricks-explained/

Best regards,
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143624[/import]

Thank you very much! I will go over the tutorial and if I have any questions, I hope you don’t mind if I ask you! [import]uid: 203940 topic_id: 36157 reply_id: 143632[/import]

Hi Brent, for some reason, the code as it stands is breaking my code.

Can you tell me what I am doing wrong please?

These are the blocks of code I changed to yours

  
local spriteInstance = display.newSprite( imageSheet, sequencedata )  
  
spriteInstance.myName="unicorn"  
spriteInstance.x = 40  
spriteInstance.y = 200  
spriteInstance:scale(0.5,0.5)  
  
physics.addBody( spriteInstance, "dynamic", { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )  
isSensor=true  
spriteInstance.canJump = 0  
spriteInstance.isFixedRotation = true  
  
local function onScreenTouch( event )  
  
 if (event.phase == "began" spriteInstance.canJump \> 0) then  
 -- make character jump forward  
 swapSequence("jump")  
 spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )  
  
 end  
  
 if event.phase == "moved" then  
 swapSequence("dash")  
 spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )  
 --timer.performWithDelay(2900, swapSequence("run" ))  
 end  
  
 if event.phase == "ended" then  
 swapSequence("run")  
 end  
  
  
  
end  
   
Runtime:addEventListener( "touch", onScreenTouch )  
  
function charCollide( self,event )  
  
 if ( event.selfElement == 2 and event.other.objType == "ground" ) then  
 if ( event.phase == "began" ) then  
 self.canJump = self.canJump+1  
 elseif ( event.phase == "ended" ) then  
 self.canJump = self.canJump-1  
 end  
 end  
end  
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( "collision", spriteInstance)  

Please lemme know what I am doing wrong! :-/ [import]uid: 203940 topic_id: 36157 reply_id: 143736[/import]

Hello,
I notice a few things immediately:

  1. If you scale a sprite, the image part will scale but the physics body won’t scale with it. If you need to see the actual bodies as they are interacting, turn on “hybrid” physics view. Also, please note that if you put physics objects into different display groups, you must keep those display groups “aligned” with each other (in other words, do not shift them around or try to move a display group for reasons of moving physical objects within it). That is a common mistake, and it will break the collision positional sensing.
physics.setDrawMode( "hybrid" )
  1. It looks like you removed the “foot sensor” body part from the unicorn. Was this intentional?

  2. There’s a syntax error in the following line… you need an and between the two cases. Also, you should bundle the phase checking into one “if > elseif > else > end” routine, versus three separate "if > then > end " routines.

if (event.phase == "began" spriteInstance.canJump \> 0) then

should be…

if (event.phase == "began" and spriteInstance.canJump \> 0) then

[import]uid: 200026 topic_id: 36157 reply_id: 143768[/import]

Hi Brent, thanks for the help. In regards the foot sensor, I took it out the body because for some reason, it broke the code when I tried to reload it in Corona. I have done everything you said, however, it is breaking.

Maybe it will be easier if I paste the whole code of what I am doing here. I am learning lua and corona by trying to remake robot unicorn attack game. I only want him to double jump and no more. Here is the entire code, and apologies for the inconvenience!

[code]

display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()

–physics.setDrawMode( “hybrid” ) – shows collision engine outlines only–

–collision filters

local landCollisionFilter = { categoryBits = 1, maskBits = 6 }
local rockCollisionFilter = { categoryBits = 2, maskBits = 7 }
local unicornCollisionFilter = { categoryBits = 4, maskBits = 3 }

local beepSound = audio.loadSound( “…/images/beep.wav” )

local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")
local background = display.newImage( “…/images/mainBg.jpg”)
background.x= 760
background.y= 150
background.xScale= 4
background.yScale= 4

local background2 = display.newImage( “…/images/mainBg.jpg”)
background2.x= 2800
background2.y= 150
background2.xScale= 4
background2.yScale= 4

local backgroundfar = display.newImage("…/images/cloudsBg.png")
backgroundfar.x = 480
backgroundfar.y = 100

local backgroundnear1 = display.newImage("…/images/cloudsBg.png")
backgroundnear1.x = 240
backgroundnear1.y = 80

local backgroundnear2 = display.newImage("…/images/cloudsBg.png")
backgroundnear2.x = 760
backgroundnear2.y = 80

local ground = display.newImage( “…/images/ground.png” )
ground.x, ground.y = 0, 310
ground.myName=“land”
ground.objType = “ground”

local ground1 = display.newImage( “…/images/ground.png” )
ground1.x, ground1.y = 479, 310
ground1.myName=“land”
ground.objType = “ground”

physics.addBody( ground, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
physics.addBody( ground1, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
– Prevent the unicorn from going too high off screen

–local ceiling = display.newRect(0, 0, display.contentWidth, 1)
–physics.addBody(ceiling, “static”, { bounce = 0.1} )
– physics for the rocks

local rock = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock.x, rock.y = 450, 0
rock:scale (0.8,0.8)
rock.myName=“rock”

local rock1 = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock1.x, rock1.y = 900, 0
rock1:scale (0.8, 0.8)
rock1.myName=“rock”

physics.addBody( rock, { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )
physics.addBody( rock1 , { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )

local beepSound = audio.loadSound( “…/images/beep.wav” )
local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")

–the update function will control most everything that happens in our game
–this will be called every frame(30 frames per second in our case, which is the Corona SDK default)
-----------physics for the land

acc=1

function updateBackgrounds()
–far background movement
backgroundfar.x = backgroundfar.x - (.5)
–near background movement
backgroundnear1.x = backgroundnear1.x - (3)
–if the sprite has moved off the screen move it back to the
–other side so it will move back on
background.x = background.x - (.2)
background2.x = background2.x - (.2)
if(backgroundnear1.x < -239) then
backgroundnear1.x = 760
end

backgroundnear2.x = backgroundnear2.x - (3)

if(backgroundnear2.x < -239) then
backgroundnear2.x = 760
end

if background.x < -1061 then
background.x=3011
end
if background2.x < -1061 then
background2.x=3011
end
if ground.x < -245 then
ground.x=740
end
if ground1.x < -245 then
ground1.x=740
end
if rock.x < -50 then
rock.x=440
end
if rock1.x < -50 then
rock1.x=400
end

ground.x=ground.x-(math.min(acc,8))
ground1.x=ground1.x-(math.min(acc,8))
rock.x=rock.x-(math.min(acc,25))
rock1.x=rock1.x-(math.min(acc,25))
acc= acc+(0.01)

end

local function update( event )
–updateBackgrounds will call a function made specifically to handle the background movement
updateBackgrounds()

– tried perform with Delay here , caused a recurring runtime error
end

–this is how we call the update function, make sure that this line comes after the
–actual function or it will not be able to find it
–timer.performWithDelay(how often it will run in milliseconds, function to call,
–how many times to call(-1 means forever))
timer.performWithDelay(1, update, -1)

local options =
{
frames = require(“ss”).frames
}

–load the sprite

local imageSheet = graphics.newImageSheet( “ss.png”, options )

– load the sets of sprite sequences

local sequencedata= {

{ name=“dash”, start=1, count=14, time=300 },
{ name=“jump”, frames={30,29,28,27,26,25,24,23,22,21,20,19,18,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31}, loopCount=1, time=1000 },
{ name=“land”, start=31, count=26, time=2500 },
{name=“run”, frames={88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59}, time=600 },
{ name=“trail”, start=89, count=10, time=1000 },

}
local spriteInstance = display.newSprite( imageSheet, sequencedata )

spriteInstance.myName=“unicorn”
spriteInstance.x = 40
spriteInstance.y = 200
spriteInstance:scale(0.5,0.5)

physics.addBody( spriteInstance, “dynamic”, { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )
isSensor=true
spriteInstance.canJump = 0
spriteInstance.isFixedRotation = true
local function swapSequence(sequence)

spriteInstance:setSequence(sequence)
spriteInstance:play(sequence)

end

local function onScreenTouch( event )

if (event.phase == “began” spriteInstance.canJump > 0) then
– make character jump forward
swapSequence(“jump”)
spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )

else

if event.phase == “moved” then
swapSequence(“dash”)
spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )
–timer.performWithDelay(2900, swapSequence(“run” ))
else

if

event.phase == “ended” then
swapSequence(“run”)
end

end
Runtime:addEventListener( “touch”, onScreenTouch )

local gameover =display.newImage("…/images/gameover.png")
gameover.x=240
gameover.y=160
gameover.alpha=0

function remove()

spriteInstance:applyForce( 0, -3000, spriteInstance.x, spriteInstance.y )

transition.to(gameover, {delay=1000,time=1000, alpha=1})
timer.performWithDelay(1000, endGame)
end

function endGame()

spriteInstance:removeSelf()
rock:removeSelf()
rock1:removeSelf()
ground:removeSelf()
ground1:removeSelf()
background:removeSelf()
background2:removeSelf()
backgroundfar:removeSelf()
backgroundnear1:removeSelf()
backgroundnear2:removeSelf()

end

function charCollide( self,event )

if ( event.selfElement == 2 and event.other.objType == “ground” ) then
if ( event.phase == “began” ) then
self.canJump = self.canJump+1
elseif ( event.phase == “ended” ) then
self.canJump = self.canJump-1
end
end
end
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( “collision”, spriteInstance)
rock.collision = onLocalCollision
rock:addEventListener( “collision”, rock )

rock1.collision = onLocalCollision
rock1:addEventListener( “collision”, rock1 )

spriteInstance.collision = onLocalCollision
spriteInstance:addEventListener( “collision”, spriteInstance )
local cover = display.newImage("…/images/cover1.png")
cover.x = 240
cover.y = 160

function cover:tap( event )
transition.to(cover, {delay=0,time=500, alpha=0})

audio.play( beepSound )
audio.play( bgmusic )
end

cover:addEventListener( “tap”, cover )

–function onLocalCollision( self, event )
– if ( event.phase == “began” ) then

– if (self.myName=“rock” && event.other.myName=“unicorn” )
– timer.performWithDelay(2900, remove)
– elseif (self.myName=“unicorn” && event.other.myName=“rock” )
– timer.performWithDelay(2900, remove)
– end

–end
–end

–function collisionHandler(event)
– if(event.phase==“began” ) then
– if (event.object1.myName==“unicorn” and event.object2.myName==“rock”)
– remove()
– end

– end
–end

–Runtime:addEventListener(“postCollision”,collisonHandler)
[/code] [import]uid: 203940 topic_id: 36157 reply_id: 143783[/import]

Hi @siddigie1234,
While I and the community would like to help figure out the issue, it’s better if you give smaller elements of code, specific error messages, a description of the problem occurring, etc. Most of us just don’t have time to look through a big page of code and figure out what’s going on.

If you can narrow this down to something specific, I or somebody can probably help further.

Thanks!
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143995[/import]

Hi @siddigie1234,
Welcome to Corona! Your question is very clear, and it’s answered in my recent tutorial here:

http://www.coronalabs.com/blog/2013/02/19/more-physics-tricks-explained/

Best regards,
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143624[/import]

Thank you very much! I will go over the tutorial and if I have any questions, I hope you don’t mind if I ask you! [import]uid: 203940 topic_id: 36157 reply_id: 143632[/import]

Hi Brent, for some reason, the code as it stands is breaking my code.

Can you tell me what I am doing wrong please?

These are the blocks of code I changed to yours

  
local spriteInstance = display.newSprite( imageSheet, sequencedata )  
  
spriteInstance.myName="unicorn"  
spriteInstance.x = 40  
spriteInstance.y = 200  
spriteInstance:scale(0.5,0.5)  
  
physics.addBody( spriteInstance, "dynamic", { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )  
isSensor=true  
spriteInstance.canJump = 0  
spriteInstance.isFixedRotation = true  
  
local function onScreenTouch( event )  
  
 if (event.phase == "began" spriteInstance.canJump \> 0) then  
 -- make character jump forward  
 swapSequence("jump")  
 spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )  
  
 end  
  
 if event.phase == "moved" then  
 swapSequence("dash")  
 spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )  
 --timer.performWithDelay(2900, swapSequence("run" ))  
 end  
  
 if event.phase == "ended" then  
 swapSequence("run")  
 end  
  
  
  
end  
   
Runtime:addEventListener( "touch", onScreenTouch )  
  
function charCollide( self,event )  
  
 if ( event.selfElement == 2 and event.other.objType == "ground" ) then  
 if ( event.phase == "began" ) then  
 self.canJump = self.canJump+1  
 elseif ( event.phase == "ended" ) then  
 self.canJump = self.canJump-1  
 end  
 end  
end  
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( "collision", spriteInstance)  

Please lemme know what I am doing wrong! :-/ [import]uid: 203940 topic_id: 36157 reply_id: 143736[/import]

Hello,
I notice a few things immediately:

  1. If you scale a sprite, the image part will scale but the physics body won’t scale with it. If you need to see the actual bodies as they are interacting, turn on “hybrid” physics view. Also, please note that if you put physics objects into different display groups, you must keep those display groups “aligned” with each other (in other words, do not shift them around or try to move a display group for reasons of moving physical objects within it). That is a common mistake, and it will break the collision positional sensing.
physics.setDrawMode( "hybrid" )
  1. It looks like you removed the “foot sensor” body part from the unicorn. Was this intentional?

  2. There’s a syntax error in the following line… you need an and between the two cases. Also, you should bundle the phase checking into one “if > elseif > else > end” routine, versus three separate "if > then > end " routines.

if (event.phase == "began" spriteInstance.canJump \> 0) then

should be…

if (event.phase == "began" and spriteInstance.canJump \> 0) then

[import]uid: 200026 topic_id: 36157 reply_id: 143768[/import]

Hi Brent, thanks for the help. In regards the foot sensor, I took it out the body because for some reason, it broke the code when I tried to reload it in Corona. I have done everything you said, however, it is breaking.

Maybe it will be easier if I paste the whole code of what I am doing here. I am learning lua and corona by trying to remake robot unicorn attack game. I only want him to double jump and no more. Here is the entire code, and apologies for the inconvenience!

[code]

display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()

–physics.setDrawMode( “hybrid” ) – shows collision engine outlines only–

–collision filters

local landCollisionFilter = { categoryBits = 1, maskBits = 6 }
local rockCollisionFilter = { categoryBits = 2, maskBits = 7 }
local unicornCollisionFilter = { categoryBits = 4, maskBits = 3 }

local beepSound = audio.loadSound( “…/images/beep.wav” )

local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")
local background = display.newImage( “…/images/mainBg.jpg”)
background.x= 760
background.y= 150
background.xScale= 4
background.yScale= 4

local background2 = display.newImage( “…/images/mainBg.jpg”)
background2.x= 2800
background2.y= 150
background2.xScale= 4
background2.yScale= 4

local backgroundfar = display.newImage("…/images/cloudsBg.png")
backgroundfar.x = 480
backgroundfar.y = 100

local backgroundnear1 = display.newImage("…/images/cloudsBg.png")
backgroundnear1.x = 240
backgroundnear1.y = 80

local backgroundnear2 = display.newImage("…/images/cloudsBg.png")
backgroundnear2.x = 760
backgroundnear2.y = 80

local ground = display.newImage( “…/images/ground.png” )
ground.x, ground.y = 0, 310
ground.myName=“land”
ground.objType = “ground”

local ground1 = display.newImage( “…/images/ground.png” )
ground1.x, ground1.y = 479, 310
ground1.myName=“land”
ground.objType = “ground”

physics.addBody( ground, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
physics.addBody( ground1, “static”, { friction=1.0, density=1.0, bounce=0.3,filter=landCollisionFilter} )
– Prevent the unicorn from going too high off screen

–local ceiling = display.newRect(0, 0, display.contentWidth, 1)
–physics.addBody(ceiling, “static”, { bounce = 0.1} )
– physics for the rocks

local rock = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock.x, rock.y = 450, 0
rock:scale (0.8,0.8)
rock.myName=“rock”

local rock1 = display.newImage( “…/images/Rock.png” )
rock:setReferencePoint( display.BottomLeftReferencePoint )
rock1.x, rock1.y = 900, 0
rock1:scale (0.8, 0.8)
rock1.myName=“rock”

physics.addBody( rock, { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )
physics.addBody( rock1 , { friction=0, density=1.0, bounce=0.2,radius=30,filter=rockCollisionFilter } )

local beepSound = audio.loadSound( “…/images/beep.wav” )
local bgmusic = audio.loadSound("…/images/robot-unicorn-attack-song-hd-erasure-always.mp3")

–the update function will control most everything that happens in our game
–this will be called every frame(30 frames per second in our case, which is the Corona SDK default)
-----------physics for the land

acc=1

function updateBackgrounds()
–far background movement
backgroundfar.x = backgroundfar.x - (.5)
–near background movement
backgroundnear1.x = backgroundnear1.x - (3)
–if the sprite has moved off the screen move it back to the
–other side so it will move back on
background.x = background.x - (.2)
background2.x = background2.x - (.2)
if(backgroundnear1.x < -239) then
backgroundnear1.x = 760
end

backgroundnear2.x = backgroundnear2.x - (3)

if(backgroundnear2.x < -239) then
backgroundnear2.x = 760
end

if background.x < -1061 then
background.x=3011
end
if background2.x < -1061 then
background2.x=3011
end
if ground.x < -245 then
ground.x=740
end
if ground1.x < -245 then
ground1.x=740
end
if rock.x < -50 then
rock.x=440
end
if rock1.x < -50 then
rock1.x=400
end

ground.x=ground.x-(math.min(acc,8))
ground1.x=ground1.x-(math.min(acc,8))
rock.x=rock.x-(math.min(acc,25))
rock1.x=rock1.x-(math.min(acc,25))
acc= acc+(0.01)

end

local function update( event )
–updateBackgrounds will call a function made specifically to handle the background movement
updateBackgrounds()

– tried perform with Delay here , caused a recurring runtime error
end

–this is how we call the update function, make sure that this line comes after the
–actual function or it will not be able to find it
–timer.performWithDelay(how often it will run in milliseconds, function to call,
–how many times to call(-1 means forever))
timer.performWithDelay(1, update, -1)

local options =
{
frames = require(“ss”).frames
}

–load the sprite

local imageSheet = graphics.newImageSheet( “ss.png”, options )

– load the sets of sprite sequences

local sequencedata= {

{ name=“dash”, start=1, count=14, time=300 },
{ name=“jump”, frames={30,29,28,27,26,25,24,23,22,21,20,19,18,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31}, loopCount=1, time=1000 },
{ name=“land”, start=31, count=26, time=2500 },
{name=“run”, frames={88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59}, time=600 },
{ name=“trail”, start=89, count=10, time=1000 },

}
local spriteInstance = display.newSprite( imageSheet, sequencedata )

spriteInstance.myName=“unicorn”
spriteInstance.x = 40
spriteInstance.y = 200
spriteInstance:scale(0.5,0.5)

physics.addBody( spriteInstance, “dynamic”, { friction=1.0, density=1.0, bounce=0.3, radius=28,filter=unicornCollisionFilter} )
isSensor=true
spriteInstance.canJump = 0
spriteInstance.isFixedRotation = true
local function swapSequence(sequence)

spriteInstance:setSequence(sequence)
spriteInstance:play(sequence)

end

local function onScreenTouch( event )

if (event.phase == “began” spriteInstance.canJump > 0) then
– make character jump forward
swapSequence(“jump”)
spriteInstance:applyForce( 10, -1000, spriteInstance.x, spriteInstance.y )

else

if event.phase == “moved” then
swapSequence(“dash”)
spriteInstance:applyForce( 30, 0, spriteInstance.x, spriteInstance.y )
–timer.performWithDelay(2900, swapSequence(“run” ))
else

if

event.phase == “ended” then
swapSequence(“run”)
end

end
Runtime:addEventListener( “touch”, onScreenTouch )

local gameover =display.newImage("…/images/gameover.png")
gameover.x=240
gameover.y=160
gameover.alpha=0

function remove()

spriteInstance:applyForce( 0, -3000, spriteInstance.x, spriteInstance.y )

transition.to(gameover, {delay=1000,time=1000, alpha=1})
timer.performWithDelay(1000, endGame)
end

function endGame()

spriteInstance:removeSelf()
rock:removeSelf()
rock1:removeSelf()
ground:removeSelf()
ground1:removeSelf()
background:removeSelf()
background2:removeSelf()
backgroundfar:removeSelf()
backgroundnear1:removeSelf()
backgroundnear2:removeSelf()

end

function charCollide( self,event )

if ( event.selfElement == 2 and event.other.objType == “ground” ) then
if ( event.phase == “began” ) then
self.canJump = self.canJump+1
elseif ( event.phase == “ended” ) then
self.canJump = self.canJump-1
end
end
end
spriteInstance.collision = charCollide ; spriteInstance:addEventListener( “collision”, spriteInstance)
rock.collision = onLocalCollision
rock:addEventListener( “collision”, rock )

rock1.collision = onLocalCollision
rock1:addEventListener( “collision”, rock1 )

spriteInstance.collision = onLocalCollision
spriteInstance:addEventListener( “collision”, spriteInstance )
local cover = display.newImage("…/images/cover1.png")
cover.x = 240
cover.y = 160

function cover:tap( event )
transition.to(cover, {delay=0,time=500, alpha=0})

audio.play( beepSound )
audio.play( bgmusic )
end

cover:addEventListener( “tap”, cover )

–function onLocalCollision( self, event )
– if ( event.phase == “began” ) then

– if (self.myName=“rock” && event.other.myName=“unicorn” )
– timer.performWithDelay(2900, remove)
– elseif (self.myName=“unicorn” && event.other.myName=“rock” )
– timer.performWithDelay(2900, remove)
– end

–end
–end

–function collisionHandler(event)
– if(event.phase==“began” ) then
– if (event.object1.myName==“unicorn” and event.object2.myName==“rock”)
– remove()
– end

– end
–end

–Runtime:addEventListener(“postCollision”,collisonHandler)
[/code] [import]uid: 203940 topic_id: 36157 reply_id: 143783[/import]

Hi @siddigie1234,
While I and the community would like to help figure out the issue, it’s better if you give smaller elements of code, specific error messages, a description of the problem occurring, etc. Most of us just don’t have time to look through a big page of code and figure out what’s going on.

If you can narrow this down to something specific, I or somebody can probably help further.

Thanks!
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143995[/import]

Hi @siddigie1234,
Welcome to Corona! Your question is very clear, and it’s answered in my recent tutorial here:

http://www.coronalabs.com/blog/2013/02/19/more-physics-tricks-explained/

Best regards,
Brent Sorrentino [import]uid: 200026 topic_id: 36157 reply_id: 143624[/import]