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 package this(Entity entity, Shape shape) 25 { 26 _entity = entity; 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 @property bool collisionOccured() 40 { 41 return collisions.length > 0; 42 } 43 44 /// 45 Vector2 getSize(); 46 /// 47 bool intersects(RectCollider collider); 48 /// 49 bool intersects(CircleCollider collider); 50 /// 51 bool intersects(PointCollider collider); 52 /// 53 Vector2 resolve(RectCollider collider); 54 /// 55 Vector2 resolve(CircleCollider collider); 56 /// 57 Vector2 resolve(PointCollider collider); 58 59 /// 60 Vector2 getPosition() 61 { 62 return Vector2( 63 entity.position.x + offset.x, 64 entity.position.y + offset.y 65 ); 66 } 67 68 /// 69 Rect getBounds() 70 { 71 Vector2 size = getSize(); 72 Vector2 position = getPosition(); 73 74 return Rect( 75 position.x - size.x / 2, 76 position.y + size.y / 2, 77 size.x, 78 size.y 79 ); 80 } 81 82 /// 83 void addTag(int tag) 84 { 85 tags.insertBack(tag); 86 } 87 88 /// 89 void removeTag(int tag) 90 { 91 tags.remove(tag); 92 } 93 94 /// 95 bool hasTag(int tag) 96 { 97 return tags.contains(tag); 98 } 99 100 /// 101 bool intersects(Collider2D collider) 102 { 103 final switch(collider._shape) 104 { 105 case Shape.POINT: 106 return intersects(cast(PointCollider) collider); 107 case Shape.CIRCLE: 108 return intersects(cast(CircleCollider) collider); 109 case Shape.RECTANGLE: 110 return intersects(cast(RectCollider) collider); 111 } 112 } 113 114 /// Returns a vector that can be used to move the entity out of the collider 115 Vector2 resolve(Collider2D collider) 116 { 117 final switch(collider._shape) 118 { 119 case Shape.POINT: 120 return resolve(cast(PointCollider) collider); 121 case Shape.CIRCLE: 122 return resolve(cast(CircleCollider) collider); 123 case Shape.RECTANGLE: 124 return resolve(cast(RectCollider) collider); 125 } 126 } 127 }