com.dongbat.invasion.util.PhysicsUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.dongbat.invasion.util.PhysicsUtil.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dongbat.invasion.util;

import com.artemis.Entity;
import com.artemis.managers.GroupManager;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.QueryCallback;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.dongbat.invasion.component.Physics;

/**
 *
 * @author password
 */
public class PhysicsUtil {

    public enum OutOfBound {

        NONE, VERTICAL, HORIZONTAL
    }

    private static World physicsWorld;

    // TODO change to private when moving from Box2D debug to using graphics
    public static World getWorld() {
        if (physicsWorld == null) {
            physicsWorld = new World(new Vector2(0, Constants.PHYSICS.DEFAULT_GRAVITY), false);
        }
        return physicsWorld;
    }

    private static Body getBody(Entity entity) {
        return EntityUtil.getComponent(entity, Physics.class).getBody();
    }

    public static void setPosition(Entity entity, Vector2 position) {
        Body body = getBody(entity);
        body.setTransform(position, body.getAngle());
    }

    public static Vector2 getPosition(Entity entity) {
        return getBody(entity).getPosition();
    }

    public static void setVelocity(Entity entity, Vector2 velocity) {
        getBody(entity).setLinearVelocity(velocity);
    }

    public static Vector2 getVelocity(Entity entity) {
        return getBody(entity).getLinearVelocity();
    }

    public static void applyImpulse(Entity entity, Vector2 impulse) {
        Body body = getBody(entity);
        body.applyLinearImpulse(impulse, body.getWorldCenter(), true);
    }

    public static void applyForce(Entity entity, Vector2 force) {
        Body body = getBody(entity);
        body.applyForce(force, body.getWorldCenter(), true);
    }

    public static void applyImpulseOnEnemy(Entity entity, Vector2 impulse) {
        if (EntityUtil.isEnemy(entity)) {
            float angle = impulse.angle();
            float rotateAngle = angle > 90 ? 180 - angle : -angle;
            Vector2 apply = impulse.rotate(rotateAngle);
            applyImpulse(entity, apply);
        }
    }

    public static void applyForceOnEnemy(Entity entity, Vector2 force) {
        if (EntityUtil.isEnemy(entity)) {
            float angle = force.angle();
            float rotateAngle = angle > 90 ? 180 - angle : -angle;
            Vector2 apply = force.rotate(rotateAngle);
            applyForce(entity, apply);
        }
    }

    public static Entity findNearestEnemy(Vector2 location) {
        ImmutableBag<Entity> allEnemies = ECSUtil.getWorld().getManager(GroupManager.class)
                .getEntities(Constants.ENEMY.GROUP_NAME);
        Entity nearest = null;
        float closestDistanceSq = Float.MAX_VALUE;

        for (Entity enemy : allEnemies) {
            Vector2 position = getBody(enemy).getPosition();
            float distanceSq = new Vector2(position).sub(location).len2();
            if (distanceSq < closestDistanceSq) {
                nearest = enemy;
                closestDistanceSq = distanceSq;
            }
        }

        return nearest;
    }

    public static Array<Entity> findEnemiesInRadius(final Vector2 location, final float radius) {
        final Array<Entity> enemies = new Array<Entity>();

        QueryCallback callback = new QueryCallback() {

            @Override
            public boolean reportFixture(Fixture fixture) {
                Body body = fixture.getBody();
                Entity entity = (Entity) body.getUserData();
                if (EntityUtil.isEnemy(entity)) {
                    float distanceSq = new Vector2(body.getPosition()).sub(location).len2();
                    if (distanceSq <= radius * radius) {
                        enemies.add(entity);
                    }
                }
                return true;
            }
        };
        Vector2 lowerLeft = new Vector2(location).sub(radius, radius);
        Vector2 upperRight = new Vector2(location).add(radius, radius);
        getWorld().QueryAABB(callback, lowerLeft.x, lowerLeft.y, upperRight.x, upperRight.y);

        return enemies;
    }

    public static Body createBody(Vector2 position, float radius) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(position);

        Body body = getWorld().createBody(bodyDef);

        CircleShape circle = new CircleShape();
        circle.setRadius(radius);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circle;
        fixtureDef.density = 1;
        fixtureDef.isSensor = true;
        body.createFixture(fixtureDef);
        circle.dispose();

        return body;
    }

    public static OutOfBound isGoingOutOfBound(Entity entity) {
        Vector2 pos = getBody(entity).getPosition();

        OrthographicCamera camera = PhysicsCameraUtil.getCamera();
        // unproject (0,0) and (WIDTH, HEIGHT)
        Vector3 tl = camera.unproject(new Vector3(0, 0, 0));
        Vector3 br = camera.unproject(new Vector3(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 0));

        if (pos.x <= tl.x || pos.x >= br.x) {
            return OutOfBound.HORIZONTAL;
        }

        if (pos.y <= br.y) {
            return OutOfBound.VERTICAL;
        }

        return OutOfBound.NONE;
    }

    public static float getRadius(Entity e) {
        return EntityUtil.getComponent(e, Physics.class).getRadius();
    }

    public static void removeBody(Body body) {
        getWorld().destroyBody(body);
    }
}