Android遊戲開發學習之引擎用法執行個體詳解_Android

來源:互聯網
上載者:User

本文執行個體講述了Android遊戲開發學習之引擎用法。分享給大家供大家參考。具體如下:

汽車引擎是汽車的心臟,其決定了汽車的效能和穩定性,是人們在購車時相當關注的。而遊戲中的物理引擎就如汽車的引擎一樣,佔據了非常重要的位置。一款好的物理引擎可以非常真實地類比現實世界,使得遊戲更加逼真,提供更好的娛樂體驗。

一、JBox2D簡介

JBox2D是開源物理引擎Box2D的Java版本,可以直接用於Android。由於JBox2D的圖形渲染使用的是Processing庫,因此在Android平台上使用JBox2D時,圖形渲染工作只能自行開發。該引擎能夠根據開發人員設定的參數,如重力、密度、摩擦係數和彈性係數等,自動地進行2D剛體物理運動的全方位類比。

二、樣本

1.小球彈跳進階版

在第1節中小球的下落、碰撞、彈起都是用代碼來維護的,下面使用物理引擎來實現,並且加入了剛體之間的碰撞。

(1)常量類Constant

package box2d.bheap; public class Constant {   public static final float RATE=10; //螢幕與現實世界的比例   public static final boolean DRAW_THREAD_FLAG=true; //繪製線程工作標識位   public static final float TIME_STEP=2.0f/60.0f; //類比的頻率   public static final int ITERA=10; //迭代次數   public static int SCREEN_WIDTH; //螢幕寬度   public static int SCREEN_HEIGHT; //螢幕高度 }

(2)抽象類別MyBody

該類為自訂的抽象類別,是所有自訂剛體類的基類。由於JBox2D中的剛體類對象僅具有物理模擬計算的功能,並沒有提供Android平台下的繪製功能,直接使用不是很方便。因此,這裡定義了MyBody對自訂剛體的繪製及JBox2D物理模擬對象進行了封裝。

package box2d.bheap; import org.jbox2d.dynamics.Body; import android.graphics.Canvas; import android.graphics.Paint; public abstract class MyBody {   Body body; //JBox2D物理引擎中的剛體    int color; //剛體的顏色   public abstract void drawSelf(Canvas canvas,Paint paint); //繪製的方法 }

(3)圓形剛體類MyCircleColor

package box2d.bheap; import org.jbox2d.dynamics.Body; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Style; import static box2d.bheap.Constant.*; //靜態匯入 public class MyCircleColor extends MyBody {   float radius; //圓形半徑   public MyCircleColor(Body body,float radius,int color) {     this.body=body;     this.radius=radius;     this.color=color;   }   @Override   public void drawSelf(Canvas canvas, Paint paint) {     paint.setColor(color&0xCFFFFFF); //設定顏色     float x=body.getPosition().x*RATE;     float y=body.getPosition().y*RATE;     canvas.drawCircle(x, y, radius, paint); //畫圓     paint.setStyle(Style.STROKE); //設定空心無填充     paint.setStrokeWidth(1);     paint.setColor(color); //畫邊     canvas.drawCircle(x, y, radius, paint);     paint.reset(); //恢複畫筆設定   } }

(4)矩形剛體類MyRectColor

package box2d.bheap; import static box2d.bheap.Constant.RATE; import org.jbox2d.dynamics.Body; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; public class MyRectColor extends MyBody {   float halfWidth;//半寬   float halfHeight;//半高   public MyRectColor(Body body,float halfWidth,float halfHeight,int color)   {     this.body=body;     this.halfWidth=halfWidth;     this.halfHeight=halfHeight;        this.color=color;   }   public void drawSelf(Canvas canvas,Paint paint)   {          paint.setColor(color&0x8CFFFFFF);      float x=body.getPosition().x*RATE;     float y=body.getPosition().y*RATE;     float angle=body.getAngle();     canvas.save();     Matrix m1=new Matrix();     m1.setRotate((float)Math.toDegrees(angle),x, y);     canvas.setMatrix(m1);     canvas.drawRect(x-halfWidth, y-halfHeight, x+halfWidth, y+halfHeight, paint);      paint.setStyle(Paint.Style.STROKE);     paint.setStrokeWidth(1);//設定線條寬度     paint.setColor(color);     canvas.drawRect(x-halfWidth, y-halfHeight, x+halfWidth, y+halfHeight, paint);      paint.reset();        canvas.restore();   } }

(5)產生剛體形狀的工具類Box2DUtil

package box2d.bheap; import static box2d.bheap.Constant.RATE; import org.jbox2d.collision.CircleDef; import org.jbox2d.collision.PolygonDef; import org.jbox2d.dynamics.Body; import org.jbox2d.dynamics.BodyDef; import org.jbox2d.dynamics.World; public class Box2DUtil {   /**    * 建立矩形物體(顏色)    */   public static MyRectColor createBox (       float x,       float y,       float halfWidth,       float halfHeight,       boolean isStatic, //是否為靜止的       World world,       int color   ) {     PolygonDef shape=new PolygonDef(); //建立多邊形描述對象     if(isStatic) {       shape.density=0;     } else {       shape.density=1.0f;     }     shape.friction=0.0f; //設定摩擦係數     shape.restitution=0.6f; //設定能量損失率     shape.setAsBox(halfWidth/RATE, halfHeight/RATE);     BodyDef bodyDef=new BodyDef(); //建立剛體描述對象     bodyDef.position.set(x/RATE,y/RATE); //設定位置     Body bodyTemp=world.createBody(bodyDef); //在世界中建立剛體     bodyTemp.createShape(shape); //指定剛體形狀     bodyTemp.setMassFromShapes(); //設定物體品質     return new MyRectColor(bodyTemp, halfWidth, halfHeight, color);  }   /**    * 建立圓形物體(顏色)    */   public static MyCircleColor createCircle (       float x,       float y,       float radius,       World world,       int color   ) {     CircleDef shape=new CircleDef(); //建立圓描述對象     shape.density=2; //設定密度     shape.friction=0.0f; //設定摩擦係數     shape.restitution=0.95f; //設定能量損失率     shape.radius=radius/RATE;//設定半徑     BodyDef bodyDef=new BodyDef(); //建立剛體描述對象     bodyDef.position.set(x/RATE,y/RATE); //設定位置     Body bodyTemp=world.createBody(bodyDef); //在世界中建立剛體     bodyTemp.createShape(shape); //指定剛體形狀     bodyTemp.setMassFromShapes(); //設定物體品質     return new MyCircleColor(bodyTemp, radius, color);   } }

(6)顏色工具類ColorUtil

package box2d.bheap; public class ColorUtil {   static int[][] result=      {       {56,225,254},         {41,246,239},       {34,244,197},       {44,241,161},       {65,239,106},       {45,238,59},       {73,244,51},         {99,233,58},       {129,243,34},       {142,245,44},       {187,243,32},       {232,250,28},       {242,230,46},       {248,196,51},       {244,125,31},       {247,88,46},       {249,70,40},       {249,70,40},       {248,48,48},       {250,30,30},       {252,15,15},       {255,0,0},      };     public static int getColor(int index)     {       int[] rgb=result[index%result.length];       int result=0xff000000;       result=result|(rgb[0]<<16);       result=result|(rgb[1]<<8);       result=result|(rgb[2]);       return result;     } }

(7)主控制類MyBox2dActivity

package box2d.bheap;    import java.util.ArrayList; import java.util.Random; import org.jbox2d.collision.AABB;   import org.jbox2d.common.Vec2;   import org.jbox2d.dynamics.World;    import android.app.Activity;   import android.content.pm.ActivityInfo; import android.os.Bundle;   import android.util.DisplayMetrics; import android.view.Window;   import android.view.WindowManager;  import static box2d.bheap.Constant.*; public class MyBox2dActivity extends Activity  {     AABB worldAABB;//建立 一個管理碰撞的世界     World world;   Random random=new Random();   //物體列表   ArrayList<MyBody> bl=new ArrayList<MyBody>();   public void onCreate(Bundle savedInstanceState)    {       super.onCreate(savedInstanceState);     //設定為全屏     requestWindowFeature(Window.FEATURE_NO_TITLE);       getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,       WindowManager.LayoutParams. FLAG_FULLSCREEN);      //設定為橫屏模式     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);     //擷取螢幕尺寸     DisplayMetrics dm=new DisplayMetrics();     getWindowManager().getDefaultDisplay().getMetrics(dm);      if(dm.widthPixels<dm.heightPixels)     {        SCREEN_WIDTH=dm.widthPixels;        SCREEN_HEIGHT=dm.heightPixels;     }     else     {       SCREEN_WIDTH=dm.heightPixels;       SCREEN_HEIGHT=dm.widthPixels;       }     worldAABB = new AABB();       //上下界,以螢幕的左上方為 原點,如果建立的剛體到達螢幕的邊緣的話,會停止類比       worldAABB.lowerBound.set(-100.0f,-100.0f);     worldAABB.upperBound.set(100.0f, 100.0f);//注意這裡使用的是現實世界的單位       Vec2 gravity = new Vec2(0.0f,10.0f);     boolean doSleep = true;     //建立世界      world = new World(worldAABB, gravity, doSleep);          //建立4邊     final int kd=40;//寬度或高度     MyRectColor mrc=Box2DUtil.createBox(kd/4, SCREEN_HEIGHT/2, kd/4, SCREEN_HEIGHT/2, true,world,0xFFe6e4FF);     bl.add(mrc);     mrc=Box2DUtil.createBox(SCREEN_WIDTH-kd/4, SCREEN_HEIGHT/2, kd/4, SCREEN_HEIGHT/2, true,world,0xFFe6e4FF);     bl.add(mrc);     mrc=Box2DUtil.createBox(SCREEN_WIDTH/2, kd/4, SCREEN_WIDTH/2, kd/4, true,world,0xFFe6e4FF);     bl.add(mrc);     mrc=Box2DUtil.createBox(SCREEN_WIDTH/2, SCREEN_HEIGHT-kd/4, SCREEN_WIDTH/2, kd/4, true,world,0xFFe6e4FF);     bl.add(mrc);     //建立磚塊     //磚塊間距 行間距為20   模組寬度為10 最多一行為9塊     final int bs=20;     final int bw=(int)((SCREEN_WIDTH-2*kd-11*bs)/18);     //============================================================    for(int i=2;i<10;i++)     {       if((i%2)==0)       {         //左側藍木塊         for(int j=0;j<9-i;j++)         {           mrc=Box2DUtil.createBox           (             kd/2+bs+bw/2+i*(kd+5)/2+j*(kd+5)+3,             SCREEN_HEIGHT+bw-i*(bw+kd)/2,             bw/2,             kd/2,             false,             world,             ColorUtil.getColor(Math.abs(random.nextInt()))           );           bl.add(mrc);         }         //右側藍木塊         for(int j=0;j<9-i;j++)         {           mrc=Box2DUtil.createBox           (             3*kd/2+bs-bw/2+i*(kd+5)/2+j*(kd+5)-3,             SCREEN_HEIGHT+bw-i*(bw+kd)/2,             bw/2,             kd/2,             false,             world,             ColorUtil.getColor(Math.abs(random.nextInt()))           );           bl.add(mrc);         }       }         if((i%2)!=0)       {         for(int j=0;j<10-i;j++)         {           mrc=Box2DUtil.createBox           (             kd/2+bs+kd/2+(i-1)*(kd+5)/2+j*(kd+5),             SCREEN_HEIGHT-(kd-bw)/2-(i-1)*(bw+kd)/2,             kd/2,             bw/2,             false,             world,             ColorUtil.getColor(Math.abs(random.nextInt()))           );           bl.add(mrc);         }       }     }     mrc=Box2DUtil.createBox     (       5*kd+bs+20,       SCREEN_HEIGHT-(kd+bw)*4-kd,       bw/2,       kd/2,       false,       world,       ColorUtil.getColor(Math.abs(random.nextInt()))     );     bl.add(mrc);     //建立球     MyCircleColor ball=Box2DUtil.createCircle(SCREEN_WIDTH/2-24, kd, kd/2, world,ColorUtil.getColor(Math.abs(random.nextInt())));     bl.add(ball);     ball.body.setLinearVelocity(new Vec2(0,50));     GameView gv= new GameView(this);    setContentView(gv);  }}

(8)顯示介面類GameView

package box2d.bheap;import android.graphics.Canvas; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; public class GameView extends SurfaceView implements Callback{   MyBox2dActivity activity;   Paint paint;   DrawThread dt;   public GameView(MyBox2dActivity activity) {     super(activity);     this.activity=activity;     this.getHolder().addCallback(this);      paint =new Paint();     paint.setAntiAlias(true);     dt=new DrawThread(this);     dt.start();   }   public void onDraw(Canvas canvas) {     if(canvas==null) {       return ;     }     canvas.drawARGB(255, 255, 255, 255); //設定背景顏色白色     for (MyBody mb : activity.bl) {       mb.drawSelf(canvas, paint);     }   }   @Override   public void surfaceChanged(SurfaceHolder holder, int format, int width,       int height) {   }   @Override   public void surfaceCreated(SurfaceHolder holder) {         repaint();   }   @Override   public void surfaceDestroyed(SurfaceHolder holder) {   }   public void repaint() {     SurfaceHolder holder=this.getHolder();     Canvas canvas=holder.lockCanvas();     try {       synchronized(holder){         onDraw(canvas);       }     } catch(Exception e){       e.printStackTrace();     } finally {       if(canvas!=null) {         holder.unlockCanvasAndPost(canvas);        }     }   } }

(9)繪製線程類DrawThread

package box2d.bheap; import static box2d.bheap.Constant.*; //繪製線程 public class DrawThread extends Thread {   GameView gv;   public DrawThread(GameView gv)   {     this.gv=gv;   }   @Override   public void run()   {     while(DRAW_THREAD_FLAG)     {       gv.activity.world.step(TIME_STEP, ITERA);//開始類比       gv.repaint();       try        {         Thread.sleep(20);       } catch (InterruptedException e)        {         e.printStackTrace();       }     }   } }

希望本文所述對大家的jsp程式設計有所協助。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.