when i use the underneath code in my main.lua file it displays the ad as i want it to be.
but when i add "ads.hide()" (the ad stay on every scene) in the "exitScene" scene section i get this error in the terminal " attempt to index global 'ads' (a nil value)" which i understand as the ads don't display in the simulator but when i open the app op my phone (galaxy s4) non of the buttons respond, and it just stay on the main.lua file/scene
local provider = "admob"
local appID = "**********"
local ads = require "ads"
local screenGroup = self.view
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
local function adListener( event )
local msg = event.response
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
local screenGroup = self.view
showAd( "banner" )
else
end
end
if appID then
ads.init( provider, appID, adListener )
end
local sysModel = system.getInfo("model")
local sysEnv = system.getInfo("environment")
showAd = function( adType )
local screenGroup = self.view
local adX, adY = display.screenOriginX, 400
statusText.text = ""
ads.show( adType, { x=adX, y=adY } )
end
if sysEnv == "simulator" then
else
local screenGroup = self.view
showAd( "banner" )
end
Hi how can i close or destroy a "admob" ad on screen change ?
You need to require ads in every scene you create
Add this line to every Lua file that are using the ads plugin
local ads = require("ads")
ads.hide( )
ads:removeSelf()
ads=nil
you can insert above into any event listener or something else.
You need to call this function in every screen.
if ads then
ads.hide()
end
Note: When you are generating dynamic ads then there are time duration between the ads.
So if the ads is on the screen it will hide otherwise not.
But when you not check the if condition and move to next scene the ads will load again.
Related
I had a problem creating a loading scene in between scenes, the solution I got was to use an overlay, I've been trying this for days but for some reason I can't get it to work. I have two scenes, one that shows a list of items, and another that shows a page of text based on which row was clicked. The problem now is the first scene, that shows the list, downloads images to display and of course this takes a while so whenever i transition into that screen, the app appears to be frozen while everything loads up.
I've found out that it does actually go into the overlay scene, since the print statements i put in it print out, but it just doesn't display anything and when i removed the code that hides the overlay after, it still appears to hang, it goes into the overlay scene, doesn't display anything and then renders the table before finally displaying the overlay so instead of showing an overlay, having everything load up beneath, and then hiding the overlay, it appears to be frozen in the current scene, loads up everything beneath, shows overlay and then hides overlay right after.
My code for the three scenes are below, the one I'm posting now is the only one that actually worked once and then never again, it showed the overlay while everything loaded like I wanted but for some reason, it never worked again after that one time. I'm getting really frustrated with it and no forum has given me a solution, I'd really really appreciate some help. Thanks!
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()
--NavigationBar elements initiated
--Removed for readability
--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
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( "itempage" , {params=params})
end
function scene:create( event )
local sceneGroup = self.view
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
--overlay
composer.showOverlay( "loading", { isModal = true })
elseif phase == "did" then
--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
}
-- Table
local tableView = widget.newTableView(
{
left = 0,
top = navBar.height,
height = display.contentHeight-navBar.height,
width = display.contentWidth,
onRowRender = onRowRender,
onRowTouch = onRowTouch,
listener = scrollListener
}
)
--json work
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
-- create a white background to fill screen
local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 ) -- white
sceneGroup:insert( background )
-- Insert rows
for i = 1, #items do
-- Insert a row into the tableView
print( "Adding a row!" )
tableView:insertRow{
rowHeight = 100,
rowColor = { default={ 0.8, 0.8, 0.8, 0.8 } },
lineColor = { 1, 0, 0 },
params=items[i]
}
end
sceneGroup:insert( tableView )
composer.hideOverlay( "fade", 100 )
end
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()
-- Create the widget
function scene:create( event )
local sceneGroup = self.view
local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 ) -- white
local text = display.newText( "Loading scene", 0, 0, nil, 14 )
text:setFillColor( 0 )
text.anchorX = display.contentCenterX
text.x = display.contentCenterX
text.y = display.contentCenterY
sceneGroup:insert( background )
sceneGroup:insert( text )
print ( "In loading create")
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == "will" then
elseif phase == "did" then
print ( "In loading show")
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()
--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(composer.getSceneName("previous"))
end
return true
end
--Remaining 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
I suggest you do not use scene.show event for loading.
Use timer.performWithDelay to load all data:
--in scene:show
elseif phase == "did" then
timer.performWithDelay(0, function()
local scrollBarOptions = {
--put your code here
composer.hideOverlay( "fade", 100 )
end)
Your current code didn't show overlay because engine waits for scene:show event before rendering anything. So rendering of overlay and images occured after all images are loaded.
In my code timer.performWithDelay doesn't block scene:show execution, so you will see overlay rendered before loading images
i have a question with corona (LUA), at the moment im showing interstitial ad when tap button occurs. I have this and its working (sometimes takes like 5-10-15 seconds to load and ad, i dont know why:
local ads = require("ads")
local interstitialAppID = "ca-app-pub-xxxxxxxxxx/xxxxxxxx21"
local testMode = true
local adProvider = "admob"
local function adListener( event )
if ( event.isError ) then
print ( "Error en el anuncio!", msg )
elseif ( event.phase == "loaded") then
print ( "Anuncio cargado!", msg )
elseif ( event.phase == "shown") then
print ( "Cargando nuevo anuncio!", msg )
ads.load ("interstitial", { appId = interstitialAppID, testMode = isTestMode } )
end
end
ads.init("admob", interstitialAppID, adListener )
ads.load ("interstitial", { appId = interstitialAppID, testMode = isTestMode } )
-- INTERSTITIAL AD
local function Adinterstatial( self, event )
ads.show( "interstitial", { appId = interstitialAppID, testMode = isTestMode
} )
end
local test = display.newImageRect( "Lore/0.png", 50, 50 )
test.x = 150
test.y = 150
test.tap = Adinterstatial
test:addEventListener( "tap" )
I want to do this for example: every 20 taps (on all the app) shows an interistitial ad.
Is this possible?
How i can do it?
Thanks.
You can add a Runtime tap event. This will get all taps on the screen, it does not matter where or what object was tapped. For example:
local numTaps = 0
local function countTaps()
numTaps = numTaps + 1
if numTaps % 20 == 0 then
-- Show the add here.
end
end
Runtime:addEventListener("tap", countTaps)
The % gets the remaindeer of the division between numTaps and 20. This means that it will be 0 every 20 taps.
As stated in the title I would like to not only call an object from an external Lua file, but I would also like to group:insert() this object into my Menu page with the properties given to it in the external lua file. Is this possible and/or efficient? I would just really like to make sure data isn't repeated through out my project.
EDIT
Here's my code so far:
The group:insert() function is throwing me an error stating it was expecting a table and that I might have been trying to call a function in which case i should use ":" instead of "."
This is menu.lua:
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
local widget = require "widget"
local m = require ("myData")
local menuFunction = require("menuFunction")
local menuSwipe
-- =======================
-- menuSwipe()
-- =======================
menuSwipe = function(self, event)
local phase = event.phase
local touchID = event.id
if(phase == "began") then
elseif(phase == "moved") then
elseif(phase == "ended" or phase == "cancelled") then
if(m.menuActivator > 0) then
menuDown(m.invisiBar, event)
else
--m.layerInfo = layers
transition.to( menuFunction.menuBar, { x = menuFunction.menuBar.x, y = 0, time = 200 } )
--transition.to( layers, { x = menuFunction.menuBar.x, y = h, time = 100 } )
m.invisiBar = display.newRect( 0,0,w,25,6)
m.invisiBar.alpha = 0
m.menuActivator = 1
end
end
end
-- ++++++++++++++++++++++
-- menuDown()
-- ++++++++++++++++++++++
function menuDown(self, event)
local phase = event.phase
local touchID = event.id
if(phase == "began") then
elseif(phase == "moved") then
elseif(phase == "ended" or phase == "cancelled") then
if(m.menuActivator == 1) then
transition.to( menuFunction.menuBar, { x = m.menuInfo.x, y = h*.964, time = 200 } )
--transition.to( group, { x = 0, y = 0, time = 10 } )
m.menuActivator = 0
end
end
end
function scene:createScene( event )
local group = self.view
group:insert( menuFunction.menuBar ) -- *** ERROR occurs here
end
function scene:enterScene( event )
local group = self.view
end
function scene:exitScene( event )
local group = self.view
end
function scene:destroyScene( event )
local group = self.view
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
This is menuFunction.lua:
local m = require("myData")
local menu = require ("menu")
local w = display.contentWidth
local h = display.contentHeight
local menuFunction = {}
--menuBar
menuFunction.menuBar = display.newImage( "images/menuBar1.png")
menuFunction.menuBar.x = w*(1/2)
menuFunction.menuBar.y = h*1.465
menuFunction.menuBar.height = h
menuFunction.menuBar:setReferencePoint(display.TopLeftReferencePoint)
menuFunction.menuBar.touch = menu.menuSwipe
menuFunction.menuBar:addEventListener("touch", menuFunction.menuBar)
return menuFunction
This is the exact error message:
ERROR: table expected. If this is a function call, you might have used '.' instead of ':'
message**
Does this happen every time this code is called, or does it by any chance work the first time and then crashes? In your case, code could work the first time you enter the scene, but the second time you do, it may crash [if you remove scenes in between].
When you do a 'require' of a file, its contents are executed and returned value is saved in the global packages table. When you require the same file again, the returned value is taken from the global packages table instead, the code is not executed again.
So if you by any chance require this file in one spot of your app, and then call :removeSelf() and nil the reference of the menuBar, the display object will be removed and its reference will cease to exist, and calling the require again, will not recreate the object. Fully removing a scene will also remove the display objects.
So what you wanted to achieve is very sensible [contrary to what #Schollii says], but your "module" should allow creation of multiple objects if you want to get rid of them during runtime.
I'm not going to correct your code, just a simple example of how you can achieve this:
-- menu.lua
local menuCreator = {}
menuCreator.newMenu = function(params)
local menu = display.newGroup()
-- create your menu here
return menu
end
return menuCreator
Now anytime you do:
local menuCreator = require("menu.lua")
you will be able to call:
local menu = menuCreator.newMenu(someParams)
and get yourself a nice new menu wherever you need.
If it's not shown all the time on screen, it may be better to create a new one whenever you need it, and then remove it from the memory.
There are several issues with this, and none of them seem related to your error but fixing them will either also fix the error or make the cause of the error more obvious. Please fix following and update:
Although Lua allows it, don't use circular includes, where A includes B which includes A. Instead have menu require menuFunction and then call a creation function in menuFuntion:
-- menuFunction.lua
local m = require("myData")
-- require("menu") -- BAD! :)
local w = display.contentWidth
local h = display.contentHeight
local menuBar = display.newImage( "images/menuBar1.png")
menuBar.x = w*(1/2)
menuBar.y = h*1.465
menuBar.height = h
menuBar:setReferencePoint(display.TopLeftReferencePoint)
local menuFunction = { menuBar = menuBar }
function createMenuBar(menuSwipe)
menuFunction.menuBar.touch = menuSwipe
menuFunction.menuBar:addEventListener("touch", menuFunction.menuBar)
return menuFunction
end
-- menu.lua
function createScene(event)
local mf = require('menuFunction')
mfFunction = mf.createMenuBar(menuSwipe)
group:insert(menuFunction.menuBar)
end
Secondly out of the four calls to group:insert() the first 3 refer to objects that are not shown in the code and don't see relevant to problem, they should be removed or if you think relevant, comment why their code now shown, or show their code.
I posted this in the corona forums but no response. There must be something obvious I'm missing, hope someone can help!
I'm starting out integrating admobs and can't seem to get an adlistener event.
I've got this code:
main.lua:
appID = "ca-app-pub-8278249997676996/7462506469"
ads = require("ads")
-- Create a text object to display ad status
statusText = display.newText( "ad status text", 0, 0, native.systemFontBold, 22 )
statusText:setTextColor( 255 )
statusText:setReferencePoint( display.CenterReferencePoint )
statusText.x, statusText.y = display.contentWidth * 0.5, 160
-- Set up ad listener.
function adListener( event )
statusText.text = "got an ad listener 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 " .. msg
statusText.x = display.contentWidth * 0.5
--showAd( "banner" )
else
statusText:setTextColor( 0, 255, 0 )
statusText.text = "Successfully Loaded Ad : " .. msg
statusText.x = display.contentWidth * 0.5
end
end
-- Initialize the 'ads' library with the provider you wish to use.
if appID then
print("initialising admob")
ads.init( "admob", appID, adListener )
end
and
anotherfile.lua
statusText.text = "Let's show an ad please"
ads.show( "banner", {x=0, y=0} )
The statusText.text changes to "let's show an ad pleas"e, and ads.show( is the next line of code. But there is no further change to statusText.text, which means the adListener is not being called. There's also no ad being shown.
In my build settings I have:
androidPermissions =
{
"android.permission.READ_PHONE_STATE",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.VIBRATE",
"android.permission.INTERNET"
},
plugins =
{
-- key is the name passed to Lua's 'require()'
["CoronaProvider.ads.admob"] =
{
-- required
publisherId = "com.sportspunter",
},
},
Any suggestions welcome please!
thanks
You changed the publisher ID in the plugin settings in your build.settings file. Try this:
publisherId = "com.coronalabs",
It looks like you have coded everything correctly, but I'm not 100% I know the correct answer. The only thing I can think of is you need to redeclare the code in main.lua in anotherfile.lua. Probably the variables aren't correctly declared so they aren't getting transferred.
Also I'm pretty sure ad's don't display on the simulator, so make sure you build for the device.
Your build.settings looks fine.
Hope this helps.
I'm using director , to move from one scene to another. I have a problem that the buttons and text fields from intor still in the top of screen when moving to any scene.
How to remove items (text fields, btns from intro.lua screen) before move to next scene?
enter code here
-- into.lua
module(..., package.seeall)
function new()
--
-- Project: NativeKeyboard2
--
local widget = require( "widget" )
require("hijacks")
local tHeight -- forward reference
-------------------------------------------
-- General event handler for fields
-------------------------------------------
-- You could also assign different handlers for each textfield
local function fieldHandler( textField )
return function( event )
if ( "began" == event.phase ) then
-- This is the "keyboard has appeared" event
-- In some cases you may want to adjust the interface when the keyboard appears.
elseif ( "ended" == event.phase ) then
-- This event is called when the user stops editing a field: for example, when they touch a different field
elseif ( "editing" == event.phase ) then
elseif ( "submitted" == event.phase ) then
-- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard
print( textField().text )
-- Hide keyboard
native.setKeyboardFocus( nil )
end
end
end
-- Predefine local objects for use later
local nameField, phoneField
local fields = display.newGroup()
-------------------------------------------
-- *** Create native input textfields ***
-------------------------------------------
-- Note: currently this feature works in device builds or Xcode simulator builds only (also works on Corona Mac Simulator)
local isAndroid = "Android" == system.getInfo("platformName")
local inputFontSize = 18
local inputFontHeight = 30
tHeight = 30
if isAndroid then
-- Android text fields have more chrome. It's either make them bigger, or make the font smaller.
-- We'll do both
inputFontSize = 14
inputFontHeight = 42
tHeight = 40
end
nameField = native.newTextField( 40, 120, 200, tHeight )
nameField.font = native.newFont( native.systemFontBold, inputFontSize )
nameField:addEventListener( "userInput", fieldHandler( function() return nameField end ) )
phoneField = native.newTextField( 40, 160, 200, tHeight )
phoneField.font = native.newFont( native.systemFontBold, inputFontSize )
phoneField.inputType = "phone"
phoneField:addEventListener( "userInput", fieldHandler( function() return phoneField end ) )
-- Add fields to our new group
fields:insert(nameField)
fields:insert(phoneField)
-------------------------------------------
-- *** Add field labels ***
-------------------------------------------
local defaultLabel = display.newText( "الاسم", 250, 120, native.systemFont, 18 )
defaultLabel:setTextColor( 255, 0, 0 )
local defaultLabel = display.newText( "رقم الجوال", 250, 160, native.systemFont, 18 )
defaultLabel:setTextColor( 255, 0, 0 )
-- -------------------------------------------
-- -- Create a Background touch event
-- -------------------------------------------
local listener = function( event )
-- Hide keyboard
print("tap pressed")
native.setKeyboardFocus( nil )
return true
end
-- Determine if running on Corona Simulator
--
local isSimulator = "simulator" == system.getInfo("environment")
if system.getInfo( "platformName" ) == "Mac OS X" then isSimulator = false; end
-- Native Text Fields not supported on Simulator
--
if isSimulator then
msg = display.newText( "الرجاء ادخال اسمك ورقم جوالك", 0, 280, native.systemFontBold, 12 )
msg.x = display.contentWidth/2 -- center title
msg:setTextColor( 255,0,0 )
end
-- -- Add listener to background for user "tap"
-- bkgd:addEventListener( "tap", listener )
-- display.remove( obj )
-- obj = nil
local introGroup = display.newGroup();
local background = display.newImage("graphics/intro_background.png")
local begin = display.newImage("graphics/begin_button.png")
begin.x = 160;
begin.y = 400;
begin.scene = "menu";
introGroup:insert(background);
introGroup:insert(begin);
begin:addEventListener("touch", changeScene)
return introGroup;
end
Corona provides a very good feature that is "Storyboard".I am giving you a brief explanation, Try this -
Storyboard - It is a scene (e.g. "screens" or "views") management library that provides developers an easy way to create and transition between scene modules in a Corona SDK app.
Syntax -
local storyboard = require "storyboard"
Example -
local scene1 = storyboard.newScene( "name of the Scene" )
Here are the different events used in the Storyboard -
1- Create Scene -
-- Called when the scene's view does not exist:
function scene:createScene( event )
local group = self.view
end
2- Enter Scene -
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
end
3- Exit Scene -
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
end
4 - Destroy Scene -
-- Called prior to the removal of scene's "view" (display group)
function scene:destroyScene( event )
local group = self.view
end
It will help you.