[LIBGDX学习]LibGDX代码详解(二十九)Bullet

该博客详细介绍了如何在LibGDX游戏开发框架中集成并使用Bullet物理引擎。通过初始化Bullet、创建世界、定义环境光源和阴影、加载模型、设置碰撞检测以及实现射击功能,展示了Bullet在游戏场景中的应用。
摘要由CSDN通过智能技术生成
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalShadowLight;
import com.badlogic.gdx.graphics.g3d.loader.ObjLoader;
import com.badlogic.gdx.graphics.g3d.utils.DepthShaderProvider;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.Ray;
import com.badlogic.gdx.physics.bullet.Bullet;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody;
import com.badlogic.gdx.physics.bullet.linearmath.LinearMath;
import com.badlogic.gdx.physics.bullet.linearmath.btIDebugDraw.DebugDrawModes;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;

/** @author xoppa */
public class BaseBulletTest extends BulletTest {
    // Set this to the path of the lib to use it on desktop instead of default lib.
    private final static String customDesktopLib = null;//"D:\\Xoppa\\code\\libgdx\\extensions\\gdx-bullet\\jni\\vs\\gdxBullet\\x64\\Debug\\gdxBullet.dll";

    private static boolean initialized = false;

    public static boolean shadows = true;

    public static void init () {
        if (initialized) return;
        // Need to initialize bullet before using it.
        if (Gdx.app.getType() == ApplicationType.Desktop && customDesktopLib != null) {
            System.load(customDesktopLib);
            System.out.println("customDesktopLib loaded");// 没有执行这个if
        } else{
            Bullet.init();
            System.out.println("Bullet initialised");// 执行的是这个else
        }
        Gdx.app.log("Bullet", "Version = " + LinearMath.btGetVersion());
        initialized = true;
    }

    public Environment environment;
    public DirectionalLight light;
    public ModelBatch shadowBatch;

    public BulletWorld world;
    public ObjLoader objLoader = new ObjLoader();
    public ModelBuilder modelBuilder = new ModelBuilder();
    public ModelBatch modelBatch;
    public Array<Disposable> disposables = new Array<Disposable>();
    private int debugMode = DebugDrawModes.DBG_NoDebug;

    protected final static Vector3 tmpV1 = new Vector3(), tmpV2 = new Vector3();

    public BulletWorld createWorld () {
        return new BulletWorld();
    }

    @Override
    public void create () {
        init();
        environment = new Environment();
        environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 1.f));
        light = shadows ? new DirectionalShadowLight(1024, 1024, 20f, 20f, 1f, 300f) : new DirectionalLight();
        light.set(0.8f, 0.8f, 0.8f, -0.5f, -1f, 0.7f);
        environment.add(light);
        if (shadows)
            environment.shadowMap = (DirectionalShadowLight)light;
        shadowBatch = new ModelBatch(new DepthShaderProvider());

        modelBatch = new ModelBatch();

        world = createWorld();
        world.performanceCounter = performanceCounter;

        final float width = Gdx.graphics.getWidth();
        final float height = Gdx.graphics.getHeight();
        if (width > height)
            camera = new PerspectiveCamera(67f, 3f * width / height, 3f);
        else
            camera = new PerspectiveCamera(67f, 3f, 3f * height / width);
        camera.position.set(10f, 10f, 10f);
        camera.lookAt(0, 0, 0);
        camera.update();

        // Create some simple models
        final Model groundModel = modelBuilder.createRect(
                20f,
                0f,
                -20f,
                -20f,
                0f,
                -20f,
                -20f,
                0f,
                20f,
                20f,
                0f,
                20f,
                0,
                1,
                0,
                new Material(ColorAttribute.createDiffuse(Color.WHITE), ColorAttribute.createSpecular(Color.WHITE), FloatAttribute
                        .createShininess(16f)), Usage.Position | Usage.Normal);
        disposables.add(groundModel);
        final Model boxModel = modelBuilder.createBox(1f, 1f, 1f, new Material(ColorAttribute.createDiffuse(Color.WHITE),
                ColorAttribute.createSpecular(Color.WHITE), FloatAttribute.createShininess(64f)), Usage.Position | Usage.Normal);
        disposables.add(boxModel);

        // Add the constructors
        world.addConstructor("ground", new BulletConstructor(groundModel, 0f)); // mass = 0: static body
        world.addConstructor("box", new BulletConstructor(boxModel, 1f)); // mass = 1kg: dynamic body
        world.addConstructor("staticbox", new BulletConstructor(boxModel, 0f)); // mass = 0: static body
    }

    @Override
    public void dispose () {
        world.dispose();
        world = null;

        for (Disposable disposable : disposables)
            disposable.dispose();
        disposables.clear();

        modelBatch.dispose();
        modelBatch = null;

        shadowBatch.dispose();
        shadowBatch = null;

        if (shadows)
            ((DirectionalShadowLight)light).dispose();
        light = null;

        super.dispose();
    }

    @Override
    public void render () {
        render(true);
    }

    public void render (boolean update) {
        fpsCounter.put(Gdx.graphics.getFramesPerSecond());

        if (update) update();

        beginRender(true);

        renderWorld();

        Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
        if (debugMode != DebugDrawModes.DBG_NoDebug) world.setDebugMode(debugMode);
        Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);

        performance.setLength(0);
        performance.append("FPS: ").append(fpsCounter.value).append(", Bullet: ")
                .append((int)(performanceCounter.load.value * 100f)).append("%");
    }

    protected void beginRender (boolean lighting) {
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight());
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        camera.update();
    }

    protected void renderWorld () {
        if (shadows) {
            ((DirectionalShadowLight)light).begin(Vector3.Zero, camera.direction);
            shadowBatch.begin(((DirectionalShadowLight)light).getCamera());
            world.render(shadowBatch, null);
            shadowBatch.end();
            ((DirectionalShadowLight)light).end();
        }

        modelBatch.begin(camera);
        world.render(modelBatch, environment);
        modelBatch.end();
    }

    public void update () {
        world.update();
    }

    public BulletEntity shoot (final float x, final float y) {
        return shoot(x, y, 30f);
    }

    public BulletEntity shoot (final float x, final float y, final float impulse) {
        return shoot("box", x, y, impulse);
    }

    public BulletEntity shoot (final String what, final float x, final float y, final float impulse) {
        // Shoot a box
        Ray ray = camera.getPickRay(x, y);
        BulletEntity entity = world.add(what, ray.origin.x, ray.origin.y, ray.origin.z);
        entity.setColor(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(),
                1f);
        ((btRigidBody)entity.body).applyCentralImpulse(ray.direction.scl(impulse));
        return entity;
    }

    public void setDebugMode (final int mode) {
        world.setDebugMode(debugMode = mode);
    }

    public void toggleDebugMode () {
        if (world.getDebugMode() == DebugDrawModes.DBG_NoDebug)
            setDebugMode(DebugDrawModes.DBG_DrawWireframe | DebugDrawModes.DBG_DrawFeaturesText | DebugDrawModes.DBG_DrawText | DebugDrawModes.DBG_DrawContactPoints);
        else if (world.renderMeshes)
            world.renderMeshes = false;
        else {
            world.renderMeshes = true;
            setDebugMode(DebugDrawModes.DBG_NoDebug);
        }
    }

    @Override
    public boolean longPress (float x, float y) {
        toggleDebugMode();
        return true;
    }

    @Override
    public boolean keyUp (int keycode) {
        if (keycode == Keys.ENTER) {
            toggleDebugMode();
            return true;
        }
        return super.keyUp(keycode);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值