quantum.game.Planet.java Source code

Java tutorial

Introduction

Here is the source code for quantum.game.Planet.java

Source

//
// Copyright (c) 2009 Mario Zechner.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the GNU Lesser Public License v2.1
// which accompanies this distribution, and is available at
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
// 
// Contributors:
//     Mario Zechner - initial API and implementation
//

package quantum.game;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Vector2;

import quantum.Renderer;

/** Planet class. A Planet is either free or in possession of a Player. A Planet has trees that produce creatures. The creature
 * properties are determined by the planets properties, namely its strength, health and speed. A Planet can only host a certain
 * number of trees depending on its radius.
 * 
 * @author Administrator */
public strictfp class Planet extends GameObject {
    int owner = -1;
    float radius;
    float strength;
    float health;
    float speed;
    int resources = 0;
    int full_resources = 0;
    boolean is_start_planet = false;
    int chain_planet = -1;

    List<Tree> trees = new LinkedList<Tree>();
    List<Creature> creatures = new ArrayList<Creature>();
    List<Creature> added_creatures = new LinkedList<Creature>();
    List<Creature> removed_creatures = new LinkedList<Creature>();
    List<Tree> removed_trees = new LinkedList<Tree>();

    float[] points = new float[361 * 2];
    HashSet<Integer> reachable_planets = new HashSet<Integer>();
    int friendly = 0;
    int enemy = 0;
    boolean is_regrowing = false;
    int unborn_friendly = 0;
    int orbiting_friendly = 0;

    float[] creature_points = new float[18];

    public void read(DataInputStream in) throws Exception {
        super.read(in);
        owner = in.readInt();
        radius = in.readFloat();
        strength = in.readFloat();
        health = in.readFloat();
        setSpeed(in.readFloat());
        setResources(in.readInt());
        full_resources = in.readInt();
        is_start_planet = in.readBoolean();
        last_idx = in.readInt();
        is_regrowing = in.readBoolean();
        chain_planet = in.readInt();

        int n = in.readInt();
        for (int i = 0; i < n; i++) {
            Tree tree = new Tree(sim);
            tree.read(in);
            trees.add(tree);
            sim.addObject(tree);
        }

        n = in.readInt();
        for (int i = 0; i < n; i++) {
            Creature creature = new Creature(sim);
            creature.read(in);
            creatures.add(creature);
            sim.addObject(creature);
        }

        createMesh();
    }

    public void write(DataOutputStream out) throws Exception {
        super.write(out);
        out.writeInt(owner);
        out.writeFloat(radius);
        out.writeFloat(strength);
        out.writeFloat(health);
        out.writeFloat(speed);
        out.writeInt(resources);
        out.writeInt(full_resources);
        out.writeBoolean(is_start_planet);
        out.writeInt(last_idx);
        out.writeBoolean(is_regrowing);
        out.writeInt(chain_planet);

        out.writeInt(trees.size());
        for (Tree tree : trees)
            tree.write(out);

        out.writeInt(creatures.size());
        for (Creature creature : creatures)
            creature.write(out);
    }

    public Planet(Simulation sim) {
        super(sim);
    }

    public Planet(Simulation sim, Vector2 pos, float radius, float strength, float health, float speed,
            int max_creatures) {
        super(sim, pos);
        this.radius = radius;
        this.strength = strength;
        this.health = health;
        setSpeed(speed);
        setResources(max_creatures);
        createMesh();
    }

    public boolean isRegrowing() {
        return is_regrowing;
    }

    public int getChainedPlanet() {
        return chain_planet;
    }

    public void setChainedPlanet(int chained_planet) {
        chain_planet = chained_planet;
    }

    public void clearReachablePlanets() {
        reachable_planets.clear();
    }

    public void addReachablePlanet(int id) {
        reachable_planets.add(id);
    }

    public Set<Integer> getReachablePlanets() {
        return reachable_planets;
    }

    public void setOwner(int id) {
        owner = id;
    }

    public boolean isStartPlanet() {
        return is_start_planet;
    }

    public void setStartPlanet(boolean val) {
        is_start_planet = val;
    }

    public void spawnCreature() {
        Vector2 pos = new Vector2(new Vector2(sim.rand() - sim.rand(), sim.rand() - sim.rand()).nor()
                .scl(radius + Constants.BOID_MIN_ORBIT
                        + (float) Math.random() * (Constants.BOID_MAX_ORBIT - Constants.BOID_MIN_ORBIT)));
        float angle = (float) Math.toDegrees(Math.atan2(pos.y, pos.x)) + 90;
        pos.add(this.pos);
        Creature creature = new Creature(sim, getId(), owner, pos.x, pos.y, angle, strength, health, speed);
        creatures.add(creature);
        sim.addObject(creature);
        creature.setScale(1);
    }

    public void addCreature(Creature creature) {
        added_creatures.add(creature);
        // creatures.add(creature);
    }

    public void removeCreature(Creature creature) {
        removed_creatures.add(creature);
        // creatures.remove(creature);
    }

    public void removeAllCreatures() {
        for (Creature creature : creatures)
            sim.removeObject(creature);
        creatures.clear();
    }

    public boolean requestResourceForCreature() {
        if (resources <= 0) {
            resources = 0;
            return false;
        } else {
            resources--;
            return true;
        }
    }

    int last_idx = 0;

    public void spawnTree() {
        int idx = last_idx + (int) (sim.rand(10, 110));
        last_idx = idx % 359;
        idx = idx % 359;
        Vector2 pos = new Vector2(points[idx * 2] * radius, points[idx * 2 + 1] * radius);
        pos.add(this.pos);
        Tree tree = new Tree(sim, pos, id);
        trees.add(tree);
        sim.addObject(tree);
    }

    public void removeTree(Tree tree) {
        removed_trees.add(tree);
    }

    public void removeAllTrees() {
        for (Tree tree : trees)
            sim.removeObject(tree);
        trees.clear();
    }

    public int getOwner() {
        return owner;
    }

    public float getStrength() {
        return strength;
    }

    public void setStrength(float strength) {
        this.strength = strength;
        for (Creature creature : creatures)
            if (creature.getOwner() == owner)
                creature.setStrength(strength);
        createMesh();
    }

    public float getHealth() {
        return health;
    }

    public void setHealth(float health) {
        this.health = health;
        for (Creature creature : creatures)
            if (creature.getOwner() == owner)
                creature.setHealth(health);

        createMesh();
    }

    public float getSpeed() {
        return speed;
    }

    public void setSpeed(float speed) {
        this.speed = Math.max(Math.min(speed, 1), Constants.BOID_MIN_SPEED_FRAC);
        for (Creature creature : creatures)
            if (creature.getOwner() == owner)
                creature.setSpeed(speed);
        createMesh();
    }

    public int getResources() {
        return resources;
    }

    public void setResources(int resources) {
        this.resources = resources;
        this.full_resources = resources;
        if (resources >= Constants.PLANET_MAX_CREATURES)
            this.resources = Constants.PLANET_MAX_CREATURES;

        this.radius = Constants.PLANET_MIN_SIZE + (Constants.PLANET_MAX_SIZE - Constants.PLANET_MIN_SIZE)
                * getResources() / Constants.PLANET_MAX_CREATURES;
        createMesh();
    }

    public float getRadius() {
        return radius;
    }

    public List<Creature> getCreatures() {
        return creatures;
    }

    public int getFriendlyCreatures(int owner) {
        int n = 0;
        for (Creature c : creatures)
            if (c.getOwner() == owner && c.isBorn() && !c.isDying())
                n++;
        return n;
    }

    public int getMoveableCreatures(int owner) {
        int n = 0;
        for (Creature c : creatures)
            if (c.getOwner() == owner && c.isBorn() && !c.isDying() && (c.isOrbiting() || c.isAttacking()))
                n++;

        return n;
    }

    public int getEnemeyCreatures(int owner) {
        int n = 0;
        for (Creature c : creatures)
            if (c.getOwner() != owner)
                n++;
        return n;
    }

    public List<Tree> getTrees() {
        return trees;
    }

    public void update() {
        orbiting_friendly = 0;
        unborn_friendly = 0;
        friendly = 0;
        enemy = 0;
        Iterator<Creature> c_iter = creatures.iterator();

        while (c_iter.hasNext()) {
            Creature creature = c_iter.next();

            if (creature.getOwner() == owner) {
                if (creature.isBorn() && !creature.isDying())
                    friendly++;
                if (!creature.isBorn())
                    unborn_friendly++;
                if (creature.isMoving() == false && creature.isBorn())
                    orbiting_friendly++;

                if (chain_planet != -1 && creature.isOrbiting()
                        && creature.getPosition().dst2(pos) < (radius * 2.6) * (radius * 2.6))
                    creature.move(chain_planet);
            } else {
                if (creature.isBorn() && !creature.isDying())
                    enemy++;
            }
        }

        if (resources < full_resources && (trees.size() == 0 || (orbiting_friendly == 0 && unborn_friendly == 0))) {
            if (is_regrowing) {
                if (sim.getTurn() % Constants.PLANET_REGROWTH == 0)
                    resources += 1;
            }
            is_regrowing = true;
        } else
            is_regrowing = false;

        c_iter = creatures.iterator();
        while (c_iter.hasNext()) {
            Creature creature = c_iter.next();

            if (creature.isDead()) {
                c_iter.remove();
                sim.removeObject(creature);
            } else
                creature.update();
        }

        for (Creature creature : removed_creatures)
            creatures.remove(creature);
        for (Creature creature : added_creatures)
            creatures.add(creature);

        int treeSize = trees.size();
        if (friendly == 0 && enemy > 0 && treeSize == 0) {
            if (creatures.size() > 0)
                this.owner = creatures.get(0).getOwner();
            else
                this.owner = -1;
            chain_planet = -1;
        }

        removed_creatures.clear();
        added_creatures.clear();

        for (Tree tree : trees) {
            tree.update();
            if (tree.isDead())
                removed_trees.add(tree);
        }

        for (Tree tree : removed_trees)
            trees.remove(tree);

        removed_trees.clear();

    }

    protected void createMesh() {

        for (int i = 0; i < 361; i++) {
            double angle = Math.toRadians(i);

            points[i * 2] = (float) Math.cos(angle);
            points[i * 2 + 1] = (float) Math.sin(angle);
        }

        creature_points = Creature.generateTriangles(strength, health, speed);
    }

    public void renderMesh(Renderer renderer, float scale, float r, float g, float b) {
        renderer.shapeRenderer.setColor(r, g, b, 1);
        renderer.shapeRenderer.begin(ShapeType.Line);
        renderer.shapeRenderer.circle(pos.x, pos.y, radius * scale, 32);
        renderer.shapeRenderer.end();
    }

    public void render(Renderer renderGL) {
        renderGL.shapeRenderer.setColor(0.7f, 0.7f, 1, 1);
        renderGL.shapeRenderer.begin(ShapeType.Line);
        renderGL.shapeRenderer.circle(pos.x, pos.y, radius, 32);
        renderGL.shapeRenderer.end();
    }

    public void renderCreature(Renderer renderer) {
        for (int i = 0; i < 18; i += 6) {
            int idx0 = (i + 1);
            int idx1 = (i);
            int idx2 = (i + 1) + 2;
            int idx3 = (i) + 2;
            int idx4 = (i + 1) + 4;
            int idx5 = (i) + 4;

            float x1 = creature_points[idx0] * (Constants.PLANET_MIN_SIZE - 10) + pos.x;
            float y1 = creature_points[idx1] * (Constants.PLANET_MIN_SIZE - 10) + pos.y;
            float x2 = creature_points[idx2] * (Constants.PLANET_MIN_SIZE - 10) + pos.x;
            float y2 = creature_points[idx3] * (Constants.PLANET_MIN_SIZE - 10) + pos.y;
            float x3 = creature_points[idx4] * (Constants.PLANET_MIN_SIZE - 10) + pos.x;
            float y3 = creature_points[idx5] * (Constants.PLANET_MIN_SIZE - 10) + pos.y;
            renderer.shapeRenderer.triangle(x1, y1, x2, y2, x3, y3);
        }
    }

    public boolean isReachablePlanet(int destinationPlanet) {
        for (Integer id : reachable_planets)
            if (id == destinationPlanet)
                return true;

        return false;
    }

    public boolean hasEnemyCreatures() {
        return enemy > 0;
    }

    public float getCreatureStrength(int id, int units) {
        float strength = 0;
        int send = 0;
        for (Creature creature : getCreatures()) {
            if (creature.getOwner() == id && creature.isBorn() && creature.isDead() == false
                    && (creature.isOrbiting() || creature.isAttacking())) {
                strength += creature.getHealth() + creature.getSpeed() + creature.getStrength();
                send++;
            }

            if (send == units)
                break;
        }

        return strength;
    }

    public float getCreatureStrengthExclude(int id) {
        float strength = 0;
        for (Creature creature : getCreatures()) {
            if (creature.getOwner() != id && creature.isBorn() && creature.isDead() == false
                    && (creature.isOrbiting() || creature.isAttacking())) {
                strength += creature.getHealth() + creature.getSpeed() + creature.getStrength();
            }
        }

        return strength;
    }

    public int getMaxResources() {
        return full_resources;
    }

    public int getUnbornCreatures() {
        return unborn_friendly;
    }

    public int getOrbitingCreatures() {
        return orbiting_friendly;
    }
}