Difference between revisions of "Hello World for Android"

From JPCT
Jump to: navigation, search
(onTouchEvent(MotionEvent me))
 
(4 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
This code should help to get you started. It displays a simple, lit cube that you can rotate by using the touch screen. It includes basic pause/resume handling.
 
This code should help to get you started. It displays a simple, lit cube that you can rotate by using the touch screen. It includes basic pause/resume handling.
 
I'll post the complete source code and comment on some important parts later on the page.
 
I'll post the complete source code and comment on some important parts later on the page.
 +
 +
Please note that this example is meant to be really basic. Usually, you don't want to have all these fields in your Activity but in some other class of yours instead. For this example, i tried to keep things really really simple, which is why everything in part of the Activity. Don't take this as an example of great design.
 +
 +
Also keep in mind that this code has been written to be executed on an old Android 1.5 "powered" device. On a current device, some tweaks might not be needed anymore. I'll comment on that in more detail in the source code comment part of this page.
  
 
====The source cde====
 
====The source cde====
Line 330: Line 334:
 
}
 
}
 
</pre>
 
</pre>
 +
 +
=====onSurfaceChanged(GL10 gl, int w, int h)=====
 +
 +
This sets up the FrameBuffer and the World and everything...if needed. In case that this method has been called before, it simply disposes the old FrameBuffer and creates a new one. One thing to note is the call to MemoryHelper.compact();. Again, this is a tribute to older Android versions, which had massive problems with garbage collection. What it does is to force the gc to run at this stage to avoid that it runs at runtime, which will cause stuttering when you don't want to see some.
 +
 +
<pre>
 +
public void onSurfaceChanged(GL10 gl, int w, int h) {
 +
if (fb != null) {
 +
fb.dispose();
 +
}
 +
fb = new FrameBuffer(gl, w, h);
 +
 +
if (master == null) {
 +
 +
world = new World();
 +
world.setAmbientLight(20, 20, 20);
 +
 +
....
 +
 +
MemoryHelper.compact();
 +
 +
if (master == null) {
 +
    Logger.log("Saving master Activity!");
 +
    master = HelloWorld.this;
 +
}
 +
}
 +
}
 +
</pre>
 +
 +
=====onDrawFrame(GL10 gl)=====
 +
 +
This is the render method, called by Android in the render thread. If you are experienced in game development, you might have used/heard of the concept of a game loop, which is a (timed) loop that constantly executes your game logic and rendering. In an Android Activity, there is no such loop, but the code inside onDrawFrame() is what comes closest to what you would usually have in your game loop...just without the loop. Don't loop within here, because that would stall the Activity.
 +
 +
As you can see, the variables set in the touch event handler above are evaluated here so that object rotations don't interfere with the rendering of the same objects. The rest is basic jPCT-AE render stuff. Whatever you do before and after, do render a scene, you'll basically do something like
 +
 +
<pre>
 +
fb.clear();
 +
world.renderScene(fb);
 +
world.draw(fb);
 +
fb.display();
 +
</pre>
 +
 +
almost every time. In addition, there's some code that displays the fps to the console. If you want to limit your frame rate to maybe 30fps to save battery, this method is a good place to do it. You can search for the source code of my Alien Runner game for an example of how to do this.
 +
 +
<pre>
 +
public void onDrawFrame(GL10 gl) {
 +
if (touchTurn != 0) {
 +
cube.rotateY(touchTurn);
 +
touchTurn = 0;
 +
}
 +
 +
if (touchTurnUp != 0) {
 +
cube.rotateX(touchTurnUp);
 +
touchTurnUp = 0;
 +
}
 +
 +
fb.clear(back);
 +
world.renderScene(fb);
 +
world.draw(fb);
 +
fb.display();
 +
 +
if (System.currentTimeMillis() - time >= 1000) {
 +
Logger.log(fps + "fps");
 +
fps = 0;
 +
time = System.currentTimeMillis();
 +
}
 +
fps++;
 +
}
 +
</pre>
 +
 +
====One last thing...====
 +
 +
In this code, i'm using a cube created by the Primitives class. These objects have no proper texture coordinates, which is why i fake some by calling
 +
 +
<pre>
 +
cube.calcTextureWrapSpherical();
 +
</pre>
 +
 +
If you are replacing the cube with some model loaded from a 3ds or an obj file, REMOVE THIS LINE or it will screw up your texture coordinates.
 +
 +
====That's it!?====
 +
 +
Yes, that's basically it. For more details on the world setup itself, you can refer to the HelloWorld for desktop jPCT which explains these parts in more details: [[Hello World]]
  
 
[[Category:jPCT-AE]]
 
[[Category:jPCT-AE]]

Latest revision as of 23:42, 2 February 2013