herzog3d.Game.java Source code

Java tutorial

Introduction

Here is the source code for herzog3d.Game.java

Source

/*
 *    Herzog3D - 3D Real Time Strategy game.
 *   Copyright (C) 2005  Shannon Smith
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package herzog3d;

import game.core.LocalGameTime;
import game.core.resource.AbstractResource;
import game.core.resource.iGameResource;
import hud.HZWidget;
import hud.ManagerOverlay;
import hud.StatusOverlay;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import map.Base;
import map.GameMap;

import org.jdom.JDOMException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import resource.Material;
import resource.ResourceLoader;
import resource.ResourceManager;
import resource.ResourceNotFoundException;
import unit.Mech;
import unit.Unit;
import unit.UnitFactory;
import util.GLUtils;
import util.GameMath;
import util.Vector3f;
import ai.RandomAI;
import ai.UnitAI.UnitMove;
import ai.UnitAI.UnitTurn;
import effects.Effect;

/*
 * Created on 26/05/2005
 */

/**
 * @author Shannon Smith
 */
public class Game implements iGameResource {

    private GameMap map;
    private List<HZObject> objects;
    private List<Unit> units;
    private List<Effect> effects;
    private List<HZWidget> overlays;
    private List<Effect> newEffects;
    private List<Player> players;
    private List<Base> bases;
    private Map<Player, UnitOrder> unitOrders;
    private Map<Player, Mech> mechs;
    private Player player;
    private ManagerOverlay managerOverlay;
    private ResourceManager resManager;
    private UnitFactory unitFactory;
    private boolean finished;
    private Camera cam;

    private static Game instance = null;

    public static Game getInstance() {
        if (instance == null) {
            instance = new Game();
        }
        return instance;
    }

    public void orderUnit(Player player, String unitName) {
        unitOrders.put(player, new UnitOrder(unitName, unitFactory.getTimeToBuild(unitName)));
        player.setUnitOrder(unitOrders.get(player));
    }

    public Unit pickupOrder(Player player) {
        UnitOrder order = unitOrders.remove(player);
        return resManager.getUnitFactory().buildUnit(player, order.getUnitName());
    }

    public Player getPlayer() {
        return player;
    }

    public Player getWinner() {
        if (!finished) {
            return null;
        } else {
            for (Player player : players) {
                if (player.getHomeBase().isAlive()) {
                    return player;
                }
            }
        }
        return null;
    }

    public ResourceManager getResources() {
        return resManager;
    }

    public GameMap getMap() {
        return map;
    }

    public Collection<Unit> getUnits() {
        return Collections.unmodifiableCollection(units);
    }

    public Collection<Mech> getMechs() {
        return Collections.unmodifiableCollection(mechs.values());
    }

    public Collection<Effect> getEffects() {
        return Collections.unmodifiableList(effects);
    }

    public Collection<Base> getBases() {
        return bases;
    }

    public void removeUnit(Unit unit) {
        units.remove(unit);
    }

    public void addUnit(Unit unit) {
        units.add(unit);
        objects.add(unit);
    }

    public boolean hasFinished() {
        return finished;
    }

    public String getNextState() {
        return "GameFinished";
    }

    public void addEffect(Effect e) {
        newEffects.add(e);
    }

    public void satisfyConstraints() {
        for (int i = 0; i < 10; i++) {
            for (HZObject obj1 : objects) {
                for (HZObject obj2 : objects) {
                    Vector3f v = obj1.intersects(obj2);
                    if (v != null) {
                        v.scale(0.2f);
                        obj1.move(v);
                    }
                }
                for (HZObject base : bases) {
                    Vector3f v = obj1.intersects(base);
                    if (v != null) {
                        // v.scale(0.9f);
                        obj1.move(v);
                    }
                }
            }
        }
    }

    public Unit getUnitAt(float x, float y, float tolerance) {
        for (Unit unit : units) {
            if (!(unit instanceof Mech)
                    && GameMath.dist(unit.getPos().x, unit.getPos().y, x, y) < (unit.getRadius() + tolerance)) {
                return unit;
            }
        }
        return null;
    }

    /**
     * All rendering is done in here
     */
    public void draw() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        cam.transform();
        GLUtils.glLightPos(1.0f, 1.0f, 1.0f);
        GL11.glColor3f(1.0f, 1.0f, 1.0f);
        getMap().draw(cam);

        for (Unit unit : units) {
            if (unit.isActive()) {
                unit.draw();
            }
        }

