-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCellPlunker.pde
203 lines (187 loc) · 7.18 KB
/
CellPlunker.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import java.util.*;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.AbstractQueue;
/*
CellPlunker
A game where there is a grid of cells, every cell can have a state of either on or off. However, there are many different types
of cells that will act differently and make there state or other custom properties change accordinly based on its surroundings or type of cell it is. This allows you to create
interesting and complex logical systems
cell types:
static
switch cell (can be turned on or off)
constant cell (is stuck on)
dynamic
//attracter cell (attracts nearby dynamic cells)
cable cell (if any of this cells neighbors are in an 'on' state, its state is on, otherwise its state is off.
inverter cell (the same as a reader cell, but inverted
*/
PShader gridShader;
PFont fnt_main_12;
PFont fnt_main_16;
Grid grid = new Grid(500, 500);
StateUpdater stateUpdater = new StateUpdater();
Camera cam = new Camera();
User user = new User();
BlockPlacementUI blockPlacementUI = new BlockPlacementUI();
BlockMenuUI blockMenuUI = new BlockMenuUI();
ImageLoader imageDB;
GUIHandler gui;
WindowWatcher windowWatcher = new WindowWatcher();
// GUI references
TextDisplay stepCounter;
TextDisplay helpMenu;
NotificationTextDisplay loadSuccessfulDisplay;
void setup() {
size(500, 500, P2D);
surface.setResizable(true);
noSmooth();
Keyboard.keys.put('w', false);
Keyboard.keys.put('a', false);
Keyboard.keys.put('s', false);
Keyboard.keys.put('d', false);
String[] vertSource = {
"uniform mat4 transform;",
"attribute vec4 vertex;",
"void main() {",
"gl_Position = transform * vertex;",
"}"
};
String[] fragSource = {
"uniform vec2 pos;",
"uniform float scale;",
"uniform vec2 grid_dim;", // grid dimensions
"uniform vec2 screen_dim;", // screen dimensions
"void main() {",
"if(fract((gl_FragCoord.x + pos.x) / (scale * 2)) > 0.5 ^ fract((gl_FragCoord.y + pos.y) / (scale * 2)) > 0.5)",
"gl_FragColor = vec4(0.1, 0.1, 0.1, 1.0);",
"else",
"gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);",
"if (gl_FragCoord.x + pos.x < 0 || gl_FragCoord.x + pos.x > grid_dim.x * scale || (screen_dim.y - gl_FragCoord.y) + pos.y < 0 || (screen_dim.y - gl_FragCoord.y) + pos.y > grid_dim.y * scale)",
"gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
"}"
};
gridShader = new PShader(this, vertSource, fragSource);
/////////////////// Image and GUI ///////////////////
imageDB = new ImageLoader();
fnt_main_12 = loadFont("data/OpenSans-12.vlw");
fnt_main_16 = loadFont("data/OpenSans-16.vlw");
textFont(fnt_main_12);
ArrayList<AbstractGUIObject> guiObjects = new ArrayList<AbstractGUIObject>();
// Add gui objects here, ex.
// guiObjects.add(new ButtonText(new GUIPosition(16, -16), LEFT, BOTTOM, "Slow", ""));
guiObjects.add(new ButtonText(new GUIPosition(16, 16), "Save", "createSave"));
guiObjects.add(new ButtonText(new GUIPosition(16, 48), "Load", "loadSave"));
stepCounter = new TextDisplay(new GUIPosition(16, -96, LEFT, BOTTOM), 128, 128, "STEP_COUNTER", 14, #ffffff);
guiObjects.add(stepCounter);
guiObjects.add(new ButtonText(new GUIPosition(16, -64, LEFT, BOTTOM), "Fast", "setFastStepSpd"));
guiObjects.add(new ButtonText(new GUIPosition(16, -32, LEFT, BOTTOM), "Slow", "setSlowStepSpd"));
guiObjects.add(new ButtonSmall(new GUIPosition(-16 + -26, 16, RIGHT, TOP), "?", "toggleHelpMenu"));
helpMenu = new TextDisplay(new GUIPosition(-16 + -256, 42, RIGHT, TOP), 256, 288,
"Help Menu:\n"
+ "General Keys:\n"
+ "'q' - toggle block menu\n"
+ "'e' - toggle state view\n"
+ "'r' - rotate selected cell\n"
+ "Movement Keys:\n"
+ "'w' - move up\n"
+ "'a' - move left\n"
+ "'s' - move down\n"
+ "'d' - move right\n"
+ "Mouse:\n"
+ "'Left click' - place selected cell\n"
+ "'Middle drag' - make selection\n"
+ "'Middle click' - place current selection\n"
+ "'Right click' - remove selected cell\n"
+ "'Scroll Up/Down' - zoom in/out", 14, #ffffff);
helpMenu.setBackgroundColor(color(0, 0, 0, 127));
guiObjects.add(helpMenu);
loadSuccessfulDisplay = new NotificationTextDisplay("CellPlunker loaded successfully");
guiObjects.add(loadSuccessfulDisplay);
gui = new GUIHandler(guiObjects);
}
void keyPressed() {
Iterator it = Keyboard.keys.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
// If key currently pressed exists in the Keyboard Hashmap
if ((Character.valueOf(Character.toLowerCase(key))) == pair.getKey()) {
// Mark key as pressed
pair.setValue(true);
}
}
switch(key) {
case 'e':
case 'E':
grid.viewCellStates = !grid.viewCellStates;
break;
case 'q':
case 'Q':
blockMenuUI.isOpened = !blockMenuUI.isOpened;
break;
case 'r': // rotate block selected if that type of block
case 'R':
if (blockPlacementUI.previewBlock instanceof RotatableCell) {
RotatableCell toRotate = (RotatableCell) blockPlacementUI.previewBlock;
toRotate.rotateLeft();
}
break;
case 'v':
case 'V':
if (blockMenuUI.isOpened == false) {
Cell hovering = grid.cellAt(blockPlacementUI.previewBlock.pos);
if (hovering != null) {
println(hovering.toString()); // prints cell info
}
}
break;
}
}
void keyReleased() {
Iterator it = Keyboard.keys.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
// If key currently pressed exists in the Keyboard Hashmap
if ((Character.valueOf(Character.toLowerCase(key))) == pair.getKey()) {
// Mark key as pressed
pair.setValue(false);
}
}
}
void mouseWheel(MouseEvent event) {
Mouse.wheelCount = event.getCount();
}
void mousePressed(MouseEvent event) {
Mouse.justPressed = true;
Mouse.buttonRecent = mouseButton;
}
void mouseReleased(MouseEvent event) {
Mouse.justReleased = true;
}
// The game loop
void draw() {
windowWatcher.watch(); // checks for window resizing
cam.userControl();
gui.update();
// GUI references
stepCounter.text = "Steps: " + stateUpdater.stepsPerSec + "/s";
// Translations and scaling for zoom and camera panning
pushMatrix();
translate(width / 2, height / 2);
scale(cam.scale);
translate(-width / 2, -height / 2);
translate(-cam.pos.x, -cam.pos.y);
grid.draw();
blockPlacementUI.update();
popMatrix();
fill(255);
blockMenuUI.update();
gui.draw();
fill(255);
int yOffset = 64;
text("FPS: " + round(frameRate), 16, 16 + yOffset);
Mouse.resetMouseEvents();
// Lastly do the updates for the state updater
stateUpdater.update();
}