Skip to content

Commit 1fa6c6f

Browse files
committed
Added initial hit support with mini explosions and debris...
asteroids aren't broken up yet.
1 parent 2997cdf commit 1fa6c6f

File tree

10 files changed

+405
-5
lines changed

10 files changed

+405
-5
lines changed
34.4 KB
Loading

sigem/src/main/java/sigem/es/ObjectType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ public class ObjectType implements EntityComponent {
5050
public static final String TYPE_SHIP = "ship";
5151
public static final String TYPE_PLANET = "planet";
5252
public static final String TYPE_ASTEROID = "asteroid";
53+
public static final String TYPE_ASTEROID_CHUNK = "asteroidChunk";
5354
public static final String TYPE_THRUST = "thrust";
5455
public static final String TYPE_MISSILE = "missile";
56+
public static final String TYPE_PLASMA_EXPLOSION = "plasmaExplosion";
5557

5658
private int type;
5759

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* $Id$
3+
*
4+
* Copyright (c) 2019, Simsilica, LLC
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
*
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in
16+
* the documentation and/or other materials provided with the
17+
* distribution.
18+
*
19+
* 3. Neither the name of the copyright holder nor the names of its
20+
* contributors may be used to endorse or promote products derived
21+
* from this software without specific prior written permission.
22+
*
23+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34+
* OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*/
36+
37+
package sigem.sim;
38+
39+
import java.util.Random;
40+
41+
import org.slf4j.*;
42+
43+
import com.simsilica.es.*;
44+
import com.simsilica.mathd.*;
45+
import com.simsilica.sim.*;
46+
47+
import sigem.es.*;
48+
49+
/**
50+
* Checks for missile-asteroid hits or high energy asteroid
51+
* hits and implements asteroid damage.
52+
*
53+
* @author Paul Speed
54+
*/
55+
public class AsteroidHitListener extends AbstractGameSystem
56+
implements ContactListener {
57+
58+
static Logger log = LoggerFactory.getLogger(AsteroidHitListener.class);
59+
60+
private EntityData ed;
61+
private GameEntities gameEntities;
62+
private Random rand = new Random(0);
63+
64+
public AsteroidHitListener() {
65+
}
66+
67+
@Override
68+
protected void initialize() {
69+
this.ed = getSystem(EntityData.class, true);
70+
this.gameEntities = getSystem(GameEntities.class, true);
71+
72+
getSystem(CollisionSystem.class).addContactListener(this);
73+
}
74+
75+
@Override
76+
protected void terminate() {
77+
getSystem(CollisionSystem.class).removeContactListener(this);
78+
}
79+
80+
@Override
81+
public void newContact( Contact c ) {
82+
ObjectType type1 = ed.getComponent(c.b1.bodyId, ObjectType.class);
83+
ObjectType type2 = ed.getComponent(c.b2.bodyId, ObjectType.class);
84+
85+
String t1 = type1.getTypeName(ed);
86+
String t2 = type2.getTypeName(ed);
87+
88+
if( !ObjectType.TYPE_ASTEROID.equals(t1) && !ObjectType.TYPE_ASTEROID.equals(t2) ) {
89+
// Neither side is an asteroid... nothing to do
90+
return;
91+
}
92+
93+
// If either side is a chunk then we'll negate the energy
94+
if( ObjectType.TYPE_ASTEROID_CHUNK.equals(t1) || ObjectType.TYPE_ASTEROID_CHUNK.equals(t2) ) {
95+
c.energy = 0;
96+
return;
97+
}
98+
99+
log.info("contact:" + c + " types:" + t1 + ", " + t2);
100+
101+
if( ObjectType.TYPE_MISSILE.equals(t1) ) {
102+
// Blow up b2
103+
missileHit(c.b1, c.b2, c);
104+
} else if( ObjectType.TYPE_MISSILE.equals(t2) ) {
105+
// Blow up b1
106+
missileHit(c.b2, c.b1, c);
107+
}
108+
109+
}
110+
111+
protected void missileHit( Body missile, Body asteroid, Contact contact ) {
112+
EntityId shooter = ed.getComponent(missile.bodyId, CreatedBy.class).getCreatorId();
113+
log.info("Shooter:" + shooter + " name:" + ed.getComponent(shooter, Name.class));
114+
115+
ed.removeEntity(missile.bodyId);
116+
gameEntities.createExplosion(missile.pos, 1);
117+
118+
// Create some asteroid debris
119+
int count = rand.nextInt(3) + 3;
120+
for( int i = 0; i < count; i++ ) {
121+
double x = rand.nextDouble() * 2 - 1;
122+
double z = rand.nextDouble() * 2 - 1;
123+
Vec3d dir = new Vec3d(x, 0, z);
124+
double size = 0.2 + rand.nextDouble() * 0.4;
125+
126+
EntityId chunk = gameEntities.createAsteroidChunk(missile.pos, dir,
127+
new Vec3d(rand.nextDouble() + 1, rand.nextDouble(), 0),
128+
size);
129+
}
130+
131+
if( asteroid.radius <= 1 ) {
132+
// Just gone
133+
ed.removeEntity(asteroid.bodyId);
134+
return;
135+
}
136+
137+
// Else we need to break it up
138+
139+
}
140+
}

sigem/src/main/java/sigem/sim/Body.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
import java.util.concurrent.atomic.AtomicLong;
4040

41+
import com.google.common.base.MoreObjects;
42+
4143
import com.simsilica.es.EntityId;
4244
import com.simsilica.mathd.*;
4345

@@ -98,4 +100,17 @@ public void integrate( double stepTime ) {
98100
// other things know where the object is for real
99101
bounds.setCenter(pos);
100102
}
103+
104+
@Override
105+
public String toString() {
106+
return MoreObjects.toStringHelper(getClass().getSimpleName())
107+
.add("bodyId", bodyId)
108+
.add("pos", pos)
109+
.add("velocity", velocity)
110+
.add("acceleration", acceleration)
111+
.add("radius", radius)
112+
.add("invMass", invMass)
113+
.add("driver", driver)
114+
.toString();
115+
}
101116
}

