diff options
Diffstat (limited to '')
-rw-r--r-- | src/Actor.java | 107 | ||||
-rw-r--r-- | src/Battle.java | 304 | ||||
-rw-r--r-- | src/Map.java | 154 | ||||
-rw-r--r-- | src/MapEditor.java | 226 | ||||
-rw-r--r-- | src/MapLoader.java | 60 | ||||
-rw-r--r-- | src/MapScene.java | 229 | ||||
-rw-r--r-- | src/Palette.java | 15 | ||||
-rw-r--r-- | src/Scene.java | 104 | ||||
-rw-r--r-- | src/Sub.java | 80 | ||||
-rw-r--r-- | src/Tile.java | 105 | ||||
-rw-r--r-- | src/Weapon.java | 50 |
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; + } +} |