Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| # pygame_to_flask.py - PyGame renders, Flask serves | |
| import pygame,os | |
| import numpy as np | |
| import time | |
| import threading | |
| from flask import Flask, Response | |
| # Setup | |
| os.environ['SDL_VIDEODRIVER'] = 'dummy' | |
| WIDTH, HEIGHT = 400, 300 | |
| app = Flask(__name__) | |
| # Simple shared state | |
| current_frame = None | |
| frame_lock = threading.Lock() | |
| def index(): | |
| return '''<html><body> | |
| <canvas id="canvas" width="400" height="300"></canvas> | |
| <script> | |
| const canvas = document.getElementById('canvas'); | |
| const ctx = canvas.getContext('2d'); | |
| function loadFrame() { | |
| fetch('/pygame_frame') | |
| .then(r => r.arrayBuffer()) | |
| .then(buffer => { | |
| const imageData = new ImageData(400, 300); | |
| const rgba = imageData.data; | |
| const rgb = new Uint8Array(buffer); | |
| for (let i = 0, j = 0; i < rgba.length; i += 4, j += 3) { | |
| rgba[i] = rgb[j]; | |
| rgba[i + 1] = rgb[j + 1]; | |
| rgba[i + 2] = rgb[j + 2]; | |
| rgba[i + 3] = 255; | |
| } | |
| ctx.putImageData(imageData, 0, 0); | |
| }); | |
| } | |
| setInterval(loadFrame, 100); | |
| </script> | |
| </body></html>''' | |
| def pygame_frame(): | |
| with frame_lock: | |
| if current_frame: | |
| return Response(current_frame, mimetype='application/octet-stream') | |
| # Fallback: black frame | |
| black = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8).tobytes() | |
| return Response(black, mimetype='application/octet-stream') | |
| def pygame_render(): | |
| """PyGame rendering thread""" | |
| print("π¬ Starting PyGame...") | |
| try: | |
| pygame.init() | |
| surface = pygame.Surface((WIDTH, HEIGHT)) | |
| print("β PyGame initialized") | |
| except Exception as e: | |
| print(f"β PyGame failed: {e}") | |
| return | |
| # Simple animation | |
| x, y = 200, 150 | |
| dx, dy = 3, 2 | |
| while True: | |
| # Clear | |
| surface.fill((20, 20, 40)) | |
| # Update | |
| x += dx | |
| y += dy | |
| if x < 20 or x > 380: | |
| dx = -dx | |
| if y < 20 or y > 280: | |
| dy = -dy | |
| # Draw | |
| pygame.draw.circle(surface, (255, 100, 100), (int(x), int(y)), 20) | |
| # Convert to bytes | |
| pixels = pygame.surfarray.pixels3d(surface) | |
| with frame_lock: | |
| global current_frame | |
| current_frame = pixels.tobytes() | |
| time.sleep(1/30) | |
| # Start PyGame thread | |
| threading.Thread(target=pygame_render, daemon=True).start() | |
| # Start Flask | |
| print("π Starting Flask...") | |
| app.run(host='0.0.0.0', port=7860, threaded=True) |