- numpy
Pelota en el Laberinto
from js import window, setInterval, clearInterval, document
from pyodide import create_proxy
import random
from math import pi, sqrt
canvas = Element("my-canvas").element
ctx = canvas.getContext("2d")
ret = None
dt = 0.05 # Paso de tiempo (s)
fps = 60 # Fotogramas por segundo
start_time = None
dash_speed = 10
normal_speed = 2
maze = [
(50, 50, 250, 50), (250, 50, 250, 150), (250, 150, 150, 150), (150, 150, 150, 100),
(150, 100, 200, 100), (200, 100, 200, 50), (200, 50, 150, 50), (150, 50, 150, 75),
(150, 75, 100, 75), (100, 75, 100, 125), (100, 125, 50, 125), (50, 125, 50, 175),
(50, 175, 100, 175), (100, 175, 100, 225), (100, 225, 50, 225), (50, 225, 50, 300),
(50, 300, 100, 300), (100, 300, 100, 250), (100, 250, 200, 250), (200, 250, 200, 300),
(200, 300, 250, 300), (250, 300, 250, 400), (250, 400, 150, 400), (150, 400, 150, 350),
(150, 350, 200, 350), (200, 350, 200, 400), (200, 400, 100, 400), (100, 400, 100, 450),
(100, 450, 150, 450), (150, 450, 150, 500), (150, 500, 250, 500), (250, 500, 250, 450),
(250, 450, 300, 450), (300, 450, 300, 400), (300, 400, 350, 400), (350, 400, 350, 500),
(350, 500, 450, 500), (450, 500, 450, 450), (450, 450, 500, 450), (500, 450, 500, 400),
(500, 400, 450, 400), (450, 400, 450, 300), (450, 300, 400, 300), (400, 300, 400, 250),
(400, 250, 450, 250), (450, 250, 450, 200), (450, 200, 400, 200), (400, 200, 400, 100),
(400, 100, 450, 100), (450, 100, 450, 50), (450, 50, 350, 50), (350, 50, 350, 100),
(350, 100, 300, 100), (300, 100, 300, 50), (300, 50, 50, 50)
]
class Circle:
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
self.color = 'blue'
self.dx = 0
self.dy = 0
self.speed = normal_speed
def draw(self):
ctx.beginPath()
ctx.fillStyle = self.color
ctx.arc(self.x, self.y, self.radius, 0, 2 * pi)
ctx.fill()
def move(self):
self.x += self.dx
self.y += self.dy
if (self.x + self.radius) >= canvas.width:
self.x = canvas.width - self.radius
if (self.x - self.radius) <= 0:
self.x = self.radius
if (self.y + self.radius) >= canvas.height:
self.y = canvas.height - self.radius
if (self.y - self.radius) <= 0:
self.y = self.radius
def check_collision_with_walls(self):
for (x1, y1, x2, y2) in maze:
if x1 == x2: # Pared vertical
if x1 - self.radius <= self.x <= x1 + self.radius:
if y1 <= self.y <= y2:
self.x = x1 + self.radius * (-1 if self.dx > 0 else 1) # Ajuste de posición
self.dx *= -1
elif y1 == y2: # Pared horizontal
if y1 - self.radius <= self.y <= y1 + self.radius:
if x1 <= self.x <= x2:
self.y = y1 + self.radius * (-1 if self.dy > 0 else 1) # Ajuste de posición
self.dy *= -1
ball = Circle(75, 75, 10)
goal_x, goal_y = 400, 300 # Posición del objetivo
def draw_maze():
ctx.strokeStyle = 'black'
ctx.lineWidth = 2
for (x1, y1, x2, y2) in maze:
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.stroke()
def draw_goal():
ctx.beginPath()
ctx.arc(goal_x, goal_y, 10, 0, 2 * pi)
ctx.fillStyle = 'red'
ctx.fill()
def key_down(event):
if event.key == "ArrowUp":
ball.dy = -ball.speed
elif event.key == "ArrowDown":
ball.dy = ball.speed
elif event.key == "ArrowLeft":
ball.dx = -ball.speed
elif event.key == "ArrowRight":
ball.dx = ball.speed
elif event.key == " ": # Tecla de espacio
if ball.dx != 0:
ball.dx *= dash_speed
if ball.dy != 0:
ball.dy *= dash_speed
def key_up(event):
if event.key == "ArrowUp" or event.key == "ArrowDown":
ball.dy = 0
elif event.key == "ArrowLeft" or event.key == "ArrowRight":
ball.dx = 0
elif event.key == " ": # Tecla de espacio
ball.dx = ball.dx / dash_speed if ball.dx != 0 else 0
ball.dy = ball.dy / dash_speed if ball.dy != 0 else 0
window.addEventListener("keydown", create_proxy(key_down))
window.addEventListener("keyup", create_proxy(key_up))
def run():
global start_time
elapsed_time = (window.performance.now() - start_time) / 1000
Element("timer").element.innerText = f"Tiempo: {elapsed_time:.1f} s"
ctx.clearRect(0, 0, canvas.width, canvas.height)
draw_maze()
draw_goal()
ball.move()
ball.draw()
ball.check_collision_with_walls()
if (ball.x - goal_x)**2 + (ball.y - goal_y)**2 <= 100: # Si la pelota llega al objetivo
clearInterval(ret)
ret = None
alert("¡Pelota llegó al objetivo!")
def start_animation():
global ret, start_time
if ret is None:
start_time = window.performance.now()
ret = setInterval(create_proxy(run), int(1000 / fps))
start_animation()