-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExplosion.pde
89 lines (73 loc) · 2.56 KB
/
Explosion.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
class Explosion extends Entity {
float radius;
float damage;
float force;
int duration;
int destructions;
Explosion(PVector origin, float radius, float force, SoundFile sound) {
this.zIndex = 1200;
this.origin = origin;
this.radius = radius;
this.damage = 0.0;
this.force = force;
this.duration = 350;
this.destructions = 0;
this.updateBoundingBox();
this.applyForce();
PVector vecToCamera = PVector.sub(camera.origin, this.origin);
float distToCamera = vecToCamera.mag();
float shakeMult = map(constrain(distToCamera, 40.0, 320.0), 40.0, 320.0, 1.0, 0.5);
camera.shake(new CameraShake(
force * 0.2 * shakeMult,
(int)(radius * 16 * shakeMult),
vecToCamera.heading()
));
sound.play();
}
long getRestDuration() {
return this.duration - (this.getTicksAlive() * TICK_MS);
}
float getRestDurationFrac() {
return this.getRestDuration() / (float)this.duration;
}
void applyForce() {
List<PhysicsEntity> affectedEntities = new ArrayList<PhysicsEntity>();
affectedEntities.addAll(entities.getByClass(Tank.class));
affectedEntities.addAll(entities.getByClass(DebugBall.class));
for (PhysicsEntity entity : affectedEntities) {
float forceFrac = 1.0 - min(PVector.dist(entity.origin, this.origin) / this.radius, 1.0);
entity.applyForce(PVector.sub(entity.origin, this.origin).setMag(this.force * forceFrac));
}
}
void destroyGeometry() {
PVector[] circle = getCircleVertices(this.origin, this.radius / 1.5, 16);
for (Geometry geo : entities.getByClass(Geometry.class)) {
PVector[][] polygons = subtractPolygons(geo.getVertices(), circle);
for (PVector[] polygon : polygons) {
new Geometry(polygon, geo.colorFill, geo.solid).spawn();
}
geo.delete();
}
this.destructions++;
}
void updateBoundingBox() {
this.boundingBox = this.getBoundingBoxForRadius(this.radius);
}
void OnTick() {
float restDurationFrac = this.getRestDurationFrac();
if (this.destructions == 0 && restDurationFrac < 0.5)
this.destroyGeometry();
if (restDurationFrac <= 0)
this.delete();
}
void OnDraw() {
final float OPACITY_FRAC = 0.3; // fraction of the lifetime at the start AND end to fade in AND out respectively
float durationFrac = 1.0 - this.getRestDurationFrac();
float opacity = lerp(0, 0.9, 1.0 - (max((abs(durationFrac - 0.5) - (0.5 - OPACITY_FRAC)), 0.0) / OPACITY_FRAC));
float radius = lerp(this.radius / 5, this.radius, durationFrac);
color colorFill = lerpColor(color(#fff996), color(#ff4a3d), durationFrac);
noStroke();
fill(colorFill, opacity);
circle(this.origin.x, this.origin.y, radius * 2);
}
}