awacke1 commited on
Commit
b07c26b
·
verified ·
1 Parent(s): 6e7673f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -59
app.py CHANGED
@@ -9,10 +9,13 @@ from math import cos, sin, pi
9
  # Constants
10
  GRID_SIZE = 10
11
  MAX_PLAYERS = 10
12
- UPDATE_INTERVAL = 3
13
  GAME_STATE_FILE = "game_state.json"
14
  CELL_SIZE = 50
15
  PLAYER_SIZE = 40
 
 
 
16
 
17
  # Initialize session state
18
  if "player_name" not in st.session_state:
@@ -34,15 +37,45 @@ def save_game_state(state):
34
  with open(GAME_STATE_FILE, "w") as f:
35
  json.dump(state, f)
36
 
37
- # Function to update player position
38
- def update_player_position(player_name, x, y):
39
  state = load_game_state()
40
  if player_name in state["players"]:
41
- state["players"][player_name]["x"] = x
42
- state["players"][player_name]["y"] = y
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  else:
44
  if len(state["players"]) < MAX_PLAYERS:
45
- state["players"][player_name] = {"x": x, "y": y, "color": st.session_state.player_color}
 
 
 
 
 
 
46
  save_game_state(state)
47
 
48
  # Function to generate SVG for the game board
@@ -93,9 +126,6 @@ def generate_svg(game_state):
93
  # Player name
94
  svg += f'<text x="{x}" y="{y + PLAYER_SIZE // 2 + 15}" text-anchor="middle" fill="black" font-size="12" font-weight="bold">{player[:3].upper()}</text>'
95
 
96
- # Movement animations
97
- svg += f'<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0 0" to="0 0" dur="0.5s" repeatCount="1" />'
98
-
99
  svg += '</g>'
100
 
101
  # Draw obstacles
@@ -109,7 +139,7 @@ def generate_svg(game_state):
109
  return svg
110
 
111
  # Streamlit app
112
- st.set_page_config(layout="wide", page_title="Multiplayer Grid Game")
113
  st.title("Enhanced Multiplayer Grid Game")
114
 
115
  # Display player name and allow updates
@@ -118,7 +148,7 @@ with col1:
118
  player_name = st.text_input("Your name", value=st.session_state.player_name)
119
  if player_name != st.session_state.player_name:
120
  st.session_state.player_name = player_name
121
- update_player_position(player_name, GRID_SIZE // 2, GRID_SIZE // 2)
122
 
123
  with col2:
124
  st.color_picker("Choose your color", value=st.session_state.player_color, key="player_color")
@@ -126,31 +156,44 @@ with col2:
126
  # Create grid
127
  grid = st.empty()
128
 
129
- # JavaScript for smooth movement and player highlight
130
  js_code = """
131
- function movePlayer(playerId, fromX, fromY, toX, toY) {
132
- const player = document.getElementById(playerId);
133
- if (player) {
134
- const animation = player.querySelector('animateTransform');
135
- animation.setAttribute('from', `${fromX - toX} ${fromY - toY}`);
136
- animation.setAttribute('to', '0 0');
137
- animation.beginElement();
138
-
139
- // Update player position after animation
140
- setTimeout(() => {
141
- const transform = player.getAttribute('transform') || '';
142
- player.setAttribute('transform', transform + ` translate(${toX - fromX} ${toY - fromY})`);
143
- }, 500);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
  }
146
 
147
- function pulsePlayer(playerId) {
 
 
148
  const player = document.getElementById(playerId);
149
  if (player) {
150
- const polygon = player.querySelector('polygon');
151
- const originalColor = polygon.getAttribute('fill');
152
- polygon.setAttribute('fill', '#ff0000');
153
- setTimeout(() => polygon.setAttribute('fill', originalColor), 300);
154
  }
155
  }
156
  """
@@ -166,33 +209,43 @@ if "obstacles" not in game_state:
166
  ]
