-
Notifications
You must be signed in to change notification settings - Fork 0
/
Timeline.pde
executable file
·160 lines (146 loc) · 5.75 KB
/
Timeline.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
final int SECOND = 1000, MINUTE = 60 * SECOND;
public class Timeline implements Tickable {
String sourceFile;
int startTime = -1;
Event nextEvent = new Event("null");
boolean over = false;
int currentTime;
boolean waiting;
float waitUntil;
private Timeline(){
}
public Timeline(String source) {
sourceFile = source;
println("sourcefile set to " + sourceFile);
readEvents(source);
}
void readEvents(String source){
//Work out the list of events as read from the file.
translateEvents(loadStrings("data/timeline/" + source + ".txt"));
println("data/timeline/" + source + ".txt");
}
void translateEvents(String[] lines){ //Line by line, add to the chain of events.
Event position = nextEvent;
for(String line:lines){
line = line.trim();
position.next = translateEvent(line);
position = position.next;
}
}
boolean start(int i){
startTime = i;
return true;
}
Event translateEvent(String line){
//Then, process the lines into events
//Always call the superclass's translateEvent to ensure you don't lose any methods from above, unless it's this top class.
//Yes, I know some events return null Events (not null pointers of type Event). Luckily, this is built to handle that.
String[] split = line.split(" ");
Event e = new Event();
switch(split[0]){
case "":
case "//":
case "null":
break;
case "enemy":
if(!templates.containsKey("enemy " + split[1]))
templates.put("enemy " + split[1], new Enemy(split[1]));
e.eventType = "enemy";
e.data.put("type", split[1]);
Utility.toMap(e.data, Utility.arraySub(split, 2, split.length));
break;
case "burst":
if(!templates.containsKey("burst " + split[1])){
templates.put("burst "+split[1], new Burst(split[1]));
}
e.eventType = "burst";
e.data.put("type", split[1]);
Utility.toMap(e.data, Utility.arraySub(split, 2, split.length));
break;
case "bullet": //Literally just copies it into the list, as above. I should handle this better but overall it doesn't matter.
if(!templates.containsKey("bullet " + split[1])){
templates.put("bullet "+split[1], new Bullet(split[1]));
}
e.eventType = "bullet";
e.data.put("type", split[1]);
Utility.toMap(e.data, Utility.arraySub(split, 2, split.length));
break;
case "wait":
case "pause":
e.eventType = "wait";
e.data.put("time", new Integer(Integer.parseInt(split[1])));
break;
case "end":
case "finish":
case "stop":
e.eventType = "end";
break;
default:
break;
}
return e;
}
boolean processEvent(Event e, int time){
//Handles events as they come up in the actual execution of the timeline. The timeline-only process just spawns and waits.
//println(e.eventType);
switch(e.eventType){
case "wait":
waitUntil = time + ((Integer) e.data.get("time")).intValue();
waiting = true;
break;
case "burst":
((Burst) templates.get("burst " + (String) e.data.get("type"))).spawn(e);
break;
case "bullet":
((Bullet) templates.get("bullet " + (String) e.data.get("type"))).spawn(e);
//println("This code is the timeline bullet spawn");
break;
case "enemy":
((Enemy) templates.get("enemy " + (String) e.data.get("type"))).spawn(e);
break;
case "end":
over = true;
break;
default:
break;
}
return true;
}
boolean tick(int m) {
//Takes the interval between the current time and the last tick, as provided either from the gamemanager or its subclasses, and ticks itself.
currentTime += m;
if(startTime == -1 || over == true){
return false;
}else{
while(over == false){
if(waiting){
if(currentTime > waitUntil){
waiting = false;
}
else{
return true;
}
}
if(processEvent(nextEvent, currentTime)){
nextEvent = nextEvent.next;
if(nextEvent == null) over = true; //Catch files which didn't end their scripts properly.
}
}
return true;
}
}
void interrupt(){
waiting = false;
}
class Event{
public String eventType = "null"; //null, enemy, burst, bullet, end
public String[] datum; //In other words, if string or complex data ever needs moving. Will be obsoleted by data eventually;
public HashMap data = new HashMap<Object, Object>();
public Event next = null; //Next event, one way linked-list style. No need to ever go back, so leave the old ones to garbage collection
public Event(){
}
public Event(String eventType){
this.eventType = eventType;
}
}
}