Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1078968
  • 博文数量: 403
  • 博客积分: 10272
  • 博客等级: 上将
  • 技术积分: 4407
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 14:22
文章分类

全部博文(403)

文章存档

2012年(403)

分类: 嵌入式

2012-03-05 13:28:17

在游戏开发中难免会需要模拟现实情况,一般常见的就是模拟物理世界。

比如物体碰撞,车辆前进,物体下落等。也许有人会觉得原来有实现过一些效果没有看到用什么物理知识呢。

在我看来引入物理引擎并不是必须的,但是这样可以让游戏更逼真。物理引擎的话首选Box2d,但是它是C++写的,直接用不方便。

在Android游戏开发中使用物理引擎一般有三个比较好的选择:

1.JBox2d

Box2d的Java移植版本,速度有点慢。不过对于不熟悉C++的朋友而言这个可以拿来看看原理。

2.Havok

这个就不多说了,我怎么没有用过。

3.Libgdx

libgdx用了jni封装了box2d,速度和易用性都不错。

下面我们来看看一个示例,原来没有接触过box2d的朋友最好先找资料看看。

代码如下:

package com.cnblogs.htynkn.listener;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class DemoGame implements ApplicationListener {

protected OrthographicCamera camera;
protected Box2DDebugRenderer renderer; // 测试用绘制器
private World world;

@Override
public void create() {
camera = new OrthographicCamera(48, 32);
camera.position.set(0, 15, 0);
renderer = new Box2DDebugRenderer();

world = new World(new Vector2(0, -9.8f), true); // 一般标准重力场
BodyDef bd = new BodyDef(); //声明物体定义
bd.position.set(2f, 2f);
bd.type=BodyType.DynamicBody;
Body b = world.createBody(bd); //通过world创建一个物体
CircleShape c = new CircleShape(); //创建一个形状(圆)
c.setRadius(1f); //设置半径
b.createFixture(c, 1f); //将形状和密度赋给物体
}

@Override
public void dispose() {

renderer.dispose();
world.dispose();

renderer = null;
world = null;
}

@Override
public void pause() {
// TODO Auto-generated method stub

}

@Override
public void render() {
world.step(Gdx.app.getGraphics().getDeltaTime(), 3, 3);
GL10 gl = Gdx.app.getGraphics().getGL10();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
camera.apply(gl);
renderer.render(world, camera.combined);
}

@Override
public void resize(int width, int height) {
// TODO Auto-generated method stub

}

@Override
public void resume() {
// TODO Auto-generated method stub

}

}



我们先创建了一个世界,重力为9.8,方向朝下。

然后声明了一个物体定义,物体为动态物体(就是可以动那种),如果创建一个圆形,将形状赋给物体。

然后调用进行模拟

world.step(Gdx.app.getGraphics().getDeltaTime(), 3, 3);

效果如下:

box2d

其实用法什么没有大的区别。libgdx并没有AABB那个类,要这只边界的话用

world.QueryAABB(callback, lowerX, lowerY, upperX, upperY)

就行了。

形状的话其实有很多,圆形,方形,矩形,多边形,可以具体参考Box2d的帮助文件。

有人觉得使用box2d很复杂,很难和现有的东西联系起来。其实我觉得box2d用着很方便,特别是和Stage联系起来很方便。

Body.setUserData(userData)

将Actor的名字赋给Body,然后在绘制时用

Stage.findActor(name)

改变actor的位置和状体就行了。

写在最后:

这里想说几个问题:

1.Box2d是一个物理引擎,不是一个游戏引擎。它模拟物理世界和法则,但是你的图像绘制什么的都是自己处理。

2.Box2d的单位是米,秒。注意单位换算,不推荐直接用1像素=1米,这样有些东西会很奇怪的,比例看情况,用个30,,50就行了。

3.Stage的坐标是左下角,Box2d一般是重心,注意变化。

4.调试的时候可以用Box2DDebugRenderer,可以清楚看到边界和重心。

阅读(2192) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

wwlhzxxx2014-10-19 16:11:13

你好,你的关于libgdx的系列博文,写的很精彩,我从中受益良多。

我是个libgdx的新手,很多概念还不是特别清楚,比如说:box2d 中body 与 libgdx中的actor,stage的关系,

如何使二战配合起来使用。

另外,如果在正式版本中,如果不使用Box2DDebugRenderer的话,应该如何渲染body,world.?

方便的话,希望能看到您关于这方面的大作。