summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Actor.java107
-rw-r--r--src/Battle.java304
-rw-r--r--src/Map.java154
-rw-r--r--src/MapEditor.java226
-rw-r--r--src/MapLoader.java60
-rw-r--r--src/MapScene.java229
-rw-r--r--src/Palette.java15
-rw-r--r--src/Scene.java104
-rw-r--r--src/Sub.java80
-rw-r--r--src/Tile.java105
-rw-r--r--src/Weapon.java50
11 files changed, 1434 insertions, 0 deletions
diff --git a/src/Actor.java b/src/Actor.java
new file mode 100644
index 0000000..ca3995a
--- /dev/null
+++ b/src/Actor.java
@@ -0,0 +1,107 @@
+public class Actor {
+ private String name;
+ private boolean alive;
+ private boolean enemy;
+ private int hp;
+ private int agility;
+ private int strenght;
+ private int defense;
+ private int x;
+ private int y;
+ private Weapon weapon;
+ private int actionsLeft;
+ private int actions = 2;
+
+ public Actor(String name, int hp, boolean enemy, int agility) {
+ this.name = name;
+ this.hp = hp;
+ this.enemy = enemy;
+ this.agility = agility;
+ this.weapon = new Weapon("fist", 1, 1, 10000000);
+
+ this.alive = true;
+ this.resetActions();
+ }
+
+ public void resetActions() {
+ this.actionsLeft = this.actions;
+ }
+
+ public int getActionsLeft() {
+ return this.actionsLeft;
+ }
+
+ public boolean hit(Actor actor, Map map) {
+ if (this.actionsLeft > 0) {
+ if (this.weapon.damage(this, actor, map)) {
+ this.actionsLeft--;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Weapon getWeapon() {
+ return this.weapon;
+ }
+
+ public void equipWeapon(Weapon weapon) {
+ this.weapon = weapon;
+ }
+
+ public boolean isAlive() {
+ return this.alive;
+ }
+
+ public void setHP(int hp) {
+ this.hp = hp;
+ if (this.hp <= 0) {
+ this.alive = false;
+ }
+ }
+
+ public void damage(int dmg) {
+ this.hp -= dmg;
+ if (this.hp <= 0) {
+ this.alive = false;
+ }
+ }
+
+ public int getAgility() {
+ return this.agility;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public int getHP() {
+ return this.hp;
+ }
+
+ public int getX() {
+ return this.x;
+ }
+
+ public int getY() {
+ return this.y;
+ }
+
+ public boolean isEnemy() {
+ return this.enemy;
+ }
+
+ public void move(int x, int y) {
+ if (this.actionsLeft > 0) {
+ this.x = x;
+ this.y = y;
+ this.actionsLeft--;
+ }
+ }
+
+ public void place(int x, int y) {
+ this.x = x;
+ this.y = y;
+
+ }
+}
diff --git a/src/Battle.java b/src/Battle.java
new file mode 100644
index 0000000..d7b63cc
--- /dev/null
+++ b/src/Battle.java
@@ -0,0 +1,304 @@
+import java.util.ArrayList;
+import java.util.Collections;
+import java.awt.Canvas;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferStrategy;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+
+public class Battle extends MapScene {
+
+ private enum Mode {
+ NONE, ATTACK, MOVE
+ };
+
+ private Sub main;
+ private int previousX = -1;
+ private int previousY = -1;
+ private Actor selectedActor;
+ private Actor lastActor;
+ private Mode mode;
+ private boolean actorClicked = false;
+ private int realX = 0;
+ private int realY = 0;
+
+ public Battle(JFrame frame, Sub sub) {
+ super(frame, sub);
+ this.main = sub;
+
+ MapLoader mapLoader = new MapLoader("../testmap.json");
+ this.map = mapLoader.getMap();
+
+ this.selectedActor = this.map.getNextActor();
+
+ this.setLayout(new BorderLayout());
+
+ JPanel bottomPanel = new JPanel();
+ bottomPanel.setLayout(new GridLayout(1,4));
+
+ JButton moveButton = new JButton("Move");
+ moveButton.setActionCommand("move");
+ JButton attackButton = new JButton("Attack");
+ attackButton.setActionCommand("attack");
+ JButton nextButton = new JButton("Next");
+ nextButton.setActionCommand("next");
+ JButton passButton = new JButton("Pass");
+ passButton.setActionCommand("pass");
+
+ moveButton.addActionListener(this);
+ attackButton.addActionListener(this);
+ nextButton.addActionListener(this);
+ passButton.addActionListener(this);
+
+ bottomPanel.add(moveButton);
+ bottomPanel.add(attackButton);
+ bottomPanel.add(nextButton);
+ bottomPanel.add(passButton);
+
+ this.add(bottomPanel, BorderLayout.PAGE_END);
+ this.add(this.canvas, BorderLayout.CENTER);
+ }
+
+ @Override
+ protected void absoluteRender(Graphics2D g) {
+ //draw cursor
+ //g.setColor(Palette.BLUE);
+ //g.fillOval(this.realX-10*this.guiSize, this.realY-10*this.guiSize, 20*this.guiSize, 20*this.guiSize);
+ //g.setColor(Palette.ORANGE);
+ //g.drawOval(this.realX-10*this.guiSize, this.realY-10*this.guiSize, 20*this.guiSize, 20*this.guiSize);
+
+ //draw panels
+ g.setColor(Palette.WHITE_T);
+ g.fillRect(this.WIDTH-100*this.guiSize, this.HEIGHT-100*this.guiSize,
+ 100*this.guiSize, 100*this.guiSize);
+ g.fillRect(0, this.HEIGHT-100*this.guiSize, 150*this.guiSize, 100*this.guiSize);
+
+ g.setColor(Palette.BLACK);
+ g.setFont(g.getFont().deriveFont(12.0F*this.guiSize));
+ Tile tile = null;
+ try{
+ tile = this.map.getTile(this.previousX, this.previousY);
+ switch (tile.getType()) {
+ case CLEAR:
+ break;
+ case GRASS:
+ g.drawString("Grass", this.WIDTH-90*this.guiSize, this.HEIGHT-80*this.guiSize);
+ break;
+ case WATER:
+ g.drawString("Water", this.WIDTH-90*this.guiSize, this.HEIGHT-80*this.guiSize);
+ break;
+ case MOUNTAIN:
+ g.drawString("Mountain", this.WIDTH-90*this.guiSize, this.HEIGHT-80*this.guiSize);
+ break;
+ }
+
+ g.setFont(g.getFont().deriveFont(8.0F*this.guiSize));
+ if (this.actorClicked && this.lastActor != null) {
+ g.setColor(Palette.WHITE_T);
+ g.fillRect(0, 0, 100*this.guiSize, 150*this.guiSize);
+ g.fillRect(this.WIDTH-100*this.guiSize, 0, 100*this.guiSize, 100*this.guiSize);
+
+ g.setColor(Palette.BLACK);
+ g.drawString(this.lastActor.getName(), 5*this.guiSize, 15*this.guiSize);
+
+ g.drawString("HP", 5*this.guiSize, 30*this.guiSize);
+ g.setColor(Palette.RED);
+ g.fillRect(20*this.guiSize, 22*this.guiSize, 70*this.guiSize, 10*this.guiSize);
+ g.setColor(Palette.DARKGREEN);
+ g.fillRect(20*this.guiSize, 22*this.guiSize, 70*this.guiSize*this.lastActor.getHP()/10, 10*this.guiSize);
+
+ g.setColor(Palette.BLACK);
+ g.drawString("Agility: " + Integer.toString(this.lastActor.getAgility()),
+ 5*this.guiSize, 45*this.guiSize);
+ } else if (this.actorClicked) {
+ g.setColor(Palette.WHITE_T);
+ g.fillRect(0, 0, 100*this.guiSize, 150*this.guiSize);
+ g.fillRect(this.WIDTH-100*this.guiSize, 0, 100*this.guiSize, 100*this.guiSize);
+
+ g.setColor(Palette.BLACK);
+ g.drawString("None left", 5*this.guiSize, 15*this.guiSize);
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (NullPointerException ext) {
+ System.out.println("map non existent");
+ ext.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void update(int deltaTime) {
+ ArrayList<Actor> actorsToRemove = new ArrayList<>();
+ int enemyCounter = 0;
+
+ for (Actor actor : this.map.getActors()) {
+ if (!actor.isAlive()) {
+ actorsToRemove.add(actor);
+ }
+ if (actor.isEnemy()) {
+ enemyCounter++;
+ }
+ }
+
+ for (Actor actor : actorsToRemove) {
+ this.map.removeActor(actor);
+ }
+
+ if (selectedActor != null) {
+ this.map.setCursor(selectedActor.getX(), selectedActor.getY());
+ } else {
+ this.map.setCursor(-1, -1);
+ }
+
+ if (enemyCounter == 0) {
+ //win
+ this.main.backToMenu();
+ }
+ }
+
+ private void aiPlay() {
+ //TODO write AI
+ //controll back to the player
+ this.map.resetActors();
+ this.selectedActor = this.map.getNextActor();
+ this.lastActor = this.selectedActor;
+ this.actorClicked = true;
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ int tileSize = this.maxSize/10;
+ Point2D p = new Point2D.Double(e.getX(), e.getY());
+ try {
+ p = this.tx.inverseTransform(p, null);
+ } catch (NoninvertibleTransformException ex) {}
+ try {
+ int x = (int) (p.getX()/tileSize);
+ int y = (int) (p.getY()/tileSize);
+ Tile tile = this.map.getTile(x, y);
+ Actor actor = null;
+ for (Actor i : this.map.getActors()) {
+ if (x == i.getX() && y == i.getY()) {
+ actor = i;
+ break;
+ }
+ }
+
+ if (actor != null) {
+ this.actorClicked = true;
+ this.lastActor = actor;
+ } else {
+ this.actorClicked = false;
+ }
+
+ if (this.mode == Mode.MOVE) {
+ if (tile.isSelected()) {
+ this.selectedActor.move(x, y);
+ this.mode = Mode.NONE;
+ this.map.clearSelected();
+ if (this.selectedActor.getActionsLeft() <= 0) {
+ this.selectedActor = this.map.getNextActor();
+ this.lastActor = this.selectedActor;
+ this.actorClicked = true;
+ }
+ }
+ } else if (this.mode == Mode.ATTACK) {
+ if (actor != null) {
+ this.selectedActor.hit(actor, this.map);
+ if (this.selectedActor.getActionsLeft() <= 0) {
+ this.selectedActor = this.map.getNextActor();
+ this.lastActor = this.selectedActor;
+ this.actorClicked = true;
+ }
+ }
+ this.mode = Mode.NONE;
+ this.map.clearSelected();
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ System.out.println("no tile clicked");
+ } catch (NullPointerException ext) {
+ //ext.printStackTrace();
+ System.out.println("map non existent");
+ }
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ this.realX = e.getX();
+ this.realY = e.getY();
+ int tileSize = this.maxSize/10;
+ Point2D p = new Point2D.Double(e.getX(), e.getY());
+ try {
+ p = this.tx.inverseTransform(p, null);
+ } catch (NoninvertibleTransformException ex) {}
+ int x = (int) (p.getX()/tileSize);
+ int y = (int) (p.getY()/tileSize);
+ try {
+ Tile tile = this.map.getTile(x, y);
+ if (x != this.previousX || y != this.previousY) {
+ if (this.mode == Mode.MOVE) {
+ this.map.clearSelected();
+ ArrayList<Tile> path = this.map.getPath(this.selectedActor, x, y);
+ Collections.reverse(path);
+ for (int i=0; i<this.selectedActor.getAgility(); i++) {
+ path.get(i).setSelected(true);
+ if (i == path.size()-1) {
+ break;
+ }
+ }
+ }
+ this.previousX = x;
+ this.previousY = y;
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ System.out.println("no tile clicked");
+ } catch (NullPointerException ext) {
+ System.out.println("map non existent");
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if ("move".equals(e.getActionCommand()) && this.selectedActor != null) {
+ this.map.clearSelected();
+ this.mode = Mode.MOVE;
+ this.lastActor = this.selectedActor;
+ this.actorClicked = true;
+ } else if ("pass".equals(e.getActionCommand())) {
+ this.map.clearSelected();
+ this.aiPlay();
+ } else if ("attack".equals(e.getActionCommand()) && this.selectedActor != null) {
+ this.map.clearSelected();
+ int range = this.selectedActor.getWeapon().getRange();
+ int x = this.selectedActor.getX();
+ int y = this.selectedActor.getY();
+ for (int r=-range; r <= range; r++) {
+ for (int c=-range; c <= range; c++) {
+ if (x+r >=0 &&
+ x+r < this.map.getSize() &&
+ y+c >= 0 &&
+ y+c < this.map.getSize()) {
+ this.map.getTile(x+r, y+c).setSelected(true);
+ }
+ }
+ }
+ this.mode = Mode.ATTACK;
+ } else if ("next".equals(e.getActionCommand())) {
+ this.map.clearSelected();
+ this.selectedActor = this.map.getNextActor();
+ this.lastActor = this.selectedActor;
+ this.actorClicked = true;
+ }
+
+ }
+}
diff --git a/src/Map.java b/src/Map.java
new file mode 100644
index 0000000..7b178cf
--- /dev/null
+++ b/src/Map.java
@@ -0,0 +1,154 @@
+import java.awt.Dimension;
+import java.util.ArrayList;
+
+public class Map {
+ private final Dimension size;
+ private final Tile grid[];
+ private ArrayList<Actor> actors = new ArrayList<Actor>();
+ private int actorIndex = -1;
+ private int selectedX;
+ private int selectedY;
+
+ public Map(Dimension size) {
+ this.size = size;
+
+ this.grid = new Tile[(int) this.size.getWidth() * (int) this.size.getHeight()];
+ for (int x = 0; x < this.size.getWidth(); x++) {
+ for (int y = 0; y < this.size.getHeight(); y++) {
+ this.grid[x * (int) this.size.getWidth() + y] = new Tile(Tile.Type.GRASS, x, y);
+ }
+ }
+ }
+
+ public ArrayList<Tile> getPath(Actor actor, int x, int y) {
+ ArrayList<Tile> unsettled = new ArrayList<Tile>();
+ ArrayList<Tile> settled = new ArrayList<Tile>();
+ Tile startTile = this.getTile(actor.getX(), actor.getY());
+
+ for (Tile i : this.getGrid()) {
+ i.setDistance(10000000);
+ }
+
+ startTile.setDistance(0);
+ unsettled.add(startTile);
+ settled.add(startTile);
+
+ boolean stop = false;
+ while (unsettled.size() != 0) {
+ Tile workingTile = unsettled.get(0);
+ unsettled.remove(workingTile);
+ for (Tile i : workingTile.getAdjacent(this)) {
+ if (settled.contains(i)) {
+ continue;
+ }
+ i.setDistance(i.getCost(actor) + workingTile.getDistance());
+ unsettled.add(i);
+ settled.add(i);
+ }
+ }
+ ArrayList<Tile> out = new ArrayList<Tile>();
+ Tile workingTile = this.getTile(x, y);
+ double bestDistance = 1000000000;
+ Tile bestTile = workingTile;
+ while (true) {
+ for (Tile i : workingTile.getAdjacent(this)) {
+ if (i.getDistance() < bestDistance) {
+ bestDistance = i.getDistance();
+ bestTile = i;
+ }
+ }
+ out.add(workingTile);
+ if (workingTile.getX() == startTile.getX() && workingTile.getY() == startTile.getY()) {
+ break;
+ }
+ workingTile = bestTile;
+ bestDistance = 1000000000;
+ }
+
+ return out;
+ }
+
+ public void update(ArrayList<Actor> actorsList, Tile[] tileGrid) {
+ for (Actor actor : actorsList) {
+ Actor newActor = new Actor(actor.getName(), actor.getHP(), actor.isEnemy(), actor.getAgility());
+ newActor.place(actor.getX(), actor.getY());
+ this.actors.add(newActor);
+ }
+
+ for (int x = 0; x < this.size.getWidth(); x++) {
+ for (int y = 0; y < this.size.getHeight(); y++) {
+ Tile.Type oldTileType = tileGrid[x * (int) this.size.getWidth() + y].getType();
+ this.grid[x * (int) this.size.getWidth() + y] = new Tile(oldTileType, x, y);
+ }
+ }
+ }
+
+ public void resetActors() {
+ for (Actor actor : this.actors) {
+ if (!actor.isEnemy()) {
+ actor.resetActions();
+ }
+ }
+ }
+
+ public Actor getNextActor() {
+ int counter = 0;
+ this.actorIndex++;
+ if (this.actorIndex >= this.actors.size()) {
+ this.actorIndex = 0;
+ }
+ Actor actor = this.actors.get(this.actorIndex);
+ while (actor.isEnemy() || actor.getActionsLeft() <= 0) {
+ this.actorIndex++;
+ if (this.actorIndex >= this.actors.size()) {
+ this.actorIndex = 0;
+ }
+ actor = this.actors.get(this.actorIndex);
+ if (counter > this.actors.size()*2) {
+ return null;
+ }
+ counter++;
+ }
+ return actor;
+ }
+
+ public void setCursor(int x, int y) {
+ this.getTile(this.selectedX, this.selectedY).setCursor(false);
+ if (x == -1 && y == -1) {
+ return;
+ }
+ this.getTile(x, y).setCursor(true);
+ this.selectedX = x;
+ this.selectedY = y;
+ }
+
+ public Tile[] getGrid() {
+ return this.grid;
+ }
+
+ public Tile getTile(int x, int y) {
+ return this.grid[x * (int) this.size.getWidth() + y];
+ }
+
+ public int getSize() {
+ return (int) this.size.getWidth();
+ }
+
+ public ArrayList<Actor> getActors() {
+ return this.actors;
+ }
+
+ public void removeActor(Actor actor) {
+ this.actors.remove(actor);
+ }
+
+ public void addActor(Actor actor) {
+ this.actors.add(actor);
+ }
+
+ public void clearSelected() {
+ for (Tile tile : this.grid) {
+ tile.setSelected(false);
+ }
+ }
+}
diff --git a/src/MapEditor.java b/src/MapEditor.java
new file mode 100644
index 0000000..864fab7
--- /dev/null
+++ b/src/MapEditor.java
@@ -0,0 +1,226 @@
+import java.util.ArrayList;
+import java.awt.Canvas;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferStrategy;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.JFileChooser;
+import javax.swing.JCheckBox;
+import java.lang.Integer;
+
+public class MapEditor extends MapScene {
+ private Tile.Type placingTile = Tile.Type.CLEAR;
+ private Actor placingActor = new Actor("", 0, false, 0);
+ private ArrayList<Object> actorFields = new ArrayList<>();
+ private JFrame actorFrame;
+ private boolean nukeActor = false;
+
+ public MapEditor(JFrame frame, Sub sub) {
+ super(frame, sub);
+ this.setLayout(new BorderLayout());
+
+ JPanel bottomPanel = new JPanel();
+ bottomPanel.setLayout(new GridLayout(1,5));
+
+ JButton newButton = new JButton("New");
+ newButton.setActionCommand("new");
+ JButton tileButton = new JButton("Placing selector");
+ tileButton.setActionCommand("tile");
+ JButton exportButton = new JButton("Export");
+ exportButton.setActionCommand("export");
+ JButton importButton = new JButton("Import");
+ importButton.setActionCommand("import");
+ JButton actorButton = new JButton("Actors");
+ actorButton.setActionCommand("actors");
+
+ newButton.addActionListener(this);
+ tileButton.addActionListener(this);
+ actorButton.addActionListener(this);
+ exportButton.addActionListener(this);
+ importButton.addActionListener(this);
+
+ bottomPanel.add(newButton);
+ bottomPanel.add(tileButton);
+ bottomPanel.add(actorButton);
+ bottomPanel.add(exportButton);
+ bottomPanel.add(importButton);
+
+ this.add(bottomPanel, BorderLayout.PAGE_END);
+ this.add(this.canvas, BorderLayout.CENTER);
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ int tileSize = this.maxSize/10;
+ Point2D p = new Point2D.Double(e.getX(), e.getY());
+ try {
+ p = this.tx.inverseTransform(p, null);
+ } catch (NoninvertibleTransformException ex) {}
+ try {
+ int x = (int) p.getX()/tileSize;
+ int y = (int) p.getY()/tileSize;
+ this.map.getTile(x, y);
+ if (this.placingTile != Tile.Type.NONE) {
+ this.map.getTile(x, y).setType(this.placingTile);
+ } else {
+ if (!this.nukeActor) {
+ Actor actor = this.placingActor;
+ actor.place(x, y);
+ this.map.addActor(actor);
+ } else {
+ Actor toNuke = this.placingActor;
+ for (Actor actor : this.map.getActors()) {
+ if (x == actor.getX() && y == actor.getY()) {
+ toNuke = actor;
+ }
+ }
+ this.map.removeActor(toNuke);
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ System.out.println("no tile clicked");
+ } catch (NullPointerException ext) {
+ System.out.println("map non existent");
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if ("new".equals(e.getActionCommand())) {
+ JTextField size = new JTextField();
+
+ JComponent[] inputs = new JComponent[] {
+ new JLabel("Size"),
+ size,
+ };
+
+ int result = JOptionPane.showConfirmDialog(null, inputs, "New map", JOptionPane.DEFAULT_OPTION);
+ if (result == JOptionPane.OK_OPTION) {
+ int sizeN = Integer.parseInt(size.getText());
+ this.map = new Map(new Dimension(sizeN, sizeN));
+ }
+ } else if ("tile".equals(e.getActionCommand())) {
+ String[] values = {"Clear", "Grass", "Water", "Mountain", "Actor", "Remove Actor"};
+
+ Object result = JOptionPane.showInputDialog(null, "Tile Type", "Tile Type Selector", JOptionPane.DEFAULT_OPTION, null, values, "0");
+ if (result != null) {
+ String selected = result.toString();
+ switch (selected) {
+ case "Clear":
+ this.placingTile = Tile.Type.CLEAR;
+ break;
+ case "Grass":
+ this.placingTile = Tile.Type.GRASS;
+ break;
+ case "Water":
+ this.placingTile = Tile.Type.WATER;
+ break;
+ case "Mountain":
+ this.placingTile = Tile.Type.MOUNTAIN;
+ break;
+ case "Actor":
+ this.placingTile = Tile.Type.NONE;
+ this.nukeActor = false;
+ break;
+ case "Remove Actor":
+ this.placingTile = Tile.Type.NONE;
+ this.nukeActor = true;
+ break;
+
+ }
+ }
+ } else if ("export".equals(e.getActionCommand())) {
+ JFileChooser fc = new JFileChooser();
+ fc.showSaveDialog(null);
+
+ MapLoader mapLoader = new MapLoader(fc.getSelectedFile());
+ mapLoader.saveMap(this.map);
+ } else if ("import".equals(e.getActionCommand())) {
+ JFileChooser fc = new JFileChooser();
+ fc.showOpenDialog(null);
+
+ MapLoader mapLoader = new MapLoader(fc.getSelectedFile());
+ this.map = mapLoader.getMap();
+ } else if ("actors".equals(e.getActionCommand())) {
+ JFrame actorFrame = new JFrame("Actors");
+ actorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ actorFrame.setSize(new Dimension(300, 400));
+ actorFrame.setLocationRelativeTo(null);
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new GridLayout(5,2));
+
+ JLabel lName = new JLabel("Name");
+ JTextField name = new JTextField();
+ JLabel lAgility = new JLabel("Agility");
+ JTextField agility = new JTextField();
+ JLabel lHp = new JLabel("max HP");
+ JTextField hp = new JTextField();
+ JCheckBox enemy = new JCheckBox("Enemy");
+ JLabel empty = new JLabel();
+ JButton ok = new JButton("Confirm");
+ ok.setActionCommand("actOk");
+ JButton cancel = new JButton("Cancel");
+ cancel.setActionCommand("actCancel");
+
+ ArrayList<Object> actorFields = new ArrayList<>();
+ actorFields.add(name);
+ actorFields.add(hp);
+ actorFields.add(agility);
+ actorFields.add(enemy);
+ this.actorFields = actorFields;
+
+ ok.addActionListener(this);
+ cancel.addActionListener(this);
+
+ panel.add(lName);
+ panel.add(name);
+ panel.add(lAgility);
+ panel.add(agility);
+ panel.add(lHp);
+ panel.add(hp);
+ panel.add(enemy);
+ panel.add(empty);
+ panel.add(ok);
+ panel.add(cancel);
+
+ actorFrame.add(panel);
+ actorFrame.pack();
+ actorFrame.setVisible(true);
+
+ this.actorFrame = actorFrame;
+ } else if ("actOk".equals(e.getActionCommand())) {
+ JTextField nameField = (JTextField) this.actorFields.get(0);
+ String name = nameField.getText();
+ JTextField hpField = (JTextField) this.actorFields.get(1);
+ int hp = Integer.parseInt(hpField.getText());
+ JTextField agilityField = (JTextField) this.actorFields.get(2);
+ int agility = Integer.parseInt(agilityField.getText());
+ JCheckBox enemyBox = (JCheckBox) this.actorFields.get(3);
+ Actor actor = new Actor(name, hp, enemyBox.isSelected(), agility);
+ this.placingActor = actor;
+ this.actorFrame.setVisible(false);
+ this.actorFrame.dispose();
+ } else if ("actCancel".equals(e.getActionCommand())) {
+ this.actorFrame.setVisible(false);
+ this.actorFrame.dispose();
+ }
+
+ }
+}
diff --git a/src/MapLoader.java b/src/MapLoader.java
new file mode 100644
index 0000000..6478961
--- /dev/null
+++ b/src/MapLoader.java
@@ -0,0 +1,60 @@
+import java.lang.String;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.awt.Dimension;
+import com.google.gson.Gson;
+
+class MapLoader {
+ File path;
+
+ public MapLoader(Object path) {
+ if (path instanceof java.io.File) {
+ this.path = (File) path;
+ } else {
+ this.path = new File((String) path);
+ }
+ }
+
+ public Map getMap() {
+ String mapText = "";
+ String line = null;
+ FileReader fr = null;
+ BufferedReader bf = null;
+
+ try {
+ fr = new FileReader(this.path);
+ bf = new BufferedReader(fr);
+ while ((line = bf.readLine()) != null) {
+ mapText = mapText + line;
+ }
+ bf.close();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ Gson gson = new Gson();
+ Map importMap = gson.fromJson(mapText, Map.class);
+
+ //update map with new classes
+ Map map = new Map(new Dimension(importMap.getSize(), importMap.getSize()));
+ map.update(importMap.getActors(), importMap.getGrid());
+ return map;
+ }
+
+ public void saveMap(Map map) {
+ Gson gson = new Gson();
+ String mapText = gson.toJson(map);
+ PrintWriter out = null;
+ try {
+ out = new PrintWriter(this.path + ".json");
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ }
+ out.println(mapText);
+ out.close();
+ }
+}
diff --git a/src/MapScene.java b/src/MapScene.java
new file mode 100644
index 0000000..41ad546
--- /dev/null
+++ b/src/MapScene.java
@@ -0,0 +1,229 @@
+import java.awt.Canvas;
+import java.awt.Graphics2D;
+import java.awt.BasicStroke;
+import java.awt.Dimension;
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferStrategy;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+import com.google.gson.Gson;
+
+public class MapScene extends Scene implements ActionListener {
+ protected Map map;
+ protected int panX = 0;
+ protected int panY = 0;
+ protected boolean panning = false;
+ protected double zoom = 1;
+ protected int mouseX;
+ protected int mouseY;
+ protected boolean zooming = false;
+ protected int maxSize;
+ protected AffineTransform tx = new AffineTransform();
+
+ public MapScene(JFrame frame, Sub sub) {
+ super(frame, sub);
+
+ //this.map = new Map(new Dimension(10, 10));
+ }
+
+ @Override
+ protected void render() {
+ if (this.WIDTH < this.HEIGHT) {
+ this.maxSize = WIDTH;
+ } else {
+ this.maxSize = HEIGHT;
+ }
+ if (this.map != null) {
+ Graphics2D g = (Graphics2D) this.buffer.getDrawGraphics();
+ //clear
+ g.setColor(Palette.BLACK);
+ g.fillRect(0, 0, this.WIDTH, this.HEIGHT);
+
+ //zoom and pan
+ if (this.zooming) {
+ Point2D p1 = new Point2D.Double(this.mouseX, this.mouseY);
+ Point2D p2 = null;
+ try {
+ p2 = tx.inverseTransform(p1, null);
+ } catch (NoninvertibleTransformException ex) {}
+ this.tx.setToIdentity();
+ this.tx.translate(p1.getX(), p1.getY());
+ this.tx.scale(this.zoom, this.zoom);
+ this.tx.translate(-p2.getX(), -p2.getY());
+ this.zooming = false;
+ }
+ if (this.panning) {
+ this.tx.translate(this.panX/this.zoom, this.panY/this.zoom);
+ this.panning = false;
+ this.panX = 0;
+ this.panY = 0;
+ }
+
+ g.transform(this.tx);
+
+ //draw tiles
+ int tileSize = this.maxSize / 10;
+ for (Tile tile : this.map.getGrid()) {
+ switch (tile.getType()) {
+ case CLEAR:
+ continue;
+ case GRASS:
+ g.setColor(Palette.GREEN);
+ break;
+ case WATER:
+ g.setColor(Palette.BLUE);
+ break;
+ case MOUNTAIN:
+ g.setColor(Palette.BROWN);
+ break;
+ }
+
+ g.fillRect(
+ tileSize * tile.getX(), tileSize * tile.getY(),
+ tileSize, tileSize);
+
+ if (tile.isSelected()) {
+ g.setColor(Palette.ORANGE_T);
+ //g.fillRect(tileSize * tile.getX() + tileSize/4, tileSize * tile.getY() + tileSize/4,
+ // tileSize/2, tileSize/2);
+ g.fillRect(
+ tileSize * tile.getX(), tileSize * tile.getY(),
+ tileSize, tileSize);
+ }
+
+ //TODO set as class variables the storkes
+ if (tile.cursorOnIt()) {
+ BasicStroke oldStroke = (BasicStroke) g.getStroke();
+ g.setStroke(new BasicStroke(
+ 10.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL
+ ));
+ g.setColor(Palette.ORANGE);
+ g.drawRect(
+ tileSize * tile.getX(), tileSize * tile.getY(),
+ tileSize, tileSize);
+ g.setStroke(oldStroke);
+ }
+
+
+ g.setPaint(Palette.BLACK);
+ g.drawRect(
+ tileSize * tile.getX(), tileSize * tile.getY(),
+ tileSize, tileSize);
+ }
+
+ g.setColor(Palette.ORANGE);
+ int maxBound = this.map.getSize()*tileSize;
+ g.drawRect(0, 0, maxBound, maxBound);
+
+ //draw actors
+ g.setFont(g.getFont().deriveFont(g.getFont().getSize()*2.0F));
+ for (Actor actor: this.map.getActors()) {
+ if (actor.isEnemy()) {
+ g.setColor(Palette.RED);
+ } else {
+ g.setColor(Palette.BLUE);
+ }
+ g.fillRect(tileSize * actor.getX() + tileSize/5, tileSize * actor.getY() + tileSize/5,
+ 3*tileSize/5, 3*tileSize/5);
+ g.setColor(Palette.BLACK);
+ g.drawString(actor.getName(), tileSize*actor.getX() + tileSize/5, tileSize*actor.getY()-tileSize/20);
+ g.setColor(Palette.RED);
+ g.fillRect(tileSize*actor.getX() + tileSize/5, tileSize*actor.getY()-tileSize/20+tileSize/30,
+ (tileSize*4/5), tileSize/10);
+ g.setColor(Palette.DARKGREEN);
+ g.fillRect(tileSize*actor.getX() + tileSize/5, tileSize*actor.getY()-tileSize/20+tileSize/30,
+ (tileSize*4/5)*actor.getHP()/10, tileSize/10);
+ }
+
+
+ AffineTransform invertTx = null;
+ try {
+ invertTx = this.tx.createInverse();
+ } catch (NoninvertibleTransformException ex) {}
+
+ g.transform(invertTx);
+ this.absoluteRender(g);
+
+ g.dispose();
+ this.buffer.show();
+ }
+ }
+
+ protected void absoluteRender(Graphics2D g) {
+
+ }
+
+ @Override
+ protected void update(int deltaTime) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ int keyCode = e.getKeyCode();
+ switch (keyCode) {
+ case KeyEvent.VK_UP:
+ this.panY += 10;
+ break;
+ case KeyEvent.VK_DOWN:
+ this.panY -= 10;
+ break;
+ case KeyEvent.VK_LEFT:
+ this.panX += 10;
+ break;
+ case KeyEvent.VK_RIGHT:
+ this.panX -= 10;
+ break;
+ }
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ this.mouseX = e.getX();
+ this.mouseY = e.getY();
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ this.panX += x - this.mouseX;
+ this.panY += y - this.mouseY;
+ this.mouseX = x;
+ this.mouseY = y;
+ this.panning = true;
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ this.mouseX = e.getX();
+ this.mouseY = e.getY();
+ if (this.zoom > 0.3 || e.getWheelRotation() < 0) {
+ this.zoom -= ((double) e.getWheelRotation())/5;
+ }
+ this.zooming = true;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {}
+}
diff --git a/src/Palette.java b/src/Palette.java
new file mode 100644
index 0000000..ee4d747
--- /dev/null
+++ b/src/Palette.java
@@ -0,0 +1,15 @@
+import java.awt.Color;
+
+public class Palette {
+ public final static Color BLACK = new Color(29, 31, 33);
+ public final static Color WHITE = new Color(197, 200, 198);
+ public final static Color WHITE_T = new Color(197, 200, 198, 200);
+ public final static Color RED = new Color(165, 66, 66);
+ public final static Color YELLOW = new Color(250, 198, 116);
+ public final static Color GREEN = new Color(181, 189, 104);
+ public final static Color DARKGREEN = new Color(140, 148, 64);
+ public final static Color BLUE = new Color(95, 129, 157);
+ public final static Color ORANGE = new Color(222, 147, 95);
+ public final static Color ORANGE_T = new Color(222, 147, 95, 100);
+ public final static Color BROWN = new Color(51, 41, 33);
+}
diff --git a/src/Scene.java b/src/Scene.java
new file mode 100644
index 0000000..dcc3e5e
--- /dev/null
+++ b/src/Scene.java
@@ -0,0 +1,104 @@
+import java.awt.Canvas;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.BorderLayout;
+import java.awt.event.KeyListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.image.BufferStrategy;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+public class Scene extends JPanel implements Runnable, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
+ protected int WIDTH;
+ protected int HEIGHT;
+ protected BufferStrategy buffer;
+ protected long desiredFPS = 60;
+ protected long desiredDeltaLoop = (1000*1000*1000)/desiredFPS;
+ protected JFrame frame;
+ protected boolean running;
+ protected Canvas canvas;
+ protected int guiSize = 2;
+
+ protected Scene(JFrame frame, Sub sub) {
+ this.frame = frame;
+ //getting window size
+ this.WIDTH = (int) this.frame.getSize().getWidth();
+ this.HEIGHT = (int) this.frame.getSize().getHeight();
+
+ this.canvas = new Canvas();
+
+ this.canvas.setBounds(0, 0, this.WIDTH, this.HEIGHT);
+ this.canvas.setIgnoreRepaint(true);
+
+ this.canvas.addKeyListener(this);
+ this.canvas.addMouseListener(this);
+ this.canvas.addMouseMotionListener(this);
+ this.canvas.addMouseWheelListener(this);
+ }
+
+ public void start() {
+ this.canvas.createBufferStrategy(2);
+ this.buffer = this.canvas.getBufferStrategy();
+
+ this.canvas.requestFocus();
+ this.running = true;
+ new Thread(this).start();
+ }
+
+ public void run() {
+ long beginLoopTime;
+ long endLoopTime;
+ long currentUpdateTime = System.nanoTime();
+ long lastUpdateTime;
+ long deltaLoop;
+
+ while (running) {
+ beginLoopTime = System.nanoTime();
+
+ //getting window size
+ this.WIDTH = (int) this.frame.getSize().getWidth();
+ this.HEIGHT = (int) this.frame.getSize().getHeight();
+
+ this.render();
+
+ lastUpdateTime = currentUpdateTime;
+ currentUpdateTime = System.nanoTime();
+ this.update((int) ((currentUpdateTime - lastUpdateTime)/(1000*1000)));
+
+ endLoopTime = System.nanoTime();
+ deltaLoop = endLoopTime - beginLoopTime;
+
+ if (deltaLoop > this.desiredDeltaLoop) {
+ //late
+ } else {
+ try {
+ Thread.sleep((this.desiredDeltaLoop - deltaLoop)/(1000*1000));
+ } catch (InterruptedException e ) {
+
+ }
+ }
+ }
+ }
+
+ protected void render() {}
+ protected void update(int deltaTime) {}
+
+ @Override
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {}
+ public void mouseClicked(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseDragged(MouseEvent e) {}
+ public void mouseMoved(MouseEvent e) {}
+ public void mouseWheelMoved(MouseWheelEvent e) {}
+
+}
diff --git a/src/Sub.java b/src/Sub.java
new file mode 100644
index 0000000..06e59c2
--- /dev/null
+++ b/src/Sub.java
@@ -0,0 +1,80 @@
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class Sub implements ActionListener {
+ public static final Dimension WINDOW_SIZE = new Dimension(600, 400);
+
+ private JFrame frame;
+ private JPanel menu;
+
+ public Sub() {
+ this.frame = new JFrame("Sub");
+
+ this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ this.frame.setSize(WINDOW_SIZE);
+ this.frame.setPreferredSize(WINDOW_SIZE);
+ this.frame.setLocationRelativeTo(null);
+
+ JPanel menu = new JPanel();
+ menu.setLayout(new GridLayout(3, 1));
+ JButton editor = new JButton("Editor");
+ editor.setActionCommand("editor");
+ JButton battle = new JButton("Battle");
+ battle.setActionCommand("battle");
+ JButton exit = new JButton("Exit");
+ exit.setActionCommand("exit");
+
+ editor.addActionListener(this);
+ battle.addActionListener(this);
+ exit.addActionListener(this);
+
+ menu.add(editor);
+ menu.add(battle);
+ menu.add(exit);
+
+ this.menu = menu;
+
+ this.frame.add(this.menu);
+ this.frame.pack();
+
+ this.frame.setVisible(true);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if ("editor".equals(e.getActionCommand())) {
+ MapEditor test = new MapEditor(frame, this);
+ this.frame.getContentPane().removeAll();
+ this.frame.getContentPane().invalidate();
+ this.frame.getContentPane().add(test);
+ this.frame.getContentPane().revalidate();
+ test.start();
+ } else if ("battle".equals(e.getActionCommand())) {
+ Battle test = new Battle(frame, this);
+ this.frame.getContentPane().removeAll();
+ this.frame.getContentPane().invalidate();
+ this.frame.getContentPane().add(test);
+ this.frame.getContentPane().revalidate();
+ test.start();
+ } else if ("exit".equals(e.getActionCommand())) {
+ this.frame.setVisible(false);
+ this.frame.dispose();
+ }
+ }
+
+ public void backToMenu() {
+ this.frame.getContentPane().removeAll();
+ this.frame.getContentPane().invalidate();
+ this.frame.getContentPane().add(this.menu);
+ this.frame.getContentPane().revalidate();
+ }
+
+ public static void main(String[] args) {
+ Sub sub = new Sub();
+ }
+}
diff --git a/src/Tile.java b/src/Tile.java
new file mode 100644
index 0000000..f2548f7
--- /dev/null
+++ b/src/Tile.java
@@ -0,0 +1,105 @@
+import java.util.ArrayList;
+
+public class Tile {
+ public enum Type {
+ CLEAR, GRASS, WATER, MOUNTAIN, NONE
+ };
+
+ private final int x, y;
+ private Type type;
+ private boolean selected;
+ private boolean cursorOnIt;
+ private double cost;
+ private double distance;
+
+ public Tile(Type type, int x, int y) {
+ this.setType(type);
+ this.x = x;
+ this.y = y;
+ }
+
+ public ArrayList<Tile> getAdjacent(Map map) {
+ ArrayList<Tile> out = new ArrayList<>();
+
+ if (this.getX() > 0) {
+ out.add(map.getTile(this.getX()-1, this.getY()));
+ }
+
+ if (this.getX() < map.getSize()-1) {
+ out.add(map.getTile(this.getX()+1, this.getY()));
+ }
+
+ if (this.getY() > 0) {
+ out.add(map.getTile(this.getX(), this.getY()-1));
+ }
+
+ if (this.getY() < map.getSize()-1) {
+ out.add(map.getTile(this.getX(), this.getY()+1));
+ }
+
+ return out;
+ }
+
+ public boolean cursorOnIt() {
+ return this.cursorOnIt;
+ }
+
+ public void setCursor(boolean cursor) {
+ this.cursorOnIt = cursor;
+ }
+
+ public double getDistance() {
+ return this.distance;
+ }
+
+ public void setDistance(double distance) {
+ this.distance = distance;
+ }
+
+ public double getCost(Actor actor) {
+ return this.cost;
+ }
+
+ public Type getType() {
+ return this.type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ switch (this.type) {
+ case CLEAR:
+ this.cost = 1000000000.0;
+ break;
+ case GRASS:
+ this.cost = 1.0;
+ break;
+ case WATER:
+ this.cost = 3.0;
+ break;
+ case MOUNTAIN:
+ this.cost = 8.0;
+ break;
+ }
+ }
+
+ public int getX() {
+ return this.x;
+ }
+
+ public int getY() {
+ return this.y;
+ }
+
+ public void setSelected(boolean set) {
+ this.selected = set;
+ }
+
+ public boolean toggleSelect() {
+ this.selected = !this.selected;
+ return this.selected;
+ }
+
+ public boolean isSelected() {
+ return this.selected;
+ }
+}
diff --git a/src/Weapon.java b/src/Weapon.java
new file mode 100644
index 0000000..36c2ab7
--- /dev/null
+++ b/src/Weapon.java
@@ -0,0 +1,50 @@
+public class Weapon {
+ private boolean broken;
+ private int damage;
+ private int durability;
+ private int range;
+ private String name;
+
+ public Weapon(String name, int damage, int range, int durability) {
+ this.name = name;
+ this.damage = damage;
+ this.range = range;
+ this.durability = durability;
+
+ this.broken = false;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public int getDamage() {
+ return this.damage;
+ }
+
+ public boolean damage(Actor attacker, Actor attacked, Map map) {
+ if (this.broken) {
+ return false;
+ }
+
+ this.durability--;
+ if (this.durability <= 0) {
+ this.broken = true;
+ }
+
+ if (map.getTile(attacked.getX(), attacked.getY()).isSelected()) {
+ attacked.damage(this.damage);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public int getRange() {
+ return this.range;
+ }
+
+ public int getDurability() {
+ return this.durability;
+ }
+}