Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Adding ads to my first game
Started by citizengoosevv Sep 02 2019 11:44 AM

7 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

citizengoosevv

[GLOBAL: userInfoPane.html]
citizengoosevv
  • Observer

  • 5 posts
  • Corona SDK

Hello everybody!

 

So, i finished my first game and run into the issue of implementing ads... such a complex matter.

For some reason you have to pay to use admob, so ill skip that since im not willing to invest $200 on my first game.

I found the most popular free alternative was Inmobi.

I created my Inmobi account, created an app, selected the ads, chose none for my mediation platform and none for dev platform.

So, i read up on the corona documentation. I copied this to my build.settings(yes, I copied this under the plug in section)


  ["plugin.inMobi"] =
        {
            publisherId = "com.coronalabs"
        },

and I have this on my main.lua file:

 

local inMobi = require( "plugin.inMobi" )


-- Pre-declare a placement ID
local placementID = "HereAreNumbers" -- This was changed for this post


local function adListener( event )


    if ( event.phase == "init" ) then  -- Successful initialization
        -- Load a banner ad
        inMobi.load( "interstitial", placementID )


    elseif ( event.phase == "failed" ) then  -- The ad failed to load
        print( event.type )
        print( event.placementId )
        print( event.isError )
        print( event.response )
    end
end


-- Initialize the InMobi plugin
inMobi.init( adListener, { accountId="numbersAndLetters" } ) -- changed for this post


-- Sometime later, check if the ad is loaded
if ( inMobi.isLoaded( placementID ) ) then
    -- Show the ad
  inMobi.show( placementID, { yAlign="bottom" } )
end

 

And.. nothing really works.

In the simulator, it says that I have to test it on an actual device, but it doesn't work on my phone.

So... what am I doing wrong?

 



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

adListener is an asynchronous function. That means that it doesn't necessarily execute by the time the program moves on to the next line of code.

 

In your case, you are trying to see if an ad can be shown only a few lines after you've initialised the plugin. This happens in an instant and the plugin has not had the time to initialise itself. In your adListener's "init" phase, you load the first ad, however, this occurs much later than your "inMobi.isLoaded( placementID )" check.

 

So, simply put, you just need to do is to wait for the plugin to be initialised first. One easy way of testing this on a device would be to create a white rectangle on the screen. Once the "init" phase is done, you can set the rectangle's fill color to something else. Then, add a touch listener to the rect and check if an ad is available by pressing that.



[TOPIC: post.html]
#3

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,062 posts
  • Enterprise

You really should read this tutorial:

 

http://docs.coronalabs.com/tutorial/basics/ads/index.html

 

While its code is for AdMob, the discussion is general to all ad networks and for the most part the code is general enough, concept wise for any ad plugin.

 

This should be required reading for anyone who wants to add ads to their apps.  There is a companion blog post that covers monetization in general. You should read and understand this too:

 

https://coronalabs.com/blog/2018/10/02/monetization-best-practices-and-a-new-ad-tutorial/

 

Rob



[TOPIC: post.html]
#4

citizengoosevv

[GLOBAL: userInfoPane.html]
citizengoosevv
  • Observer

  • 5 posts
  • Corona SDK

 

 

So, simply put, you just need to do is to wait for the plugin to be initialised first. One easy way of testing this on a device would be to create a white rectangle on the screen. Once the "init" phase is done, you can set the rectangle's fill color to something else. Then, add a touch listener to the rect and check if an ad is available by pressing that.

 

Thanks for the help, didn't know that about the adListener.

 

I did what you said, but still doesn't work. Its as if the ad never gets initialized.  inMobi.isLoaded(placementID) is always false, even when I click on something to check if its true.



