LIBGDX学习]LibGDX代码详解(四十二)Bullet 碰撞与接触

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObjectWrapper;
import com.badlogic.gdx.physics.bullet.collision.ContactResultCallback;
import com.badlogic.gdx.physics.bullet.collision.btManifoldPoint;
import com.badlogic.gdx.physics.bullet.collision.btPersistentManifold;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;

/** @author Xoppa */
public class CollisionTest extends ShootTest {
    BulletEntity projectile;// 就是射出去的box
    Array hits = new Array();
    Array contacts = new Array();
    Array colors = new Array();

    public class TestContactResultCallback extends ContactResultCallback {// 这个是测试实时的碰撞?
        @Override
        public float addSingleResult (btManifoldPoint cp, btCollisionObjectWrapper colObj0Wrap, int partId0, int index0,
                                      btCollisionObjectWrapper colObj1Wrap, int partId1, int index1) {

            // 判断0号碰撞对象是不是子弹,不是子弹就添加到hits名单中?
            btCollisionObject other = colObj0Wrap.getCollisionObject() == projectile.body ? colObj1Wrap.getCollisionObject()
                    : colObj0Wrap.getCollisionObject();

            if (other != null && other.userData != null && other.userData instanceof BulletEntity) {
                BulletEntity ent = (BulletEntity)other.userData;// 获取other的entity
                if (ent != ground && !hits.contains(ent, true)) hits.add((BulletEntity)other.userData);
            }
            return 0f;
        }
    }

    TestContactResultCallback contactCB;

    public void updateContactInfo () {
        int n = world.dispatcher.getNumManifolds();// 获取碰撞点?
        for (int i = 0; i < n; i++) {
            btPersistentManifold manifold = world.dispatcher.getManifoldByIndexInternal(i);
            btCollisionObject objA = manifold.getBody0();
            btCollisionObject objB = manifold.getBody1();
            if (objA != ground.body && objB != ground.body) {
                if (objA.userData != null && objA.userData instanceof BulletEntity) {
                    BulletEntity ent = (BulletEntity)objA.userData;
                    // 如果不是发射出去的箱子?
                    // 新发射一个箱子,projectile就变成新箱子。
                    if (ent != projectile && !contacts.contains(ent, true) && !hits.contains(ent, true)) contacts.add(ent);//contacts添加一个箱子
                }
                if (objB.userData != null && objB.userData instanceof BulletEntity) {
                    BulletEntity ent = (BulletEntity)objB.userData;
                    if (ent != projectile && !contacts.contains(ent, true) && !hits.contains(ent, true)) contacts.add(ent);
                }
            }
        }
    }

    @Override
    public void create () {
        super.create();

        contactCB = new TestContactResultCallback();
    }

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

    // Pool容量16?
    private Pool colorPool = new Pool() {
        @Override
        protected Color newObject () {
            return new Color();
        }
    };

    public void process () {
        Color color = null;
        update();
        hits.clear();
        contacts.clear();

        // Note that this might miss collisions, use InternalTickCallback to check for collision on every tick.
        // See InternalTickTest on how to implement it.

        // Check what the projectile hits
        if (projectile != null) {// 发射的箱子红色
            color = projectile.getColor();
            projectile.setColor(Color.RED);
            world.collisionWorld.contactTest(projectile.body, contactCB);
        }
        // Check for other collisions
        updateContactInfo();

        if (hits.size > 0) {// 打中的变成红色?
            for (int i = 0; i < hits.size; i++) {

                // 注意colors是Array而不是color
                colors.add(colorPool.obtain().set(hits.get(i).getColor()));

                hits.get(i).setColor(Color.RED);
            }
        }
/*        System.out.println("contacts: "+contacts.size);
        System.out.println("hits: "+hits.size);*/
        if (contacts.size > 0) {
            for (int i = 0; i < contacts.size; i++) {
                colors.add(colorPool.obtain().set(contacts.get(i).getColor()));
                contacts.get(i).setColor(Color.BLUE);
            }
        }
        render(false);
        if (projectile != null) projectile.setColor(color);
        for (int i = 0; i < hits.size; i++)
            hits.get(i).setColor(colors.get(i));
        for (int i = 0; i < contacts.size; i++)
            contacts.get(i).setColor(colors.get(hits.size + i));
        colorPool.freeAll(colors);
        colors.clear();
    }

    @Override
    public boolean tap (float x, float y, int count, int button) {
        projectile = shoot(x, y);
        return true;
    }

    @Override
    public void dispose () {
        super.dispose();
        projectile = null;
    }
}

你可能感兴趣的:(libgdx)