package org.ntlab.SproutServerMicro.battles; import framework.model3D.Placeable; import framework.model3D.Position3D; import framework.model3D.Universe; import framework.physics.Ground; import org.ntlab.SproutServerMicro.rooms.Room; import org.ntlab.SproutServerMicro.rooms.Rooms; import javax.vecmath.Vector3d; import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; /** * バトル * * @author matsumoto_k */ public class Battle { private HashMap<Integer, Team> teamMap = new HashMap<>(); // チームの情報を保持 private double time = BattlesConst.BATTLE_INIT_TIME; // タイム private Universe universe = null; private Ground ground = null; private int teamId1 = -1; // チームを判別するID private int teamId2 = -1; // チームを判別するID /** * バトルの状態に関する変数 * battle:対戦中, end:終了 */ private String state = "battle"; public Battle(Room room1, Room room2) { universe = new Universe(); teamId1 = room1.getRoomId(); teamId2 = room2.getRoomId(); teamMap.put(room1.getRoomId(), new Team(room1)); teamMap.put(room2.getRoomId(), new Team(room2)); ground = createStage(); placeStage(ground); } public Team getTeam(int roomId) { return teamMap.get(roomId); } public HashMap<Integer, Team> getTeamMap() { return teamMap; } public void setTeamMap(HashMap<Integer, Team> teamMap) { this.teamMap = teamMap; } public double getTime() { return time; } public void setTime(double time) { } public String getState() { return state; } public void setState(String state) { this.state = state; } /** * ステージを作成 * * @return ステージオブジェクト */ private Ground createStage() { String path = ""; try { path = URLDecoder.decode(Battles.getInstance().getClass().getResource("standardStage.obj").getPath(), "utf-8"); } catch (Exception e) { System.out.println("error path"); } return new StandardStage(path); } /** * ステージを配置 * * @param ground 配置するステージオブジェクト */ private void placeStage(Ground ground) { universe.place(ground); } /** * idによってチームを取得する * * @param teamId 取得したいチームのID * @return チーム */ private Team findTeamByID(int teamId) { return teamMap.get(teamId); } /** * 対戦相手のチームを取得 * * @param teamId 自身のteamId * @return 対戦相手のチーム */ private Team getOppositeTeam(int teamId) { if (teamId != teamId1) return findTeamByID(teamId1); return findTeamByID(teamId2); } /** * クライアントからのアップデート * * @param userId * @param teamId * @param playerData 更新するプレイヤーデータ */ public void update(int userId, int teamId, PlayerData playerData) { Player player = findTeamByID(teamId).findPlayerById(userId); Position3D position3D = player.getPlayerPosition3d(); // 更新する前のプレイヤーの位置を記録 Vector3d vector3d = player.getPlayerVector3d(); // 更新する前のプレイヤーの向きを状態を記録 /* プレイヤーのアップデート */ player.update(playerData.getUserPosition(), playerData.getUserVector()); /* プレイヤー同士の衝突判定 */ boolean collision = checkPlayerCollision(player, userId); player.setPlayerCollision(collision); /* プレイヤー同士が衝突していた時は前の状態に戻す */ if (player.isPlayerCollision()) { player.update(position3D, vector3d); } /* playerと相手チームの弾の衝突判定 */ checkCollisionWithWeapons(player, teamId); /* playerDataに弾の情報が含まれている ∧ プレイヤーが生きている 場合実行 */ if (playerData.isWeaponShoot() && player.isAlive()) { // switch (Role.getRole(Rooms.getInstance().roomList.get(teamId).getMemberList().get(userId).getRole())){ //case Gunman: Bullet bullet = findTeamByID(teamId).createBullet(playerData.getWeaponPosition(), playerData.getWeaponVector(), playerData.getWeaponVelocity()); universe.place(bullet.getActor()); // break; //case Witch: //Magic magic = findTeamByID(teamId).createMagic(playerData.getWeaponPosition(), playerData.getWeaponVector(), playerData.getWeaponVelocity()); //universe.place(magic.getActor()); // break; //} } /* 生存者による勝利のチェック */ updateResultByAllDead(); } /** * プレイヤーの衝突判定 * * @param player プレイヤーインスタンス * @param userId userId * @return 衝突している時はtrue, していない時はfalse */ public boolean checkPlayerCollision(Player player, int userId) { return findTeamByID(teamId1).checkCollision(player, userId) || findTeamByID(teamId2).checkCollision(player, userId); } private void playerUpdate(Player player, Position3D userPosition, Vector3d userVector) { player.update(userPosition, userVector); } /** * プレイヤーと相手チームの武器の衝突判定 * * @param player * @param teamId */ public void checkCollisionWithWeapons(Player player, int teamId) { ArrayList<Placeable> colliedObjects = getOppositeTeam(teamId).getColliedObjects(player); // 取り除くオブジェクトを取得に変更する for (Placeable obj : colliedObjects) { universe.displace(obj); } } /** * バトルをアップデートする */ public void update() { if (getTime() > 0) { this.time -= BattlesConst.UPDATE_INTERVAL; } else { updateResultByTimeOut(); return; } /* universeに配置している全ての武器を動かす */ universe.update(BattlesConst.UPDATE_INTERVAL); checkAllWeaponCollision(findTeamByID(teamId1), findTeamByID(teamId2)); updateResultByAllDead(); } /** * 両チームのプレイヤーと弾の当たり判定 */ public void checkAllWeaponCollision(Team team1, Team team2) { ArrayList<Placeable> displaceObj = team1.getColliedObjects(team2); for (Placeable obj : displaceObj) { universe.displace(obj); } displaceObj = team2.getColliedObjects(team1); for (Placeable obj : displaceObj) { universe.displace(obj); } } /** * 生存者の数によって勝敗をチェックする */ private void updateResultByTimeOut() { if (findTeamByID(teamId1).getAliveCount() > findTeamByID(teamId2).getAliveCount()) findTeamByID(teamId1).setResult(true); else findTeamByID(teamId2).setResult(true); finish(); } /** * 生存者による勝敗のチェック */ private void updateResultByAllDead() { Team team1 = findTeamByID(teamId1); Team team2 = findTeamByID(teamId2); if (team1.isAllPlayerDead() || team2.isAllPlayerDead()) { team1.setResult(!team1.isAllPlayerDead()); team2.setResult(!team2.isAllPlayerDead()); finish(); } } /** * バトルを終了させる */ public void finish() { state = "end"; Rooms.getInstance().getRoomList().get(teamId1).roomInitialize(); Rooms.getInstance().getRoomList().get(teamId2).roomInitialize(); } }