package cactusServer.models; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.ntlab.radishforandroidstudio.framework.model3D.CollisionResult; import org.ntlab.radishforandroidstudio.framework.model3D.Object3D; import org.ntlab.radishforandroidstudio.framework.model3D.Position3D; import org.ntlab.radishforandroidstudio.framework.physics.PhysicsUtility; import org.ntlab.radishforandroidstudio.java3d.Vector3d; import cactusServer.entities.Bullet; import cactusServer.entities.Instance; import cactusServer.entities.MovableObject; import cactusServer.entities.Player; import net.arnx.jsonic.JSONHint; public class CollisionManager { private static CollisionManager theInstance; private HashMap<String, Instance> instances; private ArrayList<CollisionResult> resultList; private CollisionManager() { instances = Instances.getInstance().getInstances(); resultList = new ArrayList<CollisionResult>(); } public static CollisionManager getInstance() { if (theInstance == null) { theInstance = new CollisionManager(); } return theInstance; } @JSONHint(ignore = true) public ArrayList<CollisionResult> getResultList() { return resultList; } public void collisionRun(long interval) { resultList.clear(); for (String instanceId : instances.keySet()) { Instance instance = Instances.getInstance().getInstance(instanceId); instance.getUniverse().update(interval); collisionPlayersObjects(instanceId, instance); // collisionBulletsAndOthers(instanceId, instance); } } public void collisionPlayersObjects(String instanceId, Instance instance) { for (MovableObject object : instance.getObjects().values()) { for (Player player : Instances.getInstance().getPlayers(instanceId).values()) { collisionMove(object, player); } for (MovableObject object2 : instance.getObjects().values()) { if (!object.equals(object2)) { collisionMove(object, object2); } } } for (Player player : Instances.getInstance().getPlayers(instanceId).values()) { for (Player player2 : Instances.getInstance().getPlayers(instanceId).values()) { if (!player.equals(player2)) { collisionMove(player2, player); } } } } public void collisionMove(MovableObject object, Player player) { CollisionResult result; result = PhysicsUtility.checkCollision((Object3D) player.getPlaceable().getBody(), null, object.getObject(), null); if (result != null) { System.out.println("オブジェクトとプレイヤーが衝突"); System.out.println("CollisionManager#objMove1"); objMove(result, object, false); } } public void collisionMove(MovableObject object1, MovableObject object2) { CollisionResult result; result = PhysicsUtility.checkCollision(object1.getObject(), null, object2.getObject(), null); if (result != null) { System.out.println(); Vector3d vec1 = object1.getVelocity().getVector3d(); Vector3d vec2 = object2.getVelocity().getVector3d(); if (vec1.length() > vec2.length()) { System.out.println("CollisionManager#objMove2"); objMove(result, object1, true); } else { System.out.println("CollisionManager#objMove2"); objMove(result, object2, true); } } } public void collisionMove(Player player1, Player player2) { CollisionResult result; result = PhysicsUtility.checkCollision((Object3D) player1.getPlaceable().getBody(), null, (Object3D) player2.getPlaceable().getBody(), null); if (result != null) { System.out.println("プレイヤー同士が衝突"); objMove(result, player1, true); } } private void objMove(CollisionResult result, MovableObject object, boolean negate) { result.normal.scale(-1); Vector3d vec = object.getPosition().getVector3d(); if (negate) result.normal.negate(); vec.add(result.normal); object.setPosition(new Position3D(vec)); System.out.println("CollisionManager#objMove3:" + this + ":" + new Position3D(vec)); } private void objMove(CollisionResult result, Player player, boolean negate) { result.normal.scale(-1); Vector3d vec = player.getPosition().getVector3d(); if (negate) result.normal.negate(); vec.add(result.normal); player.setPosition(new Position3D(vec)); } private void collisionBulletsAndOthers(String instanceId, Instance instance) { // collisionBulletAndOtherBullets(instance); for (Map.Entry<String, HashMap<String, Bullet>> playersBulletsEntry : instance.getBullets().entrySet()) { String bulletOwnerPlayerId = playersBulletsEntry.getKey(); Map<String, Bullet> bulletMap = playersBulletsEntry.getValue(); for (Map.Entry<String, Bullet> bulletEntry : bulletMap.entrySet()) { Bullet bullet = bulletEntry.getValue(); if (!bullet.isAlive()) continue; String bulletId = bulletEntry.getKey(); // collisionBulletAndPlayers(instanceId, instance, bulletOwnerPlayerId, bulletId, bullet); if (!bullet.isAlive()) continue; // collisionBulletAndObjects(instance, bulletOwnerPlayerId, bulletId, bullet); } } } private boolean collisionBulletAndPlayers(String instanceId, Instance instance, String bulletOwnerPlayerId, String bulletId, Bullet bullet) { Instances instances = Instances.getInstance(); for (Map.Entry<String, Player> playersEntry : instances.getPlayers(instanceId).entrySet()) { if (isCollision(bullet, playersEntry.getValue())) { if (!(playersEntry.getKey().equals(bulletOwnerPlayerId))) { // Player(自分を除く)と弾が当たった時の処理を書く } // Player(自分を含む)に当たった弾の生存フラグを折る bullet.setAlive(false); System.out.println(bulletId + " と プレイヤーの衝突"); return true; } } return false; } private boolean collisionBulletAndObjects(Instance instance, String bulletOwnerPlayerId, String bulletId, Bullet bullet) { for (MovableObject object : instance.getObjects().values()) { if (isCollision(bullet, object)) { bullet.setAlive(false); System.out.println(bulletId + " と 可動物の衝突"); return true; } } return false; } private void collisionBulletAndOtherBullets(Instance instance) { List<Map.Entry<String, Bullet>> allBulletsEntryList = new ArrayList<>(); for (HashMap<String, Bullet> playerBullets : instance.getBullets().values()) { allBulletsEntryList.addAll(playerBullets.entrySet()); } for (int i = 0; i < allBulletsEntryList.size() - 1; i++) { Map.Entry<String, Bullet> bulletEntry1 = allBulletsEntryList.get(i); Bullet bullet1 = bulletEntry1.getValue(); if (!bullet1.isAlive()) continue; for (int j = i + 1; j < allBulletsEntryList.size(); j++) { Map.Entry<String, Bullet> bulletEntry2 = allBulletsEntryList.get(j); Bullet bullet2 = bulletEntry2.getValue(); if (!bullet2.isAlive()) continue; if (isCollision(bullet1, bullet2)) { bullet1.setAlive(false); bullet2.setAlive(false); System.out.println(bulletEntry1.getKey() + " と " + bulletEntry2.getKey() + "の衝突"); break; } } } } private boolean isCollision(Bullet bullet, Player player) { CollisionResult result; result = PhysicsUtility.checkCollision((Object3D) (bullet.getPlaceable()), null, (Object3D) player.getPlaceable().getBody(), null); return (result != null); } private boolean isCollision(Bullet bullet, MovableObject object) { CollisionResult result; result = PhysicsUtility.checkCollision((Object3D) (bullet.getPlaceable()), null, object.getObject(), null); return (result != null); } private boolean isCollision(Bullet bullet1, Bullet bullet2) { CollisionResult result; result = PhysicsUtility.checkCollision((Object3D) (bullet1.getPlaceable()), null, (Object3D) (bullet2.getPlaceable()), null); return (result != null); } }