Herramientas de usuario

Herramientas del sitio


informatica:programacion:python:pyxel:juego_tipo_celeste

Celeste clon

Juego tipo Celeste usando Pyxel.

El código fue generado por DeepSeek (una inteligencia artificial generativa)

import pyxel
 
class Player:
    def __init__(self):
        self.reset_position()
        self.vx = 0
        self.vy = 0
        self.jump_power = -4.5
        self.gravity = 0.3
        self.dash_speed = 5
        self.dash_cooldown = 0
        self.dash_duration = 0
        self.on_ground = False
 
    def reset_position(self):
        self.x = 40
        self.y = 40
 
    def update(self, platforms):
        if self.dash_duration <= 0:
            if pyxel.btn(pyxel.KEY_LEFT):
                self.vx = max(-3, self.vx - 0.5)
            elif pyxel.btn(pyxel.KEY_RIGHT):
                self.vx = min(3, self.vx + 0.5)
            else:
                self.vx *= 0.8
 
        if pyxel.btnp(pyxel.KEY_Z) and self.on_ground:
            self.vy = self.jump_power
            self.on_ground = False
 
        self.dash_cooldown = max(0, self.dash_cooldown - 1)
        if pyxel.btnp(pyxel.KEY_X) and self.dash_cooldown == 0:
            self.dash_cooldown = 60
            self.dash_duration = 10
            self.vx = (pyxel.btn(pyxel.KEY_RIGHT) - pyxel.btn(pyxel.KEY_LEFT)) * self.dash_speed
            self.vy = (pyxel.btn(pyxel.KEY_DOWN) - pyxel.btn(pyxel.KEY_UP)) * self.dash_speed * 0.7
 
        self.dash_duration = max(0, self.dash_duration - 1)
 
        if not self.on_ground and self.dash_duration == 0:
            self.vy += self.gravity
 
        self.x = max(0, min(self.x, 160 - 8))
 
        self.x += self.vx
        self.check_collisions(platforms, "horizontal")
 
        self.y += self.vy
        self.check_collisions(platforms, "vertical")
 
    def check_collisions(self, platforms, axis):
        self.on_ground = False
        for (px, py, w, h) in platforms:
            if (self.x + 8 > px and self.x < px + w and
                self.y + 8 > py and self.y < py + h):
 
                if axis == "horizontal":
                    if self.vx > 0:
                        self.x = px - 8
                    elif self.vx < 0:
                        self.x = px + w
                    self.vx = 0
                else:
                    if self.vy > 0:
                        self.y = py - 8
                        self.on_ground = True
                    elif self.vy < 0:
                        self.y = py + h
                    self.vy = 0
 
    def draw(self):
        pyxel.rect(self.x, self.y, 8, 8, 8)
 
