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.
recently I was coding a new game when I ran across a problem of which I cannot seem to be able to fix.
This is the code :
function newPower()
rand = math.random( 100 )
if (rand < 80) then
powerup = display.newImage("power.png");
powerup.class = "powerup"
powerup.x = 60 + math.random( 160 )
powerup.y = -100
physics.addBody( powerup, { density=0.9, friction=0.3, bounce=0.3} )
powerup:addEventListener( "touch", handlePowerTouch )
end
end
local function handlePowerTouch( event )
if event.phase == "began" then
currentScore = currentScore * 2
currentScoreDisplay.text = string.format( "%06d", currentScore )
event.target:removeSelf()
return true
end
end
local function spawnpowers()
-- Spawn a new powerup every second until canceled.
spawnPower = timer.performWithDelay( 1000, newPower, -1 )
end
Any help fixing this issue would be greatly appreciated!
The issue I'm having is when I click "run" or "play" the game starts working then crashes and displays this message:
addEventListener: listener cannot be nil: nil stack traceback:
?: in function 'addeventListener'
game.lua63: in function'_listener' <-- i have given you game.lua:63 above.
Thanks
powerup:addEventListener( "touch", handlePowerTouch )
Here handlePowerTouch is nil as the function definition follows after this line.
Move your function definition in front of that line, then it should work.
Btw, is there any reason why you have so many global variables? You should use local variables wherever possible.
I've just started using Corona SDK, and I'm having some problems applying physics on moving platforms.
Basically I have a platforms moving right to left, and when a object lands on the platform there is no friction, the object fails to move with the platform, so once the platform has moved from underneath the object, the object falls to the bottom of the screen. Has anybody else had this problem? I guess maybe a physics object loses some of its attributes but i don't know which one.
I want that the object can move with the platform, same direction and velocity.
Here's a code sample:
.....
elements = display.newGroup()
elements.anchorChildren = true
elements.anchorX = 0
elements.anchorY = 1
elements.x = 0
elements.y = 0
screenGroup:insert(elements)
player = display.newImageRect("player.png",30,50)
player.anchorX = 50
player.anchorY = 50
player.x = 80
player.y = display.viewableContentHeight - 80
physics.addBody(player, "static", {density=.1, bounce=0.1, friction=1.0})
player:setLinearVelocity( 100, -600 )
screenGroup:insert(player)
.....
....
local gameStarted = false
function jumptoplatform(event)
if event.phase == "began" then
if gameStarted == false then
player.bodyType = "dynamic"
addplatformsTimer = timer.performWithDelay(1000, addplatforms, -1)
moveplatformsTimer = timer.performWithDelay(2, moveplatforms, -1)
gameStarted = true
player:setLinearVelocity( 100, -600 )
else
player:setLinearVelocity( 100, -600 )
end
end
end
function moveplatforms()
for a = elements.numChildren,1,-1 do
if(elements[a].x > -150) then
elements[a].x = elements[a].x - 6
else
elements:remove(elements[a])
end
end
end
function addplatforms()
platform1 = display.newImageRect("platform.png",200,80)
platform1.anchorX = 0
platform1.anchorY = 1
platform1.x = 450
platform1.y = yPosition()
physics.addBody(platform1, "static", {density=1, bounce=0.1, friction=1.0})
elements:insert(platform1)
end
.....
Maybe I have to add an onCollision function, to handle it?, or use joints? Any idea will be appreciated..
When you create a physics body, "static" body type means that bodies does not move under simulation and they behave as if they have infinite mass. Static bodies can be moved manually by the user, but they do not accept the application of velocity. Static bodies collide only with dynamic bodies, not with other static bodies or kinematic bodies.
(More details here: http://docs.coronalabs.com/api/type/Body/bodyType.html)
Try like this:
physics.addBody(player, "dynamic", {density=.1, bounce=0.1, friction=1.0})
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.
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/