Skip to content

Commit 3d15f68

Browse files
committed
Replays working
1 parent 81a8477 commit 3d15f68

9 files changed

Lines changed: 174 additions & 24 deletions

File tree

rectangles/engine/Platform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void handleEvent(Event e) {
126126
this.getPy().update(this, Rectangles.objects);
127127
HashMap<String, Object> data = new HashMap<>();
128128
data.put("caller", this.getUUID());
129-
Event py = new Event(Event.EVENT_PHYSICS, e.getTime() + Rectangles.physicsTimeline.getTickSize(), data);
129+
Event py = new Event(Event.EVENT_PHYSICS, e.getTime() + (long) Rectangles.physicsTimeline.getTickSize(), data);
130130
Rectangles.eventManager.raiseEvent(py);
131131
}
132132
break;

rectangles/engine/Player.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public void handleEvent(Event e) {
148148
data.put("x", s.getPy().getLocation().x);
149149
data.put("y", s.getPy().getLocation().y);
150150
Event mov = new Event(Event.EVENT_MOVEMENT, Rectangles.globalTimeline.getCurrentTime()
151-
+ Rectangles.physicsTimeline.getTickSize(), data);
151+
+ (long) Rectangles.physicsTimeline.getTickSize(), data);
152152
Rectangles.eventManager.raiseEvent(mov);
153153
}
154154
break;
@@ -178,7 +178,7 @@ public void handleEvent(Event e) {
178178
this.getPy().update(this, Rectangles.objects);
179179
HashMap<String, Object> data = new HashMap<>();
180180
data.put("caller", this.getUUID());
181-
Event py = new Event(Event.EVENT_PHYSICS, e.getTime() + Rectangles.physicsTimeline.getTickSize(), data);
181+
Event py = new Event(Event.EVENT_PHYSICS, e.getTime() + (long) Rectangles.physicsTimeline.getTickSize(), data);
182182
Rectangles.eventManager.raiseEvent(py);
183183
}
184184
break;