class App:
    def __init__(self):
        pyxel.init(160, 120, title="Celeste-like", fps=30)
        self.player = Player()
        self.levels = [
            {
                'platforms': [(0, 112, 160, 8), (40, 80, 40, 8), (100, 60, 30, 8)],
                'coins': [(50, 100), (80, 80), (120, 40)]
            },
            {
                'platforms': [(0, 112, 160, 8), (20, 90, 30, 8), (80, 70, 40, 8), (120, 50, 20, 8)],
                'coins': [(30, 70), (100, 60), (140, 30)]
            },
            {
                'platforms': [(0, 112, 160, 8), (10, 100, 20, 8), (60, 80, 30, 8), (110, 60, 40, 8)],
                'coins': [(20, 90), (70, 60), (130, 40)]
            }
        ]
        self.current_level = 0
        self.current_platforms = []
        self.current_coins = []
        self.score = 0
        self.game_state = "start"
        self.load_level()
        pyxel.run(self.update, self.draw)
 
    def reset_game(self):
        self.current_level = 0
        self.score = 0
        self.load_level()
        self.player.reset_position()
        self.player.vx = 0
        self.player.vy = 0
 
    def load_level(self):
        self.current_platforms = self.levels[self.current_level]['platforms']
        self.current_coins = list(self.levels[self.current_level]['coins'])
 
    def check_coin_collision(self):
        for coin in self.current_coins[:]:
            if (self.player.x <= coin[0] <= self.player.x + 8 and
                self.player.y <= coin[1] <= self.player.y + 8):
                self.current_coins.remove(coin)
                self.score += 10
 
    def update(self):
        if self.game_state == "start":
            if pyxel.btnp(pyxel.KEY_Z):
                self.game_state = "playing"
 
        elif self.game_state == "playing":
            self.player.update(self.current_platforms)
            self.check_coin_collision()
 
            # Cambio de nivel por borde derecho
            if self.player.x >= 160 - 8:
                if self.current_level < len(self.levels) - 1 and not self.current_coins:
                    self.current_level += 1
                    self.load_level()
                    self.player.reset_position()
                elif self.current_level == len(self.levels) - 1 and not self.current_coins:
                    self.game_state = "victory"
                self.player.vx = 0
                self.player.vy = 0
 
            # Retroceder de nivel (no requiere coleccionables)
            elif self.player.x <= 0 and self.current_level > 0:
                self.current_level -= 1
                self.load_level()
                self.player.reset_position()
                self.player.x = 160 - 8
                self.player.vx = 0
                self.player.vy = 0
 
        elif self.game_state == "victory":
            if pyxel.btnp(pyxel.KEY_Z):
                self.reset_game()
                self.game_state = "start"
 
    def draw(self):
        pyxel.cls(0)
 
        if self.game_state == "start":
            self.draw_start_screen()
        elif self.game_state == "playing":
            self.draw_game()
        elif self.game_state == "victory":
            self.draw_victory_screen()
 
    def draw_start_screen(self):
        pyxel.text(50, 40, "CELESTE-LIKE", pyxel.COLOR_YELLOW)
        pyxel.text(30, 60, "PRESIONA Z PARA COMENZAR", pyxel.COLOR_WHITE)
        pyxel.text(20, 80, "CONTROLES:", pyxel.COLOR_LIGHT_BLUE)
        pyxel.text(20, 90, "FLECHAS: MOVER", pyxel.COLOR_WHITE)
        pyxel.text(20, 100, "Z: SALTAR", pyxel.COLOR_WHITE)
        pyxel.text(20, 110, "X: DASH", pyxel.COLOR_WHITE)
 
    def draw_game(self):
        # Plataformas
        for plat in self.current_platforms:
            pyxel.rect(*plat, 3)
 
        # Monedas
        for coin in self.current_coins:
            pyxel.circ(coin[0], coin[1], 2, pyxel.COLOR_YELLOW)
 
        # Jugador
        self.player.draw()
 
        # UI
        nivel_texto = f"NIVEL: {self.current_level + 1}/{len(self.levels)}"
        pyxel.text(5, 5, nivel_texto, 7)
        pyxel.text(5, 15, f"PUNTOS: {self.score}", pyxel.COLOR_YELLOW)
        coins_collected = len(self.levels[self.current_level]['coins']) - len(self.current_coins)
        pyxel.text(5, 25, f"MONEDAS: {coins_collected}/{len(self.levels[self.current_level]['coins'])}", pyxel.COLOR_WHITE)
 
        if self.player.dash_cooldown > 0:
            pyxel.rect(10, 35, 20, 4, 1)
            pyxel.rect(10, 35, (20 * (60 - self.player.dash_cooldown) // 60), 4, 11)
 
    def draw_victory_screen(self):
        pyxel.text(50, 50, "¡VICTORIA!", pyxel.COLOR_YELLOW)
        pyxel.text(40, 70, f"PUNTUACION FINAL: {self.score}", pyxel.COLOR_WHITE)
        pyxel.text(50, 90, "PRESIONA Z", pyxel.COLOR_LIGHT_BLUE)
        pyxel.text(45, 100, "PARA REINICIAR", pyxel.COLOR_LIGHT_BLUE)
 
App()
informatica/programacion/python/pyxel/juego_tipo_celeste.txt · Última modificación: por tempwin