package manakeri.Zombicalypse; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g3d.decals.CameraGroupStrategy; import com.badlogic.gdx.graphics.g3d.decals.Decal; import com.badlogic.gdx.graphics.g3d.decals.DecalBatch; import com.badlogic.gdx.math.Vector3; /** * @author manakeri */ public class Zombies { class DIRECTION { static final short LEFT = 0; static final short BACK = 2; static final short RIGHT = 4; static final short FRONT = 6; static final short DEAD = 255; } class Zombie { private final Vector3 position; private final Vector3 direction; private float timePassed; private short state; private Decal frame; public Zombie(City _city) { position = new Vector3(); direction = new Vector3(); direction.set(TGame.rand.nextFloat(), 0, TGame.rand.nextFloat()); do { position.set(TGame.rand.nextFloat(), 0, TGame.rand.nextFloat()); } while (!_city.isRoad(position.x, position.z)); state = 0; } } private final static short ROWS = 8; private final static short COLS = 8; private final static short SIZE = 128; private final Zombie[] zombies; private DecalBatch batch; private final int _amount; private final City _city; private final TextureRegion[] walk = new TextureRegion[ROWS * COLS]; public Zombies(City city, int amount) { _amount = amount; _city = city; zombies = new Zombie[amount]; for (int i = 0; i < zombies.length; i++) { zombies[i] = new Zombie(city); } Texture tex = new Texture("data/img/zombie_walk.png"); for (int y = 0; y < ROWS; y++) { for (int x = 0; x < COLS; x++) { walk[y * COLS + x] = new TextureRegion(tex, x * SIZE, y * SIZE, SIZE, SIZE); } } } public int amount() { int _amount = 0; for (Zombie zomb : zombies) { if (zomb.state != DIRECTION.DEAD) { _amount++; } } return _amount; } public void checkHit(City city, int x, int z) { for (Zombie zomb : zombies) { if (zomb.state != DIRECTION.DEAD) { int zx = (int) (zomb.position.x * city.getWidth()); int zz = (int) (zomb.position.z * city.getHeight()); if (zx == x && zz == z) { zomb.state = DIRECTION.DEAD; if (TGame.DEBUG) { Gdx.app.log(TGame.TAG, "zx: " + zx + ", zz: " + zz + ", hx: " + x + ", hz: " + z); } } } } } public void draw(Camera cam, float delta) { for (Zombie zomb : zombies) { if (zomb.state != DIRECTION.DEAD) { updatePos(zomb, delta); int dir = 0; float zdiff = cam.direction.z - zomb.direction.z; float xdiff = cam.direction.x - zomb.direction.x; // Gdx.app.log(TGame.TAG, "direction x: " + xdiff + // ", direction z: " + zdiff); if (Math.abs(xdiff) > Math.abs(zdiff)) { if (xdiff > 0) { dir = DIRECTION.RIGHT; } else { dir = DIRECTION.LEFT; } } else { if (zdiff > 0) { dir = DIRECTION.FRONT; } else { dir = DIRECTION.BACK; } } /* * if (zomb.direction.x < 0) { dir = DIRECTION.LEFT; } if * (zomb.direction.x > 0) { dir = DIRECTION.RIGHT; } */ zomb.frame = Decal.newDecal(1, 1, walk[dir * COLS + zomb.state], true); zomb.frame.setPosition(zomb.position.x * _city.getWidth(), zomb.position.y, zomb.position.z * _city.getHeight()); zomb.frame.lookAt(cam.position, cam.up.nor()); batch.add(zomb.frame); zomb.timePassed += delta; if (zomb.timePassed > 0.3f * Math.max( Math.abs(zomb.direction.x), Math.abs(zomb.direction.z))) { zomb.timePassed = 0; if (zomb.state < 8) { zomb.state++; } else { zomb.state = 1; } } } } batch.flush(); } public void init(Camera cam) { batch = new DecalBatch(_amount, new CameraGroupStrategy(cam)); } private void updatePos(Zombie zomb, float delta) { zomb.position.add(new Vector3(zomb.direction).mul(delta * 0.01f)); if (!_city.isRoad(zomb.position.x, zomb.position.z)) { zomb.direction.set(-zomb.direction.x, 0, -zomb.direction.z); // direction[i].set( TGame.rand.nextFloat(), 0, // TGame.rand.nextFloat()); } } }