Skip to content

Commit fb43b17

Browse files
committed
Game control is hooked up to the physics object. Next I may hack in
a position feedback without SimEthereal just to show the 'bad' way to do networking.
1 parent 0655489 commit fb43b17

File tree

8 files changed

+154
-18
lines changed

8 files changed

+154
-18
lines changed

sim-eth-basic/src/main/java/example/GameSessionState.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ protected void onDisable() {
127127
* Notified by the server about game-session related events.
128128
*/
129129
private class GameSessionObserver implements GameSessionListener {
130-
public void playerJoined( int clientId, String playerName ){
130+
public void playerJoined( int clientId, String playerName, int shipId ){
131131
getState(MessageState.class).addMessage("> " + playerName + " has joined.", ColorRGBA.Yellow);
132132
}
133133

134-
public void playerLeft( int clientId, String playerName ) {
134+
public void playerLeft( int clientId, String playerName, int shipId ) {
135135
getState(MessageState.class).addMessage("> " + playerName + " has left.", ColorRGBA.Yellow);
136136
}
137137
}

sim-eth-basic/src/main/java/example/net/GameSessionListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ public interface GameSessionListener {
5050
* Called when a new player has joined the game.
5151
*/
5252
@Asynchronous
53-
public void playerJoined( int clientId, String playerName );
53+
public void playerJoined( int clientId, String playerName, int shipId );
5454

5555
/**
5656
* Called when an existing player has left the game.
5757
*/
5858
@Asynchronous
59-
public void playerLeft( int clientId, String playerName );
59+
public void playerLeft( int clientId, String playerName, int shipId );
6060
}

sim-eth-basic/src/main/java/example/net/client/GameSessionClientService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,18 @@ public void start() {
143143
private class GameSessionCallback implements GameSessionListener {
144144

145145
@Override
146-
public void playerJoined( int clientId, String playerName ) {
146+
public void playerJoined( int clientId, String playerName, int shipId ) {
147147
log.debug("playerJoined(" + clientId + ", " + playerName + ")");
148148
for( GameSessionListener l : listeners ) {
149-
l.playerJoined(clientId, playerName);
149+
l.playerJoined(clientId, playerName, shipId);
150150
}
151151
}
152152

153153
@Override
154-
public void playerLeft( int clientId, String playerName ) {
154+
public void playerLeft( int clientId, String playerName, int shipId ) {
155155
log.debug("playerLeft(" + clientId + ", " + playerName + ")");
156156
for( GameSessionListener l : listeners ) {
157-
l.playerLeft(clientId, playerName);
157+
l.playerLeft(clientId, playerName, shipId);
158158
}
159159
}
160160
}

sim-eth-basic/src/main/java/example/net/server/GameServer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public class GameServer {
7070

7171
public GameServer( int port, String description ) throws IOException {
7272
this.description = description;
73+
74+
this.systems = new GameSystemManager();
7375

7476
// Create the SpiderMonkey server and setup our standard
7577
// initial hosted services
@@ -80,14 +82,13 @@ public GameServer( int port, String description ) throws IOException {
8082
server.getServices().addServices(new RpcHostedService(),
8183
new RmiHostedService(),
8284
new AccountHostedService(description),
83-
new GameSessionHostedService()
85+
new GameSessionHostedService(systems)
8486
);
8587

86-
this.systems = new GameSystemManager();
8788
this.loop = new GameLoop(systems);
8889

8990
// Add the various game services to the GameSystemManager
90-
systems.addSystem(new SimplePhysics());
91+
systems.register(SimplePhysics.class, new SimplePhysics());
9192

9293
// Add any hosted services that require those systems to already
9394
// exist

sim-eth-basic/src/main/java/example/net/server/GameSessionHostedService.java

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,12 @@
5454
import com.jme3.network.service.rmi.RmiRegistry;
5555

5656
import com.simsilica.event.EventBus;
57+
import com.simsilica.sim.GameSystemManager;
5758

5859
import example.net.GameSession;
5960
import example.net.GameSessionListener;
61+
import example.sim.ShipDriver;
62+
import example.sim.SimplePhysics;
6063

6164
/**
6265
* Provides game session management for connected players. This is where
@@ -72,12 +75,18 @@ public class GameSessionHostedService extends AbstractHostedConnectionService {
7275

7376
private static final String ATTRIBUTE_SESSION = "game.session";
7477

78+
private GameSystemManager gameSystems;
79+
private SimplePhysics physics;
80+
7581
private RmiHostedService rmiService;
7682
private AccountObserver accountObserver = new AccountObserver();
7783

7884
private List<GameSessionImpl> players = new CopyOnWriteArrayList<>();
7985

80-
public GameSessionHostedService() {
86+
public GameSessionHostedService( GameSystemManager gameSystems ) {
87+
88+
this.gameSystems = gameSystems;
89+
8190
// We do not autohost because we want to host only when the
8291
// player is actually logged on.
8392
setAutoHost(false);
@@ -99,7 +108,18 @@ protected void onInitialize( HostedServiceManager s ) {
99108
// Register ourselves to listen for global account events
100109
EventBus.addListener(accountObserver, AccountEvent.playerLoggedOn, AccountEvent.playerLoggedOff);
101110
}
102-
111+
112+
@Override
113+
public void start() {
114+
super.start();
115+
116+
// Get the physics system... it's not available yet when onInitialize() is called.
117+
physics = gameSystems.get(SimplePhysics.class);
118+
if( physics == null ) {
119+
throw new RuntimeException("GameSessionHostedService requires a SimplePhysics system.");
120+
}
121+
}
122+
103123
@Override
104124
public void startHostingOnConnection( HostedConnection conn ) {
105125

@@ -171,19 +191,32 @@ private class GameSessionImpl implements GameSession {
171191

172192
private HostedConnection conn;
173193
private GameSessionListener callback;
194+
private int bodyId;
195+
private ShipDriver shipDriver;
174196

175197
public GameSessionImpl( HostedConnection conn ) {
176198
this.conn = conn;
199+
200+
// Create a ship for the player
201+
this.shipDriver = new ShipDriver();
202+
this.bodyId = physics.createBody(shipDriver);
203+
}
204+
205+
public void close() {
206+
// Remove out physics body
207+
physics.removeBody(bodyId);
177208
}
178209

179210
public void playerJoined( GameSessionImpl player ) {
180211
getCallback().playerJoined(player.conn.getId(),
181-
AccountHostedService.getPlayerName(player.conn));
212+
AccountHostedService.getPlayerName(player.conn),
213+
player.bodyId);
182214
}
183215

184216
public void playerLeft( GameSessionImpl player ) {
185217
getCallback().playerLeft(player.conn.getId(),
186-
AccountHostedService.getPlayerName(player.conn));
218+
AccountHostedService.getPlayerName(player.conn),
219+
player.bodyId);
187220
}
188221

189222
protected GameSessionListener getCallback() {
@@ -204,6 +237,7 @@ public void move( Quaternion rotation, Vector3f thrust ) {
204237
}
205238

206239
// Need to forward this to the game world
240+
shipDriver.applyMovementState(rotation, thrust);
207241
}
208242
}
209243
}

sim-eth-basic/src/main/java/example/sim/Body.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
* A physical body in space. These are modeled as a "point mass"
4545
* in the sense that their orientation does not integrate, nor does
4646
* it affect integration. ie: there is no rotational acceleration
47-
* or velocity. Rotation is kept because it's convenient.
47+
* or velocity (at least not yet and there won't ever be in the true
48+
* physics sense). Rotation is kept because it's convenient.
4849
*
4950
* @author Paul Speed
5051
*/
@@ -54,12 +55,12 @@ public class Body {
5455

5556
public int bodyId = nextBodyId.getAndIncrement();
5657

57-
public Quatd rotation = new Quatd();
5858
public Vec3d pos = new Vec3d();
5959
public Vec3d velocity = new Vec3d();
6060
public Vec3d acceleration = new Vec3d();
6161
public double radius = 1;
6262

63+
public Quatd orientation = new Quatd();
6364
public volatile ControlDriver driver;
6465

6566
public Body() {
@@ -75,7 +76,8 @@ public void integrate( double stepTime ) {
7576

7677
// Integrate position
7778
pos.addScaledVectorLocal(velocity, stepTime);
78-
79+
80+
//System.out.println(bodyId + " pos:" + pos + " dir:" + orientation.mult(new Vec3d(0, 0, 1)));
7981
// That's it. That's a physics engine.
8082
}
8183
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* $Id$
3+
*
4+
* Copyright (c) 2016, 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 example.sim;
38+
39+
import com.jme3.math.*;
40+
41+
import com.simsilica.mathd.*;
42+
43+
/**
44+
* Uses rotation and a 3-axis thrust vector to supply
45+
* specific velocity to a body. We ignore the normal
46+
* physics acceleration for now and just set the velocity directly
47+
* based on our accelerated thrust values.
48+
*
49+
* @author Paul Speed
50+
*/
51+
public class ShipDriver implements ControlDriver {
52+
53+
// Keep track of what the player has provided.
54+
private volatile Quaternion orientation = new Quaternion();
55+
private volatile Vector3f thrust = new Vector3f();
56+
57+
private double pickup = 3;
58+
59+
// The velocity in ship space, not world space
60+
private Vec3d velocity = new Vec3d();
61+
62+
public void applyMovementState( Quaternion orientation, Vector3f thrust ) {
63+
this.orientation = orientation;
64+
this.thrust = thrust;
65+
}
66+
67+
private double applyThrust( double v, double thrust, double tpf ) {
68+
if( v < thrust ) {
69+
v = Math.min(thrust, v + pickup * tpf);
70+
} else if( v > thrust ) {
71+
v = Math.max(-thrust, v - pickup * tpf);
72+
}
73+
return v;
74+
}
75+
76+
@Override
77+
public void update( double stepTime, Body body ) {
78+
79+
// Grab local versions of the player settings in case another
80+
// thread sets them while we are calculating.
81+
Quaternion quat = orientation;
82+
Vector3f vec = thrust;
83+
84+
velocity.x = applyThrust(velocity.x, vec.x, stepTime);
85+
velocity.y = applyThrust(velocity.y, vec.y, stepTime);
86+
velocity.z = applyThrust(velocity.z, vec.z, stepTime);
87+
88+
// Setup the current world rotation of the body
89+
body.orientation.set(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
90+
91+
// Apply the accelerated velocity oriented into world space
92+
body.velocity = body.orientation.mult(velocity, body.velocity);
93+
}
94+
}

sim-eth-basic/src/main/java/example/sim/SimplePhysics.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ public SimplePhysics() {
6363
}
6464

6565
public int createBody() {
66+
return createBody(null);
67+
}
68+
69+
public int createBody( ControlDriver driver ) {
6670
Body result = new Body();
71+
result.driver = driver;
6772
toAdd.add(result);
6873
index.put(result.bodyId, result);
6974
return result.bodyId;

0 commit comments

Comments
 (0)