informatica:programacion:python:pyxel:juego_tipo_breakout
¡Esta es una revisión vieja del documento!
Breakout clon
Juego tipo Breakout / Arkanoid usando Pyxel.
El código fue generado por DeepSeek (una inteligencia artificial generativa)
import pyxel import math import random class Breakout: def __init__(self): pyxel.init(160, 256, title="Pyxel Breakout", fps=60) self.reset_game() self.setup_sounds() pyxel.run(self.update, self.draw) def reset_game(self): self.paddle_x = 64 self.paddle_speed = 4 self.lives = 3 self.score = 0 self.ball_x = 80 self.ball_y = 200 self.ball_angle = random.uniform(math.pi * 5/4, math.pi * 7/4) # Ángulo hacia arriba self.ball_speed = 3.5 self.ball_active = False self.blocks = [] self.create_level(1) self.powerups = [] self.active_powerup = None self.powerup_time = 0 def create_level(self, level): colors = [2, 3, 4, 5, 6, 8, 9, 10] for y in range(4 + level): for x in range(10): self.blocks.append({ 'x': x * 16, 'y': y * 12 + 40, 'color': colors[(y + x) % len(colors)], 'hp': 1 if y < 2 else 2 }) def setup_sounds(self): pyxel.sound(0).set(notes="C4", tones="T", volumes="5", effects="N", speed=10) pyxel.sound(1).set(notes="E4", tones="T", volumes="5", effects="N", speed=10) def update(self): if self.lives <= 0 or len(self.blocks) == 0: if pyxel.btnp(pyxel.KEY_R): self.reset_game() return paddle_width = 48 if self.active_powerup == 'expand' else 32 # Movimiento paleta if pyxel.btn(pyxel.KEY_LEFT): self.paddle_x = max(0, self.paddle_x - self.paddle_speed) if pyxel.btn(pyxel.KEY_RIGHT): self.paddle_x = min(160 - paddle_width, self.paddle_x + self.paddle_speed) # Lógica de la bola if self.ball_active: self.ball_x += math.cos(self.ball_angle) * self.ball_speed self.ball_y += math.sin(self.ball_angle) * self.ball_speed # Colisión con paredes if self.ball_x < 2 or self.ball_x > 158: self.ball_angle = math.pi - self.ball_angle self.ball_x = max(2, min(158, self.ball_x)) pyxel.play(0, 0) # Colisión con techo if self.ball_y < 2: self.ball_angle = -self.ball_angle self.ball_y = 2 pyxel.play(0, 0) # Colisión con paleta (sistema mejorado) if (self.paddle_x - 2 < self.ball_x < self.paddle_x + paddle_width + 2 and 200 <= self.ball_y <= 210): # Cálculo preciso del punto de impacto hit_pos = (self.ball_x - self.paddle_x) / paddle_width self.ball_angle = math.pi * (1.25 + hit_pos * 0.5) # Ángulos entre 125% y 175% de π self.ball_y = 195 # Posicionar claramente encima de la paleta self.ball_x += math.cos(self.ball_angle) * 5 # Impulso adicional pyxel.play(0, 0) # Colisión con bloques for block in self.blocks[:]: if (block['x'] < self.ball_x < block['x'] + 16 and block['y'] < self.ball_y < block['y'] + 8): block['hp'] -= 1 self.score += 10 * block['hp'] + 10 # Cálculo de rebote preciso bx_center = block['x'] + 8 by_center = block['y'] + 4 dx = self.ball_x - bx_center dy = self.ball_y - by_center if abs(dx) > abs(dy): self.ball_angle = math.pi - self.ball_angle else: self.ball_angle = -self.ball_angle if block['hp'] <= 0: self.blocks.remove(block) if random.random() < 0.2: self.powerups.append({ 'x': block['x'], 'y': block['y'], 'type': random.choice(['expand', 'laser', 'multi']) }) pyxel.play(0, 0) break # Actualizar power-ups for powerup in self.powerups[:]: powerup['y'] += 1 if powerup['y'] > 256: self.powerups.remove(powerup) elif (self.paddle_x < powerup['x'] < self.paddle_x + paddle_width and 200 < powerup['y'] < 210): self.activate_powerup(powerup['type']) self.powerups.remove(powerup) pyxel.play(0, 1) # Manejar power-up activo if self.active_powerup: self.powerup_time -= 1 if self.powerup_time <= 0: self.active_powerup = None self.paddle_x = 64 # Verificar pérdida de bola if self.ball_y > 256: self.lives -= 1 self.ball_active = False self.reset_ball(paddle_width) else: # Posición inicial centrada en la paleta self.ball_x = self.paddle_x + (paddle_width // 2) if pyxel.btnp(pyxel.KEY_SPACE): self.ball_active = True # Ángulo hacia arriba entre 45° izquierda y 45° derecha self.ball_angle = random.uniform(math.pi * 5/4, math.pi * 7/4) def activate_powerup(self, power_type): self.active_powerup = power_type self.powerup_time = 600 if power_type == 'expand': self.paddle_x = max(0, self.paddle_x - 16) self.paddle_speed = 3 def reset_ball(self, paddle_width): self.ball_active = False self.ball_x = self.paddle_x + (paddle_width // 2) self.ball_y = 200 def draw(self): pyxel.cls(0) # Dibujar bloques for block in self.blocks: pyxel.rect(block['x'], block['y'], 16, 8, block['color']) if block['hp'] > 1: pyxel.rect(block['x']+4, block['y']+3, 8, 2, 0) # Dibujar paleta paddle_width = 48 if self.active_powerup == 'expand' else 32 pyxel.rect(self.paddle_x, 200, paddle_width, 8, 7) # Dibujar bola ball_color = 10 if self.ball_active else 8 pyxel.circ(self.ball_x, self.ball_y, 3, ball_color) # Dibujar power-ups for powerup in self.powerups: color = 8 if powerup['type'] == 'expand' else 9 if powerup['type'] == 'laser' else 10 pyxel.rect(powerup['x'], powerup['y'], 8, 8, color) # UI pyxel.text(5, 5, f"SCORE: {self.score}", 7) pyxel.text(120, 5, f"VIDAS: {'♥' * self.lives}", 7) if not self.ball_active and self.lives > 0: pyxel.text(40, 220, "PRESIONA [ESPACIO] PARA LANZAR", 9) pyxel.rect(self.paddle_x + (paddle_width//2) - 2, 197, 4, 4, 10) # Estados de juego if self.lives <= 0: pyxel.text(60, 120, "GAME OVER", pyxel.frame_count % 16) pyxel.text(40, 140, "Presiona R para reiniciar", 7) elif len(self.blocks) == 0: pyxel.text(60, 120, "¡NIVEL COMPLETADO!", 11) pyxel.text(40, 140, "Presiona R para siguiente nivel", 7) Breakout()
informatica/programacion/python/pyxel/juego_tipo_breakout.1741963342.txt.gz · Última modificación: por tempwin