[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

When you have problems such as this, the first step should always be to consult the documentation (which Rob has linked). If that doesn't work, then you should post code of what you've done, like you originally did. Now I can only guess and say that "you did it wrong". Have you setup the plugin properly in your build settings? How do you check if the ad is loaded and when, does your device has Internet connection, etc.?



[TOPIC: post.html]
#6

citizengoosevv

[GLOBAL: userInfoPane.html]
citizengoosevv
  • Observer

  • 5 posts
  • Corona SDK

When you have problems such as this, the first step should always be to consult the documentation (which Rob has linked). If that doesn't work, then you should post code of what you've done, like you originally did. Now I can only guess and say that "you did it wrong". Have you setup the plugin properly in your build settings? How do you check if the ad is loaded and when, does your device has Internet connection, etc.?

all right, heres what ive got on my main.lua:

 

local inMobi = require( "plugin.inMobi" )
-- Pre-declare a placement ID
local placementID = "1569390117164"


local function adListener( event )


    if ( event.phase == "init" ) then  -- Successful initialization
        -- Load a banner ad
        inMobi.load( "banner", placementID )


    elseif ( event.phase == "failed" ) then  -- The ad failed to load
        print( event.type )
        print( event.placementId )
        print( event.isError )
        print( event.response )
    end
end


-- Initialize the InMobi plugin
inMobi.init( adListener, { accountId="f834a961c20f49a08d042b66a42e3939 " } )
-- Modules
physics = require("physics")
physics.start()
local obstacleRate = 10
display.setDefault("background", 0, 0, 0)
--trail color
local trailColor = {173, 255, 254}
--tap and hold var
local tap = false
local holdTap = false
local speed = 20
--Show text
local speedText = display.newText(speed, 132, 0)

-- Define Player
local slowdown = 0.99
local sheetData = {width=40, height=40, numFrames=3, sheetContentWidth=120, sheetContentHeight=40}
local playerSheet = graphics.newImageSheet("player.png", sheetData)
local playerSequenceData = {
    {name = "idle", frames={1}, time = 250},
    {name = "left", frames={2}, time = 250},
    {name = "right", frames={3}, time = 250}
}
local player = display.newSprite(playerSheet, playerSequenceData)
player.timeScale = 0.5
player:setSequence("idle")
player:play()
player.x = 0
player.y = 200
player.dir = "right"
physics.addBody(player, "dynamic", {density = 5, bounce=0.3, friction = 2})

--Move Player
function movePlayer(self, event)
  
    if self.dir == "right" then
        self:applyForce(60, 0, self.x, self.y)
        if ( inMobi.isLoaded( placementID ) ) then------------------------Here I test the add(this function is called when clicked)
         -- inMobi.show( placementID, { yAlign="bottom" } )
         speed = 30
        end
    else
        self:applyForce(-60, 0, self.x, self.y)
    end
    
    
end
-- Touch Controls
function onTouch(event)
    if event.phase == "began" then
        if tap == false then
            local vx, vy= player:getLinearVelocity()
            player:setLinearVelocity(vx * 0.4, vy)
            tap = true
        end
        if player.dir == "right" then
            player:setSequence("right")
        else
            player:setSequence("left")
        end 
        player.enterFrame = movePlayer
        Runtime:addEventListener("enterFrame", player)
        print("began")
        trailColor = {173, 255, 254}
        holdTap = true
    elseif event.phase == "ended" then
        Runtime:removeEventListener("enterFrame", player)
        if player.dir == "right" then
            player.dir = "left"
        else
            player.dir = "right"
        end 
        print("ended")
        player:setSequence("idle")
        trailColor = {173, 255, 254}
        tap = false
        holdTap = false
    end
end

-- Player Trail
function particleEffect()
    local chance = math.random(1, 1)
    if chance == 1 then
        local pX = math.random(player.x - 5, player.x + 5)
        local yOffset = 20
        if holdTap then
            yOffset = 20
        else 
            yOffset = 20
        end
        local pY = player.y - yOffset
        local particle = display.newCircle(pX, pY, 3)
        particle.x, particle.y = pX, pY
        physics.addBody(particle, "dynamic")
        particle.isSensor = true
        particle:applyForce(0, -(speed/100), particle.x, particle.y)
        particle.gravityScale = 0
        if holdTap then
            particle:setFillColor(0.5, 0.9999, 0.9999)
        else
            particle:setFillColor(0.8, 0.999, 0.999)
        end
        timer.performWithDelay(1200, function()
            particle:removeSelf()
            particle=nil
        end)
        transition.fadeOut(particle, {time=1300})
    end
end
-- Obstacle Spawner
function IncomingObstacles()
    local chance = math.random(1, obstacleRate)
    if chance == 1 then
        local oX = math.random(0, 300)
        local oY = 550
        local obstacle = display.newImage("1.png")
        obstacle.x, obstacle.y = oX, oY
        physics.addBody(obstacle, "dynamic")
        obstacle.isSensor = true
        obstacle:applyForce(0, -speed, obstacle.x, obstacle.y)
        obstacle.gravityScale = 0
        timer.performWithDelay(4500, function()
            obstacle:removeSelf()
            obstacle=nil
        end)
    end
end

-- EnterFrame Function----------------------------------------------------
function enterFrame(event)
    --Keep Player height
    player.y = 200
    particleEffect()
    IncomingObstacles()
    --Warp
    if player.x > 350 then
        player. x = 0
    elseif player.x < -50 then
        player.x = 345
    end
end
-------------------------------------------------------------
-- Listeners
Runtime:addEventListener("enterFrame", enterFrame)
Runtime:addEventListener("touch", onTouch)

this is my build.settings:

--
-- For more information on build.settings, see the Project Build Settings guide at:
-- https://docs.coronalabs.com/guide/distribution/buildSettings
--
settings =
{
 orientation =
 {
  -- Supported values for orientation:
  -- portrait, portraitUpsideDown, landscapeLeft, landscapeRight
  default = "portrait",
  supported = { "portrait", },
 },
 --
 -- Android section
 --
 android =
 {
  usesPermissions =
  {
   "android.permission.INTERNET",
   "android.permission.ACCESS_WIFI_STATE",
            "android.permission.READ_PHONE_STATE",
            "android.permission.ACCESS_NETWORK_STATE",
  },
 },
 --
 -- iOS section
 --
 iphone =
 {
  xcassets = "Images.xcassets",
  plist =
  {
   UIStatusBarHidden = false,
   UILaunchStoryboardName = "LaunchScreen",
  },
 },
 --
 -- Plugins section
 --
 plugins =
 {
  ["plugin.inMobi"] =
        {
            publisherId = "com.coronalabs"
        },
 },
 --
 -- Project section
 --
 excludeFiles =
 {
  -- Exclude unnecessary files for each platform
  all = { "Icon.png", "Icon-*dpi.png", "Images.xcassets", },
  android = { "LaunchScreen.storyboardc", },
 },
}

and just in case the config file(the only thing I edited was the xalign and yalign:

--
-- For more information on config.lua see the Project Configuration Guide at:
-- https://docs.coronalabs.com/guide/basics/configSettings
--
application =
{
    content =
    {
        width = 320,
        height = 480, 
        scale = "letterbox",
        fps = 60,
        xAlign = "center",
        yAlign = "center",
        --[[
        imageSuffix =
        {
                ["@2x"] = 2,
                ["@4x"] = 4,
        },
        --]]
    },
}

These are all the files in the game(mind you this isn't the actual game I mentioned earlier, its a small prototype I used to test the ads)



[TOPIC: post.html]
#7

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,062 posts
  • Enterprise

Showing banner ads during game play isn't a good idea. Players are focused on game play and you're just wasting your ad provider's inventory. You're attempting to show an add every time you move your player.

 

You should, on success of the ad loading, get an event that trigger's your adListener function and maybe there you might want to consider showing the ad and let it auto refresh.

 

Look at this adListener....

local json = require("json")
local function adListener( event )
	print( json.prettify( event ) )

    if ( event.phase == "init" ) then  -- Successful initialization
        -- Load a banner ad
        inMobi.load( "banner", placementID )

    elseif ( event.phase == "loaded" ) then
    	inMobie.show( placementID )

    elseif ( event.phase == "failed" ) then  -- The ad failed to load
        print( event.type )
        print( event.placementId )
        print( event.isError )
        print( event.response )
    end
end

the big thing here is that you need to print the event table when you enter the adListener function so that you can see the flow of what's going on. I normally don't like to show ads after the loading event. But you don't seem to be using scene management which is a more logical place to manage showing ads. You can show banners on your menu screens, or game over screens etc.

 

But still we need to know why you're not getting the ads and the only way to do that is to add the prints that I did and use "adb logcat" to look at an Android device's console log.  If you're building for iOS, let me know we will need a different way to print the table since apple now combines that print into a useless single line.

 

Rob



[TOPIC: post.html]
#8

citizengoosevv

[GLOBAL: userInfoPane.html]
citizengoosevv
  • Observer

  • 5 posts
  • Corona SDK

Showing banner ads during game play isn't a good idea. Players are focused on game play and you're just wasting your ad provider's inventory. You're attempting to show an add every time you move your player.

 

You should, on success of the ad loading, get an event that trigger's your adListener function and maybe there you might want to consider showing the ad and let it auto refresh.

 

Look at this adListener....

local json = require("json")
local function adListener( event )
	print( json.prettify( event ) )

    if ( event.phase == "init" ) then  -- Successful initialization
        -- Load a banner ad
        inMobi.load( "banner", placementID )

    elseif ( event.phase == "loaded" ) then
    	inMobie.show( placementID )

    elseif ( event.phase == "failed" ) then  -- The ad failed to load
        print( event.type )
        print( event.placementId )
        print( event.isError )
        print( event.response )
    end
end

the big thing here is that you need to print the event table when you enter the adListener function so that you can see the flow of what's going on. I normally don't like to show ads after the loading event. But you don't seem to be using scene management which is a more logical place to manage showing ads. You can show banners on your menu screens, or game over screens etc.

 

But still we need to know why you're not getting the ads and the only way to do that is to add the prints that I did and use "adb logcat" to look at an Android device's console log.  If you're building for iOS, let me know we will need a different way to print the table since apple now combines that print into a useless single line.

 

Rob

 

Thanks a ton rob!

Yeah, im not gonna have the banner every time someone touches the screen, I was just testing. Im gonna use the interstitial ad when the player dies or finishes a level (50% chance for each)

 

Anyhow I checked the log and it didnt recognize the placementID, probably because I didnt enter the app URL on inmobis dashboard ( its mandatory) .

stupid mistake, I know.




[topic_controls]
[/topic_controls]