sigem/src/main/java/sigem/sim/CollisionSystem.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,19 @@ public class CollisionSystem extends AbstractGameSystem
6464

6565
private SafeArrayList<Body> bodies = new SafeArrayList<>(Body.class);
6666

67+
private SafeArrayList<ContactListener> listeners = new SafeArrayList<>(ContactListener.class);
68+
6769
public CollisionSystem() {
6870
}
6971

72+
public void addContactListener( ContactListener l ) {
73+
listeners.add(l);
74+
}
75+
76+
public void removeContactListener( ContactListener l ) {
77+
listeners.remove(l);
78+
}
79+
7080
@Override
7181
protected void initialize() {
7282
this.ed = getSystem(EntityData.class);
@@ -78,6 +88,12 @@ protected void initialize() {
7888
protected void terminate() {
7989
getSystem(SimplePhysics.class).removePhysicsListener(this);
8090
}
91+
92+
protected void fireNewContact( Contact c ) {
93+
for( ContactListener l : listeners.getArray() ) {
94+
l.newContact(c);
95+
}
96+
}
8197

8298
@Override
8399
public void beginFrame( SimTime time ) {
@@ -136,6 +152,14 @@ public void endFrame( SimTime time ) {
136152
contact.energy = energy;
137153
//log.info("speed1:" + speed1 + " speed2:" + speed2 + " energy:" + energy);
138154

155+
// Notiy the listeners about the contact... this gives
156+
// them a chance to adjust contact parameters before
157+
// we deal with energy
158+
fireNewContact(contact);
159+
if( contact.energy == 0 ) {
160+
continue;
161+
}
162+
139163
// We want the collisions to be elastic... if we only
140164
// use the exact energy it will only be enough to stop
141165
// the objects, not separate them with a bounce.
@@ -181,6 +205,14 @@ private Contact checkContact( Body b1, Body b2 ) {
181205
c.cn.y = 0; // just in case
182206
c.cn.divideLocal(dist);
183207
c.pen = dist - b1.radius - b2.radius;
208+
209+
if( c.pen < 0 ) {
210+
// Put the contact point halfway between the bounaries
211+
c.cp = b1.pos.add(c.cn.mult(b1.radius + c.pen * 0.5));
212+
} else {
213+
// Put the conact point on b1's surface
214+
c.cp = b1.pos.add(c.cn.mult(b1.radius));
215+
}
184216

185217
return c;
186218
}

sigem/src/main/java/sigem/sim/Contact.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
package sigem.sim;
3838

39+
import com.google.common.base.MoreObjects;
40+
3941
import com.simsilica.mathd.*;
4042

4143
/**
@@ -55,4 +57,16 @@ public Contact( Body b1, Body b2 ) {
5557
this.b1 = b1;
5658
this.b2 = b2;
5759
}
60+
61+
@Override
62+
public String toString() {
63+
return MoreObjects.toStringHelper(getClass().getSimpleName())
64+
.add("b1", b1)
65+
.add("b2", b2)
66+
.add("pen", pen)
67+
.add("cp", cp)
68+
.add("cn", cn)
69+
.add("energy", energy)
70+
.toString();
71+
}
5872
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* $Id$
3+
*
4+
* Copyright (c) 2019, Simsilica, LLC
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
*
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in
16+
* the documentation and/or other materials provided with the
17+
* distribution.
18+
*
19+
* 3. Neither the name of the copyright holder nor the names of its
20+
* contributors may be used to endorse or promote products derived
21+
* from this software without specific prior written permission.
22+
*
23+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34+
* OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*/
36+
37+
package sigem.sim;
38+
39+
40+
/**
41+
* Notified about contacts produced by the collision system.
42+
*
43+
* @author Paul Speed
44+
*/
45+
public interface ContactListener {
46+
public void newContact( Contact c );
47+
}

0 commit comments

Comments
 (0)