167
  save_game_state(game_state)
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  # Main game loop
170
- while True:
171
- # Load current game state
172
- game_state = load_game_state()
173
-
174
- # Generate and display SVG
175
- svg = generate_svg(game_state)
176
- grid.markdown(svg, unsafe_allow_html=True)
177
-
178
- # Handle player movement
179
- col1, col2 = st.columns(2)
180
- with col1:
181
- if st.button("Select Your Character"):
182
- st.session_state.selected_player = st.session_state.player_name
183
- st_javascript(f"pulsePlayer('player-{st.session_state.player_name}')")
184
-
185
- with col2:
186
- if st.session_state.selected_player:
187
- target_x = st.number_input("Target X", min_value=0, max_value=GRID_SIZE-1, value=GRID_SIZE//2)
188
- target_y = st.number_input("Target Y", min_value=0, max_value=GRID_SIZE-1, value=GRID_SIZE//2)
189
- if st.button("Move"):
190
- current_pos = game_state["players"].get(st.session_state.player_name, {"x": GRID_SIZE // 2, "y": GRID_SIZE // 2})
191
- from_x, from_y = current_pos["x"] * CELL_SIZE + CELL_SIZE // 2, current_pos["y"] * CELL_SIZE + CELL_SIZE // 2
192
- to_x, to_y = target_x * CELL_SIZE + CELL_SIZE // 2, target_y * CELL_SIZE + CELL_SIZE // 2
193
- st_javascript(f"movePlayer('player-{st.session_state.player_name}', {from_x}, {from_y}, {to_x}, {to_y})")
194
- update_player_position(st.session_state.player_name, target_x, target_y)
195
-
196
- # Wait for update interval
197
- time.sleep(UPDATE_INTERVAL)
198
- st.experimental_rerun()
 
9
  # Constants
10
  GRID_SIZE = 10
11
  MAX_PLAYERS = 10
12
+ UPDATE_INTERVAL = 0.05 # Decreased for smoother animation
13
  GAME_STATE_FILE = "game_state.json"
14
  CELL_SIZE = 50
15
  PLAYER_SIZE = 40
16
+ VELOCITY_FACTOR = 0.5
17
+ FRICTION = 0.98
18
+ BOUNCE_FACTOR = -0.8
19
 
20
  # Initialize session state
21
  if "player_name" not in st.session_state:
 
37
  with open(GAME_STATE_FILE, "w") as f:
38
  json.dump(state, f)
39
 
40
+ # Function to update player position and velocity
41
+ def update_player_position(player_name, vx, vy):
42
  state = load_game_state()
43
  if player_name in state["players"]:
44
+ player = state["players"][player_name]
45
+ player["vx"] = player.get("vx", 0) + vx * VELOCITY_FACTOR
46
+ player["vy"] = player.get("vy", 0) + vy * VELOCITY_FACTOR
47
+
48
+ # Apply friction
49
+ player["vx"] *= FRICTION
50
+ player["vy"] *= FRICTION
51
+
52
+ # Update position
53
+ player["x"] += player["vx"]
54
+ player["y"] += player["vy"]
55
+
56
+ # Boundary check and bounce
57
+ if player["x"] < 0:
58
+ player["x"] = 0
59
+ player["vx"] *= BOUNCE_FACTOR
60
+ elif player["x"] > GRID_SIZE - 1:
61
+ player["x"] = GRID_SIZE - 1
62
+ player["vx"] *= BOUNCE_FACTOR
63
+
64
+ if player["y"] < 0:
65
+ player["y"] = 0
66
+ player["vy"] *= BOUNCE_FACTOR
67
+ elif player["y"] > GRID_SIZE - 1:
68
+ player["y"] = GRID_SIZE - 1
69
+ player["vy"] *= BOUNCE_FACTOR
70
  else:
71
  if len(state["players"]) < MAX_PLAYERS:
72
+ state["players"][player_name] = {
73
+ "x": GRID_SIZE // 2,
74
+ "y": GRID_SIZE // 2,
75
+ "vx": 0,
76
+ "vy": 0,
77
+ "color": st.session_state.player_color
78
+ }
79
  save_game_state(state)
80
 
81
  # Function to generate SVG for the game board
 
126
  # Player name
127
  svg += f'<text x="{x}" y="{y + PLAYER_SIZE // 2 + 15}" text-anchor="middle" fill="black" font-size="12" font-weight="bold">{player[:3].upper()}</text>'
128
 
 
 
 
129
  svg += '</g>'
130
 
131
  # Draw obstacles
 
139
  return svg
140
 
141
  # Streamlit app
142
+ st.set_page_config(layout="wide", page_title="Enhanced Multiplayer Grid Game")
143
  st.title("Enhanced Multiplayer Grid Game")
144
 
145
  # Display player name and allow updates
 
148
  player_name = st.text_input("Your name", value=st.session_state.player_name)
149
  if player_name != st.session_state.player_name:
150
  st.session_state.player_name = player_name
151
+ update_player_position(player_name, 0, 0)
152
 
153
  with col2:
154
  st.color_picker("Choose your color", value=st.session_state.player_color, key="player_color")
 
156
  # Create grid
157
  grid = st.empty()
158
 
159
+ # JavaScript for smooth movement and player control
160
  js_code = """
161
+ let keyState = {};
162
+ let lastUpdateTime = Date.now();
163
+
164
+ document.addEventListener('keydown', (e) => {
165
+ keyState[e.key.toLowerCase()] = true;
166
+ });
167
+
168
+ document.addEventListener('keyup', (e) => {
169
+ keyState[e.key.toLowerCase()] = false;
170
+ });
171
+
172
+ function updatePlayerPosition() {
173
+ const now = Date.now();
174
+ const dt = (now - lastUpdateTime) / 1000; // Time difference in seconds
175
+ lastUpdateTime = now;
176
+
177
+ let vx = 0, vy = 0;
178
+ if (keyState['w']) vy -= 1;
179
+ if (keyState['s']) vy += 1;
180
+ if (keyState['a']) vx -= 1;
181
+ if (keyState['d']) vx += 1;
182
+
183
+ if (vx !== 0 || vy !== 0) {
184
+ const magnitude = Math.sqrt(vx * vx + vy * vy);
185
+ vx /= magnitude;
186
+ vy /= magnitude;
187
+ window.Streamlit.setComponentValue({vx: vx * dt, vy: vy * dt});
188
  }
189
  }
190
 
191
+ setInterval(updatePlayerPosition, 50); // Update every 50ms for smooth movement
192
+
193
+ function movePlayer(playerId, x, y) {
194
  const player = document.getElementById(playerId);
195
  if (player) {
196
+ player.setAttribute('transform', `translate(${x * 50} ${y * 50})`);
 
 
 
197
  }
198
  }
199
  """
 
209
  ]
210
  save_game_state(game_state)
211
 
212
+ # Movement buttons
213
+ col1, col2, col3 = st.columns(3)
214
+ with col1:
215
+ if st.button("↑"):
216
+ update_player_position(st.session_state.player_name, 0, -1)
217
+ with col2:
218
+ if st.button("←"):
219
+ update_player_position(st.session_state.player_name, -1, 0)
220
+ if st.button("→"):
221
+ update_player_position(st.session_state.player_name, 1, 0)
222
+ with col3:
223
+ if st.button("↓"):
224
+ update_player_position(st.session_state.player_name, 0, 1)
225
+
226
  # Main game loop
227
+ def main():
228
+ while True:
229
+ # Load current game state
230
+ game_state = load_game_state()
231
+
232
+ # Generate and display SVG
233
+ svg = generate_svg(game_state)
234
+ grid.markdown(svg, unsafe_allow_html=True)
235
+
236
+ # Handle player movement from JavaScript
237
+ js_result = st.session_state.get('js_result', None)
238
+ if js_result:
239
+ vx, vy = js_result.get('vx', 0), js_result.get('vy', 0)
240
+ update_player_position(st.session_state.player_name, vx, vy)
241
+
242
+ # Update player positions on the client side
243
+ for player, data in game_state["players"].items():
244
+ st_javascript(f"movePlayer('player-{player}', {data['x']}, {data['y']})")
245
+
246
+ # Wait for update interval
247
+ time.sleep(UPDATE_INTERVAL)
248
+ st.experimental_rerun()
249
+
250
+ if __name__ == "__main__":
251
+ main()