Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android 3D游戲開發教程

Android 3D游戲開發教程

編輯:Android開發實例

第一部分首先介紹OpenGL相關的術語,並引導你開始3D開發的第一步。
這個關於3D游戲的系列的叫做 Vortex .
這個教程主要focus在3D編程上,其他的東西比如菜單和程序生命周期雖然是代碼的一部分,但是在這裡不會被提到。
首先開始介紹OpenGL的術語。 
頂點Vertex
頂點是3D空間中的一個點,也是許多對象的基礎元素。在OpenGL中你可以生命少至二維坐標(X,Y),多至四維(X,Y,Z,W). w軸是可選的,默認的值是1.0. Z軸也是可選的,默認為0. 在這個系列中,我們將要用到3個主要的坐標X,Y,Z,因為W一般都是被用來作為占位符。vertex的復數是vertices(這對非英語母語的人來說比較重要,因為這容易產生歧義)。所有的對象都是用vertices作為它們的點,因為點就是vertex。
三角形Triangle
三角形需要三個點才能創建。因此在OpenGL中,我們使用3個頂點來創建一個三角形。
多邊形Polygon
多邊形是至少有3個連接著的點組成的一個對象。三角形也是一個多邊形。
圖元Primitives
一個Primitive是一個三維的對象,使用三角形或者多邊形創建。形象的說,一個有50000個頂點的非常精細的模型是一個Primitive,同樣一個只有500個頂點的低模也叫做一個Primitive。
現在我們可以開始變成了。
創建一個工程交Vortex,activity也是這個名字。我們的工程應該大概是這個樣子的:

 

 1 package com.droidnova.android.games.vortex;
2
3  import android.content.Context;
4  import android.opengl.GLSurfaceView;
5
6  public class VortexView extends GLSurfaceView {
7 private static final String LOG_TAG = VortexView.class.getSimpleName();
8 private VortexRenderer _renderer;
9
10 public VortexView(Context context) {
11 super(context);
12 _renderer = new VortexRenderer();
13 setRenderer(_renderer);
14 }
15 }
16  

 

如上所示,我們繼承了GLSurfaceView是因為它會幫助我們畫3D圖像。接下來看VortexRenderer類。一個Renderer包含畫一幀所必需的所有東西。 引用自這兒references 。Renderer負責OpenGL call來render一個幀。
來看一下這個類:

 

 1 package com.droidnova.android.games.vortex;
2
3  import javax.microedition.khronos.egl.EGLConfig;
4  import javax.microedition.khronos.opengles.GL10;
5
6  import android.opengl.GLSurfaceView;
7
8  public class VortexRenderer implements GLSurfaceView.Renderer {
9  private static final String LOG_TAG = VortexRenderer.class.getSimpleName();
10
11  private float _red = 0.9f;
12  private float _green = 0.2f;
13 private float _blue = 0.2f;
14
15 @Override
16 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
17 // Do nothing special.
18 }
19
20 @Override
21 public void onSurfaceChanged(GL10 gl, int w, int h) {
22 gl.glViewport(0, 0, w, h);
23 }
24
25 @Override
26 public void onDrawFrame(GL10 gl) {
27 // define the color we want to be displayed as the "clipping wall"
28 gl.glClearColor(_red, _green, _blue, 1.0f);
29 // clear the color buffer to show the ClearColor we called above...
30 gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
31 }
32 }
33

好,我們做了什麼?
首先我們實現了GLSurfaceView.Renderer這個接口,主要是實現3個方法:onSurfaceCreated(), onSurfaceChanged() 和 onDrawFrame()。這些方法很容易理解,第一個在surface創建以後調用,第二個是在surface發生改變以後調用,例如從豎屏切換到橫屏的時候,最後一個方法是當任何時候調用一個畫圖方法的時候。
從11行到13行,我們用浮點數來定義RGB顏色系統中的每一個顏色。
在28行,我們通過glClearColor()方法為底色定義了顏色。底色是在我們能看到的所有東西的後面,所以所有在底色後面的東西都是不可見的。可以想象這種東西為濃霧,擋住了所有的東西。然後我們將要為之設置距離來show一下它怎麼用的。那時候你就一定會明白它是怎麼存在的了。
為了讓顏色變化可見,我們必須調用glClear()以及顏色緩沖的Mask來清空buffer,然後為我們的底色使用新的底色。 
 為了能看到它在起作用,我們這裡為MotionEvent創建一個response,使用它來改變顏色。首先在VortexRenderer中來創建一個設置顏色的函數。

 

1 public void setColor(float r, float g, float b) {
2 _red = r;
3 _green = g;
4 _blue = b;
5 }
6

下面是VortexView類中創建的方法來處理MotionEvent。

 

 

1 public boolean onTouchEvent(final MotionEvent event) {
2 queueEvent(new Runnable() {
3 public void run() {
4 _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
5 }
6 });
7 return true;
8 }
9

 

 

我們創建了一個匿名的Runnable對象,這裡的run()方法調用renderer中的setColor方法。這有會根據MotionEvent坐標做一些小的計算。
現在我們已經有了一個小小的程序來使用OpenGl來改變我們的背景色了。
    在德語中我們叫這種小case為“Mit Kanonen auf Spatzen schießen”,翻譯過來應該是“你在車輪上打死了一只蒼蠅”。這說的恰到好處,這只是一個最最最小的例子,要學習OpenGL,你現在要准備更多更多的東西。
這部分最後提一下OpenGL的文檔documentation for OpenGL 。這個東西雖然可用想不高,但是它最少是一個文檔。
Eclipse工程源代碼在這裡下載(原地址): Vortex Part I

 

