1 module prova.attachables.colliders.collider2d; 2 3 import prova; 4 5 package(prova) enum Shape { POINT, RECTANGLE, CIRCLE } 6 7 /// 8 abstract class Collider2D 9 { 10 /// 11 Vector2 offset; 12 package(prova) LinkedList!(Collider2D) collisions; 13 package(prova) LinkedList!(Collider2D) previousCollisions; 14 package(prova) SpacialMap2D spacialMap; 15 private LinkedList!(int) tags; 16 private Entity _entity; 17 private Shape _shape; 18 19 /// 20 package this(Shape shape) 21 { 22 _shape = shape; 23 collisions = new LinkedList!(Collider2D); 24 tags = new LinkedList!(int); 25 } 26 27 /// 28 @property Entity entity() 29 { 30 return _entity; 31 } 32 33 /// 34 package(prova) @property void entity(Entity entity) 35 { 36 _entity = entity; 37 } 38 39 /// 40 @property bool collisionOccured() 41 { 42 return collisions.length > 0; 43 } 44 45 /// 46 Vector2 getSize(); 47 /// 48 bool intersects(RectCollider collider); 49 /// 50 bool intersects(CircleCollider collider); 51 /// 52 bool intersects(PointCollider collider); 53 /// 54 Vector2 resolve(RectCollider collider); 55 /// 56 Vector2 resolve(CircleCollider collider); 57 /// 58 Vector2 resolve(PointCollider collider); 59 60 /// 61 Vector2 getPosition() 62 { 63 Vector3 position = _entity.getWorldPosition(); 64 65 return Vector2(position.x, position.y) + offset; 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 128 /// Should be called when a collider is resized 129 protected void updateSize() 130 { 131 if(spacialMap) { 132 spacialMap.updateBucketSize(this); 133 } 134 } 135 }