Newer
Older
CactusServer / src / main / java / cactusServer / models / CollisionManager.java
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);
			collisionBulletsAndOthersTmp(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);
				}
			}
		}
	}

	public void collisionMove(MovableObject object, Player player) {
		CollisionResult result;
		result = PhysicsUtility.checkCollision(player.getObject(), null, object.getObject(), null);
		if (result != null) {
			System.out.println("プレイヤーとオブジェクトの衝突");
			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()) {
				objMove(result, object1, true);
			} else {
				objMove(result, object2, 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));
	}
	
	private void collisionBulletsAndOthersTmp(String instanceId, Instance instance) {
//		collisionBulletAndOtherBulletsTmp(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();
				collisionBulletAndPlayersTmp(instanceId, instance, bulletOwnerPlayerId, bulletId, bullet);
//				if (!bullet.isAlive()) continue;
				collisionBulletAndObjectsTmp(instance, bulletOwnerPlayerId, bulletId, bullet);
			}
		}
	}
	
//	private void collisionBulletsAndOthers(String instanceId, Instance instance) {
//		Iterator<Map.Entry<String, HashMap<String, Bullet>>> playersBulletsEntryIt = instance.getBullets().entrySet()
//				.iterator();
//		while (playersBulletsEntryIt.hasNext()) {
//			Map.Entry<String, HashMap<String, Bullet>> playersBulletsEntry = playersBulletsEntryIt.next();
//			String bulletOwnerPlayerId = playersBulletsEntry.getKey();
//			Map<String, Bullet> bulletMap = playersBulletsEntry.getValue();
//			Iterator<Map.Entry<String, Bullet>> bulletEntryIt = bulletMap.entrySet().iterator();
//			while (bulletEntryIt.hasNext()) {
//				Map.Entry<String, Bullet> bulletEntry = bulletEntryIt.next();
//				String bulletId = bulletEntry.getKey();
//				Bullet bullet = bulletEntry.getValue();
//				boolean isRemoved = collisionBulletAndPlayers(instanceId, instance, bulletOwnerPlayerId, bulletId,
//						bullet, bulletEntryIt);
//				if (!isRemoved) {
//					collisionBulletAndObjects(instance, bulletOwnerPlayerId, bulletId, bullet, bulletEntryIt);
//				}
//			}
//		}
//	}

//	private boolean collisionBulletAndPlayers(String instanceId, Instance instance, String bulletOwnerPlayerId,
//			String bulletId, Bullet bullet, Iterator<Map.Entry<String, Bullet>> bulletEntryIt) {
//		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(自分を含む)に当たった弾を消す
//				bulletEntryIt.remove();
//				instance.getUniverse().displace(bullet.getPlaceable());
//				System.out.println(bulletId + "削除");
//				return true;
//			}
//		}
//		return false;
//	}

//	private boolean collisionBulletAndObjects(Instance instance, String bulletOwnerPlayerId, String bulletId,
//			Bullet bullet, Iterator<Map.Entry<String, Bullet>> bulletEntryIt) {
//		for (MovableObject object : instance.getObjects().values()) {
//			if (isCollision(bullet, object)) {
//				bulletEntryIt.remove();
//				instance.getUniverse().displace(bullet.getPlaceable());
//				System.out.println(bulletId + "削除");
//				return true;
//			}
//		}
//		return false;
//	}
	
	private boolean collisionBulletAndPlayersTmp(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 collisionBulletAndObjectsTmp(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 collisionBulletAndOtherBulletsTmp(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() + "生存フラグ折り (弾と弾の衝突)");
					System.out.println(bulletEntry2.getKey() + "生存フラグ折り (弾と弾の衝突)");
					break;
				}
			}
		}
	}

	private boolean isCollision(Bullet bullet, Player player) {
		CollisionResult result;
		result = PhysicsUtility.checkCollision((Object3D) (bullet.getPlaceable()), null, player.getObject(), 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);
	}
}