這個系列的第二部分是關於如何添加一個三角形並可以旋轉它。
第一件事情是初始化需要顯示的三角形。我們來在VortexRenderer類中添加一個方法

 

 1 initTriangle()。 
2 // new object variables we need
3 // a raw buffer to hold indices
4 private ShortBuffer _indexBuffer;
5
6 // a raw buffer to hold the vertices
7 private FloatBuffer _vertexBuffer;
8
9 private short[] _indicesArray = {0, 1, 2};
10 private int _nrOfVertices = 3;
11
12 // code snipped
13
14 private void initTriangle() {
15 // float has 4 bytes
16 ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4);
17 vbb.order(ByteOrder.nativeOrder());
18 _vertexBuffer = vbb.asFloatBuffer();
19
20 // short has 2 bytes
21 ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2);
22 ibb.order(ByteOrder.nativeOrder());
23 _indexBuffer = ibb.asShortBuffer();
24
25 float[] coords = {
26 -0.5f, -0.5f, 0f, // (x1, y1, z1)
27 0.5f, -0.5f, 0f, // (x2, y2, z2)
28 0f, 0.5f, 0f // (x3, y3, z3)
29 };
30
31 _vertexBuffer.put(coords);
32 _indexBuffer.put(_indicesArray);
33
34 _vertexBuffer.position(0);
35 _indexBuffer.position(0);
36 }
37

讓我們從新的對象變量開始. _vertexBuffer為我們的三角形保存坐標._indexBuffer保存索引. _nrOfVertices變量定義需要多少個頂點.對於一個三角形來說,一共需要三個頂點. 這個方法首先為這裡兩個buffer分配必須的內存(14-22行). 接下來我們定義一些坐標(24-28行) 後面的注釋對用途給予了說明. 
在30行,我們將coords數組填充給_vertexBuffer . 同樣在31行將indices數組填充給_indexBuffer 。最後將兩個buffer都設置position為0.
為了防止每次都對三角形進行初始化,我們僅僅在onDrawFrame()之前的行數調用它一次。一個比較好的選擇就是在onSurfaceCreated()函數中.

 

1 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
2 // preparation
3 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
4 initTriangle();
5 }
6

glEnableClientState() 設置OpenGL使用vertex數組來畫。這是很重要的,因為如果不這麼設置OpenGL不知道如何處理我們的數據。接下來我們就要初始化我們的三角形。為什麼我們不需使用不同的buffer? 在新的onDrawFrame()方法中我們必須添加一些新的OpenGL調用。

 1 public void onDrawFrame(GL10 gl) {
2 // define the color we want to be displayed as the "clipping wall"
3 gl.glClearColor(_red, _green, _blue, 1.0f);
4
5 // clear the color buffer to show the ClearColor we called above...
6 gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
7
8 // set the color of our element
9 gl.glColor4f(0.5f, 0f, 0f, 0.5f);
10
11 // define the vertices we want to draw
12 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
13
14 // finally draw the vertices
15 gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
16 }
17

好,一步一步地看。
glClearColor() 和 glClear() 在教程I部分已經提到過。在第10行使用glColor4f(red, green, blue, alpha)設置三角形為暗紅色 .
在第13行,我們使用glVertexPointer()初始化Vertex Pointer. 第一個參數是大小,也是頂點的維數。我們使用的是x,y,z三維坐標。第二個參數,GL_FLOAT定義buffer中使用的數據類型。第三個變量是0,是因為我們的坐標是在數組中緊湊的排列的,沒有使用offset。最後哦胡第四個參數頂點緩沖。
最後,glDrawElements()將所有這些元素畫出來。第一個參數定義了什麼樣的圖元將被畫出來。第二個參數定義有多少個元素,第三個是indices使用的數據類型。最後一個是繪制頂點使用的索引緩沖。
當最後測試這個應用的使用,你會看到一個在屏幕中間靜止的三角形。當你點擊屏幕的時候,屏幕的背景顏色還是會改變。
現在往裡面添加對三角形的旋轉。下面的代碼是寫在VortexRenderer類中的.

 

1 private float _angle;
2
3 public void setAngle(float angle) {
4 _angle = angle;
5 }
6

 

glRotatef()方法在glColor4f()之前被onDrawFrame()調用.

 

1 public void onDrawFrame(GL10 gl) {
2 // set rotation
3 gl.glRotatef(_angle, 0f, 1f, 0f);
4
5 gl.glColor4f(0.5f, 0f, 0f, 0.5f);
6 // code snipped
7 }
8

這時候我們可以繞y軸旋轉。如果需要改變只需要改變glRotate()方法中的0f。這個參數中的值表示一個向量,標志三角形繞著旋轉的坐標軸。
要讓它可用,我們必須在VortexView中的onTouchEvent()中添加一個調用。

 

 1 public boolean onTouchEvent(final MotionEvent event) {
2 queueEvent(new Runnable() {
3 public void run() {
4 _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
5 _renderer.setAngle(event.getX() / 10);
6 }
7 });
8 return true;
9 }
10

 

上面代碼中除以10是為了減小角度變換的速度。
現在編譯運行這個程序。如果你在屏幕的最左邊點擊,你會看到三角形輕微旋轉。如果你將手指移到右邊,旋轉的速度就會變得很快。
Eclipse工程的源代碼在這裡下載(原鏈接): Vortex Part II

轉自:http://www.cnblogs.com/jk1001/archive/2010/08/16/1800373.html

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved