I'm implementing AdMob in my game but there is a problem: after closing the rewarderAd video, the game does not respond to touch, nor log anything.
I searched on Web founding a suggestion to insert gameView.requestFocus();
in the ad's callback but it doesn't work.
MyGdxGame.java (core):
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
public final static float CARD_WIDTH = 1f;
public final static float CARD_RATIO_W_H = 277f / 200f;
public final static float CARD_HEIGHT = CARD_WIDTH * CARD_RATIO_W_H;
public final static float MINIMUM_VIEWPORT_SIZE = 7f;
float widthPixel;
float heightPixel;
float widthPixel1Card;
float heightPixel1Card;
CardBatch cards;
CardActions actions;
Vector3 vector3touch;
Stage stage;
Label labelStart;
ModelBatch modelBatch;
TextureAtlas atlas;
ShapeRenderer shapeRenderer;
OrthographicCamera cam;
private Viewport viewport;
private IActivityRequestHandler myRequestHandler;
public MyGdxGame(IActivityRequestHandler handler) {
myRequestHandler = handler;
}
@Override
public void create () {
widthPixel = Gdx.graphics.getWidth();
heightPixel = Gdx.graphics.getHeight();
widthPixel1Card = widthPixel / MINIMUM_VIEWPORT_SIZE;
heightPixel1Card = widthPixel1Card * CARD_RATIO_W_H;
shapeRenderer = new ShapeRenderer();
modelBatch = new ModelBatch();
atlas = new TextureAtlas("carddeck.atlas");
Material material = new Material(
TextureAttribute.createDiffuse(atlas.getTextures().first()),
new BlendingAttribute(false, 1f),
FloatAttribute.createAlphaTest(0.2f));
cards = new CardBatch(material);
cam = new OrthographicCamera(MINIMUM_VIEWPORT_SIZE, MINIMUM_VIEWPORT_SIZE * CARD_RATIO_W_H);
viewport = new FitViewport(MINIMUM_VIEWPORT_SIZE, MINIMUM_VIEWPORT_SIZE * CARD_RATIO_W_H, cam);
Gdx.input.setInputProcessor(this);
actions = new CardActions();
vector3touch = new Vector3();
stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getWidth() * CARD_RATIO_W_H));
Texture texture = new Texture(Gdx.files.internal("arial32.png"), true); // true enables mipmaps
texture.setFilter(Texture.TextureFilter.MipMapLinearNearest, Texture.TextureFilter.Linear); // linear filtering in nearest mipmap image
BitmapFont fontDistanceField = new BitmapFont(Gdx.files.internal("arial32.fnt"), new TextureRegion(texture), false);
Label.LabelStyle labelStyleDistanceField = new Label.LabelStyle();
labelStyleDistanceField.font = fontDistanceField;
labelStart = new Label("Touch to start", labelStyleDistanceField);
labelStart.setSize(widthPixel/2, heightPixel1Card);
labelStart.setPosition(widthPixel/2-widthPixel1Card*1.5f, (heightPixel/2f)-heightPixel1Card);
labelStart.setAlignment(Align.left);
labelStart.setWrap(false);
labelStart.setColor(Color.BLACK);
stage.addActor(labelStart);
}
@Override
public void render() {
final float delta = Math.min(1/30f, Gdx.graphics.getDeltaTime());
Gdx.gl.glClearColor(167/255f, 219/255f, 216/255f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
drawCoordsDebug();
actions.update(delta);
modelBatch.begin(cam);
modelBatch.render(cards);
modelBatch.end();
stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
stage.draw();
}
public static class CardActions {
Pool<CardAction> actionPool = new Pool<CardAction>() {
protected CardAction newObject() {
return new CardAction(CardActions.this);
}
};
Array<CardAction> actions = new Array<>();
public void actionComplete(CardAction action) {
action.card.inMovimento = false;
actions.removeValue(action, true);
actionPool.free(action);
}
public void update(float delta) {
for (CardAction action : actions) {
action.update(delta);
}
}
// ...
}
public static class CardAction {
public CardActions parent;
public Card card;
public final Vector3 fromPosition = new Vector3();
public float fromAngle;
public final Vector3 toPosition = new Vector3();
public float toAngle;
public float speed;
public float alpha;
public CardAction(CardActions parent) {
this.parent = parent;
}
public void update(float delta) {
alpha += delta * speed;
if (alpha >= 1f) {
alpha = 1f;
parent.actionComplete(this);
}
card.position.set(fromPosition).lerp(toPosition, alpha);
card.angle = fromAngle + alpha * (toAngle - fromAngle);
card.update();
}
}
@Override
public void resize(int width, int height) {
cam.position.set(0, 0, 10);
cam.lookAt(0, 0, 0);
cam.update();
viewport.update(width, height);
stage.getViewport().update(width, height);
}
@Override
public boolean keyDown(int keycode) {return false; }
@Override
public boolean keyUp(int keycode) {return false; }
@Override
public boolean keyTyped(char character) {return false; }
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {return false; }
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
Gdx.app.log("touchUp", "");
return true;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {return false; }
@Override
public boolean mouseMoved(int screenX, int screenY) {return false; }
@Override
public boolean scrolled(int amount) {return false; }
public void drawCoordsDebug() {
shapeRenderer.setProjectionMatrix(cam.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.setColor(Color.WHITE);
float wTot = Gdx.graphics.getWidth();
float hTot = Gdx.graphics.getHeight();
shapeRenderer.circle(0, 0, 1f);
for(float w = 0; w >= -wTot; w--) {
shapeRenderer.line(new Vector2(w,-hTot), new Vector2(w,hTot));
}
for(float w = 0; w <= wTot; w++) {
shapeRenderer.line(new Vector2(w,-hTot), new Vector2(w,hTot));
}
for(float h = 0; h >= -hTot; h--) {
shapeRenderer.line(new Vector2(-wTot, h), new Vector2(wTot, h));
}
for(float h = 0; h <= hTot; h++) {
shapeRenderer.line(new Vector2(-wTot, h), new Vector2(wTot, h));
}
shapeRenderer.end();
}
@Override
public void dispose () {
modelBatch.dispose();
atlas.dispose();
cards.dispose();
shapeRenderer.dispose();
stage.dispose();
}
}
DesktopLauncher.java:
public class DesktopLauncher implements IActivityRequestHandler {
private static DesktopLauncher application;
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
if (application == null) {
application = new DesktopLauncher();
}
new LwjglApplication(new MyGdxGame(application), config);
}
@Override
public void showAds(boolean show) {
}
}
AndroidLauncher.java:
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.RequestConfiguration;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
public class AndroidLauncher extends AndroidApplication implements IActivityRequestHandler {
private final int SHOW_ADS = 1;
private final int HIDE_ADS = 0;
protected AdView mAdView;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MobileAds.initialize(this, initializationStatus -> { });
// Create and setup the AdMob view
mAdView = new AdView(this);
mAdView.setAdSize(AdSize.BANNER);
mAdView.setAdUnitId("");
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
// Create the layout
RelativeLayout layout = new RelativeLayout(this);
// Do the stuff that initialize() would do for you
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
// Add the libGDX view
View gameView = initializeForView(new MyGdxGame(this));
layout.addView(gameView);
// Add the AdMob view
RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layout.addView(mAdView, adParams);
layout.setKeepScreenOn(true);
setContentView(layout);
}
protected Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case SHOW_ADS:
{
Activity activityContext = AndroidLauncher.this;
if (rewardedAd.isLoaded()) {
RewardedAdCallback adCallback = new RewardedAdCallback() {
@Override
public void onRewardedAdOpened() {
// Ad opened.
}
@Override
public void onRewardedAdClosed() {
// Ad closed.
rewardedAd = createAndLoadRewardedAd();
gameView.requestFocus();
}
@SuppressLint("ApplySharedPref")
@Override
public void onUserEarnedReward(@NonNull RewardItem reward) {
gameView.requestFocus();
}
@Override
public void onRewardedAdFailedToShow(int errorCode) {
// Ad failed to display.
}
};
rewardedAd.show(activityContext, adCallback);
} else {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
}
}
break;
}
case HIDE_ADS:
{
mAdView.setVisibility(View.GONE);
break;
}
}
}
};
// This is the callback that posts a message for the handler
@Override
public void showAds(boolean show) {
handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS);
}
@Override
protected void onResume() {
super.onResume();
gameView.requestFocus();
}
}
Also the method touchUp
does not print anything in the log.
A few attempts:
Replacing gameView.requestFocus();
whit this:
runOnUiThread(new Runnable() {
@Override
public void run() {
gameView.requestFocus();
}
});
The strange thing is that it happens on Android 10, while on Android 6.0 all works fine even without these lines of code.
Note: I know that the rewardedAd must used only if the user want to view it to receive a reward, here I'm using it to test the flow, before continuing implementing it correctly in the Game.
Thanks a lot!
from Activity "freezed" after onResume
No comments:
Post a Comment