Android游戏开发学习之引擎用法实例详解

本文实例讲述了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程序设计有所帮助。

时间: 2024-10-21 18:16:07

Android游戏开发学习之引擎用法实例详解的相关文章

Android游戏开发学习之引擎用法实例详解_Android

本文实例讲述了Android游戏开发学习之引擎用法.分享给大家供大家参考.具体如下: 汽车引擎是汽车的心脏,其决定了汽车的性能和稳定性,是人们在购车时相当关注的.而游戏中的物理引擎就如汽车的引擎一样,占据了非常重要的位置.一款好的物理引擎可以非常真实地模拟现实世界,使得游戏更加逼真,提供更好的娱乐体验. 一.JBox2D简介 JBox2D是开源物理引擎Box2D的Java版本,可以直接用于Android.由于JBox2D的图形渲染使用的是Processing库,因此在Android平台上使用JB

Android开发之TimePicker控件用法实例详解_Android

本文实例分析了Android开发之TimePicker控件用法.分享给大家供大家参考,具体如下: 新建项目: New Android Project-> Project name:HelloSpinner Build Target:Android 2.2 Application name:HelloSpinner Package name:com.b510 Create Activity:MainActivity Min SDK Version:9 Finish 运行效果: 如果: return

Android中AlertDialog各种对话框的用法实例详解_Android

 目标效果: 程序运行,显示图一的几个按钮,点击按钮分别显示图二到图六的对话框,点击对话框的某一项或者按钮,也会显示相应的吐司输出. 1.activity_main.xml页面存放五个按钮. activity_main.xml页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools

Android开发之TimePicker控件用法实例详解

本文实例分析了Android开发之TimePicker控件用法.分享给大家供大家参考,具体如下: 新建项目: New Android Project-> Project name:HelloSpinner Build Target:Android 2.2 Application name:HelloSpinner Package name:com.b510 Create Activity:MainActivity Min SDK Version:9 Finish 运行效果: 如果: return

Android中AlertDialog各种对话框的用法实例详解

目标效果: 程序运行,显示图一的几个按钮,点击按钮分别显示图二到图六的对话框,点击对话框的某一项或者按钮,也会显示相应的吐司输出. 1.activity_main.xml页面存放五个按钮. activity_main.xml页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&

android模拟器开发和测试nfc应用实例详解_Android

从Android2.3开始支持NFC.不过NFC应用只能在Android手机(或平板电脑)上测试和开发,而且Android手机还必须有NFC芯 片.而且如果测试NFC传输文件时至少需要两部支持NFC的手机.当然,如果测试读写NFC标签,还需要一些NFC标签或帖子.而且NFC在模拟器上时不能运行的.所以从这一点来说,NFC开发需要更多的设备,比较麻烦.这也蓝牙.传感器是一样的.都不能在Android模拟器上开发和测试.真不知道Google为什么不解决这一问题. 不过这种问题也不是不能解决,而且并不

android模拟器开发和测试nfc应用实例详解

从Android2.3开始支持NFC.不过NFC应用只能在Android手机(或平板电脑)上测试和开发,而且Android手机还必须有NFC芯 片.而且如果测试NFC传输文件时至少需要两部支持NFC的手机.当然,如果测试读写NFC标签,还需要一些NFC标签或帖子.而且NFC在模拟器上时不能运行的.所以从这一点来说,NFC开发需要更多的设备,比较麻烦.这也蓝牙.传感器是一样的.都不能在Android模拟器上开发和测试.真不知道Google为什么不解决这一问题. 不过这种问题也不是不能解决,而且并不

Android Dialog对话框用法实例详解_Android

本文实例讲述了Android Dialog对话框用法.分享给大家供大家参考,具体如下: Activities提供了一种方便管理的创建.保存.回复的对话框机制,例如 onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog(int),dismissDialog(int)等方法,如果使用这些方法的话,Activity将通过getOwnerActivity()方法返回该Activity管理的对话框(dialog). 1. onCreat

Android游戏开发学习①弹跳小球实现方法_Android

本文实例讲述了Android游戏开发学习①弹跳小球实现方法.分享给大家供大家参考.具体如下: 在学习了一点点Android之后,觉得有必要记录下来,于是就开了这个新坑,慢慢来填吧. 1.运动体Movable类 本例主要模拟了一组大小不一的球以一定的水平初速度从高处落下的运动轨迹.其中的小球为一个可移动物体Movable对象,该类中除了包含小球图片对象之外,还包括了如位置坐标.水平速度.垂直速度等一系列用于模拟小球运动的成员变量和一些方法. Movable类: package com.ball;