i get this error only when this scene is reloaded ,it gives getLinearVelocity nil value error ,when the scene is loaded for the first time it doesn’t have any issue but when it is loaded again the error appears,i am a beginner ,please do help
–
– menu.lua
–
local relayout = require(‘libs.relayout’)
local composer = require( “composer” )
local scene = composer.newScene()
local newEndLevelPopup = require(‘classes.end_level_popup’).newEndLevelPopup – Win/Lose dialog windows
– include Corona’s “widget” library
local widget = require “widget”
local Trajectory = require( “dmc_library.dmc_trajectory” )
– forward declarations and other locals
local playBtn
local timerGroup
local point_list = {}
–====================================================================–
– Setup, Constants
–====================================================================–
local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 0 )
local fruitGroup
local avalFruit = {}
display.setStatusBar( display.HiddenStatusBar )
local gushProp = {density = 1.0, friction = 0.3, bounce = 0.2, filter = {categoryBits = 4, maskBits = 8} }
math.randomseed( os.time() )
local secondsLeft = 10
local sheetOptions =
{
frames =
{
{ – 1) asteroid 1
x = 0,
y = 0,
width = 102,
height = 85
},
{ – 2) asteroid 2
x = 0,
y = 85,
width = 90,
height = 83
},
{ – 3) asteroid 3
x = 0,
y = 168,
width = 50,
height = 330
},
{ – 4) ship
x = 320,
y = 0,
width = 90,
height = 400
},
{ – 5) laser
x = 98,
y = 265,
width = 14,
height = 40
},
},
}
– Gush properties
local minGushRadius = 4
local maxGushRadius = 13
local numOfGushParticles = 15
local gushFadeTime = 200
local gushFadeDelay = 200
local clockText
local minGushVelocityX = -350
local maxGushVelocityX = 350
local minGushVelocityY = -350
local maxGushVelocityY = 350
– coordinate points for each test location
–
local POINTS = {
{ -50, 500 }, {400,500}
}
local objectSheet = graphics.newImageSheet( “assets/knives.png”, sheetOptions )
– tables of values, used for random choices
–
local fruit
local HEIGHTS = { 300, 350,400 , 455 }
local TIMES = { 1900, 2000, 2300, 2800 }
local splashImgs = {}
local minVelocityY = 850
local maxVelocityY = 1100
local minVelocityX = -200
local maxVelocityX = 200
local minAngularVelocity = 10
local maxAngularVelocity = 100
– Chopped fruit physics properties
local minAngularVelocityChopped = 100
local maxAngularVelocityChopped = 200
local backGroup = display.newGroup() – Display group for the background image
local mainGroup = display.newGroup()
fruitGroup = display.newGroup()
local sceneGroup=display.newGroup()
local fruitProp1 = {density = 1.0, friction = 0.3, bounce = 0.2, filter = {categoryBits = 2, maskBits = 1}}
local fruitProp = {density = 1.0, friction = 0.3, bounce = 0.2, filter = {categoryBits = 2, maskBits = 1}}
–[[function initballs()
{
local fire=“assets/balls/b1.png”
local ice=“assets/balls/b2.png”
local pearl=“assets/balls/b3.png”
local bluep=“assets/balls/b4.png”
local bomb=“assets/balls/b5.png”
local yball=“assets/balls/b6.png”
}]]
function initFruitAndSplash()
local watermelon = {}
watermelon.whole = “assets/fruits/watermelon.png”
watermelon.top = “assets/fruits/watermelon1.png”
watermelon.bottom = “assets/fruits/watermelon2.png”
watermelon.splash = “splash1.png”
watermelon.name=“w”
table.insert(avalFruit, watermelon)
local strawberry = {}
strawberry.whole = “assets/fruits/strawberry.png”
strawberry.top = “assets/fruits/strawberry1.png”
strawberry.bottom = “assets/fruits/strawberry2.png”
strawberry.splash = “assets/fruits/splash2.png”
strawberry.name=“sy”
table.insert(avalFruit, strawberry)
local apple={}
apple.whole=“assets/fruits/apple.png”
apple.top=“assets/fruits/apple1.png”
apple.bottom=“assets/fruits/apple2.png”
apple.name=“ap”
table.insert(avalFruit,apple)
local lemon={}
lemon.whole=“assets/fruits/lemon.png”
lemon.top=“assets/fruits/lemon1.png”
lemon.bottom=“assets/fruits/lemon2.png”
lemon.name=“li”
table.insert(avalFruit,lemon)
local pineapple={}
pineapple.whole=“assets/fruits/pineapple.png”
pineapple.top=“assets/fruits/pineapple1.png”
pineapple.bottom=“assets/fruits/pineapple2.png”
pineapple.name=“pl”
table.insert(avalFruit,pineapple)
local pears={}
pears.whole=“assets/fruits/pears.png”
pears.top=“assets/fruits/pears1.png”
pears.bottom=“assets/fruits/pears2.png”
pears.name=“pr”
table.insert(avalFruit,pears)
local coconut={}
coconut.whole=“assets/fruits/coconut.png”
coconut.top=“assets/fruits/coconut1.png”
coconut.bottom=“assets/fruits/coconut2.png”
coconut.name=“co”
table.insert(avalFruit,coconut)
local lime ={}
lime.whole=“assets/fruits/lime.png”
lime.top=“assets/fruits/lime1.png”
lime.bottom=“assets/fruits/lime2.png”
lime.name=“lm”
table.insert(avalFruit,lime)
local mango={}
mango.whole=“assets/fruits/mango.png”
mango.top=“assets/fruits/mango1.png”
mango.bottom=“assets/fruits/mango2.png”
mango.name=“mg”
table.insert(avalFruit,mango)
local apricot={}
apricot.whole=“assets/fruits/apricot.png”
apricot.top=“assets/fruits/apricot1.png”
apricot.bottom=“assets/fruits/apricot2.png”
apricot.name=“ap”
table.insert(avalFruit,apricot)
local plum={}
plum.whole=“assets/fruits/plum.png”
plum.top=“assets/fruits/plum1.png”
plum.bottom=“assets/fruits/plum2.png”
plum.name=“pl”
table.insert(avalFruit,plum)
local banana={}
banana.whole=“assets/fruits/banana.png”
banana.top=“assets/fruits/banana1.png”
banana.bottom=“assets/fruits/banana2.png”
banana.name=“ba”
table.insert(avalFruit,banana)
local bomb={}
bomb.whole=“assets/balls/b2.png”
bomb.top=“assets/balls/b2.png”
bomb.bottom=“assets/balls/b2.png”
bomb.name=“bm”
table.insert(avalFruit,bomb)
– Initialize splash images
table.insert(splashImgs, “assets/fruits/splash1.png”)
table.insert(splashImgs, “assets/fruits/splash2.png”)
table.insert(splashImgs, “assets/fruits/splash3.png”)
end
– ‘onRelease’ event listener for playBtn
local function timeScene()
– go to level1.lua scene
composer.gotoScene( “Scenes.timer”, “fade”, 150 )
return true – indicates successful touch
end
function getRandomFruit()
local fruitProp = avalFruit[math.random(1, #avalFruit)]
fruit = display.newImage(fruitProp.whole)
fruit.whole = fruitProp.whole
fruit.top = fruitProp.top
fruit.bottom = fruitProp.bottom
fruit.splash = fruitProp.splash
fruit.name=fruitProp.name
return fruit
end
local function fireLaser()
local newLaser = display.newImageRect( mainGroup, objectSheet, 4, 20, 90 )
physics.addBody( newLaser, “dynamic”, { isSensor=true } )
newLaser.rotation=0
newLaser.isBullet = true
newLaser.myName = “laser”
newLaser.x = ship.x
newLaser.y = ship.y
val=newLaser.x
newLaser:toBack()
transition.to( newLaser, { y=-1, time=200,
onComplete = function() display.remove( newLaser ) end
} )
end
local function updateTime( event )
– Decrement the number of seconds
secondsLeft = secondsLeft - 1
– Time is tracked in seconds; convert it to minutes and seconds
local minutes = math.floor( secondsLeft / 60 )
local seconds = secondsLeft % 60
– Make it a formatted string
local timeDisplay = string.format( “%02d:%02d”, minutes, seconds,secondsLeft )
– Update the text object
clockText.text = timeDisplay
sceneGroup:insert(clockText)
if(secondsLeft==0)then
composer.gotoScene( “Scenes.menu2”, { time=800, effect=“crossFade” } )
end
end
local function dragShip( event )
local ship = event.target
local phase = event.phase
if ( “began” == phase ) then
– Set touch focus on the ship
display.currentStage:setFocus( ship )
– Store initial offset position
ship.touchOffsetX = event.x - ship.x
elseif ( “moved” == phase ) then
– Move the ship to the new touch position
ship.x = event.x - ship.touchOffsetX
elseif ( “ended” == phase or “cancelled” == phase ) then
– Release touch focus on the ship
display.currentStage:setFocus( nil )
end
return true – Prevents touch propagation to underlying objects
end
local doTransition, startTest – forward declare functions
– drawGrid()
– create and position the grid points - locations for trajectory tests
–
local function drawGrid()
local o
for i=1, #POINTS do
o = display.newCircle( POINTS[i][1], POINTS[i][2], 3 )
backGroup:insert( o )
end
end
– doTransition()
– recursive function which sets up test points with colored markers and runs a transition
–
– list (table}: array of array of point pairs
– eg { { {0,100}, {10,100} }, { {0,100}, {20,100} }, … }
– createProjectile (function ref): function to call to create a projectile object
– params (table): table of parameters to pass in
–
function doTransition( list, createProjectile, params )
local oB, oE, oP – object Begin, End, Projectile
local height, time – random height and time for transition
– get next set of point pairs
local pB, pE = unpack( table.remove( list ) )
– clean up params if necessary
local params = params == nil and {} or params
local rotate = params.rotate
– begin point - green
oB = display.newCircle( pB[1], pB[2], 5 )
oB:setFillColor( 0, 1, 0 )
– end point – red
oE = display.newCircle( pE[1], pE[2], 5 )
oE:setFillColor( 1, 0, 0 )
– projectile
oP = createProjectile()
oP.x, oP.y = pB[1], pB[2]
– onComplete function, called after trajectory transition is finished
local complete = function()
– clean up test items
if( oP.removeSelf ~= nil ) then – Check if it’s still added to the display…
oP:removeSelf()
end
if( oE.removeSelf ~= nil ) then – Check if it’s still added to the display…
oE:removeSelf()
end
if( oB.removeSelf ~= nil ) then
– Check if it’s still added to the display…
oB:removeSelf()
end
– see if anything left in the list of Point Pairs
if #list > 0 then
if(secondsLeft>0)then
doTransition( list, createProjectile, params )
else
table.remove(list)
params=0
end
else
– start over
if(secondsLeft>0)then
startTest( createProjectile, params )
else
table.remove(list)
params=0
end
end
end
– get random height and time for next transition
if(secondsLeft>0)then
height = HEIGHTS[math.random( #HEIGHTS )]
time = TIMES[math.random( #TIMES )]
– DO IT !!
Trajectory.move( oP, { time=time, pBegin=pB, pEnd=pE, height=height, rotate=rotate, onComplete=complete } )
end
end
– startTest()
– creates the list of Point Pairs to test, skipping pairs which are the same
– calls recursive function doTransition with list for processing
–
function startTest( projectileFunction, params )
– create list
for i=#POINTS, 1, -1 do
for j=#POINTS, 1, -1 do
if i ~= j then
table.insert( point_list, { POINTS[i], POINTS[j] } )
end
end
end
– do test
doTransition( point_list, projectileFunction, params )
end
function getBall()
local object=display.newImage(“assets/balls/b1.png”)
return object
end
–== Projectile Creation functions ==–
–
local createBlueRoundProjectile = function()
local o = getRandomFruit() or getBall()
physics.addBody( o, “dynamic”, { radius=30, bounce=0.8 } )
o.myName = “fruit”
local p = { rotate=true, direction=“left” }
return o, p
end
local createPurpleRectProjectile = function()
local o = getRandomFruit() or getBall()
physics.addBody( o, “dynamic”, { radius=30, bounce=0.8 } )
o.myName = “fruit”
local p = { rotate=true, direction=“right” }
return o,p
end
local createYellowRectProjectile = function()
local o = getRandomFruit() or getBall()
physics.addBody( o, “dynamic”, { radius=30, bounce=0.8 } )
o.myName = “fruit”
local p = { rotate=true, direction=“right” }
return o,p
end
–== Main Function
local function onCollision( event )
if ( event.phase == “began” ) then
local obj1 = event.object1
local obj2 = event.object2
if ( ( obj1.myName == “laser” and obj2.myName == “fruit” ) or
( obj1.myName == “fruit” and obj2.myName == “laser” ) )
then
– Remove both the laser and asteroid
if(obj1.myName==“fruit”)then
chopFruit(event.object1)
else
chopFruit(event.object2)
end
for i = #point_list, 1, -1 do
if ( point_list[i] == obj1 or point_list[i] == obj2 ) then
table.remove( point_list, i )
break
end
end
– Increase score
elseif ( ( obj1.myName == “ship” and obj2.myName == “asteroid” ) or
( obj1.myName == “asteroid” and obj2.myName == “ship” ) )
then
end
end
end
function scene:create( event )
local _W, _H, _CX, _CY = relayout._W, relayout._H, relayout._CX, relayout._CY
sceneGroup = self.view
– 10 minutes * 60 seconds
clockText= display.newText( “1:30”, display.contentCenterX, display.contentCenterY, native.systemFont, 72 )
clockText:setFillColor( 1, 1, 1 )
clockText.alpha=0.2
local countDownTimer = timer.performWithDelay( 1000, updateTime, secondsLeft )
– Called when the scene’s view does not exist.
– i
– INSERT code here to initialize the scene
– e.g. add display objects to ‘sceneGroup’, add touch listeners, etc.
local group = self.view
– display a background image
local background = display.newImageRect( “assets/timerbg.png”, display.actualContentWidth, display.actualContentHeight )
background.anchorX = 0
background.anchorY = 0
background.x = 0 + display.screenOriginX
background.y = 0 + display.screenOriginY
ship = display.newImageRect( mainGroup, objectSheet, 4, 20, 90 )
ship.x = display.contentCenterX
ship.rotation=0
ship.y = display.contentHeight -40
ship.myName = “ship”
–== Show multiple transitions ==–
sceneGroup:insert(background)
sceneGroup:insert(ship)
sceneGroup:addEventListener( “tap”, fireLaser )
– timerGroup:addEventListener(“tap”,timeScene)
end
function goback()
if(secondsLeft==0)
then
composer.removeScene(‘Scenes.timer’)
composer.gotoScene(‘Scenes.menu2’)
end
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == “will” then
elseif phase == “did” then
– Called when the scene is now on screen
–
– INSERT code here to make the scene come alive
– e.g. start timers, begin animation, play audio, etc.
initFruitAndSplash()
timer.performWithDelay(1000,function ()startTest( createBlueRoundProjectile ,{rotate=true})
end
)
– start test 2, 15s delay
timer.performWithDelay( 5000, function()
startTest( createPurpleRectProjectile, { rotate=true } )
end )
– start test 3, 30s delay
timer.performWithDelay( 8000, function()
startTest( createYellowRectProjectile, { rotate=true } )
end )
timer.performWithDelay( 20000, function()
startTest( createBlueRoundProjectile, { rotate=true } )
end )
end
end
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if event.phase == “will” then
– Called when the scene is on screen and is about to move off screen
–
– INSERT code here to pause the scene
– e.g. stop timers, stop animation, unload sounds, etc.)
elseif phase == “did” then
– Called when the scene is now off screen
composer.removeScene(“Scenes.timer”)
end
end
function scene:destroy( event )
local sceneGroup = self.view
– Called prior to the removal of scene’s “view” (sceneGroup)
–
– INSERT code here to cleanup the scene
– e.g. remove display objects, remove touch listeners, save state, etc.
end
function chopFruit(fruit)
if(string.match(fruit.name,“bm”))then
createGush(fruit)
else
createGush(fruit)
createFruitPiece(fruit,“top”)
createFruitPiece(fruit,“bottom”)
end
fruit:removeSelf()
end
function getRandomValue(min, max)
return min + math.abs(((max - min) * math.random()))
end
function createGush(fruit)
local i
for i = 0, numOfGushParticles do
local gush = display.newCircle( fruit.x, fruit.y, math.random(minGushRadius, maxGushRadius) )
if(string.match(fruit.name,“w”)or string.match(fruit.name,“sy”))then
gush:setFillColor(255, 0, 0, 255)
else if(string.match(fruit.name,“pl”)or string.match(fruit.name,“mg”))then
gush:setFillColor(255,218,0,255)
end
end
gushProp.radius = gush.width / 2
timer.performWithDelay( 1, function()
physics.addBody(gush, “dynamic”, gushProp)
local xVelocity = math.random(minGushVelocityX, maxGushVelocityX)
local yVelocity = math.random(minGushVelocityY, maxGushVelocityY)
gush:setLinearVelocity(xVelocity, yVelocity)
transition.to(gush, {time = gushFadeTime, delay = gushFadeDelay, width = 0, height = 0, alpha = 0, onComplete = function(event) gush:removeSelf() end})
end
)
end
end
function createFruitPiece(fruit, section)
local fruitVelX, fruitVelY = fruit:getLinearVelocity()
– Calculate the position of the chopped piece
local half = display.newImage(fruit[section])
half.x = fruit.x - fruit.x – Need to have the fruit’s position relative to the origin in order to use the rotation matrix
local yOffSet = section == “top” and -half.height / 3 or half.height / 3
half.y = fruit.y + yOffSet - fruit.y
local newPoint = {}
newPoint.x = half.x * math.cos(fruit.rotation * (math.pi / 180)) - half.y * math.sin(fruit.rotation * (math.pi / 180))
newPoint.y = half.x * math.sin(fruit.rotation * (math.pi / 180)) + half.y * math.cos(fruit.rotation * (math.pi / 180))
half.x = newPoint.x + fruit.x – Put the fruit back in its original position after applying the rotation matrix
half.y = newPoint.y + fruit.y
fruitGroup:insert(half)
– Set the rotation
half.rotation = fruit.rotation
fruitProp.radius = half.width / 2 – We won’t use a custom shape since the chopped up fruit doesn’t interact with the player
timer.performWithDelay( 1, function()
physics.addBody( half, fruitProp1
)
half.myName=“fruitslice”
local velocity = math.sqrt(math.pow(fruitVelX, 2) + math.pow(fruitVelY, 2))
local xDirection = section == “top” and -1 or 1
local velocityX = math.cos((half.rotation + 90) * (math.pi / 180)) * velocity*xDirection
local velocityY = math.sin((half.rotation + 90) * (math.pi / 180)) * velocity
half:setLinearVelocity(velocityX*.9+110,velocityY*.9+110)-- velocityY)
local minAngularVelocity = getRandomValue(minAngularVelocityChopped, maxAngularVelocityChopped)
local direction = (math.random() < .4) and -1 or 1
half.angularVelocity = minAngularVelocity * direction
end
)
– Set the linear velocity
– Calculate its angular velocity
end
– let’s get this party started !
–
– Listener setup
scene:addEventListener( “create”, scene )
scene:addEventListener( “show”, scene )
scene:addEventListener( “hide”, scene )
scene:addEventListener( “destroy”, scene )
Runtime:addEventListener( “collision”, onCollision )
return scene