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................. 😃
Related
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 want to be able to pass the value from a stepper widget in corona into a json file. So far I've got my stepper to display and increment and decrement and display the current value on screen. I've written a function to save the value to a file as json, but i'm having trouble calling that function. I want to be able to have other setting on screen which have their values save to json. Here the code I have to save the setting:
local function saveSettings (e)
-- body
print("testtesttest")
if (file) then
local content = file:read("*a")
else
settings = {}
settings.houses = StepperNo
file = io.open(path, "w")
local json_setting = json.encode(settings)
file:write(json_setting)
io.close(file)
end
end
and then the code to display the stepper:
local StepperNo = 1
local displayNoOfHouses = display.newText("Number of houses: "..StepperNo,180,135, native.systemFontBold,16)
local function onStepperPress( e )
if ("increment" == e.phase) then
StepperNo = StepperNo + 1
elseif ("decrement") == e.phase then
StepperNo = StepperNo - 1
end
displayNoOfHouses.text = "Number of houses: "..StepperNo
end
local HouseStepper = widget.newStepper {left = 100, top = 100, minimumValue = 0, maximumValue = 9, onPress = onStepperPress}
I dont know how to call the savesetting function after the stepper is pressed. I think I might have done this incorrectly or may be missing something obvious, I am very new to Lua...
There is a very simple to implement table saver and loader presented in this tutorial:
http://coronalabs.com/blog/2014/10/14/tutorial-saving-and-loading-lua-tables-with-json/
It uses JSON to encode a Lua table to save and when needed, read the JSON back in and decode it to a Lua table.
I'm pretty new to corona and I can't seem to find a solution for my problem:
I have levels in my game and I am using storyboards, when the player clicks on the nextlevelbutton they get sent to the level2 scene, the scene starts with storyboard.removeALL() but that doesn't remove the previous scene and my background is messed up.
function nextlevel(event)
storyboard.gotoScene( "level2" )
end
function win ()
nextlevelbutton = display.newRoundedRect( display.contentCenterX, 285, 120, 30, 3 )
nextlevelbutton:setFillColor( 61/255,61/255,61/255 )
nextleveltxt = display.newText( { text = "Next Level", font = native.systemFontBold, fontsize = 20, x= display.contentCenterX, y = 285 } )
nextlevelbutton:addEventListener( "tap", nextlevel )
end
This is all inside the scene:enterScene function.
This is the start of the level2 scene:
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
storyboard.removeAll( )
I tried putting the nextlevel event inside the win function but nothing happened.
Thanks
This should help you:
http://www.coronalabs.com/blog/2013/04/02/cleaning-up-display-objects-andlisteners/
If your loading a menu and you want to remove EVERYTHING from all other classes then use:
storyboard.purgeAll()
that should stop all the listeners and remove all the objects.
Another thing you could do is add this code:
function scene:didExitScene( event )
storyboard.purgeScene( "sceneyouareleaving" )
end
scene:addEventListener( "didExitScene" )
All you need to do is call that function and your done :)
Hope this helps!
Also, as your 'messed up' background might suggest, please remember to add all the objects you create to view group:
function scene:createScene(event)
local group = self.view
local params = event.params
And then when you create objects, eg:
background = display.newImageRect("gfx/bg.png", 1425, 900)
background:setReferencePoint(display.TopLeftReferencePoint)
background.x = 0
background.y = 0
background:setFillColor(0, 255, 255)
Remember to add it to group:
group:insert(background)
I somehow managed to solve it. I think I did something wrong with the positions of the functions and groups. Anyway thanks for helping!
I created an example app with Corona and I tried to implement admob functions.
I ran the admob example and it worked. But when I combined it with this sample code below it stopped working.
At the emulator it runs normally. But when I upload the apk to my phone, I got a black screen.
Not an error, but a weird black screen.
Do you know what am I doing wrong?
-----------------------------------------------------------------------------------------
--
-- menu.lua
--
-----------------------------------------------------------------------------------------
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
-- include Corona s "widget" library
local widget = require "widget"
--------------------------------------------
-- forward declarations and other locals
local playBtn
local optsBtn
local helpBtn
-- ************* ADMOB *********************
-- Hide the status bar
display.setStatusBar( display.HiddenStatusBar )
-- The name of the ad provider.
local provider = "admob"
-- Your application ID
local appID = "a1522213c297e5a"
-- Load Corona 'ads' library
local ads = require "ads"
--------------------------------------------------------------------------------
-- Setup ad provider
--------------------------------------------------------------------------------
-- Create a text object to display ad status
local statusText = display.newText( "", 0, 0, native.systemFontBold, 22 )
statusText:setTextColor( 255 )
statusText:setReferencePoint( display.CenterReferencePoint )
statusText.x, statusText.y = display.contentWidth * 0.5, 160
local showAd
-- Set up ad listener.
local function adListener( event )
-- event table includes:
-- event.provider
-- event.isError (e.g. true/false )
local msg = event.response
-- just a quick debug message to check what response we got from the library
print("Message received from the ads library: ", msg)
if event.isError then
statusText:setTextColor( 255, 0, 0 )
statusText.text = "Error Loading Ad"
statusText.x = display.contentWidth * 0.5
showAd( "banner" )
else
statusText:setTextColor( 0, 255, 0 )
statusText.text = "Successfully Loaded Ad"
statusText.x = display.contentWidth * 0.5
end
end
-- Initialize the 'ads' library with the provider you wish to use.
if appID then
ads.init( provider, appID, adListener )
end
--------------------------------------------------------------------------------
-- UI
--------------------------------------------------------------------------------
-- initial variables
local sysModel = system.getInfo("model")
local sysEnv = system.getInfo("environment")
-- create a background for the app
--local backgroundImg = display.newImageRect( "background.jpg", display.contentWidth, display.contentHeight )
--backgroundImg:setReferencePoint( display.TopLeftReferencePoint )
--backgroundImg.x, backgroundImg.y = 0, 0
statusText:toFront()
-- Shows a specific type of ad
showAd = function( adType )
local adX, adY = display.screenOriginX, display.screenOriginY
statusText.text = ""
ads.show( adType, { x=adX, y=adY } )
end
-- if on simulator, let user know they must build for device
if sysEnv == "simulator" then
local font, size = native.systemFontBold, 22
local warningText = display.newRetinaText( "Please build for device or Xcode simulator to test this sample.", 0, 0, 290, 300, font, size )
warningText:setTextColor( 255 )
warningText:setReferencePoint( display.CenterReferencePoint )
warningText.x, warningText.y = display.contentWidth * 0.5, display.contentHeight * 0.5
else
-- start with banner ad
showAd( "interstitial" )
end
-- ************* FIM ADMOB *****************
-- 'onRelease' event listener for playBtn
local function onPlayBtnRelease()
-- go to level1.lua scene
storyboard.gotoScene( "level1", "fade", 500 )
return true -- indicates successful touch
end
-- Options
local function onOptionsBtnRelease()
-- go to level1.lua scene
storyboard.gotoScene( "options", "fade", 500 )
return true -- indicates successful touch
end
-- Options
local function onHelpBtnRelease()
-- go to level1.lua scene
storyboard.gotoScene( "help", "fade", 500 )
return true -- indicates successful touch
end
-----------------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
--
-- NOTE: Code outside of listener functions (below) will only be executed once,
-- unless storyboard.removeScene() is called.
--
-----------------------------------------------------------------------------------------
-- Called when the scene s view does not exist:
function scene:createScene( event )
local group = self.view
-- display a background image
local background = display.newImageRect( "background.jpg", display.contentWidth, display.contentHeight )
background:setReferencePoint( display.TopLeftReferencePoint )
background.x, background.y = 0, 0
-- create/position logo/title image on upper-half of the screen
local titleLogo = display.newImageRect( "title.png", 264, 42 )
titleLogo:setReferencePoint( display.CenterReferencePoint )
titleLogo.x = display.contentWidth * 0.5
titleLogo.y = display.contentHeight / 5
-- create a widget button (which will loads level1.lua on release)
playBtn = widget.newButton{
label="Play Now",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onPlayBtnRelease -- event listener function
}
playBtn:setReferencePoint( display.CenterReferencePoint )
playBtn.x = display.contentWidth*0.5
playBtn.y = display.contentHeight * 2 / 5
-- button for options (options.lua)
optsBtn = widget.newButton{
label="Options",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onOptionsBtnRelease -- event listener function
}
optsBtn:setReferencePoint( display.CenterReferencePoint )
optsBtn.x = display.contentWidth*0.5
optsBtn.y = display.contentHeight * 3 / 5
-- button for options (help.lua)
helpBtn = widget.newButton{
label="Help",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onHelpBtnRelease -- event listener function
}
helpBtn:setReferencePoint( display.CenterReferencePoint )
helpBtn.x = display.contentWidth*0.5
helpBtn.y = display.contentHeight * 4 / 5
-- all display objects must be inserted into group
group:insert( background )
group:insert( titleLogo )
group:insert( playBtn )
group:insert( optsBtn )
group:insert( helpBtn )
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
-- INSERT code here (e.g. start timers, load audio, start listeners, etc.)
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
-- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.)
end
-- If scene s view is removed, scene:destroyScene() will be called just prior to:
function scene:destroyScene( event )
local group = self.view
if playBtn then
playBtn:removeSelf() -- widgets must be manually removed
playBtn = nil
end
end
-----------------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
-----------------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene s view does not exist
scene:addEventListener( "createScene", scene )
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )
-- "exitScene" event is dispatched whenever before next scene s transition begins
scene:addEventListener( "exitScene", scene )
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )
-----------------------------------------------------------------------------------------
return scene
In your build.settings check whether you've added the followings:
android =
{
usesPermissions =
{
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.READ_PHONE_STATE",
},
}
Keep coding.................. :)
Well, just adding this, it worked:
-- ************* ADMOB *********************
-- Hide the status bar
display.setStatusBar( display.HiddenStatusBar )
-- The name of the ad provider.
local adNetwork = "admob"
-- Your application ID
local appID = "a1522213c297e5a"
-- Load Corona 'ads' library
local ads = require "ads"
-- Initialize the 'ads' library with the provider you wish to use.
if appID then
ads.init( adNetwork, appID )
end
-- initial variables
local sysModel = system.getInfo("model")
local sysEnv = system.getInfo("environment")
local bgW, bgH = 320, 480
if appID then
local adX, adY = display.contentCenterX, 0
local halfW = display.contentWidth * 0.5
local font, size = "Helvetica-Bold", 16
if sysEnv == "simulator" then
local warningText2 = display.newText( "Please build for device ", adX, adY, font, size )
local warningText3 = display.newText( "to test this sample code.", adX, adY, font, size )
warningText2:setTextColor( 255, 255, 255)
warningText3:setTextColor( 255, 255, 255)
warningText2:setReferencePoint( display.CenterReferencePoint )
warningText3:setReferencePoint( display.CenterReferencePoint )
warningText2.x, warningText2.y = halfW, 0
warningText3.x, warningText3.y = halfW, 16
else
ads.show( "banner", { x=adX, y=adY} )
end
else
-- If no appId is set, show a message on the screen
local warningText1 = display.newText( "No appID has been set.", 0, 105, font, size )
warningText1:setTextColor( 255, 255, 255)
warningText1:setReferencePoint( display.CenterReferencePoint )
warningText1.x = halfW
end
And, at the build.settings file:
add this:
plugins =
{
-- key is the name passed to Lua's 'require()'
["CoronaProvider.ads.admob"] =
{
-- required
publisherId = "com.coronalabs",
},
},
Now I just need to adjust some variables to correctly arange the ad at the screen.
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