国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android游戲開發學習之引擎用法實例詳解

2020-04-11 11:23:23
字體:
來源:轉載
供稿:網友

本文實例講述了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程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉义县| 兴文县| 偃师市| 周口市| 玉林市| 西吉县| 湄潭县| 松溪县| 东丽区| 鹿邑县| 康马县| 珠海市| 福海县| 宁国市| 龙门县| 靖远县| 嘉鱼县| 郯城县| 黄冈市| 康保县| 广西| 盐亭县| 于都县| 磐石市| 襄垣县| 大姚县| 禹州市| 顺义区| 安陆市| 板桥市| 会昌县| 临高县| 绥阳县| 神池县| 龙南县| 如东县| 保定市| 三台县| 灵石县| 双城市| 松阳县|