        for (Base base : bases) {
            base.draw(map);
        }
        for (Effect effect : effects) {
            effect.draw();
        }

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, 800, 600, 0, 0, 1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glDisable(GL11.GL_LIGHTING);
        Material.DEFAULT_WHITE.bind();
        for (HZWidget overlay : overlays) {
            if (overlay.isVisible()) {
                overlay.draw();
            }
        }
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_DEPTH_TEST);

    }

    public void onKeyPress() {
        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (Keyboard.getEventKey() == Keyboard.KEY_UP) {
                    player.setMove(UnitMove.MOVE_FORWARD);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_DOWN) {
                    player.setMove(UnitMove.MOVE_BACKWARD);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_LEFT) {
                    player.setTurn(UnitTurn.TURN_LEFT);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_RIGHT) {
                    player.setTurn(UnitTurn.TURN_RIGHT);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_A) {
                    player.setTransform(true);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_S) {
                    player.setFire(true);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_D) {
                    managerOverlay.setVisible(!managerOverlay.isVisible());
                    player.setMove(UnitMove.MOVE_STOP);
                    player.setTurn(UnitTurn.TURN_STOP);
                }
            } else {
                if (Keyboard.getEventKey() == Keyboard.KEY_UP) {
                    player.setMove(UnitMove.MOVE_STOP);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_DOWN) {
                    player.setMove(UnitMove.MOVE_STOP);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_LEFT) {
                    player.setTurn(UnitTurn.TURN_STOP);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_RIGHT) {
                    player.setTurn(UnitTurn.TURN_STOP);
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_A) {
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_S) {
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_D) {
                }
            }
        }
    }

    public boolean isFinished() {
        return finished;
    }

    public Base getBase(float x, float y) {
        for (Base base : bases) {
            if (base.isInTile((int) x, (int) y)) {
                return base;
            }
        }
        return null;
    }

    @Override
    public void init() {
        ResourceLoader loader = new ResourceLoader();
        System.out.print("Loading resources...");
        ResourceManager res = null;
        try {
            res = loader.loadResources(new File("data/resources.xml"));
        } catch (ResourceNotFoundException | IOException | JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("done.");

        Player[] players = new Player[2];
        players[0] = new Player("Player1", null);
        players[0].setColour(new Color(255, 96, 96));
        players[1] = new Player("Player2", null);
        players[1].setColour(new Color(96, 96, 255));

        map = res.getMap("Abgrund");
        this.cam = new Camera(this);
        this.resManager = res;
        this.player = players[0];

        objects = new LinkedList<HZObject>();
        bases = new ArrayList<Base>();
        units = new ArrayList<Unit>();
        mechs = new HashMap<Player, Mech>();
        effects = new LinkedList<Effect>();
        newEffects = new ArrayList<Effect>();
        overlays = new ArrayList<HZWidget>();
        unitOrders = new HashMap<Player, UnitOrder>();
        this.players = new ArrayList<Player>();
        unitFactory = resManager.getUnitFactory();
        Collections.addAll(this.players, players);

        Iterator<String> playerLocations = map.getPlayerTemplates().iterator();

        for (int i = 0; i < players.length; i++) {
            if (!playerLocations.hasNext()) {
                throw new IllegalStateException("Too many players for map!");
            }
            Mech mech = new Mech(players[i], resManager);
            mech.setAI(players[i]);
            players[i].setMech(mech);
            players[i].setUnit(mech);
            mechs.put(players[i], mech);
            units.add(mech);
            String locID = playerLocations.next();
            System.out.println("Adding player at: " + locID);
            bases.addAll(map.createPlayerBases(players[i], locID, resManager));
            objects.add(mech);
            mech.setPos(players[i].getHomeBase().getCenter());
            mech.move(0, 0, 4);
        }
        cam.setMech(players[0].getMech());
        managerOverlay = new ManagerOverlay(this);
        managerOverlay.setGeometry(208, 64, 384, 416);
        overlays.add(new StatusOverlay(resManager, players[0]));
        overlays.add(managerOverlay);

        //      for (int i = 0; i < 50; i++) {
        //         Unit unit = res.getUnitFactory().buildUnit(
        //               (i % 2 == 0) ? players[0] : players[1], "Tank");
        //         float x = (float) Math.random() * 48 + 1f;
        //         float y = (float) Math.random() * 48 + 1f;
        //         while (this.getUnitAt(x, y, 0) != null) {
        //            x = (float) Math.random() * 16 + 1f;
        //            y = (float) Math.random() * 16 + 1f;
        //         }
        //         unit.getPos().set(x, y, 0);
        //         unit.setAI(new RandomAI(unit));
        //         this.addUnit(unit);
        //      }
        System.out.print("Binding textures...");
        res.bindTextures();
        System.out.println("done.");
    }

    @Override
    public void update() {
        onKeyPress();

        float step = (float) LocalGameTime.getDelta();
        cam.update(step);

        for (Iterator<Unit> i = units.iterator(); i.hasNext();) {
            Unit unit = i.next();
            if (unit.getArmour() < 0) {
                i.remove();
            } else if (unit.isActive()) {
                unit.update(this, step);
            }
        }

        satisfyConstraints();

        for (Iterator<Effect> i = effects.iterator(); i.hasNext();) {
            Effect effect = i.next();
            effect.update(this, step);
            if (!effect.isActive()) {
                i.remove();
            }
        }
        for (UnitOrder order : unitOrders.values()) {
            order.update(step);
        }
        effects.addAll(newEffects);
        newEffects.clear();

        if (managerOverlay.isVisible()) {
            managerOverlay.update(step);
        }

        int survivingPlayers = 0;
        for (Player player : players) {
            if (player.getHomeBase() != null && player.getHomeBase().isAlive()) {
                survivingPlayers++;
            }
        }
        if (survivingPlayers < 2) {
            finished = true;
        }

        draw();
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}