|
@@ -0,0 +1,484 @@
|
|
|
+/*
|
|
|
+ * To change this license header, choose License Headers in Project Properties.
|
|
|
+ * To change this template file, choose Tools | Templates
|
|
|
+ * and open the template in the editor.
|
|
|
+ */
|
|
|
+package bs;
|
|
|
+
|
|
|
+import bswfx.BomberStudent;
|
|
|
+import java.util.HashMap;
|
|
|
+import org.json.JSONArray;
|
|
|
+import org.json.JSONObject;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @author loquicom
|
|
|
+ */
|
|
|
+public class Game {
|
|
|
+
|
|
|
+ protected HashMap<Integer, Player> player = new HashMap<>();
|
|
|
+ protected int mainPlayer;
|
|
|
+ protected int width;
|
|
|
+ protected int height;
|
|
|
+ protected String map[][];
|
|
|
+
|
|
|
+ public Game(JSONObject jo) {
|
|
|
+ //Recup la map
|
|
|
+ JSONObject joMap = jo.getJSONObject("map");
|
|
|
+ this.width = joMap.getInt("width");
|
|
|
+ this.height = joMap.getInt("height");
|
|
|
+ this.map = this.parseMap(joMap.getString("content"));
|
|
|
+ //Creation joueur principale
|
|
|
+ JSONObject joPlayer = jo.getJSONObject("player");
|
|
|
+ Player p = new Player(joPlayer, jo.getString("startPos"));
|
|
|
+ this.player.put(joPlayer.getInt("id"), p);
|
|
|
+ this.map[p.getX()][p.getY()] = "" + p.getId();
|
|
|
+ this.mainPlayer = p.getId();
|
|
|
+ //Creation autre joueurs
|
|
|
+ if (jo.has("players")) {
|
|
|
+ JSONArray ja = jo.getJSONArray("players");
|
|
|
+ for (int i = 0; i < ja.length(); i++) {
|
|
|
+ joPlayer = ja.getJSONObject(i);
|
|
|
+ int id = joPlayer.getInt("id");
|
|
|
+ if (id != this.mainPlayer) {
|
|
|
+ p = new Player(id, joPlayer.getString("pos"));
|
|
|
+ this.player.put(id, p);
|
|
|
+ this.map[p.getX()][p.getY()] = "" + id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* --- Méthodes jeu --- */
|
|
|
+ public void join(int id, String pos) {
|
|
|
+ Player p = new Player(id, pos);
|
|
|
+ this.player.put(id, p);
|
|
|
+ this.map[p.getX()][p.getY()] = "" + id;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean move(int player, int dir) {
|
|
|
+ //Recup le joueur
|
|
|
+ Player p = this.player.get(player);
|
|
|
+ if (p == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Calcul nouvelle coord
|
|
|
+ int x = p.getX();
|
|
|
+ int y = p.getY();
|
|
|
+ switch (dir) {
|
|
|
+ case Player.UP:
|
|
|
+ if (y > 0) {
|
|
|
+ y--;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Player.LEFT:
|
|
|
+ if (x > 0) {
|
|
|
+ x--;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Player.DOWN:
|
|
|
+ if (y < this.height - 1) {
|
|
|
+ y++;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Player.RIGHT:
|
|
|
+ if (x < this.width - 1) {
|
|
|
+ x++;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Regarde si le joueur marche sur un objet
|
|
|
+ switch (this.map[x][y]) {
|
|
|
+ case "cb":
|
|
|
+ this.getObject(Player.CLASSIC);
|
|
|
+ break;
|
|
|
+ case "mb":
|
|
|
+ this.getObject(Player.MINE);
|
|
|
+ break;
|
|
|
+ case "rb":
|
|
|
+ this.getObject(Player.REMOTE);
|
|
|
+ break;
|
|
|
+ case "bu":
|
|
|
+ this.getObject(Player.BOMBUP);
|
|
|
+ break;
|
|
|
+ case "bd":
|
|
|
+ this.getObject(Player.BOMBDOWN);
|
|
|
+ break;
|
|
|
+ case "f":
|
|
|
+ this.getObject(Player.FIREPOWER);
|
|
|
+ break;
|
|
|
+ case "s":
|
|
|
+ this.getObject(Player.SCOOTER);
|
|
|
+ break;
|
|
|
+ case "bl":
|
|
|
+ this.getObject(Player.BROKENLEG);
|
|
|
+ break;
|
|
|
+ case "i":
|
|
|
+ this.getObject(Player.MAJOR);
|
|
|
+ break;
|
|
|
+ case "lm":
|
|
|
+ this.getObject(Player.LIFEMAX);
|
|
|
+ break;
|
|
|
+ case "lu":
|
|
|
+ this.getObject(Player.LIFEUP);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //Deplacement
|
|
|
+ p.setDir(dir);
|
|
|
+ this.map[x][y] = "" + p.getId();
|
|
|
+ this.map[p.getX()][p.getY()] = "_";
|
|
|
+ //Met à jour le joueur
|
|
|
+ p.setX(x);
|
|
|
+ p.setY(y);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean newBomb(int type, String coord) {
|
|
|
+ //Recup la position
|
|
|
+ int pos[] = this.parseCoord(coord);
|
|
|
+ //Met la bombe sur la map
|
|
|
+ switch (type) {
|
|
|
+ case Player.CLASSIC:
|
|
|
+ this.map[pos[0]][pos[1]] = "b";
|
|
|
+ break;
|
|
|
+ case Player.MINE:
|
|
|
+ this.map[pos[0]][pos[1]] = "m";
|
|
|
+ break;
|
|
|
+ case Player.REMOTE:
|
|
|
+ this.map[pos[0]][pos[1]] = "r";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeBomb(String coord) {
|
|
|
+ int pos[] = this.parseCoord(coord);
|
|
|
+ if (this.map[pos[0]][pos[1]].equals("b") || this.map[pos[0]][pos[1]].equals("m") || this.map[pos[0]][pos[1]].equals("r")) {
|
|
|
+ this.map[pos[0]][pos[1]] = "_";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean newObject(int type, String coord) {
|
|
|
+ //Recup la position
|
|
|
+ int pos[] = this.parseCoord(coord);
|
|
|
+ //Met la bombe sur la map
|
|
|
+ switch (type) {
|
|
|
+ case Player.CLASSIC:
|
|
|
+ this.map[pos[0]][pos[1]] = "cb";
|
|
|
+ break;
|
|
|
+ case Player.MINE:
|
|
|
+ this.map[pos[0]][pos[1]] = "mb";
|
|
|
+ break;
|
|
|
+ case Player.REMOTE:
|
|
|
+ this.map[pos[0]][pos[1]] = "rb";
|
|
|
+ break;
|
|
|
+ case Player.BOMBUP:
|
|
|
+ this.map[pos[0]][pos[1]] = "bu";
|
|
|
+ break;
|
|
|
+ case Player.BOMBDOWN:
|
|
|
+ this.map[pos[0]][pos[1]] = "bd";
|
|
|
+ break;
|
|
|
+ case Player.FIREPOWER:
|
|
|
+ this.map[pos[0]][pos[1]] = "f";
|
|
|
+ break;
|
|
|
+ case Player.SCOOTER:
|
|
|
+ this.map[pos[0]][pos[1]] = "s";
|
|
|
+ break;
|
|
|
+ case Player.BROKENLEG:
|
|
|
+ this.map[pos[0]][pos[1]] = "bl";
|
|
|
+ break;
|
|
|
+ case Player.MAJOR:
|
|
|
+ this.map[pos[0]][pos[1]] = "i";
|
|
|
+ break;
|
|
|
+ case Player.LIFEUP:
|
|
|
+ this.map[pos[0]][pos[1]] = "lu";
|
|
|
+ break;
|
|
|
+ case Player.LIFEMAX:
|
|
|
+ this.map[pos[0]][pos[1]] = "lm";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean getObject(int type) {
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
+ //Creation json en fonction type
|
|
|
+ switch (type) {
|
|
|
+ case Player.CLASSIC:
|
|
|
+ param.put("type", "bomb");
|
|
|
+ param.put("class", "classic");
|
|
|
+ break;
|
|
|
+ case Player.MINE:
|
|
|
+ param.put("type", "bomb");
|
|
|
+ param.put("class", "mine");
|
|
|
+ break;
|
|
|
+ case Player.REMOTE:
|
|
|
+ param.put("type", "bomb");
|
|
|
+ param.put("class", "remote");
|
|
|
+ break;
|
|
|
+ case Player.BOMBUP:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "bomb_up");
|
|
|
+ break;
|
|
|
+ case Player.BOMBDOWN:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "bomb_down");
|
|
|
+ break;
|
|
|
+ case Player.FIREPOWER:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "fire_power");
|
|
|
+ break;
|
|
|
+ case Player.SCOOTER:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "scooter");
|
|
|
+ break;
|
|
|
+ case Player.BROKENLEG:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "broken_legs");
|
|
|
+ break;
|
|
|
+ case Player.MAJOR:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "major");
|
|
|
+ break;
|
|
|
+ case Player.LIFEUP:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "life_up");
|
|
|
+ break;
|
|
|
+ case Player.LIFEMAX:
|
|
|
+ param.put("type", "bonusMalus");
|
|
|
+ param.put("class", "life_max");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Envoi
|
|
|
+ if (!BomberStudent.bsc.send("POST", "object/new", param)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Reception
|
|
|
+ JSONObject res = BomberStudent.bsc.receive();
|
|
|
+ if (res.getInt("status") != 201) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //MaJ joueur
|
|
|
+ Player p = this.player.get(this.mainPlayer);
|
|
|
+ p.setLife(res.getInt("life"));
|
|
|
+ p.setMaxLife(res.getInt("maxLife"));
|
|
|
+ p.setSpeed(res.getInt("speed"));
|
|
|
+ p.setBomb(res.getInt("currentNbClassicBomb"));
|
|
|
+ p.setMine(res.getInt("currentNbMine"));
|
|
|
+ p.setRemote(res.getInt("currentNbRemoteBomb"));
|
|
|
+ p.setMaxBomb(res.getInt("maxNbBomb"));
|
|
|
+ //Ajout bonus
|
|
|
+ if (type == Player.FIREPOWER) {
|
|
|
+ p.setFirepower(p.getFirepower() + 1);
|
|
|
+ } else if (type == Player.MAJOR) {
|
|
|
+ System.out.println("Get major");
|
|
|
+ //p.setMajor(true); Inutile le serveur n'envoi pas les infos de degats pendant la durée du Major
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updateMap(String mapContent) {
|
|
|
+ String map[][] = this.parseMap(mapContent);
|
|
|
+ //Compare les 2 cartes
|
|
|
+ for (int i = 0; i < height; i++) {
|
|
|
+ for (int j = 0; j < width; j++) {
|
|
|
+ if (this.map[j][i].equals("*")) {
|
|
|
+ this.map[j][i] = map[j][i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updateLife(int newLife) {
|
|
|
+ Player p = this.player.get(this.mainPlayer);
|
|
|
+ //Si non invincible
|
|
|
+ if (!p.isMajor()) {
|
|
|
+ if (newLife > 0) {
|
|
|
+ p.setLife(newLife);
|
|
|
+ } else {
|
|
|
+ BomberStudent.end();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean quit(int id) {
|
|
|
+ //Recup joueur
|
|
|
+ Player p = this.player.get(id);
|
|
|
+ if (p == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Le retire
|
|
|
+ this.player.remove(id);
|
|
|
+ this.map[p.getX()][p.getY()] = "_";
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* --- Méthodes affichage --- */
|
|
|
+ public String toHtml() {
|
|
|
+ String html = "<!DOCTYPE html><html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"file:" + System.getProperty("user.dir") + "/file/css/map.css\"></head><body><div id=\"game\"><table><tbody>";
|
|
|
+ for (int i = 0; i < height; i++) {
|
|
|
+ html += "<tr>";
|
|
|
+ for (int j = 0; j < width; j++) {
|
|
|
+ html += "<td><img src=\"file:" + System.getProperty("user.dir") + "/";
|
|
|
+ switch (this.map[j][i].charAt(0)) {
|
|
|
+ case '_':
|
|
|
+ html += "file/sprite/sol.png";
|
|
|
+ break;
|
|
|
+ case '-':
|
|
|
+ html += "file/sprite/limite.png";
|
|
|
+ break;
|
|
|
+ case '*':
|
|
|
+ html += "file/sprite/mur.png";
|
|
|
+ break;
|
|
|
+ case 'b':
|
|
|
+ switch (this.map[j][i]) {
|
|
|
+ case "bu":
|
|
|
+ html += "file/sprite/bomb_up.png";
|
|
|
+ break;
|
|
|
+ case "bd":
|
|
|
+ html += "file/sprite/bomb_down.png";
|
|
|
+ break;
|
|
|
+ case "bl":
|
|
|
+ html += "file/sprite/broken_leg.png";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ html += "file/sprite/bomb.png";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'm':
|
|
|
+ switch (this.map[j][i]) {
|
|
|
+ case "mb":
|
|
|
+ html += "file/sprite/mine_bomb.png";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ html += "file/sprite/mine.png";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'r':
|
|
|
+ switch (this.map[j][i]) {
|
|
|
+ case "rb":
|
|
|
+ html += "file/sprite/remote_bomb.png";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ html += "file/sprite/remote.png";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'c':
|
|
|
+ html += "file/sprite/classic_bomb.png";
|
|
|
+ break;
|
|
|
+ case 'f':
|
|
|
+ html += "file/sprite/fire_power.png";
|
|
|
+ break;
|
|
|
+ case 's':
|
|
|
+ html += "file/sprite/scooter.png";
|
|
|
+ break;
|
|
|
+ case 'i':
|
|
|
+ html += "file/sprite/major.png";
|
|
|
+ break;
|
|
|
+ case 'l':
|
|
|
+ switch (this.map[j][i]) {
|
|
|
+ case "lu":
|
|
|
+ html += "file/sprite/life_up.png";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ html += "file/sprite/life_max.png";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '0':
|
|
|
+ case '1':
|
|
|
+ case '2':
|
|
|
+ case '3':
|
|
|
+ case '4':
|
|
|
+ case '5':
|
|
|
+ case '6':
|
|
|
+ case '7':
|
|
|
+ case '8':
|
|
|
+ case '9':
|
|
|
+ Player p = this.player.get(Integer.parseInt(this.map[j][i]));
|
|
|
+ if (p.main) {
|
|
|
+ html += "file/sprite/player.png";
|
|
|
+ } else {
|
|
|
+ html += "file/sprite/other.png";
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ html += "\"></td>";
|
|
|
+ }
|
|
|
+ html += "</tr>";
|
|
|
+ }
|
|
|
+ html += "</tbody></table></div></body></html>";
|
|
|
+ return html;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void showMap() {
|
|
|
+ for (int i = 0; i < height; i++) {
|
|
|
+ for (int j = 0; j < width; j++) {
|
|
|
+ System.out.print(this.map[j][i]);
|
|
|
+ }
|
|
|
+ System.out.println("");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* --- Getter/Setter --- */
|
|
|
+ public Player getPlayer(int index) {
|
|
|
+ return this.player.get(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getMainPlayerId() {
|
|
|
+ return this.mainPlayer;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getHeight() {
|
|
|
+ return this.height;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getWidth() {
|
|
|
+ return this.width;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* --- Methodes privée --- */
|
|
|
+ private String[][] parseMap(String mapContent) {
|
|
|
+ String[][] map = new String[this.width][this.height];
|
|
|
+ for (int i = 0; i < this.height; i++) {
|
|
|
+ for (int j = 0; j < this.width; j++) {
|
|
|
+ map[j][i] = "" + mapContent.charAt((i * this.width) + j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int[] parseCoord(String coord) {
|
|
|
+ int res[] = new int[2];
|
|
|
+ //Cherche le separateur
|
|
|
+ int pos = 0;
|
|
|
+ while (pos < coord.length()) {
|
|
|
+ if (coord.charAt(pos) == ',') {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ //Si pas de separateur
|
|
|
+ if (pos == coord.length()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //Recup les 2 string + extraction int
|
|
|
+ String substr1 = coord.substring(0, pos);
|
|
|
+ String substr2 = coord.substring(pos + 1);
|
|
|
+ res[0] = Integer.parseInt(substr1);
|
|
|
+ res[1] = Integer.parseInt(substr2);
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|