- 浏览: 260830 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (303)
- c (31)
- c++ (16)
- java (18)
- c# (1)
- python (3)
- java web (6)
- oracle (7)
- sqlserver (2)
- mysql (2)
- android (24)
- android系统 (15)
- android多媒体部分 (15)
- android游戏 (12)
- linux (26)
- javaScript (1)
- ajax (1)
- node JS (2)
- html (5)
- apache (3)
- jboss (1)
- weblogic (0)
- 通信协议 (10)
- 云计算 (1)
- 分布式 (5)
- ejb (1)
- webservice (5)
- 设计模式 (16)
- JNI (6)
- swing (13)
- 版本控制 (1)
- UML (1)
- xml (4)
- spring (5)
- hibernate (5)
- struts1 (3)
- struts2 (4)
- ibatis (0)
- tomcat (2)
- 心得体会 (1)
- css (1)
- 嵌入式 (41)
- arm体系结构 (10)
导入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游戏开发学习笔记一(学习书籍 Android游戏编程之从零开始)
2012-09-05 11:52 673/** * 一个简单的游戏框架 * 没有按键处理,声音 ... -
android游戏开发学习笔记二(学习书籍 Android游戏编程之从零开始)
2012-09-05 11:54 639/** * 画布 * * @author 岳 ... -
android游戏开发学习笔记三(学习书籍 Android游戏编程之从零开始)
2012-09-05 11:55 705/** * 画笔 * * @author 岳 ... -
android游戏开发学习笔记四(学习书籍 Android游戏编程之从零开始)
2012-09-05 11:57 634/** * 位图 * * @author 岳振华 * ... -
android游戏开发学习笔记五(学习书籍 Android游戏编程之从零开始)
2012-09-05 12:01 546/** * 剪切动画+移动位图 * * @author ... -
android游戏开发学习笔记六(学习书籍 Android游戏编程之从零开始)
2012-09-07 10:37 725/** * 位图 * * @author 岳振华 * ... -
android游戏开发学习笔之七 (学习书籍 Android游戏编程之从零开始)
2012-09-07 10:39 805/** * 可视区域 * * @time 上午10:42 ... -
android游戏开发学习笔之八 (学习书籍 Android游戏编程之从零开始)
2012-09-09 11:23 735/** * 操作游戏中的人物 * * @time 上午1 ... -
android游戏开发学习笔之九 (学习书籍 Android游戏编程之从零开始)
2012-09-09 11:25 686/** * 矩形碰撞 * * @time 上午11:29 ... -
android jbox2d学习笔记一 滑轮关节
2012-09-13 12:45 803/** * 滑轮关节 * * @time 下午12:49 ... -
andriod jbox2d学习笔记二 通过移动关节移动body
2012-09-13 12:47 814/** * 通过移动关节移动body * * @time ...
相关推荐
《Android游戏开发:深入理解JBox2D物理引擎》 在Android游戏开发中,物理引擎是构建逼真、动态游戏场景的关键技术之一。JBox2D作为一款基于Java的开源物理引擎,为开发者提供了强大的2D物理模拟功能,使得游戏中的...
本资源是关于使用JBox2D库进行安卓Android游戏开发的完整源码,这为我们提供了一个深入理解安卓游戏编程的实践案例。JBox2D是一个基于Java的物理引擎,它是Box2D的Java版本,Box2D是广泛应用于2D物理模拟的开源库,...
《jBox2D 2.1.2:构建Android游戏世界的探索之旅》 jBox2D,一个基于Java实现的Box2D物理引擎的版本,是游戏开发领域中不可或缺的工具,尤其对于2D游戏来说,它能为游戏提供真实且动态的物理效果。在本文中,我们将...
对于想要学习Android游戏开发,尤其是物理效果实现的开发者来说,jBox2D是一个理想的起点。 首先,BallGame游戏的核心在于jBox2D的物理世界设置。在源码中,你会看到如何初始化一个`World`对象,这是所有物理模拟的...
《基于JBox2D的Android游戏开发全源码》是一个非常适合Android开发初学者以及毕业设计项目的实践案例。这个源码库包含了一款Android游戏的完整实现,它利用了JBox2D物理引擎来创建真实感的游戏环境。在这里,我们将...
总之,这个基于JBox2D的Android游戏开发全源码是一个宝贵的教育资源,可以帮助你深入理解2D物理引擎在实际项目中的应用,以及Android游戏开发的各个方面,包括图形渲染、用户交互、物理模拟和性能优化。通过分析和...
由JBox2D 2.1.2 版本(目前官方最新版)源码修改而来,专门适合android平台使用,效率更高!
《基于JBox2D的Android高仿愤怒的小鸟游戏源码解析》 愤怒的小鸟作为一款全球热门的游戏,其简洁的操作、丰富的关卡设计和趣味的物理效果吸引了无数玩家。在Android平台上,开发者们常常利用开源游戏引擎进行游戏...
jBox2D是基于Box2D的一个Java实现,广泛应用于2D物理模拟,特别适合游戏开发和动态视觉元素的构建。 首先,我们需要了解jBox2D的基本概念。jBox2D提供了一个二维物理世界的模拟环境,包括刚体(rigid bodies)、...
在这个项目源码中,你可以学习到如何在Android上集成Webview与JBox2D,以及如何利用它们构建一个交互式的物理模拟应用。通过对源代码的深入研究,可以掌握这两项技术的结合使用,为你的Android开发带来更多的可能性...
总的来说,"Android游戏 jbox2d源码及jar包"为开发者提供了一个深入研究2D物理引擎的平台,通过学习和实践,开发者可以创建出更为逼真的Android游戏,提升游戏的趣味性和沉浸感。在实际开发中,结合源码理解和调试,...
《jBox2D源码解析及其在Android平台的应用》 jBox2D是一个基于Java语言的物理模拟库,它是Box2D的Java版本,而Box...对于想要深入学习2D物理引擎开发或提升游戏品质的开发者来说,jBox2D是一个值得研究和掌握的工具。
jbox2d 自己写的demo for android,可以用于参考学习jbox2d
JBox2D保留了Box2D的核心特性,如刚体动力学、碰撞检测、关节、形状创建等,同时与Java语言特性无缝集成,适合在Android平台上进行2D游戏开发。 二、源码结构分析 在"Android应用源码之JBox2D-src"中,我们可以看到...
JBox2D文档JBox2D文档JBox2D文档JBox2D文档JBox2D文档JBox2D文档
《Android应用源码之基于JBox2D的Android游戏开发全源码》是一个适用于毕业设计学习的项目,它深入展示了如何在Android平台上构建一款游戏,特别是利用了JBox2D库进行物理模拟。JBox2D是Java版的Box2D物理引擎,广泛...
由于JBox2D的图形渲染使用的是Processing库,因此在Android平台上使用JBox2D时,图形渲染工作只能自行开发。该引擎能够根据开发人员设定的参数,如重力、密度、摩擦系数和弹性系数等,自动地进行2D刚体物理运动的全...
割绳子(Cut the Rope)是一款备受欢迎的手机游戏,其Android版本的源码使用了jBox2D库,这是一个基于Box2D物理引擎的Java实现。Box2D是广泛应用于2D物理模拟的开源库,它使得开发者可以轻松创建具有真实感的动态...
《Jbox2d完整例子解析:游戏引擎与类设计思路》 ...通过学习和分析这个例子,开发者不仅能掌握Jbox2d的基本用法,还能理解游戏开发中的关键设计思想,这对于进一步开发自己的游戏项目具有重要的指导意义。
本项目是移植java版 jbox2d 测试项目到android平台上的完整源码,我实现了其中四个比较典型的例子,其他的暂时没做。 大家可以通过此案例掌握 box2d DebugDraw 用法 及box2d 各种入门提高