Android游戲引擎libgdx使用教程9:libgdx中Box2d的用法
在游戲開發(fā)中難免會(huì)需要模擬現(xiàn)實(shí)情況,一般常見的就是模擬物理世界。
比如物體碰撞,車輛前進(jìn),物體下落等。也許有人會(huì)覺得原來有實(shí)現(xiàn)過一些效果沒有看到用什么物理知識(shí)呢。
在我看來引入物理引擎并不是必須的,但是這樣可以讓游戲更逼真。物理引擎的話首選Box2d,但是它是C++寫的,直接用不方便。
在Android游戲開發(fā)中使用物理引擎一般有三個(gè)比較好的選擇:
1.JBox2d
Box2d的Java移植版本,速度有點(diǎn)慢。不過對(duì)于不熟悉C++的朋友而言這個(gè)可以拿來看看原理。
2.Havok
這個(gè)就不多說了,我怎么沒有用過。
3.Libgdx
libgdx用了jni封裝了box2d,速度和易用性都不錯(cuò)。
下面我們來看看一個(gè)示例,原來沒有接觸過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; // 測(cè)試用繪制器
- 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); // 一般標(biāo)準(zhǔn)重力場(chǎng)
- BodyDef bd = new BodyDef(); //聲明物體定義
- bd.position.set(2f, 2f);
- bd.type=BodyType.DynamicBody;
- Body b = world.createBody(bd); //通過world創(chuàng)建一個(gè)物體
- CircleShape c = new CircleShape(); //創(chuàng)建一個(gè)形狀(圓)
- c.setRadius(1f); //設(shè)置半徑
- 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
- }
- }
我們先創(chuàng)建了一個(gè)世界,重力為9.8,方向朝下。
然后聲明了一個(gè)物體定義,物體為動(dòng)態(tài)物體(就是可以動(dòng)那種),如果創(chuàng)建一個(gè)圓形,將形狀賦給物體。
然后調(diào)用進(jìn)行模擬
world.step(Gdx.app.getGraphics().getDeltaTime(),3,3);
效果如下:
其實(shí)用法什么沒有大的區(qū)別。libgdx并沒有AABB那個(gè)類,要這只邊界的話用
world.QueryAABB(callback,lowerX,lowerY,upperX,upperY)
就行了。
形狀的話其實(shí)有很多,圓形,方形,矩形,多邊形,可以具體參考Box2d的幫助文件。
有人覺得使用box2d很復(fù)雜,很難和現(xiàn)有的東西聯(lián)系起來。其實(shí)我覺得box2d用著很方便,特別是和Stage聯(lián)系起來很方便。
用Body.setUserData(userData)
將Actor的名字賦給Body,然后在繪制時(shí)用
Stage.findActor(name)
改變actor的位置和狀體就行了。
寫在最后:
這里想說幾個(gè)問題:
1.Box2d是一個(gè)物理引擎,不是一個(gè)游戲引擎。它模擬物理世界和法則,但是你的圖像繪制什么的都是自己處理。
2.Box2d的單位是米,秒。注意單位換算,不推薦直接用1像素=1米,這樣有些東西會(huì)很奇怪的,比例看情況,用個(gè)30,,50就行了。
3.Stage的坐標(biāo)是左下角,Box2d一般是重心,注意變化。
4.調(diào)試的時(shí)候可以用Box2DDebugRenderer,可以清楚看到邊界和重心。