I've done my app and it works great on the Corona Simulator, but, once I run it on my device, it doesn't run a bunch of instruction.
These are:
function onCollision( event )
if ( event.phase == "began" ) then
if event.object1.myName == "ground" and event.object2.myName == "spaceShip" then
local a = score.get()
print(a)
local b = score.load()
print(b)
if (a < b) then
best.alpha = 1
scoreToBeat.text = score.load()
scoreToBeat.alpha = 1
else
score.save()
newRecord.alpha = 1
end
timer.cancel(tmrScore)
gameOver.alpha = 1
tapToReplay.alpha = 1
replay.alpha = 0.01
fade.alpha = 0
timer.cancel(tmrIS)
spaceShip.alpha = 1
if(playEffects) then
media.playEventSound( "sounds/gameover.mp3" )
playEffects = false
end
speed = 0
end
end
end
Runtime:addEventListener( "collision", onCollision )
Particularly, it performs only "speed = 0" and only the first time I run the app, which means that if I start a new game, it won't even work "speed = 0".
I'm 100% sure that the app is running on the device is the same that runs on the simulator (I tried to change some text).
What can I do?
There could be multiple reasons: the physics not started when get back to scene; the objects aren't dynamic; one of them no longer exists or is no longer a physics object; the handler was removed when game ended and not restarted.
To figure out, add some print statements to see what parts execute:
function onCollision( event )
print 'entered collision'
if ( event.phase == "began" ) then
print 'collision began'
if event.object1.myName == โgdโ and event.object2.myName == โheroโ then
print 'collision objects are gd and hero'
speed = 0
if (score.get() < score.load()) then
print 'score smaller'
...
else
print 'score not smaller'
...
end
else
print( 'collision objects are', event.object1.myName, event.object2.myName )
end
end
end
Update:
I had a typo score = 0, should have been speed = 0.
Related
I am working on a program that will create a bunch of clones, and it will delete a clone when the clone is taped on. I only want it to delete the clone that is taped on. I am having an issue with the touch event listener. It says that I am trying to index a nil variable, but I defined it earlier in the program.
I have tried changing the variable to be a global variable.
display.setDefault("background", 0, 0, 200)
math.randomseed(os.time())
local boat = display.newImage( "boatt.png" )
boat.x = 163
boat.y = 225
local score = 0
local spawnCnt = 0
local spawnTable = {}
local startTime = os.time()
local startTime2 = os.time()
local fish_tapped
local function spawn ()
local obj = display.newImageRect("fishpic.png",70,70)
obj.x = math.random(1, 300)
obj.y = (0 - math.random(30, 400))
obj.isDone = false
-- Note: Second argument is function name without brakets
obj:addEventListener("touch", touched()) --i added brackets to this
return obj
end
local function onSpawn ()
spawnCnt = spawnCnt + 1
spawnTable[spawnCnt] = spawn()
end
local function movement (event)
-- SPAWN OBJECT USING TIMER
if os.time() - startTime >= 1 then
onSpawn()
startTime = os.time()
end
-- MOVE OBJECT
if spawnCnt > 0 then
for i = 1, spawnCnt do
if spawnTable[i].isDone == false then
if spawnTable[i].y > 600 or spawnTable[i].fish_tapped == true then
spawnTable[i].y = 700
spawnTable[i].isDone = true
display.remove(self)
self = nil
else
spawnTable[i].y = spawnTable[i].y + 4
end
end
end
end
end
Runtime:addEventListener ("enterFrame",movement)
--when i tried to have touched() in the event listener for touch it said that i was calling a
--nill value, so I made the funciton global.
function touched( event )
local obj = event.target
obj.fish_tapped = true
end
Try (not tested)
local function movement (event)
...
-- Replace
-- if spawnTable[i].y > 600 or fish_tapped == true then
-- with
if spawnTable[i].y > 600 or spawnTable[i].fish_tapped == true then
...
end
local function touched( event )
local obj = event.target
obj.fish_tapped = true
end
local function spawn ()
local obj = display.newImageRect("fishpic.png",70,70)
obj.x = math.random(1, 300)
obj.y = (0 - math.random(30, 400))
obj.isDone = false
-- Note: Second argument is function name without brakets
obj:addEventListener("touch", touched)
return obj
end
Read more:
Scope for Beginners
Tap/Touch Anatomy
I'm working on a business app using corona. The interfcae is sort of like the gmail mobile app interface. You've got a screen with a table, when a row is clicked, it opens a new page.
Description of interface: The app gets text and imagelinks from indexed elements in a json object. For each element(jsonObject[i]) in the json object, a row is created and the images are downloaded from the link passed contained in the "imagelink" field in each json element, while texts are gotten from other fields in the same json element. I'm using sockets to get the image and store them in a temporary location that way the images download before everything shows up. And when a row is clicked, it passes the current json element (jsonObject[i]) as well as the tempimage downloaded, and on this new page, the tempImage and some other fields that weren't used in the table are displayed.
Issue: When moving back and front from the scene with the table and the page displayed when a row is clicked, it takes sometime to load up. Understandable since it has to download images, to help with this I created a scene called "loading" to call in between the two other scenes, For now it just has a plane white box (Screen size) that I want it to display while the next scene takes it's time to load, that way it doesn't look like the app is frozen.
My problem: The "loading" scene doesn't work, I know the app loads it cause I removed the part in the code that goes to the next screen, and the loading scene shows up, but when it's added back, everything transitions the way it did before, the current screen appears to be frozen and then goes to the next screen like the "loading" scene isn't there. Could I please get some help with this? I tried using "loadScene" before "goto" but I got a lot of errors. Thank you!
My code:
ItemListPage.lua
local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )
-- Load the relevant LuaSocket modules
local http = require( "socket.http" )
local ltn12 = require( "ltn12" )
local scene = composer.newScene()
--To help with navigation, these two variables are set on all scenes except loading
--nextScene is the scene I want loaded after the "loading scene"
--prevScene is the current scene which will soon become the previous.
composer.setVariable( "nextScene", "itemDisplayPage")
composer.setVariable( "prevScene", composer.getSceneName("current"))
--NavigationBar elements initiated
--Removed for readability
--Load Json from local file
local filename = system.pathForFile( "items.json", system.ResourceDirectory )
local decoded, pos, msg = json.decodeFile( filename )
if not decoded then
print( "Decode failed at "..tostring(pos)..": "..tostring(msg) )
else
print( "File successfully decoded!" )
end
local items=decoded.items
--items being JsonObject explained in queston
--image handler
local function networkListener( event )
if ( event.isError ) then
print ( "Network error - download failed" )
end
print ( "event.response.fullPath: ", event.response.fullPath )
print ( "event.response.filename: ", event.response.filename )
print ( "event.response.baseDirectory: ", event.response.baseDirectory )
end
--Table stuff
local scrollBarOptions = {
sheet = scrollBarSheet, -- Reference to the image sheet
topFrame = 1, -- Number of the "top" frame
middleFrame = 2, -- Number of the "middle" frame
bottomFrame = 3 -- Number of the "bottom" frame
}
local function onRowRender( event )
-- Get reference to the row group
local row = event.row
local params=event.row.params
local itemRow=3;
-- Cache the row "contentWidth" and "contentHeight" because the row bounds can change as children objects are added
local rowHeight = row.contentHeight
local rowWidth = row.contentWidth
row.rowTitle = display.newText( row, params.topic, 0, 0, nil, 14 )
row.rowTitle:setFillColor( 0 )
row.rowTitle.anchorX = 0
row.rowTitle.x = 0
row.rowTitle.y = (rowHeight/2) * 0.5
--Other elements removed for readabilty (it's all just text objects)
--Download Image
--params referring to items[i]
local imagelink =params.imagelink
-- Create local file for saving data
local path = system.pathForFile( params.imagename, system.TemporaryDirectory )
myFile = io.open( path, "w+b" )
-- Request remote file and save data to local file
http.request{
url = imagelink,
sink = ltn12.sink.file( myFile )
}
row.Image = display.newImageRect(row, params.imagename, system.TemporaryDirectory, 25, 25)
row.Image.x = 20
row.Image.y = (rowHeight/2) * 1.5
row:insert( row.rowTitle )
row:insert( row.Image )
end
local function onRowTouch( event )
local row = event.target
local params=event.target.params
composer.removeScene(composer.getSceneName("current"))
composer.gotoScene( "loading" , {params=params})
end
-- Table
local tableView = widget.newTableView(
{
left = 0,
top = navBar.height,
height = display.contentHeight-navBar.height,
width = display.contentWidth,
onRowRender = onRowRender,
onRowTouch = onRowTouch,
listener = scrollListener
}
)
function scene:create( event )
local sceneGroup = self.view
-- create a white background to fill screen
local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 ) -- white
-- Insert rows
for i = 1, #sermons do
-- Insert a row into the tableView
tableView:insertRow{
rowHeight = 100,
rowColor = { default={ 0.8, 0.8, 0.8, 0.8 } },
lineColor = { 1, 0, 0 },
params=items[i]
}
end
-- all objects must be added to group (e.g. self.view)
sceneGroup:insert( background )
sceneGroup:insert( tableView )
end
-- other functions and elements unused and removed for readability
loading.lua
local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )
local scene = composer.newScene()
local nextParams
function scene:create( event )
local sceneGroup = self.view
nextParams= event.params
-- create a white background to fill screen
local background = display.newRect( display.contentCenterX,
display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 ) -- white
-- all objects must be added to group (e.g. self.view)
sceneGroup:insert( background )
end
local function showNext(event)
--go to next scene
composer.removeScene(composer.getSceneName("current"))
--Goes to next scene with parameters passed from previous scene
composer.gotoScene(composer.getVariable( "nextScene" ), {params=nextParams})
return true
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == "will" then
-- Called when the scene is still off screen and is about to move on screen
elseif phase == "did" then
showNext()
end
end
-- other functions and elements unused and removed for readability
ItemDisplayPage.lua
local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )
local scene = composer.newScene()
--To help with navigation, these two variables are set on all scenes except loading
--nextScene is the scene I want loaded after the "loading scene"
--prevScene is the current scene which will soon become the previous.
composer.setVariable( "nextScene", composer.getVariable( "prevScene" ))
composer.setVariable( "prevScene", composer.getSceneName("current"))
--NavigationBar elements initiated
--This creates the "back button", when clicked it returns to the previous scene, in this case "itemListPage"
--it takes, no parameters
local function handleLeftButton( event )
if ( event.phase == "ended" ) then
composer.removeScene(composer.getSceneName("current"))
composer.gotoScene( "loading" , {params=nil})
end
return true
end
--Remaning navbar elements removed for readability
function scene:create( event )
local sceneGroup = self.view
local params=event.params
-- create a white background to fill screen
local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 ) -- white
--creating header bar
local bar = display.newRect( navBar.height + (headerBarHeight*0.5), display.contentCenterY, display.contentWidth, headerBarHeight )
bar:setFillColor( 1 )
-- create stuff
local title = display.newText(params.topic, 0, 0, nil, 14 )
title:setFillColor( 0 )
title.anchorX = 0
title.x = margin
title.y = ((2*headerBarHeight/2) * 0.5)+navBar.height
local Image = display.newImageRect(params.imagename, system.TemporaryDirectory, 25, 25)
Image.x = 50
Image.y = display.contentCenterY
-- all objects must be added to group (e.g. self.view)
sceneGroup:insert( background )
sceneGroup:insert( title )
sceneGroup:insert( Image)
end
-- other functions and elements unused and removed for readability
If I understand correctly your scenes are shown in following order:
ItemListPage -> loading -> ItemDisplayPage
But loading scene doesn't have any heavy work to do - so it is redundant.
On ItemListPage.lua you load images in onRowRender callback. This callback is called when you call tableView:insertRow(...) in scene:create. So there is the root of freese
I suggest you to create loading overlay on ItemListPage scene create event. Part of code with table creation should run after you show loading overlay to user - in ItemListPage scene:show event
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == "will" then
elseif phase == "did" then
composer.showOverlay( "loading", { isModal = true })
-- Insert rows
for i = 1, #sermons do
--put your code here
end
composer.hideOverlay( "fade", 100 )
end
end
I went through some of help and with that I removed all variables, timer, event listener at exit of screen. but still I'm facing the same issue i.e. the first time when I play the game, its working fine and when I replay the game then its speed increases by itself and app crashes lastly.
There are some obstacles that I added in game, due to which its happening. So when I make them as comment, its work fine.
I'm adding those variables here:-
------------------------CREATE BIRDS----------------------------
currentXLocObstacleBird = currentXLocObstacleBird - SCREEN_WIDTH
while (currentXLocObstacleBird < SCREEN_WIDTH) do
obstacleType = math.random(4)
local birdHeight = math.random(display.topStatusBarContentHeight + 200, display.contentHeight - 200)
if (obstacleType % 2 == 0) then -- one in two chance of displaying a each of the snake
obstacleType = mathDiv(obstacleType, 2)
if (obstacleType == 1) then
obstacles_Variables.imgBirdY = display.newSprite( otherSpriteSheet , birdSequenceData2)
obstacles_Variables.imgBirdY:play()
if (a == 1) then -- if it is for first screen then start from zero otherwise start from loc+screnwidth ie. second screen
obstacles_Variables.imgBirdY.x = currentXLocObstacleBird
birdYPolygon = display.newPolygon(currentXLocObstacleBird, birdHeight, {0,20, 50,0, 115,50, 50,40 })
else
obstacles_Variables.imgBirdY.x = currentXLocObstacleBird + SCREEN_WIDTH
birdYPolygon = display.newPolygon(currentXLocObstacleBird + SCREEN_WIDTH, birdHeight, {0,20, 50,0, 115,50, 50,40 }) -- birdShape)
physics.addBody(birdYPolygon, "static",{density = 0, bounce = 0, friction = 0 })
end
obstacles_Variables.imgBirdY.y = birdHeight
obstacles_Variables.imgBirdY.name = "yelloBird1"
obstacles_Variables.imgBirdY.screenIndex = a -- indicates which screen this object belongs to (from SCREENS_PER_LEVEL)
obstacles_Variables.imgBirdY.isVisible = false
obstacles_Variables.imgBirdY.speed = Speed_Constant_Array.SPEED_BIRD_1
obstacles_Variables.imgBirdY:rotate(15)
groupObstacles:insert(obstacles_Variables.imgBirdY)
-- birdYPolygon.name = "yelloBird"
-- birdYPolygon.screenIndex = a
-- birdYPolygon.isVisible = false
-- birdYPolygon.speed = Speed_Constant_Array.SPEED_BIRD_1
-- groupObstacles:insert(birdYPolygon)
currentXLocObstacleBird = currentXLocObstacleBird + 2 * WIDTH_YELLOW_BIRD
elseif(obstacleType == 2) then
obstacles_Variables.imgBirdG = display.newSprite( otherSpriteSheet , birdSequenceData)
obstacles_Variables.imgBirdG:play()
if (a == 1) then -- if it is for first screen then start from zero otherwise start from loc+screnwidth ie. second screen
obstacles_Variables.imgBirdG.x = currentXLocObstacleBird
birdGPolygon = display.newPolygon(currentXLocObstacleBird, birdHeight, {0,20, 50,0, 115,50, 50,40 }) --birdShape2)
else
obstacles_Variables.imgBirdG.x = currentXLocObstacleBird + SCREEN_WIDTH
birdGPolygon = display.newPolygon(currentXLocObstacleBird + SCREEN_WIDTH, birdHeight, {0,20, 50,0, 115,50, 50,40 }) --birdShape2)
physics.addBody(birdGPolygon, "static",{density = 0, bounce = 0, friction = 0 })
end
obstacles_Variables.imgBirdG.y = birdHeight
obstacles_Variables.imgBirdG.name = "greenBird1"
obstacles_Variables.imgBirdG.screenIndex = a -- indicates which screen this object belongs to (from SCREENS_PER_LEVEL)
obstacles_Variables.imgBirdG:rotate(15)
obstacles_Variables.imgBirdG.speed = Speed_Constant_Array.SPEED_BIRD_2
obstacles_Variables.imgBirdG.isVisible = false
groupObstacles:insert(obstacles_Variables.imgBirdG)
-- birdGPolygon.name = "greenBird"
-- birdGPolygon.screenIndex = a -- indicates which screen this object belongs to (from SCREENS_PER_LEVEL)
-- birdGPolygon.isVisible = false
-- birdGPolygon.speed = Speed_Constant_Array.SPEED_BIRD_2
-- birdGPolygon:setFillColor(1,0,0,0)
-- groupObstacles:insert(birdGPolygon)
currentXLocObstacleBird = currentXLocObstacleBird + 2 * WIDTH_GREEN_BIRD
end
end
currentXLocObstacleBird = currentXLocObstacleBird + math.random(500, 700) -- add some spacing for the next decor
end
finally i resolved that issue. the issue was not in this code as i shown above, this was resolved only temporarly. but again same issue started. the solution of this issue was trying to remove and cancel all addEventListener and timer.performWithdelay, this is only the solution of these type of issue. in starting we may not identify but when we try our code to run without this functionality then we can easily identify that this was only issue and by removing all event listener and cancel timer one by one will resolve our issue also
I'm new in Android games using corona and I use a timer to make a local display of coin with a 50x repetition.
What I'm trying to do is if the character collide in on of coin the coin will disappaer, the problem is how can I hide that certain coin?
here's my code how I creating the coin.
function coins()
coin1 = display.newImage( "coin1.png")
coin1.x = math.random(0, 600)
coin1.y = math.random(0, 400)
coin1.myName = "wewe"
physics.addBody(coin1, {friction = 1, density = 1})
end
timer.performWithDelay(
1000, coins, 100 )
have something like this
local function removeCoin(self,event)
if(event.phase == "began") then
self:removeSelf()
end
end
And in coins() add the following
coin1.collision = removeCoin
coin1:addEventListener("collision",coin1)
This should make it that upon a coin experiencing a collision removeCoin is invoked, which removes it's caller, in this case a coin.
You can stop both objected being removed by doing something like this:
if(event.phase == "began" and self.myName == 'coin') then
self:removeSelf()
end
I'm new to Coronoa and Lua, and I'm trying to figure out how to close a map and textbox. The map and text box appear over the home screen, and I was able to create a button (just a genreic black x) and make it close but I can not get the map or text box to close. Below is the code snippet I am using, but I am stuck. I have searched Google, and read through their documentation, and I am just missing something.
local obj = display.newImageRect( "closeButton.jpg" ,25,25 )
obj.x = 60
obj.y = 410 -- replaced with newImageRect for dynamic scaling (adjust X & Y as required)
obj.touch = function (event)
local btn = event.target
if event.phase == "ended" then
btn.alpha = 0 -- example to show the function doing something
myMap.alpha = 0
textBox.alpha = 0
end
end
-- begin detecting touches
obj:addEventListener( "touch", obj.touch)
myMap = native.newMapView( 25, 0, 275, 180 )
myMap.mapType = "hybrid" -- other mapType options are "satellite" or "hybrid"
myMap.isScrollEnabled = true
myMap.isZoomEnabled = true
myMap.isLocationUpdating = true
isVisible = myMap.isLocationVisible
myMap:setCenter( 38.354614, -81.726351 )
myMap:addMarker( 38.354614, -81.726351)
-- Adding the Text Box that contains the Directions
textBox = native.newTextBox( 22, 183, 280, 225 )
textBox.text = "blah blah blah boring directions."
local group = display.newGroup()
group:insert( obj )
I keep getting "attempt to index local 'myMap' (a nil value)", and the same error for textBox. So if anyone can help, its appreciated.
Locally declare your 'MapView' and 'textBox' above the 'obj.touch' function, as below:
local myMap;
local textBox;
Note: Corona mapView does not supported in the simulator.
Keep coding................. ๐