1 module prova.collision.collider2d; 2 3 import prova.collision, 4 prova.collision.intersects, 5 prova.collision.resolve, 6 prova.core, 7 prova.graphics, 8 prova.math, 9 prova.util; 10 11 package enum Shape { POINT, RECTANGLE, CIRCLE } 12 13 /// 14 abstract class Collider2D 15 { 16 /// 17 Vector2 offset; 18 package LinkedList!(Collider2D) collisions; 19 package LinkedList!(Collider2D) previousCollisions; 20 private LinkedList!(int) tags; 21 private Entity _entity; 22 private Shape _shape; 23 24 /// 25 package this(Shape shape) 26 { 27 _shape = shape; 28 collisions = new LinkedList!(Collider2D); 29 tags = new LinkedList!(int); 30 } 31 32 /// 33 @property Entity entity() 34 { 35 return _entity; 36 } 37 38 /// 39 package(prova) @property void entity(Entity entity) 40 { 41 _entity = entity; 42 } 43 44 /// 45 @property bool collisionOccured() 46 { 47 return collisions.length > 0; 48 } 49 50 /// 51 Vector2 getSize(); 52 /// 53 bool intersects(RectCollider collider); 54 /// 55 bool intersects(CircleCollider collider); 56 /// 57 bool intersects(PointCollider collider); 58 /// 59 Vector2 resolve(RectCollider collider); 60 /// 61 Vector2 resolve(CircleCollider collider); 62 /// 63 Vector2 resolve(PointCollider collider); 64 65 /// 66 Vector2 getPosition() 67 { 68 Vector3 position = _entity.getWorldPosition(); 69 70 return Vector2(position.x, position.y); 71 } 72 73 /// 74 Rect getBounds() 75 { 76 Vector2 size = getSize(); 77 Vector2 position = getPosition(); 78 79 return Rect( 80 position.x - size.x / 2, 81 position.y + size.y / 2, 82 size.x, 83 size.y 84 ); 85 } 86 87 /// 88 void addTag(int tag) 89 { 90 tags.insertBack(tag); 91 } 92 93 /// 94 void removeTag(int tag) 95 { 96 tags.remove(tag); 97 } 98 99 /// 100 bool hasTag(int tag) 101 { 102 return tags.contains(tag); 103 } 104 105 /// 106 bool intersects(Collider2D collider) 107 { 108 final switch(collider._shape) 109 { 110 case Shape.POINT: 111 return intersects(cast(PointCollider) collider); 112 case Shape.CIRCLE: 113 return intersects(cast(CircleCollider) collider); 114 case Shape.RECTANGLE: 115 return intersects(cast(RectCollider) collider); 116 } 117 } 118 119 /// Returns a vector that can be used to move the entity out of the collider 120 Vector2 resolve(Collider2D collider) 121 { 122 final switch(collider._shape) 123 { 124 case Shape.POINT: 125 return resolve(cast(PointCollider) collider); 126 case Shape.CIRCLE: 127 return resolve(cast(CircleCollider) collider); 128 case Shape.RECTANGLE: 129 return resolve(cast(RectCollider) collider); 130 } 131 } 132 }