`

android 游戏学习(jbox2d)

阅读更多

导入jbox2d-2.0.1-library-only.jar

/**
* 矩形对象
*
* @time 上午11:17:09
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MyRect {
private float x, y, w, h, angle;


public MyRect(float x, float y, float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}


public void drawRect(Canvas canvas, Paint paint) {
canvas.save();
canvas.rotate(angle, x + w / 2, y + h / 2);
canvas.drawRect(x, y, x + w, y + h, paint);
canvas.restore();
}


public void setX(float x) {
this.x = x;
}


public void setY(float y) {
this.y = y;
}


public void setAngle(float angle) {
this.angle = angle;
}


public float getWidth() {
return w;
}


public float getHeight() {
return h;
}
}

 

 

/**
* 砖块
*
* @time 上午11:17:44
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MyTitle {


private float x, y,//
w, h,//
angle;//
private Bitmap bg;


public MyTitle(float x, float y, float w, float h, Bitmap bg) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.bg = bg;
}


public float getX() {
return x;
}


public void setX(float x) {
this.x = x;
}


public float getY() {
return y;
}


public void setY(float y) {
this.y = y;
}


public void setWidth(float w) {
this.w = w;
}


public void setHeight(float h) {
this.h = h;
}


public float getWidth() {
return w;
}


public float getHeight() {
return h;
}


public void setAngle(float angle) {
this.angle = angle;
}


/**
* 绘制砖块
*/
public void draw(Canvas canvas, Paint paint) {
canvas.save();
canvas.rotate(angle, x + w / 2, y + h / 2);
canvas.drawBitmap(bg, x, y, paint);


canvas.restore();
}


}

 

 

/**
* 游戏主界面
*
* @time 上午11:18:15
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
@SuppressWarnings("unused")
public class BuildHourseSurfaceView extends SurfaceView implements Callback, Runnable {
private Random random;// 随机图片
private static final float RATE = 30;
private Thread thread;
private Paint paint;
private SurfaceHolder sfh;
private int screenW, screenH;
private boolean flag;
private Canvas canvas;


// 图片
private Bitmap bmp_bg,// 背景图片
bmp_title1, bmp_title2, bmp_title3;// 砖块


// 创建物理世界
private float timeStep = 1f / 10f;
private AABB aabb;
private World world;
private Vec2 gravity;
private int iterations;


// 固定body
private Body bodyWall;
// 固定body的坐标与高宽
private int bodyWallX, bodyWallY,// 坐标
bodyWallW, bodyWallH;// 高宽
// 砖块
private Body bodyHouse;


// 临时body记录上一次绑定在距离关节上的body
private Body tempBody;
// 距离关节
private DistanceJoint dj;
// ---线条的颜色值
private int[] lineColor = { 0xFFDACDC5, 0xFF825B56, 0xFF3A3E59 };


private int temp;
private boolean isDeleteJoint;
private boolean isDown;
private int isDownCount;


/**
* 构造函数
*
* @param context
*/
public BuildHourseSurfaceView(Context context) {
super(context);


screenW = this.getWidth();
screenH = this.getHeight();


paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);


sfh = this.getHolder();
sfh.addCallback(this);


this.setFocusable(true);
this.setKeepScreenOn(true);
this.setFocusableInTouchMode(true);


// 创建物理世界
aabb = new AABB();// 设置物理世界的范围
aabb.lowerBound.set(-100, -100);// 设置左上角坐标
aabb.upperBound.set(100, 100);// 设置右下角坐标
gravity = new Vec2(0f, 10f);// 设置重力向量
world = new World(aabb, gravity, true);// 创建物理世界对象


// 设置背景图
bmp_bg = BitmapFactory.decodeResource(this.getResources(), R.drawable.background);
// 实例化砖块
bmp_title1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile1);
bmp_title2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile2);
bmp_title3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.tile3);


}


@Override
public void surfaceCreated(SurfaceHolder holder) {


bodyWallW = 40;
bodyWallH = 2; // 固定关节的大小
bodyWallX = getWidth() / 2 - bodyWallW / 2;
bodyWallY = 1; // 固定关节的起始坐标


// 实例化两个绑定距离关节的 body
bodyWall = createPolygon(bodyWallX, bodyWallY, bodyWallW, bodyWallH, 0, true);
bodyHouse = createMyTitle(bodyWallX / 2, bodyWallY + bodyWallH + 50, bmp_title1.getWidth(), bmp_title1.getHeight(), 0, false);


// 创建临时body
tempBody = bodyHouse;


// 添加一个静态的下边界
createPolygon(0, getHeight(), getWidth() - 10, 10, 0, true);


// 添加一个距离关节
dj = createDistanceJoint(bodyWall, bodyHouse);


//
flag = true;
thread = new Thread(this);
thread.start();
}


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {


}


@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false;
}


/**
* 创建距离关节
*
* @param body1
* @param body2
* @return
*/
public DistanceJoint createDistanceJoint(Body body1, Body body2) {
// 创建距离关节信息
DistanceJointDef def = new DistanceJointDef();
def.body1 = body1;
def.body2 = body2;
// 初始化距 离信息
def.initialize(body1, body2, body1.getWorldCenter(), body2.getWorldCenter());
DistanceJoint distanceJoint = (DistanceJoint) world.createJoint(def);
return distanceJoint;


}


/**
* 创建砖块
*
* @param x
* @param y
* @param w
* @param h
* @param angle
* @param isStation
* @return
*/
private Body createMyTitle(float x, float y, float w, float h, float angle, boolean isStation) {
// 创建一个皮肤
PolygonDef polygonDef = new PolygonDef();
if (isStation) {
polygonDef.density = 0;// 设置矩形为静态
} else {
polygonDef.density = 1;// 设置矩形的质量
}


polygonDef.friction = 0.8f;// 摩擦力
polygonDef.restitution = 0.3f;// 恢复力
// 快捷成盒子
polygonDef.setAsBox(w / 2 / RATE, h / 2 / RATE);
polygonDef.filter.groupIndex = 2;
// 创建一个刚体
BodyDef def = new BodyDef();
// 设置刚体的坐标
def.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);
// 设置角度
def.angle = (float) (angle * Math.PI / 180);
def.angle = (float) (angle * Math.PI / 180);
random = new Random();
temp = random.nextInt(3);//
// 随机取背景图片
switch (temp) {
case 0:
bmp_bg = bmp_title1;
break;
case 1:
bmp_bg = bmp_title2;
break;
case 2:
bmp_bg = bmp_title3;
break;


}
Body body = world.createBody(def);// 创建一个物体
body.m_userData = new MyTitle(x, y, w, h, bmp_bg);
// 设置皮肤
body.createShape(polygonDef);
// 整个物体计算打包
body.setMassFromShapes();
return body;


}


/**
* 创建固定body
*
* @param x
* @param y
* 坐标
* @param w
* @param h
* 高宽
* @param angle
* 角度
* @param isStation
* 是否为静态
* @return
*/
private Body createPolygon(float x, float y, float w, float h, float angle, boolean isStation) {
// 创建皮肤
PolygonDef polygonDef = new PolygonDef();
if (isStation) {
polygonDef.density = 0;// 设置矩形为静态
} else {
polygonDef.density = 1;// 设置矩形质量
}
// 设置摩擦力
polygonDef.friction = 0.8f;
// 设置恢复力
polygonDef.restitution = 0.3f;
// 快捷成盒子
polygonDef.setAsBox(w / 2 / RATE, h / 2 / RATE);
// 创建一个刚体
BodyDef def = new BodyDef();
def.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);// 设置刚体的坐标
def.angle = (float) (angle * 180 / Math.PI);// 设置角度
Body body = world.createBody(def);
body.m_userData = new MyRect(x, y, w, h);
body.createShape(polygonDef);// 设置皮肤
body.setMassFromShapes();// 整个物体打包
return body;


}


/**
* 绘制方法
*/
private void draw() {
try {
canvas = sfh.lockCanvas();
if (null != canvas) {
canvas.drawColor(Color.BLACK);
// 绘制游戏的背景图
canvas.drawBitmap(bmp_bg, 0, -Math.abs((float) (getHeight() - bmp_bg.getHeight())), paint);


// 遍历body
Body body = world.getBodyList();
for (int i = 1; i < world.getBodyCount(); i++) {
if ((body.m_userData) instanceof MyRect) {
MyRect myRect = (MyRect) (body.m_userData);
myRect.drawRect(canvas, paint);
} else if ((body.m_userData) instanceof MyTitle) {
MyTitle myTitle = (MyTitle) (body.m_userData);
myTitle.draw(canvas, paint);
}
body = body.m_next;
}
if (null != bodyWall && null != bodyHouse) {
if (null != dj) {
// 设置画笔颜色
paint.setColor(lineColor[temp]);
// 设置画笔粗细
paint.setStrokeWidth(3);
// 绘制关节
canvas.drawLine(bodyWall.getPosition().x * RATE, bodyWall.getPosition().y * RATE, tempBody.getPosition().x * RATE, tempBody.getPosition().y * RATE, paint);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != canvas) {
sfh.unlockCanvasAndPost(canvas);
}
}


}


/**
* 游戏逻辑
*/
private void logic() {
// 运行物理世界
world.step(timeStep, iterations);


// 遍历body
Body body = world.getBodyList();
for (int i = 1; i < world.getBodyCount(); i++) {
if ((body.m_userData) instanceof MyRect) {
MyRect myRect = (MyRect) (body.m_userData);
// 更新坐标和角度
myRect.setX(body.getPosition().x * RATE - myRect.getWidth() / 2);
myRect.setY(body.getPosition().y * RATE - myRect.getHeight() / 2);
myRect.setAngle((float) (body.getAngle() * 180 / Math.PI));


} else if ((body.m_userData) instanceof MyTitle) {
MyTitle myTitle = (MyTitle) (body.m_userData);
// 更新坐标和角度
myTitle.setX(body.getPosition().x * RATE - myTitle.getWidth() / 2);
myTitle.setY(body.getPosition().y * RATE - myTitle.getHeight() / 2);
myTitle.setAngle((float) (body.getAngle() * 180 / Math.PI));
}
body = body.m_next;
}
if (isDeleteJoint) {
world.destroyJoint(dj);// 销毁关节
dj = null;
isDeleteJoint = false;
}
// 动态Body是否下落
if (isDown == true) {
// 计时器计时
isDownCount++;
// 计时器时间
if (isDownCount % 120 == 0) {
// 创建新的动态Body-砖块,并且使用临时Body保存最新动态Body
tempBody = createMyTitle(bodyWallX / 2, bodyWallY + bodyWallH + 50, bmp_title1.getWidth(), bmp_title1.getHeight(), 0, false);
// 创建新的距离关节
dj = createDistanceJoint(bodyWall, tempBody);
// 计时器重置
isDownCount = 0;
// 下落标识重置
isDown = false;
}
}


}


@SuppressWarnings("static-access")
@Override
public void run() {
while (flag) {
draw();
logic();
try {
thread.sleep((long) timeStep * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}


}


/**
* 重写触屏方法
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isDown == false) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 删除关节
isDeleteJoint = true;
// 动态body下落
isDown = true;


}
}


return true;
}


}

 

/**
* 建房子主界面
*
* @time 上午11:18:56
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// setContentView(R.layout.main);
setContentView(new BuildHourseSurfaceView(this));
}
}

分享到:
评论

相关推荐

    android 游戏引擎 jbox2d 物理引擎

    《Android游戏开发:深入理解JBox2D物理引擎》 在Android游戏开发中,物理引擎是构建逼真、动态游戏场景的关键技术之一。JBox2D作为一款基于Java的开源物理引擎,为开发者提供了强大的2D物理模拟功能,使得游戏中的...

    安卓Android源码——基于JBox2D的安卓Android游戏开发全源码.zip

    本资源是关于使用JBox2D库进行安卓Android游戏开发的完整源码,这为我们提供了一个深入理解安卓游戏编程的实践案例。JBox2D是一个基于Java的物理引擎,它是Box2D的Java版本,Box2D是广泛应用于2D物理模拟的开源库,...

    jbox2d 2.1.2 游戏世界实例 android

    《jBox2D 2.1.2:构建Android游戏世界的探索之旅》 jBox2D,一个基于Java实现的Box2D物理引擎的版本,是游戏开发领域中不可或缺的工具,尤其对于2D游戏来说,它能为游戏提供真实且动态的物理效果。在本文中,我们将...

    android 2D 引擎(jbox2d) 游戏源码(注释详细)

    对于想要学习Android游戏开发,尤其是物理效果实现的开发者来说,jBox2D是一个理想的起点。 首先,BallGame游戏的核心在于jBox2D的物理世界设置。在源码中,你会看到如何初始化一个`World`对象,这是所有物理模拟的...

    Android 基于JBox2D的Android游戏开发全源码-IT计算机-毕业设计.zip

    《基于JBox2D的Android游戏开发全源码》是一个非常适合Android开发初学者以及毕业设计项目的实践案例。这个源码库包含了一款Android游戏的完整实现,它利用了JBox2D物理引擎来创建真实感的游戏环境。在这里,我们将...

    基于JBox2D的Android游戏开发全源码.zip

    总之,这个基于JBox2D的Android游戏开发全源码是一个宝贵的教育资源,可以帮助你深入理解2D物理引擎在实际项目中的应用,以及Android游戏开发的各个方面,包括图形渲染、用户交互、物理模拟和性能优化。通过分析和...

    JBox2D引擎Android版

    由JBox2D 2.1.2 版本(目前官方最新版)源码修改而来,专门适合android平台使用,效率更高!

    android基于开源游戏引擎jbox2d开发的高仿愤怒的小鸟游戏源码.rar

    《基于JBox2D的Android高仿愤怒的小鸟游戏源码解析》 愤怒的小鸟作为一款全球热门的游戏,其简洁的操作、丰富的关卡设计和趣味的物理效果吸引了无数玩家。在Android平台上,开发者们常常利用开源游戏引擎进行游戏...

    Android-使用jbox2d物理引擎打造摩拜单车贴纸动画效果

    jBox2D是基于Box2D的一个Java实现,广泛应用于2D物理模拟,特别适合游戏开发和动态视觉元素的构建。 首先,我们需要了解jBox2D的基本概念。jBox2D提供了一个二维物理世界的模拟环境,包括刚体(rigid bodies)、...

    android webview jbox2d 源代码 项目源码

    在这个项目源码中,你可以学习到如何在Android上集成Webview与JBox2D,以及如何利用它们构建一个交互式的物理模拟应用。通过对源代码的深入研究,可以掌握这两项技术的结合使用,为你的Android开发带来更多的可能性...

    Android游戏 jbox2d源码及jar包

    总的来说,"Android游戏 jbox2d源码及jar包"为开发者提供了一个深入研究2D物理引擎的平台,通过学习和实践,开发者可以创建出更为逼真的Android游戏,提升游戏的趣味性和沉浸感。在实际开发中,结合源码理解和调试,...

    jbox2D源码及在android中的应用

    《jBox2D源码解析及其在Android平台的应用》 jBox2D是一个基于Java语言的物理模拟库,它是Box2D的Java版本,而Box...对于想要深入学习2D物理引擎开发或提升游戏品质的开发者来说,jBox2D是一个值得研究和掌握的工具。

    jbox2d demo for android

    jbox2d 自己写的demo for android,可以用于参考学习jbox2d

    Android应用源码之JBox2D-src_应用.zip

    JBox2D保留了Box2D的核心特性,如刚体动力学、碰撞检测、关节、形状创建等,同时与Java语言特性无缝集成,适合在Android平台上进行2D游戏开发。 二、源码结构分析 在"Android应用源码之JBox2D-src"中,我们可以看到...

    JBox2D文档DOC

    JBox2D文档JBox2D文档JBox2D文档JBox2D文档JBox2D文档JBox2D文档

    Android应用源码之基于JBox2D的Android游戏开发全源码-IT计算机-毕业设计.zip

    《Android应用源码之基于JBox2D的Android游戏开发全源码》是一个适用于毕业设计学习的项目,它深入展示了如何在Android平台上构建一款游戏,特别是利用了JBox2D库进行物理模拟。JBox2D是Java版的Box2D物理引擎,广泛...

    JBox2D详解

    由于JBox2D的图形渲染使用的是Processing库,因此在Android平台上使用JBox2D时,图形渲染工作只能自行开发。该引擎能够根据开发人员设定的参数,如重力、密度、摩擦系数和弹性系数等,自动地进行2D刚体物理运动的全...

    Android游戏源码基于jbox2d的割绳子游戏源码

    割绳子(Cut the Rope)是一款备受欢迎的手机游戏,其Android版本的源码使用了jBox2D库,这是一个基于Box2D物理引擎的Java实现。Box2D是广泛应用于2D物理模拟的开源库,它使得开发者可以轻松创建具有真实感的动态...

    jbox2d完整例子

    《Jbox2d完整例子解析:游戏引擎与类设计思路》 ...通过学习和分析这个例子,开发者不仅能掌握Jbox2d的基本用法,还能理解游戏开发中的关键设计思想,这对于进一步开发自己的游戏项目具有重要的指导意义。

    Android移植Jbox2D testbed

    本项目是移植java版 jbox2d 测试项目到android平台上的完整源码,我实现了其中四个比较典型的例子,其他的暂时没做。 大家可以通过此案例掌握 box2d DebugDraw 用法 及box2d 各种入门提高

Global site tag (gtag.js) - Google Analytics