Skip to content

Commit 8450868

Browse files
committed
Hacked in networked objects. Without Zay-ES and without Sim-ethereal,
it's all pretty hacky. I was trying to make an ES-free example but it's hard.
1 parent 3423e52 commit 8450868

File tree

12 files changed

+402
-24
lines changed

12 files changed

+402
-24
lines changed
15.6 KB
Binary file not shown.
4.55 KB
Loading

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public ConnectionState( AppState parent, String host, int port ) {
9090
this.host = host;
9191
this.port = port;
9292
}
93+
94+
public int getClientId() {
95+
return client.getClient().getId();
96+
}
9397

9498
public <T extends ClientService> T getService( Class<T> type ) {
9599
return client.getService(type);

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636

3737
package example;
3838

39+
import org.slf4j.*;
40+
3941
import com.jme3.app.Application;
40-
import com.jme3.math.ColorRGBA;
42+
import com.jme3.math.*;
4143

4244
import com.simsilica.event.EventBus;
4345
import com.simsilica.lemur.GuiGlobals;
@@ -46,6 +48,7 @@
4648

4749
import example.net.GameSessionListener;
4850
import example.net.client.GameSessionClientService;
51+
import example.view.ModelViewState;
4952
import example.view.PlayerMovementState;
5053
import example.view.SkyState;
5154
import example.view.SpaceGridState;
@@ -58,12 +61,20 @@
5861
*/
5962
public class GameSessionState extends CompositeAppState {
6063

64+
static Logger log = LoggerFactory.getLogger(GameSessionState.class);
65+
6166
private GameSessionObserver gameSessionObserver = new GameSessionObserver();
6267

68+
// Temporary reference FIXME
69+
private PlayerMovementState us;
70+
private int clientId;
71+
private int shipId;
72+
6373
public GameSessionState() {
6474
// add normal states on the super-constructor
6575
super(new MessageState(),
6676
new SkyState(),
77+
new ModelViewState(),
6778
new PlayerMovementState(),
6879
new SpaceGridState(GameConstants.GRID_CELL_SIZE, 10, new ColorRGBA(0.8f, 1f, 1f, 0.5f))
6980
//new SpaceGridState(2, 10, ColorRGBA.White)
@@ -74,6 +85,10 @@ public GameSessionState() {
7485
addChild(new InGameMenuState(false), true);
7586
}
7687

88+
public int getShipId() {
89+
return shipId;
90+
}
91+
7792
public void disconnect() {
7893
// Remove ourselves
7994
getStateManager().detach(this);
@@ -93,7 +108,12 @@ protected void initialize( Application app ) {
93108

94109
InputMapper inputMapper = GuiGlobals.getInstance().getInputMapper();
95110
inputMapper.activateGroup(MainGameFunctions.IN_GAME);
96-
111+
112+
// Temporary FIXME
113+
clientId = getState(ConnectionState.class).getClientId();
114+
us = getState(PlayerMovementState.class);
115+
shipId = getState(ConnectionState.class).getService(GameSessionClientService.class).getPlayerObject();
116+
log.info("Player object:" + shipId);
97117
}
98118

99119
@Override
@@ -127,12 +147,24 @@ protected void onDisable() {
127147
* Notified by the server about game-session related events.
128148
*/
129149
private class GameSessionObserver implements GameSessionListener {
150+
151+
@Override
130152
public void playerJoined( int clientId, String playerName, int shipId ){
131-
getState(MessageState.class).addMessage("> " + playerName + " has joined.", ColorRGBA.Yellow);
153+
getState(MessageState.class).addMessage("> " + playerName + " has joined.", ColorRGBA.Yellow);
132154
}
133155

156+
@Override
134157
public void playerLeft( int clientId, String playerName, int shipId ) {
135158
getState(MessageState.class).addMessage("> " + playerName + " has left.", ColorRGBA.Yellow);
136159
}
160+
161+
@Override
162+
public void updateObject( int objectId, Quaternion orientation, Vector3f pos ) {
163+
//System.out.println("updateObject(" + objectId + ", " + orientation + ", " + pos + ")");
164+
//System.out.println(" dir:" + orientation.mult(Vector3f.UNIT_Z));
165+
if( objectId == shipId ) {
166+
us.updatePlayerPosition(pos.x, pos.y, pos.z);
167+
}
168+
}
137169
}
138170
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
*/
5050
public interface GameSession {
5151

52+
/**
53+
* Returns the ID of the player object.
54+
*/
55+
public int getPlayerObject();
56+
5257
/**
5358
* Sends information to the game back end about the current
5459
* movement state of the player from user input. Because this

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

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

3737
package example.net;
3838

39+
import com.jme3.math.*;
3940
import com.jme3.network.service.rmi.Asynchronous;
4041

4142
/**
@@ -52,6 +53,15 @@ public interface GameSessionListener {
5253
@Asynchronous
5354
public void playerJoined( int clientId, String playerName, int shipId );
5455

56+
/**
57+
* Temporary call that updates a ship's position. This is the naive
58+
* way to do networking where everything is just blasted out all the time.
59+
* We'll at least use UDP to be timely... which means we'll also end up
60+
* dropping packets.
61+
*/
62+
@Asynchronous(reliable=false)
63+
public void updateObject( int bodyId, Quaternion orientation, Vector3f pos );
64+
5565
/**
5666
* Called when an existing player has left the game.
5767
*/

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public class GameSessionClientService extends AbstractClientService
7070
public GameSessionClientService() {
7171
}
7272

73+
@Override
74+
public int getPlayerObject() {
75+
return getDelegate().getPlayerObject();
76+
}
77+
7378
@Override
7479
public void move( Quaternion dir, Vector3f thrust ) {
7580
if( log.isTraceEnabled() ) {
@@ -150,6 +155,13 @@ public void playerJoined( int clientId, String playerName, int shipId ) {
150155
}
151156
}
152157

158+
@Override
159+
public void updateObject( int bodyId, Quaternion orientation, Vector3f pos ) {
160+
for( GameSessionListener l : listeners ) {
161+
l.updateObject(bodyId, orientation, pos);
162+
}
163+
}
164+
153165
@Override
154166
public void playerLeft( int clientId, String playerName, int shipId ) {
155167
log.debug("playerLeft(" + clientId + ", " + playerName + ")");

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

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@
5555

5656
import com.simsilica.event.EventBus;
5757
import com.simsilica.sim.GameSystemManager;
58+
import com.simsilica.sim.SimTime;
5859

5960
import example.net.GameSession;
6061
import example.net.GameSessionListener;
62+
import example.sim.Body;
63+
import example.sim.PhysicsListener;
6164
import example.sim.ShipDriver;
6265
import example.sim.SimplePhysics;
6366

@@ -82,6 +85,8 @@ public class GameSessionHostedService extends AbstractHostedConnectionService {
8285
private AccountObserver accountObserver = new AccountObserver();
8386

8487
private List<GameSessionImpl> players = new CopyOnWriteArrayList<>();
88+
// FIXME: remove array when we get rid of the naive listener
89+
private volatile GameSessionImpl[] playersArray = null;
8590

8691
public GameSessionHostedService( GameSystemManager gameSystems ) {
8792

@@ -118,6 +123,7 @@ public void start() {
118123
if( physics == null ) {
119124
throw new RuntimeException("GameSessionHostedService requires a SimplePhysics system.");
120125
}
126+
physics.addPhysicsListener(new NaivePhysicsSender());
121127
}
122128

123129
@Override
@@ -131,8 +137,13 @@ public void startHostingOnConnection( HostedConnection conn ) {
131137
// Expose the session as an RMI resource to the client
132138
RmiRegistry rmi = rmiService.getRmiRegistry(conn);
133139
rmi.share(session, GameSession.class);
134-
135-
players.add(session);
140+
141+
// FIXME: remove sync when we get rid of the naive listener
142+
synchronized( players ) {
143+
players.add(session);
144+
playersArray = null;
145+
}
146+
session.initialize();
136147

137148
// Notify all of our sessions
138149
for( GameSessionImpl player : players ) {
@@ -150,7 +161,11 @@ public void stopHostingOnConnection( HostedConnection conn ) {
150161

151162
GameSessionImpl session = getGameSession(conn);
152163
if( session != null ) {
153-
players.remove(session);
164+
// FIXME: remove sync when we get rid of the naive listener
165+
synchronized( players ) {
166+
players.remove(session);
167+
playersArray = null;
168+
}
154169

155170
// Notify all of our sessions
156171
for( GameSessionImpl player : players ) {
@@ -170,6 +185,24 @@ public void stopHostingOnConnection( HostedConnection conn ) {
170185
// when we've stopped hosting our service on it.
171186
}
172187
}
188+
189+
private GameSessionImpl[] getPlayerArray() {
190+
// Copy the reference so we're sure we are returning
191+
// what we null-check.
192+
GameSessionImpl[] result = playersArray;
193+
if( result != null ) {
194+
return result;
195+
}
196+
197+
synchronized(players) {
198+
// Check again
199+
if( playersArray == null ) {
200+
playersArray = new GameSessionImpl[players.size()];
201+
playersArray = players.toArray(playersArray);
202+
}
203+
return playersArray;
204+
}
205+
}
173206

174207
private class AccountObserver {
175208

@@ -183,6 +216,28 @@ public void onPlayerLoggedOff( AccountEvent event ) {
183216
stopHostingOnConnection(event.getConnection());
184217
}
185218
}
219+
220+
/**
221+
* A naive implementation of a physics listener that just blasts
222+
* everything out to all of the clients over UDP.
223+
*/
224+
private class NaivePhysicsSender implements PhysicsListener {
225+
226+
public void beginFrame( SimTime time ) {
227+
}
228+
229+
public void updateBody( Body body ) {
230+
// Lots of garbage created here but it's temporary
231+
Quaternion orientation = body.orientation.toQuaternion();
232+
Vector3f pos = body.pos.toVector3f();
233+
for( GameSessionImpl session : getPlayerArray() ) {
234+
session.updateObject(body.bodyId, orientation, pos);
235+
}
236+
}
237+
238+
public void endFrame( SimTime time ) {
239+
}
240+
}
186241

187242
/**
188243
* The connection-specific 'host' for the GameSession.
@@ -202,11 +257,38 @@ public GameSessionImpl( HostedConnection conn ) {
202257
this.bodyId = physics.createBody(shipDriver);
203258
}
204259

260+
public void initialize() {
261+
}
262+
205263
public void close() {
206264
// Remove out physics body
207265
physics.removeBody(bodyId);
208266
}
209267

268+
@Override
269+
public int getPlayerObject() {
270+
271+
// Cheat and tell this player about the other players by
272+
// sending late join messages
273+
// FIXME - this is a big hack because we're using it as the side-effect
274+
// of a remote get.
275+
for( GameSessionImpl player : players ) {
276+
playerJoined(player);
277+
}
278+
279+
return bodyId;
280+
}
281+
282+
@Override
283+
public void move( Quaternion rotation, Vector3f thrust ) {
284+
if( log.isTraceEnabled() ) {
285+
log.trace("move(" + rotation + ", " + thrust + ")");
286+
}
287+
288+
// Need to forward this to the game world
289+
shipDriver.applyMovementState(rotation, thrust);
290+
}
291+
210292
public void playerJoined( GameSessionImpl player ) {
211293
getCallback().playerJoined(player.conn.getId(),
212294
AccountHostedService.getPlayerName(player.conn),
@@ -219,6 +301,10 @@ public void playerLeft( GameSessionImpl player ) {
219301
player.bodyId);
220302
}
221303

304+
public void updateObject( int bodyId, Quaternion orientation, Vector3f pos ) {
305+
getCallback().updateObject(bodyId, orientation, pos);
306+
}
307+
222308
protected GameSessionListener getCallback() {
223309
if( callback == null ) {
224310
RmiRegistry rmi = rmiService.getRmiRegistry(conn);
@@ -230,15 +316,6 @@ protected GameSessionListener getCallback() {
230316
return callback;
231317
}
232318

233-
@Override
234-
public void move( Quaternion rotation, Vector3f thrust ) {
235-
if( log.isTraceEnabled() ) {
236-
log.trace("move(" + rotation + ", " + thrust + ")");
237-
}
238-
239-
// Need to forward this to the game world
240-
shipDriver.applyMovementState(rotation, thrust);
241-
}
242319
}
243320
}
244321

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,21 @@ public void applyMovementState( Quaternion orientation, Vector3f thrust ) {
6565
}
6666

6767
private double applyThrust( double v, double thrust, double tpf ) {
68-
if( v < thrust ) {
68+
if( thrust > 0 ) {
69+
// Accelerate
6970
v = Math.min(thrust, v + pickup * tpf);
70-
} else if( v > thrust ) {
71-
v = Math.max(-thrust, v - pickup * tpf);
72-
}
71+
} else if( thrust < 0 ) {
72+
// Decelerate
73+
v = Math.max(thrust, v - pickup * tpf);
74+
} else {
75+
if( v > 0 ) {
76+
// Fall to zero
77+
v = Math.max(0, v - pickup * tpf);
78+
} else {
79+
// Rist to zero
80+
v = Math.min(0, v + pickup * tpf);
81+
}
82+
}
7383
return v;
7484
}
7585

0 commit comments

Comments
 (0)