Java tutorial
/* * Copyright (C) 2015 fax * * 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 3 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, see <http://www.gnu.org/licenses/>. */ package org.fe.gameplay.world; import java.awt.Point; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; import org.fe.Main; import org.fe.gameplay.terrain.Block; import org.fe.gameplay.terrain.FogOfWar; import org.fe.gameplay.terrain.Terrain; import org.fe.gameplay.types.Entity; import org.fe.gameplay.types.entities.kaiserat.Mammutidae; import org.fe.gameplay.types.entities.kaiserat.Stiletto; import org.fe.graphics.FColor; import org.fe.graphics.FKeyboard; import org.fe.graphics.FMouse; import org.fe.gui.FScene; import org.fe.gameplay.types.Effect; import org.lwjgl.opengl.GL11; import org.newdawn.slick.Color; /** * * @author fax */ public class World extends FScene implements Serializable { public int player = 0; int players; public Terrain terrain; public FogOfWar fogOfWar; public Player playerHandler[]; public int seed; public int selectX, selectY, selectX2, selectY2; public int cameraX, cameraY; public World(int players) { this.players = players; this.seed = Main.RANDOM.nextInt(Integer.MAX_VALUE); this.terrain = new Terrain("skirmish_0.map"); this.fogOfWar = new FogOfWar(terrain.width, terrain.height); this.playerHandler = new Player[players]; FColor colors[] = new FColor[] { FColor.magenta, FColor.cyan, FColor.red, FColor.green, FColor.blue, FColor.yellow, FColor.orange, FColor.pink, FColor.gray, FColor.black }; for (int i = 0; i < this.players; i++) { this.playerHandler[i] = new Player(colors[i], "Player " + 1, 0, i); } } public World(int players, int seed) { this.players = players; this.seed = seed; this.terrain = new Terrain(); this.fogOfWar = new FogOfWar(terrain.width, terrain.height); this.playerHandler = new Player[players]; } public void add(Class clazz, double x, double y, double z, double a, int owner) { try { Entity e = (Entity) clazz.newInstance(); e.id = id++; e.world = this; e.x = x; e.y = y; e.z = z; e.a = a; e.owner = owner; indexedEntities.add(e); e.id = indexedEntities.size() - 1; entities.add(e); } catch (InstantiationException ex) { Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); } } public void add(Effect e) { for (int i = 0; i < effects.length; i++) { if (effects[i] == null || effects[i].remove) { effects[i] = e; break; } } } public void remove(Entity e) { indexedEntities.set(e.id, null); entities.remove(e); } private int id; private ArrayList<Entity> indexedEntities = new ArrayList<Entity>(), entities = new ArrayList<Entity>(); private Effect[] effects = new Effect[256]; @Override public void handleHover(double mx, double my) { if (FMouse.leftPressed) { selectX = selectX2 = (int) (mx + cameraX); selectY = selectY2 = (int) (my * 2 + cameraY); } if (FMouse.left) { selectX2 = (int) (mx + cameraX); selectY2 = (int) (my * 2 + cameraY); } if (FMouse.leftReleased) { for (Entity e : getEntities()) { if (e.x - e.width / 2 <= Math.max(selectX, selectX2) && e.x + e.width / 2 >= Math.min(selectX, selectX2) && e.y - e.width / 2 <= Math.max(selectY, selectY2) && e.y + e.width / 2 >= Math.min(selectY, selectY2)) { e.selected = e.owner == player && e.selectable; } else if (!(FKeyboard.isKeyDown(FKeyboard.KEY_LSHIFT) || FKeyboard.isKeyDown(FKeyboard.KEY_RSHIFT))) { e.selected = false; } } selectX = selectX2 = 0; selectY = selectY2 = 0; } if (FMouse.middle) { int cx = cameraX; int cy = cameraY; cx -= FMouse.dx; cy -= FMouse.dy * 2; if (cx < 0) { cx = 0; } if (cy < 0) { cy = 0; } if (cx + width >= terrain.width * Block.WIDTH) { cx = (int) (terrain.width * Block.WIDTH - width); } if (cy + height * 2 >= terrain.height * Block.HEIGHT * 2) { cy = (int) (terrain.height * Block.HEIGHT * 2 - height * 2); } cameraX = cx; cameraY = cy; } ArrayList<Entity> move = new ArrayList<Entity>(); if (FMouse.rightReleased) { for (Entity e : getEntities()) { if (e.selected) { move.add(e); } } } ArrayList<Point> point = new ArrayList<Point>(); int dir = 0; int length = 1; int steps = 1; int px, py; int tx = px = (int) (mx + cameraX), ty = py = (int) (my * 2 + cameraY); tx /= 64; ty /= 64; while (point.size() < move.size()) { if (tx >= 0 && ty >= 0 && tx < terrain.width && ty < terrain.height && terrain.getTile(tx, ty).passable) { point.add(new Point(tx * 64 + 32, ty * 64 + 32)); } else { } switch (dir) { case 0: tx++; steps--; if (steps == 0) { dir = 1; steps = length; } break; case 1: ty++; steps--; if (steps == 0) { dir = 2; length++; steps = length; } break; case 2: tx--; steps--; if (steps == 0) { dir = 3; steps = length; } break; case 3: ty--; steps--; if (steps == 0) { dir = 0; length++; steps = length; } break; default: break; } } while (move.size() > 0) { Entity en = null; Point pn = null; int dist = 0; for (Entity e : move) { int d = (int) Math.sqrt(Math.pow(e.x - px, 2) + Math.pow(e.y - py, 2)); if (d >= dist) { dist = d; en = e; } } dist = Integer.MAX_VALUE; for (Point p : point) { int d = (int) Math.sqrt(Math.pow(en.x - p.x, 2) + Math.pow(en.y - p.y, 2)); if (d <= dist) { dist = d; pn = p; } } en.goTo(pn.x, pn.y); move.remove(en); point.remove(pn); } super.hover(mx, my); } public Entity getEntity(int id) { return indexedEntities.get(id); } public Entity[] getEntities() { Entity e[] = new Entity[entities.size()]; for (int i = 0; i < e.length; i++) { e[i] = entities.get(i); } return e; } @Override public void init() { super.init(); for (int i = 0; i < 10; i++) { add(Stiletto.class, 64 * 2 + 32, 64 * 4 + 16, 0, 0, 0); add(Mammutidae.class, 64 * 3 + 32, 64 * 3 + 16, 0, 0, 0); add(Stiletto.class, 64 * 4 + 32, 64 * 4 + 16, 0, 0, 0); add(Mammutidae.class, 64 * 20 + 32, 64 * 3 + 16, 0, 0, 1); } } @Override public void tick() { terrain.tick++; fogOfWar.tick(); Entity[] ent = getEntities(); for (Entity e : ent) { e.tick(ent); } for (int i = 0; i < effects.length; i++) { Effect e = effects[i]; if (e != null) { e.tick(); if (e.remove) { effects[i] = null; } } } } @Override public void render() { int cameraX = this.cameraX, cameraY = this.cameraY; GL11.glTranslated(-cameraX, -cameraY / 2, 0); terrain.render(cameraX, cameraY / 2, (int) width, (int) height); Entity[] ent = getEntities(); Arrays.sort(ent); for (Entity e : ent) { if (fogOfWar.isVisible((int) e.x / 32, (int) e.y / 32)) e.render(); } for (int i = 0; i < effects.length; i++) { Effect e = effects[i]; if (e != null && e.onScreen(cameraX, cameraY, (int) width, (int) height)) { e.render(); if (e.remove) { effects[i] = null; } } } fogOfWar.render(cameraX, cameraY / 2, (int) width, (int) height); for (Entity e : ent) { if (e.onScreen(cameraX, cameraY, (int) width, (int) height)) { if (fogOfWar.isVisible((int) e.x / 32, (int) e.y / 32)) e.renderGUI(); } } if (FMouse.left) { Main.GRAPHICS.setColor(new Color(0, 0, 0, 0.15f)); Main.GRAPHICS.fillRect(selectX, (selectY) / 2, selectX2 - selectX, (selectY2 - selectY) / 2); Main.GRAPHICS.setColor(Color.white); Main.GRAPHICS.drawRect(selectX, (selectY) / 2, selectX2 - selectX, (selectY2 - selectY) / 2); } GL11.glTranslated(cameraX, cameraY / 2, 0); super.render(); } }