rectangles/engine/Rectangles.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@ public class Rectangles extends PApplet {
3535
public static Spawn[] spawnPoints = new Spawn[2];
3636
public static Random generator = new Random();
3737
public static int deathPoints = 0;
38-
public static Timeline globalTimeline = new GlobalTimeline(1000/500);
39-
public static Timeline eventTimeline = new LocalTimeline(globalTimeline, 1);
40-
public static Timeline physicsTimeline = new LocalTimeline(globalTimeline, 1);
41-
public static Timeline networkTimeline = new LocalTimeline(globalTimeline, 6);
42-
public static Timeline renderTimeline = new LocalTimeline(globalTimeline, 6);
38+
public static Timeline globalTimeline = new GlobalTimeline(1);
39+
public static Timeline eventTimeline = new LocalTimeline(globalTimeline, 2);
40+
public static Timeline physicsTimeline = new LocalTimeline(globalTimeline, 2);
41+
public static Timeline networkTimeline = new LocalTimeline(globalTimeline, 12);
42+
public static Timeline renderTimeline = new LocalTimeline(globalTimeline, 12);
4343
public static EventManager eventManager = new EventManager();
4444
public static ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
45+
public static Replay replay = new Replay();
4546

4647

4748
public static Player player;
@@ -73,6 +74,7 @@ public Rectangles(boolean isServer) {
7374
*/
7475
public void runLoop() {
7576
if (this.isServer) {
77+
// Register moving objects
7678
for (GameObj obj : movObjects) {
7779
eventManager.registerHandler(obj, Event.EVENT_COLLISION);
7880
eventManager.registerHandler(obj, Event.EVENT_MOVEMENT);
@@ -85,9 +87,15 @@ public void runLoop() {
8587
HashMap<String, Object> data = new HashMap<>();
8688
data.put("caller", obj.getUUID());
8789
Event e = new Event(Event.EVENT_PHYSICS,
88-
globalTimeline.getCurrentTime() + physicsTimeline.getTickSize(), data);
90+
globalTimeline.getCurrentTime() + (long) physicsTimeline.getTickSize(), data);
8991
eventManager.raiseEvent(e);
9092
}
93+
94+
// Register replays
95+
eventManager.registerHandler(replay, Event.EVENT_INPUT);
96+
eventManager.registerHandler(replay, Event.EVENT_MOVEMENT);
97+
eventManager.registerHandler(replay, Event.EVENT_END_REPLAY);
98+
9199
}
92100
while(true) {
93101
this.gameLoop(globalTimeline.resetDelta());
@@ -270,7 +278,7 @@ public void setup() {
270278
public void draw() {
271279
background(0);
272280
if (this.isServer) {
273-
text("Deaths: " + deathPoints , 110, 40);
281+
text("Server", 110, 40);
274282
}
275283

276284
this.renderAll(objects);
@@ -298,7 +306,8 @@ public void dispose() {
298306
}
299307

300308
public void keyPressed() {
301-
if (keyCode == LEFT || keyCode == RIGHT || key == ' ') {
309+
if (keyCode == LEFT || keyCode == RIGHT || key == ' ' || key == 'r'
310+
|| key == 's' || key == '1' || key == '2' || key == '3') {
302311
if (this.isServer) {
303312
HashMap<String, Object> data = new HashMap<>();
304313
Event e = new Event(Event.EVENT_INPUT, globalTimeline.getCurrentTime(), data);

rectangles/engine/Replay.java

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package engine;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.UUID;
6+
import java.util.concurrent.CopyOnWriteArrayList;
7+
8+
import engine.events.Event;
9+
import engine.time.LocalTimeline;
10+
import processing.core.PConstants;
11+
import processing.core.PVector;
12+
13+
public class Replay extends EngineObject {
14+
15+
private CopyOnWriteArrayList<Event> history = new CopyOnWriteArrayList<>();
16+
private CopyOnWriteArrayList<Event> startState = new CopyOnWriteArrayList<>();
17+
private LocalTimeline replayTimeline = new LocalTimeline(Rectangles.globalTimeline, 1);
18+
private boolean recording = false;
19+
private boolean playing = false;
20+
private Object lock = new Object();
21+
22+
23+
public CopyOnWriteArrayList<Event> getHistory() {
24+
return history;
25+
}
26+
27+
public void setHistory(CopyOnWriteArrayList<Event> history) {
28+
this.history = history;
29+
}
30+
31+
public LocalTimeline getReplayTimeline() {
32+
return replayTimeline;
33+
}
34+
35+
public void setReplayTimeline(LocalTimeline replayTimeline) {
36+
this.replayTimeline = replayTimeline;
37+
}
38+
39+
public boolean isRecording() {
40+
return recording;
41+
}
42+
43+
public void setRecording(boolean recording) {
44+
this.recording = recording;
45+
}
46+
47+
@Override
48+
public void handleEvent(Event e) {
49+
switch(e.getType()) {
50+
case(Event.EVENT_INPUT):
51+
switch((int) e.getData().get("keyCode")) {
52+
case('R'):
53+
synchronized (this.lock) {
54+
if (!this.recording && !this.playing) {
55+
this.recording = true;
56+
this.replayTimeline.start();
57+
this.startState.clear();
58+
this.history.clear();
59+
System.out.println("Started Recording");
60+
}
61+
62+
}
63+
break;
64+
case('S'):
65+
synchronized (this.lock) {
66+
if (!this.playing) {
67+
this.recording = false;
68+
this.playing = true;
69+
Rectangles.physicsTimeline.pause();
70+
// Make start events time after history events, then queue them
71+
for (GameObj obj : Rectangles.movObjects) {
72+
HashMap<String, Object> data = new HashMap<>();
73+
// Setting time to 0 here, change when stop recording
74+
Event s = new Event(Event.EVENT_MOVEMENT, this.replayTimeline.getCurrentTime(), data);
75+
data.put("x", obj.getPy().getLocation().x);
76+
data.put("y", obj.getPy().getLocation().y);
77+
data.put("caller", obj.getUUID());
78+
this.history.add(s);
79+
}
80+
HashMap<String, Object> data = new HashMap<>();
81+
// Setting time to 0 here, change when stop recording
82+
Event end = new Event(Event.EVENT_END_REPLAY, this.replayTimeline.getCurrentTime(), data);
83+
data.put("caller", Rectangles.player.getUUID());
84+
this.history.add(end);
85+
Rectangles.eventTimeline = new LocalTimeline(Rectangles.globalTimeline, 8);
86+
Rectangles.eventManager.getEventQueue().addAll(this.history);
87+
System.out.println("Started Replay");
88+
}
89+
}
90+
break;
91+
case('1'):
92+
Rectangles.eventTimeline = new LocalTimeline(Rectangles.globalTimeline, 8);
93+
break;
94+
case('2'):
95+
Rectangles.eventTimeline = new LocalTimeline(Rectangles.globalTimeline, 2);
96+
97+
break;
98+
case('3'):
99+
Rectangles.eventTimeline = new LocalTimeline(Rectangles.globalTimeline, 1);
100+
break;
101+
default:
102+
break;
103+
}
104+
case (Event.EVENT_MOVEMENT):
105+
synchronized (this.lock) {
106+
if (this.recording && !this.playing) {
107+
Event copy = new Event(e);
108+
copy.setTime(this.replayTimeline.getCurrentTime());
109+
copy.getData().put("isReplay", true);
110+
this.history.add(copy);
111+
}
112+
}
113+
break;
114+
case(Event.EVENT_END_REPLAY):
115+
synchronized (this.lock) {
116+
this.playing = false;
117+
Rectangles.eventTimeline = new LocalTimeline(Rectangles.globalTimeline, 2);
118+
Rectangles.physicsTimeline.unpause();
119+
}
120+
break;
121+
default:
122+
break;
123+
}
124+
}
125+
126+
public boolean isPlaying() {
127+
return this.playing;
128+
}
129+
}

rectangles/engine/events/Event.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ public class Event {
88
public static final int EVENT_DEATH = 1;
99
public static final int EVENT_SPAWN = 2;
1010
public static final int EVENT_MOVEMENT = 3;
11-
public static final int EVENT_COLLISION = 4;
12-
public static final int EVENT_PHYSICS = 5;
11+
public static final int EVENT_END_REPLAY = 4;
12+
public static final int EVENT_COLLISION = 5;
13+
public static final int EVENT_PHYSICS = 6;
1314

1415
private int type = -1;
1516

@@ -45,4 +46,11 @@ public long getTime() {
4546
public void setTime(long time) {
4647
this.time = time;
4748
}
49+
50+
// Clone event
51+
public Event(Event another) {
52+
this.type = another.type;
53+
this.time = another.time;
54+
this.data = another.data;
55+
}
4856
}

rectangles/engine/events/EventManager.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import java.util.ArrayList;
44
import java.util.Comparator;
5+
import java.util.EventObject;
56
import java.util.HashMap;
67
import java.util.concurrent.PriorityBlockingQueue;
78

9+
import org.w3c.dom.css.Rect;
10+
811
import engine.EngineObject;
912
import engine.GameObj;
1013
import engine.Rectangles;
@@ -31,7 +34,7 @@ public int compare(Event e1, Event e2) {
3134

3235

3336

34-
public void registerHandler(GameObj handler, int type) {
37+
public void registerHandler(EngineObject handler, int type) {
3538
if (!this.registrar.containsKey(type)) {
3639
this.registrar.put(type, new ArrayList<EngineObject>());
3740
}
@@ -41,14 +44,17 @@ public void registerHandler(GameObj handler, int type) {
4144
public void raiseEvent(Event e) {
4245
//System.out.println(Rectangles.eventManager.getEventQueue().size());
4346
//System.out.println(e.getType() + " : " + Rectangles.objectMap.get(e.getData().get("caller")).getType());
44-
this.eventQueue.add(e);
47+
if (e.getType() == Event.EVENT_INPUT || !Rectangles.replay.isPlaying()) {
48+
this.eventQueue.add(e);
49+
}
4550
}
4651

4752
@Override
4853
public void run() {
4954
try {
5055
Event next = this.eventQueue.take();
5156
//System.out.println(next.getType() + " : " + Rectangles.objectMap.get(next.getData().get("caller")).getType());
57+
//System.out.println(next.getData().getOrDefault("isReplay", false));
5258
if (next != null) {
5359
for (EngineObject handler : this.registrar.get(next.getType())) {
5460
handler.handleEvent(next);

rectangles/engine/time/GlobalTimeline.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public long getCurrentTime() {
6161
anchorTime = System.currentTimeMillis();
6262
}
6363
long elapsedTime = (anchorTime - this.startTime) - this.pausedTotalTime;
64-
return elapsedTime / this.tickSize;
64+
return (long) (elapsedTime / this.tickSize);
6565
}
6666

6767
@Override

rectangles/engine/time/LocalTimeline.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public long getCurrentTime() {
6565
anchorTime = anchor.getCurrentTime();
6666
}
6767
long elapsedTime = (anchorTime - this.startTime) - this.pausedTotalTime;
68-
return elapsedTime / this.tickSize;
68+
return (long) (elapsedTime / this.tickSize);
6969
}
7070

7171
@Override

rectangles/networking/Packet.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,11 @@ public Packet(PApplet inst, String serial) {
252252
break;
253253
case (PACKET_KEY_PRESS):
254254
this.keyPress = Integer.parseInt(serialData[1].split(":")[1]);
255-
if (this.keyPress == PConstants.LEFT || this.keyPress == PConstants.RIGHT || this.keyPress == ' ') {
256-
HashMap<String, Object> data = new HashMap<>();
257-
Event e = new Event(Event.EVENT_INPUT, Rectangles.globalTimeline.getCurrentTime(), data);
258-
data.put("keyCode", this.keyPress);
259-
data.put("caller", this.uuid);
260-
Rectangles.eventManager.raiseEvent(e);
261-
}
255+
HashMap<String, Object> data = new HashMap<>();
256+
Event e = new Event(Event.EVENT_INPUT, Rectangles.globalTimeline.getCurrentTime(), data);
257+
data.put("keyCode", this.keyPress);
258+
data.put("caller", this.uuid);
259+
Rectangles.eventManager.raiseEvent(e);
262260
break;
263261
default:
264262
break;

0 commit comments

Comments
 (0)