how to collide objects in corona labs - lua
I'm trying to make a game in Corona SDK where a player runs and survives through obstacles by either jumping over them or killing them using bullets. The problem is that the game ends even if the player fires the bullet. But it should be over only if the player collides with the obstacles.
This is my code till now!!
--local screen_adjustment = 1
local physics = require "physics"
physics.start()
local storyboard = require ("storyboard")
local scene = storyboard.newScene()
function scene:createScene( event )
local screenGroup=self.view
background=display.newImage("rsz_islands1-background-animation.png")
background:setReferencePoint(display.BottomLeftReferencePoint)
background.x=-50
background.y=330
background.speed=math.random(2,6)
screenGroup:insert(background)
background1=display.newImage("rsz_islands1-background-animation.png")
background1:setReferencePoint(display.BottomLeftReferencePoint)
background1.x=500
background1.y=330
background1.speed=math.random(2,6)
screenGroup:insert(background1)
rightArrow=display.newImageRect("right_arrow.png",50,100)
rightArrow:setReferencePoint(display.BottomLeftReferencePoint)
rightArrow.x=370
rightArrow.y=290
screenGroup:insert(rightArrow)
upArrow=display.newImageRect("up_Arrow.png",100,50)
upArrow:setReferencePoint(display.BottomLeftReferencePoint)
upArrow.x=250
upArrow.y=240
screenGroup:insert(upArrow)
stone=display.newImageRect("stone.png",100,50)
stone:setReferencePoint(display.BottomLeftReferencePoint)
stone.x=math.random(500,1500)
stone.y=280
stone.speed=math.random(2,6)
physics.addBody(stone,"static",{bounce=0,friction=0,})
screenGroup:insert(stone)
base = display.newRect(0,0,450,3)
base.x=-50
base.y=282
base:setReferencePoint(display.BottomLeftReferencePoint)
base:setFillColor(255,255,255)
--physics.addBody(base,"static",{bounce=0.1,friction=0.1})
physics.addBody(base,"static",{bounce=0,friction=1.0,density=1.0})
screenGroup:insert(base)
base.myName="base1"
local sheetData = {
width=65,
height=75,
numFrames=4,
sheetContentWidth=130,
sheetContentHeight=150
}
local mySprite = graphics.newImageSheet("imageSheet.png",sheetData)
local sequenceData = {
name="normalRun",
frames={1,2,3,4},
time=500,
loopcount=0
}
animation = display.newSprite(mySprite,sequenceData)
if(animation.x<50) then
animation.x=50
end
animation.y=245
physics.addBody(animation,{bounce=0.3,friction=1.0,density=1.0,radius=35})
animation:play()
screenGroup:insert(animation)
animation.myName="animation1"
local sheetTigerData = {
width=100,
height=57,
numFrames=8,
sheetContentWidth=400,
sheetContentHeight=120
}
local myTigerSprite
graphics.newImageSheet("tigerImageSheet.png",sheetTigerData)
local sequenceTigerData = {
name="normalRun",
frames={1,2,3,4,5,6,7,8},
time=500,
loopcount=0
}
tigeranimation = display.newSprite(myTigerSprite,sequenceTigerData)
--tigeranimation.x=700
tigeranimation.x=math.random(500,1500)
tigeranimation.y=255
tigeranimation.speed=math.random(2,6)
physics.addBody(tigeranimation,"static",{bounce=0,friction=.2})
tigeranimation:play()
screenGroup:insert(tigeranimation)
local sheetBirdData = {
width=60,
height=40,
numFrames=6,
sheetContentWidth=180,
sheetContentHeight=80
}
local myBirdSprite =
graphics.newImageSheet("birdimagesheet.png",sheetBirdData)
local sequenceBirdData = {
name="normalRun",
frames={1,2,3,4,5,6},
time=500,
loopcount=0
}
birdanimation = display.newSprite(myBirdSprite,sequenceBirdData)
birdanimation.x=math.random(500,2500)
birdanimation.y=math.random(100,200)
birdanimation.speed=2
birdanimation.initY=birdanimation.y
birdanimation.amp=50
birdanimation.angle=math.random(1,360)
physics.addBody(birdanimation,"static",{friction=.2,bounce=0})
birdanimation:play()
screenGroup:insert(birdanimation)
local sheetCatData = {
width=100,
height=48,
numFrames=8,
sheetContentWidth=200,
sheetContentHeight=200
}
local myCatSprite =
graphics.newImageSheet("rsz_runningcat.png",sheetCatData)
local sequenceCatData = {
name="normalRun",
frames={2,1,4,3,6,5,8,7},
time=500,
loopcount=0
}
catanimation = display.newSprite(myCatSprite,sequenceCatData)
catanimation.x=tigeranimation.x+math.random(110,1500)
catanimation.y=255
catanimation.speed=math.random(2,6)
physics.addBody(catanimation,"static",{bounce=0,friction=.2})
catanimation:play()
screenGroup:insert(catanimation)
gameSound=audio.loadStream("gamesound.mp3")
audio.play(gameSound)
gunshot=audio.loadStream("gunshot3.mp3")
end
function scrollBack( self,event )
if self.x<-590 then
self.x=500
audio.play(gameSound)
else
self.x=self.x-3
audio.play(gameSound)
end
end
function moveTiger( self,event )
if self.x<-100 then
self.x=math.random(1500,4000)
self.y=255
self.speed=math.random(3,6)
audio.play(gameSound)
else
self.x=self.x-self.speed
audio.play(gameSound)
end
end
function moveCat( self,event )
if self.x<-100 then
self.x=tigeranimation.x+math.random(800,2000)
self.y=255
self.speed=math.random(3,6)
else
self.x=self.x-self.speed
end
end
function moveStone( self,event )
if self.x<-100 then
self.x=math.random(1000,5000)
self.y=280
self.speed=math.random(3,6)
else
self.x=self.x-self.speed
end
end
function moveBird( self,event )
if self.x<-100 then
self.x=math.random(500,2500)
--self.x=300
self.y=math.random(100,200)
self.speed=2
self.amp=math.random(25,75)
self.angle=math.random(1,360)
--self.y=280
--self.speed=math.random(3,6)
else
self.x=self.x-self.speed
self.angle=self.angle+.1
self.y=self.amp*math.sin(self.angle)+self.initY
end
end
function fireLasers()
blaster = display.newImageRect( "bullet.png", 40, 15 )
physics.addBody(blaster,"dynamic")
blaster.x = animation.x+50
blaster.y = animation.y-10
--blaster.collided=false
if(animation.x<50) then
animation.x=50
end
transition.to( blaster, { time=1000, x=500} )
audio.play(gunshot)
end
function handleFireButton( event )
if ( event.phase == "began" ) then
-- Fire the weapon
fireLasers()
elseif ( event.phase == "ended" ) then
-- Stop firing the weapon
fireLasers()
end
return true
end
positionInAir = false
function jump(event)
if(event.phase == "began" and positionInAir==false) then
--playerInAir = true
--animation:setLinearVelocity( 0, 1 )
animation:applyForce(0,-1000,animation.x,animation.y)
positionInAir=true
--physics.addBody(animation,"dynamic")
--print("touch")
end
return true
end
function onCollision( event )
if(event.object1.myName == "base1" and event.object2.myName == "animation1")
then
positionInAir = false;
-- base:removeSelf()
end
end
local function onManCollide(event)
if ( event.phase == "began" ) then
storyboard.gotoScene("restart","fade",400)
audio.stop()
end
end
function scene:enterScene( event )
background.enterFrame=scrollBack
Runtime:addEventListener("enterFrame",background)
background1.enterFrame=scrollBack
Runtime:addEventListener("enterFrame",background1)
stone.enterFrame=moveStone
Runtime:addEventListener("enterFrame",stone)
tigeranimation.enterFrame=moveTiger
Runtime:addEventListener("enterFrame",tigeranimation)
birdanimation.enterFrame=moveBird
Runtime:addEventListener("enterFrame",birdanimation)
catanimation.enterFrame=moveCat
Runtime:addEventListener("enterFrame",catanimation)
animation.collision=onManCollide
animation:addEventListener("collision",onManCollide)
rightArrow:addEventListener( "touch", handleFireButton )
--Runtime:addEventListener( "touch", handleFireButton )
--Runtime:addEventListener( "enterFrame", handleFireButton )
--upArrow:addEventListener("touch", jump)
--Runtime:addEventListener( "collision", onCollision )
--Runtime:addEventListener( "touch", onScreenTouch )
--rightArrow:addEventListener( "touch", handleFireButton )
end
function scene:exitScene( event )
Runtime:removeEventListener("enterFrame",background)
Runtime:removeEventListener("enterFrame",background1)
Runtime:removeEventListener("enterFrame",stone)
Runtime:removeEventListener("enterFrame",tigeranimation)
Runtime:removeEventListener("enterFrame",birdanimation)
Runtime:removeEventListener("enterFrame",catanimation)
Runtime:removeEventListener("enterFrame",onManCollide)
rightArrow:removeEventListener( "touch", handleFireButton )
upArrow:removeEventListener("touch", jump)
Runtime:removeEventListener( "collision", onCollision )
end
function scene:destroyScene( event )
end
--local myGroup=display.newGroup()
--physics.addBody(background,"static",{bounce=0.1,friction=0.9})
--physics.addBody(background1,"static",{ bounce=0.1,friction=0.9})
scene:addEventListener("createScene",scene)
scene:addEventListener("enterScene",scene)
scene:addEventListener("exitScene",scene)
scene:addEventListener("destroyScene",scene)
return scene
You need to ask a specific question, what you have said is quite vague. Does the game end each time the player fires the bullet? Also you should consider migrating from storyboard to composer.
Related
How to also pause physics object before entering screen in corona?
I used physics.pause() and physics.start() , it works but my problem is that one function keeps displaying an object at the bottom and when I resume the game, those object are compiled and all of them enter screen at once. I hope someone can help me. here's my code: local isPaused = false function pausePhysics( event ) if "began" == event.phase then if isPaused == false then physics.pause(lobo) isPaused = true timer.pause(countDownTimer) local decide = display.newImage("wood.png") decide.x = display.contentWidth*0.5 decide.y = display.contentHeight*0.5 local yes local no local function oo() if score == 0 then onBackBtnRelease() elseif score >0 and score <=10 then GameOver1() elseif score >10 and score <=20 then GameOver2() else GameOver3() end end yes = widget.newButton { defaultFile= "yes.png", width=100, height=50, onRelease = oo } yes.x = display.contentWidth*0.3 yes.y = display.contentHeight - 200 local function hindi() if isPaused == true then physics.start() isPaused = false timer.resume(countDownTimer) display.remove(decide) decide = nil display.remove(yes) yes = nil display.remove(no) no = nil end return true end no = widget.newButton { defaultFile= "no.png", width=100, height=50, onRelease = hindi } no.x = display.contentWidth*0.7 no.y = display.contentHeight - 200 sceneGroup:insert(decide) sceneGroup:insert(yes) sceneGroup:insert(no) return true end end end local function tapos(event) if (event.phase == "began") then physics.addBody(backBtn, "static") end end Runtime:addEventListener("enterFrame", backBtn) backBtn:addEventListener("touch", pausePhysics) local function ulit() local mRandom = math.random local balloon = { ("blue.png"), ("green.png"), ("red.png"), ("orange.png"), ("pink.png"), ("violet.png"), ("yellow.png"), ("blue2.png"), ("green2.png"), ("red2.png"), ("orange2.png"), ("pink2.png"), ("violet2.png"), ("yellow2.png") } local lobo = display.newImage( balloon[mRandom(10)], mRandom(30,270), mRandom(550,650) ) physics.addBody( lobo, { density=0.1, friction=2.0, bounce=0.0, velocity=-40, isSensor=true } ); end timer.performWithDelay(300,ulit,0)
Corona SDK : How to identify the collision object?
I'm a beginner in Corona developping and i've to problem to identify the collision between 3 objects. In fact, this is my code : The first object is my player : player = display.newImageRect("ballon.png", 150,170 ) player.anchorX = 0.5 player.anchorY = 0.5 player.x = display.contentCenterX - 450 player.y = display.contentCenterY+250 physics.addBody(player, "static", {density=0.1, bounce=0.1, friction=0.1,}) player.myName="player" screenGroup:insert(player) The second object is created within a function : function addWindSlow(self,event) height = math.random(display.contentCenterY - 200, display.contentCenterY + 200) windslow = display.newImage( "wind-neg.png") windslow.x = display.contentWidth windslow.y = height windslow.speed = 4 windslow.myName="windslow" physics.addBody(windslow, "static", {density = 0.1, bounce = 0, isSensor = false}) elements:insert(windslow) end function addWindFast(self,event) height = math.random(display.contentCenterY - 200, display.contentCenterY + 200) windfast = display.newImage( "wind-pos.png") windfast.x = display.contentWidth windfast.y = height windfast.speed = 4 windfast.myName="windfast" physics.addBody(windfast, "static", {density = 0.1, bounce = 0, isSensor = false}) elements:insert(windfast) end And finally, the thirth object is the same but called "addWindFast() with a different image" So i would like to know once my player is on collision with the windslow, i need to do an action... and if it's the object windfast, another action. That's my code : function onCollision( event ) if ( event.phase == "began" ) then if event.other.windslow and event.other.isVisible==true then print("windslow has been touch !") end end end I found something about the pre-collision, I'll use it once i got the information how to "identify" the object...I'll need to prevent the collision and avoid it if the player is going to touch the windfast or windslow. We thank you for all dude !
It looks like windslow and windfast are defined outside of onCollision event handler so you should compare to those: function onCollision( event ) if ( event.phase == "began" ) then if event.other == windslow and event.other.isVisible==true then print("windslow has been touch !") end if event.other == windfast and event.other.isVisible==true then print("windfast has been touch !") end end end -- (missing from your post but probably in your code) The above assumes that you have registered for collision events on your player. You could also register a different collision handler on each wind: windslow:addEventListener("collision", onCollisionSlow) windfast:addEventListener("collision", onCollisionFast) In that case the two collision handlers could just check if event.other == player. The advantage of that is you are separating the code for each one. You could of course do the same with your player handler: function onCollisionSlow(other) print('collided with slow') end function onCollisionFast(other) print('collided with fast') end collisionHandlers = { [windslow] = onCollisionSlow, [windfast] = onCollisionFast, } function onCollision( event ) if ( event.phase == "began" ) then collisionFunc = collisionHandlers[event.other] if collisionFunc ~= nil and event.other.isVisible then collisionFunc(event.other) end end end
You could identify the other object with the myName property you've specified. For example: function onCollision( event ) if ( event.phase == "began" ) then if (event.other.myName == "windslow" and event.other.isVisible==true) then print("windslow has been touched!") elseif (event.other.myName = "windfast" and event.other.isVisible==true) then print("windfast has been touched!") end end
Add ID to listener after loading remote image
I have a listener for loading remote images, but I need to be able to pass an ID number to that listener, and I'm not really sure how to do it. My code to retrieve the remote image is: display.loadRemoteImage("http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg", "GET", networkListener, "banner.png",system.TemporaryDirectory, (globalData.contentX * rows2) + globalData.contentX/2, 20 + (i - 1) % 6 * 140 And the listener I have is: local function networkListener( event ) if ( event.isError ) then print ( "Network error - download failed" ) else local target = event.target target.alpha = 0 transition.to( target, { alpha = 1.0 } ) target.width = 590 target.height = 110 target:addEventListener( "touch", target ) scrollView:insert(target) function target:touch(event) if event.phase == "began" then display.getCurrentStage():setFocus( self ) self.isFocus = true elseif self.isFocus then if event.phase == "moved" then numMoved = numMoved + 1 if(numMoved > 10) then display.getCurrentStage():setFocus( nil ) self.isFocus = false scrollView:takeFocus( event ) end elseif event.phase == "ended" or event.phase == "cancelled" then globalData.selectedLocationID = target.id --This needs to be the ID that I pass to this listener if(globalData.approvedToggle == 1) then storyboard.gotoScene("businessScene") else storyboard.gotoScene("locationScene") end display.getCurrentStage():setFocus( nil ) self.isFocus = false end end return true end end Any help in this matter would be greatly appreciated, thanks!
I did this a while back on an Ecommerence app I was making. I'm not to familer with storyboard, but I do remember using this API. If I remember correctly, you need to use event.target as the event listener and pass everything through there. I also remember that you can embed a function inside of the display.loadRemoteImage API like this: itemImage = display.loadRemoteImage(itemData.imageURL, "GET", function(event) event.target.xScale = 0.4 event.target.yScale = 0.4 function openSite(event) if event.phase == "ended" then system.openURL( itemData.itemURL ) end end event.target:addEventListener( "tap", openSite ) end) My advice is remove all the story board stuff, and try making the API work in a different document. I think that you need to simplify it so you aren't confused. Hopefully this helps.
Images doesn´t appear in storyboard Corona SDK
I am doing a game in corona SDK, but I have this little problem. I have a menu with a button. If I press it, it sends me to the first level of my game. When I pass the final level, the game return me to the menu. Bur, if I start playing the first again, my images doesn´t appear. The images are balls, and to pass the level, you have to eliminate all the balls. To do this, I use: ball:removeSlef() ball = nil But, I don´t think that this is the problem, because I eliminate this lines, and it doesn´t work. The images are create in scene:createScene function, and insert in the Group. I short the code of the first level to be understood. local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local physics = require "physics" physics.start(); physics.pause() physics.setGravity( 0, 0 ) local cont = 0 local bur = {} function eliminar1( event ) if (cont == 0) and (event.phase == "began") then event.target:removeSelf() bur[1] = nil cont = cont + 1 end end function eliminar2( event ) if (cont == 1) and (event.phase == "began") then bur[2]:removeSelf() bur[2] = nil cont = cont + 1 end end function eliminar3( event ) if (cont == 2) and (event.phase == "began") then bur[3]:removeSelf() bur[3] = nil storyboard.gotoScene( "levels.1.level2" ) end end function scene:createScene ( event ) local screenGroup = self.view for i = 1,3 do bur[i] = display.newImage("irudiak/"..i..".png") bur[i]:translate(math.random(0,280), math.random(0,400) ) physics.addBody( bur[i], {bounce = 0.3 } ) bur[i]:setLinearVelocity(math.random(-50,50), math.random(-50,50) ) screenGroup:insert(bur[i]) end bur[1]:addEventListener("touch", eliminar1) bur[2]:addEventListener("touch", eliminar2) bur[3]:addEventListener("touch", eliminar3) end function scene:enterScene( event ) local screenGroup = self.view physics.start() end function scene:exitScene( event ) local screenGroup = self.view physics.stop() end function scene:destroyScene( event ) local screenGroup = self.view package.loaded[physics] = nil physics = nil end return scene
createScene is ran only first time when you gotoScene. Every next time only willEnterScene and enterScene are played. To play createScene again you have to remove it (storyboard.removeScene() I guess). Or you can move some stuff you need to willEnterScene. For more detailed info you can watch this: http://www.coronalabs.com/blog/2013/08/20/tutorial-reloading-storyboard-scenes/
Moving a character with Lua
I am new to Lua and am attempting to simulate a character moving. I have the character moving left and right at the moment. I would like the character to move 16 pixels at a time. That works fine given that the user doesn't touch the phone rapidly. In that case, the character moves a random number of pixels. my question is, how can i get the touch event to only register once at a time. my code: -- move character function moveCharacter(event) if event.phase == 'began' then if event.x > character.x+8 then transition.to(background, {time=800, x=background.x-16}) end if event.x < character.x-8 then transition.to(background, {time=800, x=background.x+16}) end end end function touchScreen(event) Runtime:removeEventListener('touch', moveCharacter) if event.phase == 'began' then Runtime:addEventListener('touch', moveCharacter) end end Runtime:addEventListener('touch', touchScreen)
You can try this: function moveCharEF() if event.x > character.x+8 then background.x = background - 16 end if event.x < character.x-8 then background.x = background + 16 end end function moveCharacter(event) if event.phase == 'began' then display.getCurrentStage():setFocus( event.target ) event.target.isFocus = true Runtime:addEventListener( "enterFrame", moveCharEF ) elseif event.target.isFocus then if event.phase == "ended" then Runtime:removeEventListener( "enterFrame", moveCharEF ) display.getCurrentStage():setFocus( nil ) event.target.isFocus = false end end end function touchScreen(event) Runtime:removeEventListener('touch', moveCharacter) if event.phase == 'began' then Runtime:addEventListener('touch', moveCharacter) end end Runtime:addEventListener('touch', touchScreen) By the way, I dont know about your application. So character may move too fast or too slow. Just change moveCharEF() function's related lines
Is it is what you looking for..? local isTransitionInProgress = false local function resetFlag() isTransitionInProgress = false end function moveCharacter(event) if(event.x > character.x+8 and isTransitionInProgress==false) then isTransitionInProgress = true transition.to(background, {time=800, x=background.x-16,onComplete=resetFlag()}) end if(event.x < character.x-8 and isTransitionInProgress==false) then isTransitionInProgress = true transition.to(background, {time=800, x=background.x+16,onComplete=resetFlag()}) end end background:addEventListener("tap", moveCharacter) Keep coding... :)
You can try using the "tap" listener instead of "touch". It only registers one touch at a time. Runtime:addEventListener('tap', touchScreen)