package collision; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import level.Room; import sprites.Sprite; import sprites.SpriteGroup; public class CollisionManager { private Room room; private ArrayList<GroupPair> pairs = new ArrayList<GroupPair>(); private boolean pixelPerfect = true; public CollisionManager(Room r) { room = r; } public void updateRoom(Room r) { room = r; } public void manageCollisions() { if(pairs.isEmpty()) { if(pixelPerfect) { this.checkPixelPerfectCollisions(room.getSprites(), room.getSprites()); } else { this.checkBoundingBoxCollisions(room.getSprites(), room.getSprites()); } } else { if(pixelPerfect) { for(GroupPair p: pairs) { this.checkPixelPerfectCollisions(p.a.getGroup(), p.b.getGroup()); } } else { for(GroupPair p: pairs) { this.checkBoundingBoxCollisions(p.a.getGroup(), p.b.getGroup()); } } } } public void setCollisionDetectionMode(boolean pixelPerfect) { this.pixelPerfect = pixelPerfect; } public void addPair(SpriteGroup a, SpriteGroup b) { pairs.add(new GroupPair(a, b)); } public void removePair(String nameA, String nameB) { Iterator<GroupPair> it = pairs.iterator(); while(it.hasNext()) { GroupPair temp = it.next(); if(temp.nameMatches(nameA, nameB)) { it.remove(); break; } } } private void checkBoundingBoxCollisions(List<Sprite> listA, List<Sprite> listB) { for(Sprite sn: listA) sn.updateBounds(); for(Sprite sn: listB) sn.updateBounds(); for(Sprite s: listA) { LinkedList<Sprite> collided = new LinkedList<Sprite>(); for(Sprite sn: listB) { if(s == sn) continue; if(s.getBoundingBox().withinBounds(sn.getBoundingBox())) { collided.add(sn); } } if(collided.isEmpty() == false) s.collisions(collided); } } private void checkPixelPerfectCollisions(List<Sprite> listA, List<Sprite> listB) { for(Sprite sn: listA) sn.updateBounds(); for(Sprite sn: listB) sn.updateBounds(); for(Sprite s: listA) { LinkedList<Sprite> collided = new LinkedList<Sprite>(); for(Sprite sn: listB) { if(s == sn) continue; if(s.getBoundingBox().withinBounds(sn.getBoundingBox())) { double ax1 = s.getX(); //Top left X corner of sprite A double ay1 = s.getY(); // Top left Y corner of sprite A double ax2 = s.getX()+s.getWidth(); //Bottom right X corner of Sprite A. double ay2 = s.getY()+s.getHeight(); //Bottom right Y corner of Sprite A. double bx1 = sn.getX(); double by1 = sn.getY(); double bx2 = sn.getX()+sn.getWidth(); double by2 = sn.getY()+sn.getHeight(); double cx1 = 0; //Collision box top left X corner. double cx2 = 0; //Collision box top left Y corner. double cy1 = 0; //Collision box bottom right X corner. double cy2 = 0; //Collision box bottom right Y corner. int aw1 = 0; int ah1 = 0; int bw1 = 0; int bh1 = 0; if(ax1 < bx1) { cx1 = bx1; cx2 = ax2; } else { cx1 = ax1; cx2 = bx2; } if(ay1 < by1) { cy1 = by1; cy2 = ay2; } else { cy1 = ay1; cy2 = by2; } aw1 = (int) (cx1 - ax1); ah1 = (int) (cy1 - ay1); bw1 = (int) (cx1 - bx1); bh1 = (int) (cy1 - by1); boolean[][] aMask = s.getMask(); boolean[][] bMask = sn.getMask(); collisionchecking: for(int i = 0; i < (cx2-cx1); i++) { for(int j = 0; j < (cy2-cy1); j++) { if(aMask[aw1+i][ah1+j] == bMask[bw1+i][bh1+i]) { collided.add(sn); break collisionchecking; } } } if(collided.isEmpty() == false) { s.collisions(collided); } } } } } private class GroupPair { private SpriteGroup a, b; public GroupPair(SpriteGroup a, SpriteGroup b) { this.a = a; this.b = b; } public boolean nameMatches(String a, String b) { if(this.a.getName().equals(a) && this.b.getName().equals(b)) { return true; } else { return false; } } } }