Java tutorial
/* * 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); } }