-
Notifications
You must be signed in to change notification settings - Fork 0
/
PhysicsObject.pde
177 lines (154 loc) · 6.01 KB
/
PhysicsObject.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
static final class PhysicsObjectHandler {
static private ArrayList<PhysicsObject> physicsObjects = new ArrayList<PhysicsObject>();
private PhysicsObjectHandler() {}
static void addPhysicsObject(PhysicsObject physicsObject) {
physicsObjects.add(physicsObject);
}
static void removePhysicsObject(PhysicsObject physicsObject) {
physicsObjects.remove(physicsObject);
}
static ArrayList<PhysicsObject> getAllPhysicsObjects() {
return physicsObjects;
}
// Returns an PhysicsObject at a given point. If there is no PhysicsObject at the point, it returns null.
static PhysicsObject getObjectAtPosition(Point2D point) {
ArrayList<PhysicsObject> physicsObjectsCopy = new ArrayList<PhysicsObject>(physicsObjects); // Copy physics object list to fix ConcurrentModificationException
for (PhysicsObject physicsObject : physicsObjectsCopy) {
if (physicsObject.getCollisionShape() == null) continue;
if (physicsObject.getCollisionShape().contains(point)) {
return physicsObject;
}
}
return null;
}
// Returns all PhysicsObjects that overlap with the given PhysicsObject
static ArrayList<PhysicsObject> getCollidingObjects(PhysicsObject physicsObject) {
ArrayList<PhysicsObject> collidingObjects = new ArrayList<PhysicsObject>();
ArrayList<PhysicsObject> physicsObjectsCopy = new ArrayList<PhysicsObject>(physicsObjects); // Copy physics object list to fix ConcurrentModificationException
for (PhysicsObject object : physicsObjectsCopy) {
if (physicsObject.getCollisionShape() == null) continue;
if (object.getCollisionShape() == null) continue;
CollisionShape objectCollisionShape = object.getCollisionShape();
if (objectCollisionShape.overlaps(physicsObject.getCollisionShape().getArea())) {
collidingObjects.add(object);
}
}
return collidingObjects;
}
}
abstract class PhysicsObject {
protected CollisionShape collisionShape;
protected boolean ignoreCollisions = false;
protected PVector position = new PVector();
protected PVector velocity = new PVector(0,0);
protected double speedMultiplier = 1;
protected float rotation = 0;
PhysicsObject() {
PhysicsObjectHandler.addPhysicsObject(this);
}
PhysicsObject(CollisionShape collisionShape) {
this.collisionShape = collisionShape;
PhysicsObjectHandler.addPhysicsObject(this);
}
// Called to recalculate position
// Override this
void update() {
collisionShape.setWorldTranslation(new Point2D.Double(position.x, position.y));
}
// Moves the object by its current velocity
void moveByVelocity() {
Point2D.Double targetTranslation = new Point2D.Double(position.x + velocity.x * speedMultiplier, position.y + velocity.y * speedMultiplier);
// Move along X axis
if (canMoveX(targetTranslation)) {
position.x += velocity.x * speedMultiplier;
} else {
// Move as far on the X axis as possible
if (velocity.x > 0) {
while(canMoveX(new Point2D.Double(position.x + 0.1, position.y))) {
position.x += 0.1;
}
} else {
while(canMoveX(new Point2D.Double(position.x - 0.1, position.y))) {
position.x -= 0.1;
}
}
}
// Move along Y axis
if (canMoveY(targetTranslation)) {
position.y += velocity.y * speedMultiplier;
} else {
// Move as far on the X axis as possible
if (velocity.y > 0) {
while(canMoveY(new Point2D.Double(position.x, position.y + 0.1))) {
position.y += 0.1;
}
} else {
while(canMoveY(new Point2D.Double(position.x, position.y - 0.1))) {
position.y -= 0.1;
}
}
}
}
// Returns the position of the object as a PVector
PVector getPosition() {
return position;
}
// Returns the velocity of the object as a PVector
PVector getVelocity() {
return velocity;
}
CollisionShape getCollisionShape() {
return collisionShape;
}
void removeFromWorld() {
PhysicsObjectHandler.removePhysicsObject(this);
}
// Sets the position of the object as a PVector
void setPosition(PVector position) {
this.position = position;
}
// Sets the velocity of the object as a PVector
void setVelocity(PVector velocity) {
this.velocity = velocity;
}
void setRotation(float radians) {
rotation = radians;
if (collisionShape instanceof Rotatable) ((Rotatable)collisionShape).setRotation(radians);
}
// Returns true if there isn't an object at the given point
boolean canMove(Point2D targetTranslation) {
if (ignoreCollisions) return true;
for (Point2D vertex : collisionShape.getVertices()) {
PhysicsObject physicsObject = PhysicsObjectHandler.getObjectAtPosition(new Point2D.Double(vertex.getX() + targetTranslation.getX(), vertex.getY() + targetTranslation.getY()));
if (physicsObject != this && physicsObject != null) {
return false;
}
}
return true;
}
// Returns true if there isn't an object at the given point on the X axis
boolean canMoveX(Point2D targetTranslation) {
if (ignoreCollisions) return true;
for (Point2D vertex : collisionShape.getVertices()) {
PhysicsObject physicsObject = PhysicsObjectHandler.getObjectAtPosition(new Point2D.Double(vertex.getX() + targetTranslation.getX(), vertex.getY() + position.y));
if (physicsObject != this && physicsObject != null) {
return false;
}
}
return true;
}
// Returns true if there isn't an object at the given point on the Y axis
boolean canMoveY(Point2D targetTranslation) {
if (ignoreCollisions) return true;
for (Point2D vertex : collisionShape.getVertices()) {
PhysicsObject physicsObject = PhysicsObjectHandler.getObjectAtPosition(new Point2D.Double(vertex.getX() + position.x, vertex.getY() + targetTranslation.getY()));
if (physicsObject != this && physicsObject != null) {
return false;
}
}
return true;
}
ArrayList<PhysicsObject> getAllCollisions() {
return PhysicsObjectHandler.getCollidingObjects(this);
}
}