I can get the scene from a layer, but I don't know how to have a Scene that manages layers. I can do this on iPhone, but on Android my code doesn't even get called.
This is in my start Activity:
CCDirector.sharedDirector().runWithScene(EditorScene.node());
This is my scene class:
public class EditorScene extends CCScene
{
public EditorScene()
{
CanvasBackgroundLayer canvasBackgroundLayer = (CanvasBackgroundLayer) CanvasBackgroundLayer.node();
CanvasEditorLayer canvasEditorLayer = (CanvasEditorLayer) CanvasEditorLayer.node();
addChild(canvasBackgroundLayer,0);
this.addChild(canvasEditorLayer);
}
}
My constructor here is never called. Any ideas on what to do?
Any subclasses of CCScene have to reimplement the static method node(). Have a look at the bottom of CCScene.h.
Related
I managed to test a simple app and the ads (banner and interstitial) work as expected (the test ones, because the real ones don't, idk why).
The problem is I want to integrate the ads into my main application. I did it for the banner and it works but don't know how to handle the interstitial. For the test app, I called a function when a button was pressed, but here in my app I don't want a button to be pressed in order to show an interstitial, I want this to happen every time the player dies. And I don't know how to do this.
using System;
using UnityEngine;
using GoogleMobileAds.Api;
public class ads : MonoBehaviour
{
private BannerView bannerView;
private InterstitialAd interstitial;
private void RequestBanner()...
private void RequestInterstitial()
{
string adUnitId = "ca-app-pub-3940256099942544/1033173712";
this.interstitial = new InterstitialAd(adUnitId);
AdRequest request = new AdRequest.Builder().Build();
this.interstitial.LoadAd(request);
}
public void GameOverSoShowInterstitial()
{
if (this.interstitial.IsLoaded())
{
this.interstitial.Show();
}
}
void Start()
{
MobileAds.Initialize(initStatus => { });
this.RequestBanner();
this.RequestInterstitial();
}
}
^this is my ads script
but it is located in the second scene named Menu, but since the interstitial should appear when the player dies, I should move that GameObject in the other scene that is the actual game, because it's impossible to die in the 'menu' section. And also, for checking when the ad has to appear I should use the GameManager, right? which is in the game scene, too.
public void GameOver()
{
gameOver = true;
gameScore = score.GetComponent<Score>().getScore();
score.SetActive(false);
Invoke("ActivateGameOverCanvas", 1);
pauseBtn.SetActive(false);
}
^this is the part with the gameover from gamemanager, so I think here I should introduce somehow an instruction that would generate the interstitial ad, but I don't have a clue. I tried to add the 'ads' script to gamemanager too, so at the end of the execution of GameOver function from gamemanager to call the GameOverSoShowInterstitial from ads, but it didn't work.
Any ideas? :(
1. Using objects from another Scene
When it comes to using scripts/objects from once Scene to another we generally put that object into a MonoBehaviour built-in method DontDestroyOnLoad(object);. By Using this method we can make sure that object will not be destroyed when you change the scenes. Assuming that Menu your script is in Menu Scene you can Put that object in DontDestroyOnLoad() method and it will not get destroyed throughout the game.
2. Using the Method from Add script
For this we have multiple options. Like you can find the Object Using GameObject.FindObjectOfType() or GameObject.FindGameObjectWithTag(), etc. But using Gameobject.FindXXX() method can be heavy on performance side. The battre way is to use singleton pattern. In this you basically create an object when your Game Starts(When you need the object). And there will be no other object of the same type (it mean that there will be no other object with the same script attached to the object).
3. See both of the points in Action
Your Ad script
you don't have to change any thing just have to add the Singleton pattern.
using System;
using UnityEngine;
using GoogleMobileAds.Api;
public class ads : MonoBehaviour
{
//This is a static instance of this class so that you can access it from anywhere from you game, Without creating any creating a new Object.(Point #2)
public static ads instance {
get; //These are the getter and setter methods of native C# find the reference below
private set;
}
private Awake()
{
//Check if the instance is already assigned(if there is already an object with this same script attached)
if(instance == null)
{
instance = this; //If instance is empty the assign this object to the instance
DoNotDestroyOnLoad(this.gameObject); //This line will stop Unity from destroying the object when you load new scene.(Point #1)
}
else
{
Destroy(this.gameObject); //since there is already an object of with script destroy this object so that there will be no conflicts between multiple instances of the same class.
}
}
void Start()
{
MobileAds.Initialize(initStatus => { });
this.RequestBanner();
this.RequestInterstitial();
}
public void ShowInterstitialAd()
{
... Show your Ad
}
}
Game Manager Script
public void PlayerDie() //assuming that you have a method for when your Player dies
{
...
ads.instance.ShowInterstitialAd(); //Call the ShowInterstitialAd() method because the object will not be destroyed when you load another scene.
}
I'm basically done here. I hope this helps you. here are some of the reference that might be helpful to understand this further.
Singleton pattern
Getter and setter methods of native C#
I was just wondering, if you want to create an object for a game, lets say a ball,
Should you create a class called ball that it contains the sprite and the body?, like:
public class Ball {
BaseGameActivity mActivity;
Sprite s;
Body mBody
public Ball(TextureRegion texture,BaseGameActivity mActivity){
this.mActivity=mActivity;
s= new Sprite (0,0,texture,mActivity.getVertexBufferObjectManager());
mBody=PhysicsFactory.createBoxBody(mActivity.mWorld,s, BodyDef.BodyType.StaticBody,PhysicsFactory.createFixtureDef(1,0,2));
//then it shoud be properly attached to scene and world etc...
}
}
A class that extends sprite? like:
public class Ball extends Sprite {
BaseGameActivity mActivity;
Body mBody
public Ball(TextureRegion texture,BaseGameActivity mActivity){
super (0,0,texture,mActivity.getVertexBufferObjectManager());
this.mActivity=mActivity;
mBody=PhysicsFactory.createBoxBody(mActivity.mWorld,this, BodyDef.BodyType.StaticBody,PhysicsFactory.createFixtureDef(1,0,2));
//then it shoud be properly attached to scene and world etc...
}
}
Or another way?
Which is the fastest? Which is the easier? Or the way doesn't matter?
Thanks in advance
just do like this.. u will probably need other sprites and other stuff...
public class Ball extends BaseGameActivity{
//constructor and other methods
BitmapTextureAtlas ballAtlas;
ITextureRegion ballTexture;
//in onLoadResources load ur atlas
//create texture region
//then in onCreateScene create a scene
//simply attach ur sprite ball to ur scene
}
you can create sprites anywhere.. you are not bound to create separate class for that
I think you can use both approach, it depends on you and your coding style / application infrastructure. :)
Altough I use a generic SceneManager class with a reference to the activity, instead of multiple activities
I have the following (simplified) rig so far:
MyActivity.java:
public class MyActivity extends Activity {
public GLSurfaceView myGLView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myGLView = new MyGLSurfaceView(this);
setContentView(myGLView);
}
}
MyGLSurfaceView.java:
public class MyGLSurfaceView extends GLSurfaceView {
private MyRenderer mMyRenderer = new MyRenderer();
private MyThread mMyThread = new MyThread();
public MyView(Context context) {
super(context);
setRenderer(mGameRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
mGameThread.setRunning(true);
}
}
MyRenderer.java:
public class GameRenderer implements GLSurfaceView.Renderer {
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// ...
}
}
MyThread.java:
Here I'm doing all initializations, creating objects and so on.
public class MyThread extends Thread {
private MyObject mMyObject = new MyObject();
public MyThread {
// ...
mMyObject.setRot();
this.start();
}
public void run() {
// Fixed Timestep Loop goes here
mMyObject.getRot();
}
}
MyObject.java:
This is a sample object which holds different fileds and methods.
public class MyObject {
private double mRot;
// Getters & Setters
protected double getRot() { return mRot; }
protected void setRot() {
// ... Do calculations
}
public void draw() {
// OGL Instructions go here
gl.glRotatef(1.2f, 0, 0, setRot());
}
}
Now the problem I was running into is the following: (I guess, I missed something very basic and simple :) )
As stated above, I'm creating my object instances in the MyThread class. The Thread is created in the MyGLSurface class, same goes for the Renderer. Now, that I have that two threads I can't figure out, how to use that one instance and their methods in that two separate threads.
I tried different approaches, but nothing did work. So in my opinion I made a mistake in the class design. I mean, I don't just want to get it running (that'd be quite easy), but I want to know how to do it correctly.
The main problem is actually that I can't access the MyObject's instance and simply use the draw() method in the renderer - because I don't get it.
I thought, it would be possible to call the draw() method of MyObject within the rendering thread without the need of using a singleton and so on. So simply referencing the instance to it. But somehow that seemed weird and dirty (besides that it doesn't work for me).
I tried dozens of different approaches, but I really need a bump into the right direction. I'm quite familar with OOP, but here I might really miss something.
In that many samples I found on the web (stackoverflow, Replica Island, different tutorial sites, Google I/O, DevCentral, etc.) they either didn't use a multithreaded system or they split it directly (GL objects from regular objects).
Any hint into the right direction would be much appreciated!
Another example to peruse:
https://code.google.com/p/android-breakout/
The wiki and code comments discuss the threading issues inherent in using GLSurfaceView. In particular, the game does as much setup as it can before the Renderer thread starts; once it's running, as much work as possible is done on that thread. The game state objects are effectively "owned" by the renderer thread, and the Activity is owned by the UI thread, so any "off-thread" interactions are handled by sending messages rather than making direct method calls. For example, see the handling of touch events.
It's good that you're thinking about this -- you either need synchronization or careful object discipline to avoid nasty race conditions.
See also: android game loop vs updating in the rendering thread
The nice thing about GLSurfaceView is that it creates the OpenGL rendering thread for you, so you don't need to create one yourself. The main UI thread will call the OnDraw() method in your view class and that's all the threads you need. If you really want to create your own thread for OpenGL rendering, use TextureView instead of GLSurfaceView. Here is an article that I think will help:
http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1
as far as I understood the Android-NDK-thingy it works as follows: I have to use a NativeActivity that itself calls into the attached native code handing over some OpenGL graphics context. This context can be used by the native part to draw some things with.
What I could not fiddle out until now: how about some GUI elements? Is there a possibility to call back from native code to Java just to create some UI-elements and perhaps to use layouts? Means is it possible to use the standard Android GUI elements also with such native code?
If yes: how can this be done? If not: what alternatives exist (except drawing everything manually)?
Thanks!
If you want to use GUI stuff on the openGL view, I think it would be better to use a normal Activity instead of a NativeActivity.
You can use the Android sample called GL2JNIActivity. Check that to import it from Eclipse.
You can declare some native functions in the JNI Library part (class JNILib in the sample). which you will call when you your GUI listeners get called. Basically it will look like that:
public class GL2JNILib {
static {
// Maybe you need to load other relevant libraries here
System.loadLibrary("gl2jni");
}
public static native void init(int width, int height);
public static native void step();
/*Add here your native functions to send to the native code*/
public static native void buttonClicked();
//... add other listeners here (i.e: screen touched, etc.)
}
Then in the Activity itself (in the sample that corresponds to the class JNIActivity), you can just load an XML GUI file as usual. When you get some input through the GUI, you can just call the native functions added in the GL2JNI class. More or less it will look like that:
public class GL2JNIActivity extends Activity {
GL2JNIView mView;
Button mButton;
#Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new GL2JNIView(getApplication());
setContentView(mView);
mButton = (Button)findViewById(R.id.your_button);
mButton.setOnClickListener( new Button.OnClickListener(){
#Override
public void onClick(View v) {
mView.buttonClicked();
}
});
}
/*...*/
}
Finally, you have to implement the native function in the native side:
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_buttonClicked(
JNIEnv * env, jobject obj)
{
// will be called when the button is clicked
}
In my openGL game, I draw my scene normally using a GLSurfaceView.Renderer class in the onDrawFrame(). However, when I am displaying a loading screen I would like to force the screen to draw after each item of data is loaded so the loading bar can be displayed.
Is it possible to force a bufferswap during this draw call somehow? My only alternative is to stagger my loading across multiple frames which means a lot of rework..
I guess what I am trying to call is eglSwapBuffers() but I cannot find a way to access the egl context from the GLSurfaceView or GLSurfaceView.Renderer.
Thank you for your time.
You can add also this method to your GLSurfaceView.Renderer class:
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
public void swapBuffers()
{
EGL10 curEgl = (EGL10)EGLContext.getEGL();
EGLDisplay curDisplay = curEgl.eglGetCurrentDisplay();
if (curDisplay == EGL10.EGL_NO_DISPLAY) { Log.e("myApp","No default display"); return; }
EGLSurface curSurface = curEgl.eglGetCurrentSurface(EGL10.EGL_DRAW);
if (curSurface == EGL10.EGL_NO_SURFACE) { Log.e("myApp","No current surface"); return; }
curEgl.eglSwapBuffers(curDisplay, curSurface);
}
Much the same as OpenUserX03's answer, just in Java.
No you can't (or shouldn't) force swapping buffers in the onDraw method of your Renderer.
What you should do is to make the loading of your data in a separate Thread. Your onDraw method will still be called regularly, which will let you ask to the loading thread how many items were loadede to display a progress bar / message accordingly.
It's been awhile since the answer has been accepted but you can (and there is no reason you shouldn't) force swapping the buffers in the onDrawFrame() method of your Renderer.
I had the exact same problem in my OpenGL app - I needed to render a loading screen while data was being loaded. Here is my pseudo-code example of calling eglSwapBuffers() during a load (I use JNI):
public void onDrawFrame(GL10 gl)
{
MyJNILib.render();
}
MyJNILib native pseudo-code:
#include <EGL\egl.h>
...
void render()
{
...
while (loading)
{
// Do loading stuff
...
eglSwapBuffers( eglGetCurrentDisplay(), eglGetCurrentSurface( EGL_DRAW ) );
}
...
}
A solution by force is to make your custom version GLSurfaceView class based on the source code of Android.
In the source, you can find a method called swap:
/**
* Display the current render surface.
* #return the EGL error code from eglSwapBuffers.
*/
public int swap() {
if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
return mEgl.eglGetError();
}
return EGL10.EGL_SUCCESS;
}
This should be what you want. Unfortunately, however, it is a method of private inner class called EglHelper.
/**
* An EGL helper class.
*/
private static class EglHelper {
So in your custom GLSurfaceView class (copied from Google's source), make this EglHelper class public and you can use EglHelper.swap method.
public static class EglHelper {