awacke1 commited on
Commit
4e085bd
Β·
verified Β·
1 Parent(s): 9ddeb1a

Create frontend/script.js

Browse files
Files changed (1) hide show
  1. frontend/script.js +221 -0
frontend/script.js ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let hexSize = 40;
2
+ let hexGrid = [];
3
+ let buildings = [];
4
+ let train = { x: 0, y: 0, dir: 1 };
5
+ let monsterMode = false;
6
+ let currentMonster = 'Godzilla';
7
+ let monsterX, monsterY;
8
+ let angle = Math.PI / 6;
9
+ let debugText = "Loading...";
10
+ let playerId = null;
11
+ const sqrt3 = Math.sqrt(3);
12
+
13
+ // Streamlit connection
14
+ const { Streamlit } = window;
15
+ Streamlit.events.addEventListener("message", (event) => {
16
+ const data = event.data;
17
+ hexGrid = data.game_state.hex_grid;
18
+ buildings = data.game_state.buildings;
19
+ train = data.game_state.train;
20
+ monsterMode = data.game_state.monster_mode;
21
+ currentMonster = data.game_state.current_monster;
22
+ monsterX = data.game_state.monster_x;
23
+ monsterY = data.game_state.monster_y;
24
+ playerId = data.player_id;
25
+ selectedEmoji = data.selected_emoji;
26
+ debugText = `Player ${playerId} joined. Click to build!`;
27
+ // Set train track on row 5 if not already set
28
+ for (let i = 0; i < hexGrid.length; i++) {
29
+ if (hexGrid[i][5].type === 'empty') hexGrid[i][5].type = 'track';
30
+ }
31
+ });
32
+
33
+ function setup() {
34
+ createCanvas(800, 600);
35
+ Streamlit.setFrameHeight(650);
36
+ }
37
+
38
+ function draw() {
39
+ background(220);
40
+ drawHexGrid();
41
+ drawBuildings();
42
+ drawTrain();
43
+ if (monsterMode) drawMonster();
44
+ fill(0);
45
+ textSize(12);
46
+ text(debugText, 10, 20);
47
+ }
48
+
49
+ function drawHexGrid() {
50
+ for (let i = 0; i < hexGrid.length; i++) {
51
+ for (let j = 0; j < hexGrid[i].length; j++) {
52
+ let x = i * hexSize * 1.5;
53
+ let y = j * hexSize * sqrt3 + (i % 2 === 1 ? hexSize * sqrt3 / 2 : 0);
54
+ let z = j * hexSize * Math.sin(angle);
55
+ fill(hexGrid[i][j].type === 'track' ? 100 : 150, 200, 150);
56
+ stroke(0);
57
+ beginShape();
58
+ for (let k = 0; k < 6; k++) {
59
+ let angleRad = Math.PI / 3 * k;
60
+ vertex(x + hexSize * Math.cos(angleRad), y + hexSize * Math.sin(angleRad) - z);
61
+ }
62
+ endShape(CLOSE);
63
+ if (hexGrid[i][j].emoji) {
64
+ textSize(20);
65
+ text(hexGrid[i][j].emoji, x - 10, y + 5 - z);
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ function drawBuildings() {
72
+ buildings.forEach(b => {
73
+ let x = b.x * hexSize * 1.5;
74
+ let y = b.y * hexSize * sqrt3 + (b.x % 2 === 1 ? hexSize * sqrt3 / 2 : 0);
75
+ let z = b.y * hexSize * Math.sin(angle);
76
+ fill(b.color);
77
+ noStroke();
78
+ beginShape();
79
+ if (b.type === 'Residential') {
80
+ vertex(x + 10, y + 30 - z); vertex(x + 20, y + 10 - z); vertex(x + 30, y + 30 - z);
81
+ vertex(x + 25, y + 30 - z); vertex(x + 25, y + 35 - z); vertex(x + 15, y + 35 - z);
82
+ vertex(x + 15, y + 30 - z); vertex(x + 17, y + 25 - z); vertex(x + 23, y + 25 - z);
83
+ } else if (b.type === 'Commercial') {
84
+ vertex(x + 10, y + 35 - z); vertex(x + 15, y + 15 - z); vertex(x + 25, y + 15 - z);
85
+ vertex(x + 30, y + 35 - z); vertex(x + 27, y + 35 - z); vertex(x + 27, y + 20 - z);
86
+ vertex(x + 13, y + 20 - z); vertex(x + 13, y + 35 - z);
87
+ } else if (b.type === 'Industrial') {
88
+ vertex(x + 5, y + 35 - z); vertex(x + 15, y + 20 - z); vertex(x + 25, y + 20 - z);
89
+ vertex(x + 35, y + 35 - z); vertex(x + 30, y + 35 - z); vertex(x + 30, y + 15 - z);
90
+ vertex(x + 33, y + 15 - z); vertex(x + 33, y + 35 - z);
91
+ } else if (b.type === 'School') {
92
+ vertex(x + 5, y + 35 - z); vertex(x + 10, y + 20 - z); vertex(x + 30, y + 20 - z);
93
+ vertex(x + 35, y + 35 - z); vertex(x + 25, y + 35 - z); vertex(x + 25, y + 10 - z);
94
+ vertex(x + 27, y + 10 - z); vertex(x + 27, y + 35 - z);
95
+ } else if (b.type === 'PowerPlant') {
96
+ vertex(x + 5, y + 35 - z); vertex(x + 15, y + 15 - z); vertex(x + 25, y + 15 - z);
97
+ vertex(x + 35, y + 35 - z); vertex(x + 30, y + 35 - z); vertex(x + 30, y + 25 - z);
98
+ vertex(x + 20, y + 25 - z); vertex(x + 20, y + 35 - z);
99
+ }
100
+ endShape(CLOSE);
101
+ });
102
+ }
103
+
104
+ function drawTrain() {
105
+ let tx = train.x;
106
+ let ty = train.y;
107
+ let tz = train.y * Math.sin(angle);
108
+ fill(150, 50, 50);
109
+ noStroke();
110
+ beginShape();
111
+ vertex(tx + 10, ty + 10 - tz); vertex(tx + 30, ty + 10 - tz); vertex(tx + 35, ty + 20 - tz);
112
+ vertex(tx + 30, ty + 30 - tz); vertex(tx + 10, ty + 30 - tz); vertex(tx + 5, ty + 20 - tz);
113
+ vertex(tx + 15, ty + 20 - tz); vertex(tx + 15, ty + 15 - tz); vertex(tx + 25, ty + 15 - tz);
114
+ vertex(tx + 25, ty + 20 - tz);
115
+ endShape(CLOSE);
116
+ train.x += train.dir * 2;
117
+ if (train.x > width || train.x < 0) train.dir *= -1;
118
+ saveState();
119
+ }
120
+
121
+ function drawMonster() {
122
+ let mz = monsterY * Math.sin(angle);
123
+ fill(255, 0, 0);
124
+ noStroke();
125
+ beginShape();
126
+ if (currentMonster === 'Godzilla') {
127
+ vertex(monsterX, monsterY + 40 - mz); vertex(monsterX + 10, monsterY + 20 - mz);
128
+ vertex(monsterX + 20, monsterY - mz); vertex(monsterX + 30, monsterY + 20 - mz);
129
+ vertex(monsterX + 40, monsterY + 40 - mz); vertex(monsterX + 35, monsterY + 50 - mz);
130
+ vertex(monsterX + 25, monsterY + 60 - mz); vertex(monsterX + 15, monsterY + 50 - mz);
131
+ vertex(monsterX + 20, monsterY + 40 - mz); vertex(monsterX + 25, monsterY + 30 - mz);
132
+ } else if (currentMonster === 'GiantRobot') {
133
+ vertex(monsterX, monsterY + 40 - mz); vertex(monsterX + 10, monsterY + 20 - mz);
134
+ vertex(monsterX + 15, monsterY - mz); vertex(monsterX + 25, monsterY - mz);
135
+ vertex(monsterX + 30, monsterY + 20 - mz); vertex(monsterX + 40, monsterY + 40 - mz);
136
+ vertex(monsterX + 35, monsterY + 50 - mz); vertex(monsterX + 20, monsterY + 60 - mz);
137
+ vertex(monsterX + 5, monsterY + 50 - mz); vertex(monsterX + 15, monsterY + 30 - mz);
138
+ }
139
+ endShape(CLOSE);
140
+ monsterX += random(-5, 5);
141
+ monsterY += random(-5, 5);
142
+ monsterX = constrain(monsterX, 0, width);
143
+ monsterY = constrain(monsterY, 0, height);
144
+ saveState();
145
+ }
146
+
147
+ function mousePressed() {
148
+ let i = Math.floor(mouseX / (hexSize * 1.5));
149
+ let j = Math.floor((mouseY - (i % 2 === 1 ? hexSize * sqrt3 / 2 : 0)) / (hexSize * sqrt3));
150
+ if (i >= 0 && i < hexGrid.length && j >= 0 && j < hexGrid[0].length) {
151
+ if (hexGrid[i][j].type === 'empty' && !monsterMode) {
152
+ let selectedEmoji = window.Streamlit.initialArgs.selected_emoji;
153
+ if (['🏠', '🏑', '🏒', '🏣', '🏀', 'πŸ₯', '🏦', '🏨', '🏩', 'πŸͺ'].includes(selectedEmoji)) {
154
+ let types = ['Residential', 'Commercial', 'Industrial', 'School', 'PowerPlant'];
155
+ let colors = [[0, 200, 0], [0, 0, 200], [200, 200, 0], [200, 0, 200], [100, 100, 100]];
156
+ let idx = Math.floor(Math.random() * 5);
157
+ buildings.push({ x: i, y: j, type: types[idx], color: colors[idx], player: playerId });
158
+ hexGrid[i][j].type = 'building';
159
+ } else {
160
+ hexGrid[i][j].type = 'placed';
161
+ hexGrid[i][j].emoji = selectedEmoji;
162
+ }
163
+ debugText = `Player ${playerId} placed ${selectedEmoji} at (${i}, ${j})`;
164
+ saveState();
165
+ }
166
+ }
167
+ }
168
+
169
+ function keyPressed() {
170
+ if (key === 'm' || key === 'M') {
171
+ monsterMode = !monsterMode;
172
+ debugText = `Monster Mode: ${monsterMode}`;
173
+ saveState();
174
+ }
175
+ if (key === 'g' || key === 'G') {
176
+ currentMonster = 'Godzilla';
177
+ debugText = "Monster set to Godzilla";
178
+ saveState();
179
+ }
180
+ if (key === 'r' || key === 'R') {
181
+ currentMonster = 'GiantRobot';
182
+ debugText = "Monster set to Giant Robot";
183
+ saveState();
184
+ }
185
+ if (key === 't' || key === 'T') {
186
+ train.dir *= -1;
187
+ debugText = "Train direction reversed";
188
+ saveState();
189
+ }
190
+ }
191
+
192
+ function saveState() {
193
+ const state = {
194
+ hex_grid: hexGrid,
195
+ buildings: buildings,
196
+ train: train,
197
+ monster_mode: monsterMode,
198
+ current_monster: currentMonster,
199
+ monster_x: monsterX,
200
+ monster_y: monsterY
201
+ };
202
+ Streamlit.setComponentValue(state);
203
+ }
204
+
205
+ function toggleMonster() {
206
+ monsterMode = !monsterMode;
207
+ debugText = `Monster Mode: ${monsterMode}`;
208
+ saveState();
209
+ }
210
+
211
+ function setMonster(monster) {
212
+ currentMonster = monster;
213
+ debugText = `Monster set to ${monster}`;
214
+ saveState();
215
+ }
216
+
217
+ function reverseTrain() {
218
+ train.dir *= -1;
219
+ debugText = "Train direction reversed";
220
+ saveState();
221
+ }