Cómo hacer saltar un cubo en pygame?

Resuelto
ZHN -  
 Jean -

¡Hola!

Estoy en primero y especialidad en NSI - por lo tanto, tenemos que hacer un juego. Estoy usando pygame (y pycharm) - tengo que hacer saltar mi cubo, pero no lo consigo. ¿Una solución TwT?

 import pygame import self as self from pygame import * # Tamaño de la pantalla (provisional) ANCHO_PANTALLA = 1600 ALTO_PANTALLA = 850 # Clase que define al personaje #(por ahora solo hay movimiento por toda la pantalla, debería restringirse y añadir todas sus funciones) class Personaje (pygame.sprite.Sprite): # Inicialización del personaje def __init__(self): super(Personaje, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #coordenadas base a modificar también self.rect.x= 200 self.rect.y= 520 self.salto_subida = 0 self.salto_bajada = 3 self.numero_de_saltos = 0 #self.resistencia #self.gravedad self.puntos_vida=3 def saltar(self): saltar = True gravedad = 1 altura_salto = 1 rapidez = altura_salto # Actualización cuando el jugador presiona una tecla para moverse def update(self, teclas_pulsadas): # Movimiento hacia la izquierda if teclas_pulsadas[K_LEFT]: self.rect.move_ip(-5, 0) # Movimiento hacia la derecha if teclas_pulsadas[K_RIGHT]: self.rect.move_ip(5, 0) if teclas_pulsadas[K_UP]: saltar=True if self.rect.left<0: self.rect.left=0 if self.rect.right>ANCHO_PANTALLA: self.rect.right = ANCHO_PANTALLA if self.rect.y<0: self.rect.y=0 if self.rect.y>520: self.rect.y=520 class Obstacle (pygame.sprite.Sprite): """ esta clase es realmente rudimentaria pero se muestra. el objetivo es que el obstáculo se mueva hacia la izquierda continuamente hasta salir de la pantalla y, a largo plazo, que haya varias subclases de obstáculos con formas y efectos diferentes (como en Geometry Dash) y que cuando las coordenadas del obstáculo sean iguales a las coordenadas del personaje (colisión) se quite un punto """ def __init__ (self): super (Obstacle, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Ajuste del reloj clock = pygame.time.Clock() # Grupo de Sprites todos_sprites = pygame.sprite.Group() # Creación de los elementos (es para que los elementos de las clases se muestren) jugador = Personaje() obstáculos=Obstacle() todos_sprites.add(jugador) todos_sprites.add(obstáculos) # Inicialización de la página pygame.init() pygame.display.set_caption("test juego") pantalla = pygame.display.set_mode([ANCHO_PANTALLA, ALTO_PANTALLA]) #fondo = pygame.image.load("images/background.png") # Bucle del juego (bucle continuo que actualiza continuamente el juego) continuar = True while continuar: # cerrar la ventana for event in pygame.event.get(): if event.type == pygame.QUIT: continuar = False # pantalla negra (provisional) #fd pantalla.fill((120, 170, 255)) #suelo pygame.draw.rect (pantalla, (100, 200, 80), (0, 600, 1600, 350)) #teclas teclas_pulsadas = pygame.key.get_pressed() jugador.update(teclas_pulsadas) # Copia de los objetos en la superficie pantalla for mi_sprite in todos_sprites: pantalla.blit(mi_sprite.surf, mi_sprite.rect) # Pasamos nuestra superficie para mostrarla pygame.display.flip() # Indica a Pygame que no haga más de 50 veces por segundo el bucle del juego para ralentizar el movimiento clock.tick(100) pygame.quit() 

Gracias. :)

9 respuestas

  1. Diablo76 Mensajes publicados 344 Fecha de registro   Estado Miembro Última intervención   140
     

    Hola,

    Es cierto que si estás comenzando, lanzarte a la programación orientada a objetos puede desmotivarte :(, pero si buscas en internet, deberías encontrar ejemplos que sean más accesibles para ti, como este:

    import pygame pygame.init() win = pygame.display.set_mode((500,500)) pygame.display.set_caption("Primer Juego") x = 100 y = 400 width = 40 height = 60 vel = 10 isJump = False jumpCount = 10 run = True while run: pygame.time.delay(30) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] and x > vel: x -= vel if keys[pygame.K_RIGHT] and x < 500 - vel - width: x += vel if not(isJump): if keys[pygame.K_UP] and y > vel: y -= vel if keys[pygame.K_DOWN] and y < 500 - height - vel: y += vel if keys[pygame.K_SPACE]: isJump = True else: if jumpCount >= -10: y -= (jumpCount * abs(jumpCount)) * 0.5 jumpCount -= 1 else: jumpCount = 10 isJump = False win.fill((0,0,0)) pygame.draw.rect(win, (255,0,0), (x, y, width, height)) pygame.display.update() pygame.quit()

    Te toca entenderlo y modificarlo para tu ejercicio.

    3
    1. ZHN
       

      ¡Sí! ¡Gracias! ¡Logré adaptarlo a mi código y entendí todas las líneas!

      ¡Muchas gracias! :D

      0
    2. Jean
       

      eh hola :)))

      tengo una pregunta similar a la de ZHN, así que escribo aquí para evitar abrir un duplicado
      También planeo tomar la especialidad de NSI y así he comenzado a aprender algunas cosas. Sin embargo, en mi código, no entiendo cómo podría hacer que el jugador salte incluso cuando está en el aire (como en Flappy Bird xd)

      import pygame import random # Inicialización de Pygame pygame.init() # Definición de las dimensiones de la ventana del juego SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 # Colores WHITE = (255, 255, 255) BLACK = (0, 0, 0) COLLO = (98, 119, 29) BROWN = (153, 76, 0) COLOR = (100, 100, 99) # Creación de la ventana del juego screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Clase para la creación de los enemigos class Enemy(pygame.sprite.Sprite): def __init__(self, obstacles): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(BLACK) self.rect = self.image.get_rect() self.rect.x = SCREEN_WIDTH self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) while self.rect.bottom > SCREEN_HEIGHT - 50: self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) self.speed = 3 self.obstacles = obstacles def update(self): self.rect.x -= self.speed # Verifica si hay una colisión con un obstáculo for obstacle in self.obstacles: if self.rect.colliderect(obstacle.rect): self.rect.right = obstacle.rect.left class Obstacle(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(COLOR) self.rect = self.image.get_rect() self.rect.x = SCREEN_WIDTH self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) while self.rect.bottom > SCREEN_HEIGHT - 50: self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) self.speed = random.randint(1, 3) def update(self): self.rect.x -= self.speed class Ground(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((SCREEN_WIDTH, 50)) self.image.fill(BROWN) self.rect = self.image.get_rect() self.rect.x = 0 self.rect.y = SCREEN_HEIGHT - 50 # Clase para la creación del jugador class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(COLLO) self.rect = self.image.get_rect() self.speed = 10 self.jump_speed = 20 self.is_jumping = False self.speed_y = 0 def update(self, keys): if keys[pygame.K_UP] and not self.is_jumping: self.is_jumping = True self.speed_y = -self.jump_speed if self.is_jumping or self.rect.bottom < SCREEN_HEIGHT - 50: self.speed_y += 1 self.rect.y += self.speed_y if self.rect.bottom >= SCREEN_HEIGHT - 50: self.rect.bottom = SCREEN_HEIGHT - 50 self.is_jumping = False self.speed_y = 0 # Creación de los sprites para los enemigos y el jugador all_sprites = pygame.sprite.Group() enemies = pygame.sprite.Group() obstacles = pygame.sprite.Group() player = Player() all_sprites.add(player) ground = Ground() all_sprites.add(ground) # Colocar al jugador en el suelo player.rect.y = SCREEN_HEIGHT - 100 # Bucle principal del juego running = True clock = pygame.time.Clock() score = 0 enemy_timer = 0 enemy_spawn_rate = 800 obstacle_timer = 0 obstacle_spawn_rate = 1600 while running: # Gestión de eventos for event in pygame.event.get(): if event.type == pygame.QUIT: running = False enemy_timer += clock.get_time() if enemy_timer >= enemy_spawn_rate: enemy = Enemy(obstacles) all_sprites.add(enemy) enemies.add(enemy) enemy_timer = 0 obstacle_timer += clock.get_time() if obstacle_timer >= obstacle_spawn_rate: obstacle = Obstacle() all_sprites.add(obstacle) obstacles.add(obstacle) obstacle_timer = 0 # Movimiento de los enemigos y colisión con el jugador for enemy in enemies: enemy.update() if enemy.rect.right < 0: enemies.remove(enemy) all_sprites.remove(enemy) if enemy.rect.colliderect(player.rect): running = False for obstacle in obstacles: obstacle.update() if obstacle.rect.right < 0: obstacles.remove(obstacle) all_sprites.remove(obstacle) if obstacle.rect.colliderect(player.rect): running = False keys = pygame.key.get_pressed() player.update(keys) # Mostrar a los enemigos y al jugador screen.fill(WHITE) all_sprites.draw(screen) pygame.display.flip() # Límite de 60 imágenes por segundo clock.tick(80) # Cierre de Pygame pygame.quit() 
      0
      1. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   1 588 > Jean
         

        SI no encuentras la respuesta aquí, es mejor crear una nueva discusión.

        1
      2. Jean > yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención  
         

        ok :) gracias

        0
  2. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   Ambassadeur 1 588
     

    hola, ¿no puedes mover tu cubo hacia arriba? ¿qué has intentado?

    0
  3. ZHN
     

    Hola, gracias por responderme :)

    Bueno, primero intenté

    - mover el cubo con las flechas hacia arriba y hacia abajo en toda la superficie - eso funcionó

    - luego quise hacer que saltara cuando se presiona espacio o la flecha hacia arriba, pero eso no funciona mucho (para nada xd) hice una función saltar

    def saltar(self):
           if self.a_saltar:
               if self.salto_montaje>=10:
                   self.salto_descenso-=1
                   self.salto=self.salto_descenso
                
               else:
                    self.salto_montaje+=1
                    self.salto=self.salto_montaje
                
               if self.salto_descenso<0:
                   self.salto_montaje=0
                   self.salto_descenso=5
                   self.salto.a_saltar = False
                    
           self.rect.y=self.rect.y - (10*(self.salto/2))

    lo puse en la clase Perso, escribí esto en el bucle base del juego

    if event.key == pygame.K_UP:
                        self.perso.a_saltar = True

                       self.perso.numero_de_salto+=1

    Y al final llamé a la función saltar, pero igual no funciona

    Después seguí otro tutorial pero el juego no se abre aunque no hay errores en el código :(((

    Mi objetivo ahora es simplemente hacer que el cubo salte con espacio o la flecha hacia arriba

    0
    1. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   1 588
       

      ¿Por qué no añadiste el código para saltar a la línea 58, en lugar de hacerlo en el bucle "base"?

      0
  4. ZHN
     

    el código con la función def saltar(self): ?

    import pygame import self as self from pygame import * # Tamaño de la pantalla (provisional) ANCHO_PANTALLA = 1600 ALTO_PANTALLA = 850 # Clase que define al personaje #(por ahora solo hay su movimiento por toda la pantalla, hay que restringirlo y añadir todas sus funciones) class Personaje (pygame.sprite.Sprite): # Inicialización del personaje def __init__(self): super(Personaje, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #coordenadas base a modificar también self.rect.x= 200 self.rect.y= 520 self.salto_subida = 0 self.salto_bajada = 3 self.numero_de_saltos = 0 #self.resistencia #self.gravity self.puntos_vida=3 def saltar(self): if self.a_saltar: if self.salto_subida >= 10: self.salto_bajada -= 1 self.salto = self.salto_bajada else: self.salto_subida += 1 self.salto = self.salto_subida if self.salto_bajada < 0: self.salto_subida = 0 self.salto_bajada = 5 self.salto.a_saltar = False self.rect.y = self.rect.y - (10 * (self.salto / 2)) # Actualización cuando el jugador presiona una tecla para moverse def update(self, pressed_keys): # Movimiento hacia la izquierda if pressed_keys[K_LEFT]: self.rect.move_ip(-5, 0) # Movimiento hacia la derecha if pressed_keys[K_RIGHT]: self.rect.move_ip(5, 0) if pressed_keys[K_UP]: self.a_saltar = True self.numero_de_saltos += 1 if self.rect.left < 0: self.rect.left = 0 if self.rect.right > ANCHO_PANTALLA: self.rect.right = ANCHO_PANTALLA if self.rect.y < 0: self.rect.y = 0 if self.rect.y > 520: self.rect.y = 520 class Obstaculo (pygame.sprite.Sprite): """ esta clase está realmente inestable pero se muestra. el objetivo es que el obstáculo se mueva hacia la izquierda continuamente hasta salir de la pantalla y, a largo plazo, que haya varias subclases de obstáculos con diferentes formas y efectos (como en geometry dash) y que cuando las coordenadas del obstáculo = coordenadas del personaje (colisión) eso resta un punto """ def __init__ (self): super (Obstaculo, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Ajuste del reloj clock = pygame.time.Clock() # Grupo de Sprites todos_sprites = pygame.sprite.Group() # Creación de elementos (es para que los elementos de las clases se muestren) jugador = Personaje() obstaculos=Obstaculo() todos_sprites.add(jugador) todos_sprites.add(obstaculos) # Inicialización de la página pygame.init() pygame.display.set_caption("prueba juego") pantalla = pygame.display.set_mode([ANCHO_PANTALLA, ALTO_PANTALLA]) #fondo = pygame.image.load("images/background.png") # Bucle del juego (bucle continuo que actualiza continuamente el juego) continuar = True while continuar: # cerrar la ventana for event in pygame.event.get(): if event.type == pygame.QUIT: continuar = False # pantalla negra (provisional) #fd pantalla.fill((120, 170, 255)) #suelo pygame.draw.rect (pantalla, (100, 200, 80), (0, 600, 1600, 350)) #teclas tecla_presionada = pygame.key.get_pressed() jugador.update(tecla_presionada) # Copiar los objetos sobre la superficie pantalla for mi_sprite in todos_sprites: pantalla.blit(mi_sprite.surf, mi_sprite.rect) # Pasamos nuestra superficie para mostrar pygame.display.flip() # Indica a Pygame que no haga más de 50 veces por segundo el bucle del juego para ralentizar el movimiento clock.tick(100) pygame.quit()

    ?

    0
    1. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   1 588
       

      ¿Dónde llamas a saltar()?

      0
  5. ZHN
     
    import pygame import self as self from pygame import * # Tamaño de la pantalla (provisional) ANCHO_PANTALLA = 1600 ALTURA_PANTALLA = 850 # Clase que define al personaje #(por ahora solo hay su movimiento en toda la pantalla, hay que restringirlo y añadir todas sus funciones) class Personaje (pygame.sprite.Sprite): # Inicialización del personaje def __init__(self): super(Personaje, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #coordenadas básicas a modificar también self.rect.x= 200 self.rect.y= 520 self.salto_subida = 0 self.salto_bajada = 3 self.numero_de_saltos = 0 #self.resistencia #self.gravity self.puntos_de_vida=3 def saltar(self): if self.a_saltar: if self.salto_subida >= 10: self.salto_bajada -= 1 self.salto = self.salto_bajada else: self.salto_subida += 1 self.salto = self.salto_subida if self.salto_bajada < 0: self.salto_subida = 0 self.salto_bajada = 5 self.salto.a_saltar = False self.rect.y = self.rect.y - (10 * (self.salto / 2)) # Actualización cuando el jugador presiona una tecla para moverse def update(self, pressed_keys): # Movimiento hacia la izquierda if pressed_keys[K_LEFT]: self.rect.move_ip(-5, 0) # Movimiento hacia la derecha if pressed_keys[K_RIGHT]: self.rect.move_ip(5, 0) if pressed_keys[K_UP]: self.a_saltar = True self.numero_de_saltos += 1 if self.rect.left<0: self.rect.left=0 if self.rect.right>ANCHO_PANTALLA: self.rect.right = ANCHO_PANTALLA if self.rect.y<0: self.rect.y=0 if self.rect.y>520: self.rect.y=520 class Obstacle (pygame.sprite.Sprite): """ esta clase es realmente inestable pero se muestra. el objetivo es que el obstáculo se mueva hacia la izquierda continuamente hasta salir de la pantalla y a largo plazo que haya varias subclases de obstáculos con formas y efectos diferentes (como en geometry dash) y que cuando las coordenadas del obstáculo = las coordenadas del personaje (colisión) se resta un punto """ def __init__ (self): super (Obstacle, self).__init__() #forma a reemplazar por una imagen self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Ajuste del reloj clock = pygame.time.Clock() # Grupo de Sprites todos_sprites = pygame.sprite.Group() # Creación de elementos (es para que los elementos de las clases se muestren) player = Personaje() obstacles=Obstacle() todos_sprites.add(player) todos_sprites.add(obstacles) # Inicialización de la página pygame.init() pygame.display.set_caption("test juego") ecran = pygame.display.set_mode([ANCHO_PANTALLA, ALTURA_PANTALLA]) #fond = pygame.image.load("images/background.png") # Bucle del juego (bucle continuo que actualiza continuamente el juego) continuar = True while continuar: # cerrar la ventana for event in pygame.event.get(): if event.type == pygame.QUIT: continuar = False # pantalla negra (provisional) #fd ecran.fill((120, 170, 255)) #suelo pygame.draw.rect (ecran, (100, 200, 80), (0, 600, 1600, 350)) #teclas tecla_pulsada = pygame.key.get_pressed() player.update(tecla_pulsada) # Copia de los objetos en la superficie ecran for mon_sprite in todos_sprites: ecran.blit(mon_sprite.surf, mon_sprite.rect) # Se pasa nuestra superficie para mostrarla pygame.display.flip() # Indica a Pygame que no haga más de 50 veces por segundo el bucle del juego para ralentizar el movimiento clock.tick(100) pygame.quit() 

    está en la clase personaje y lo llamo en la parte inferior

    ¿puedo llamarlo salto=saltar() ??

    0
    1. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   1 588
       

      ¿Es tu primer ejercicio en Python?

      0
  6. ZHN
     

    Sí :/

    0
    1. yg_be Mensajes publicados 23437 Fecha de registro   Estado Colaborador Última intervención   1 588
       

      No creo que vayas a progresar intentando modificar un programa que no entiendes.

      Comienza por un programa más sencillo que hagas tú mismo.

      0
  7. hudada
     

    Hola.

    Hacer saltar a un personaje u objeto es simular la gravedad, por lo tanto, hacer una desaceleración a medida que sube, e inversamente una aceleración durante la bajada, siendo uno el inverso del otro, así que conviene usar los valores de la ascensión para la caída.

    Un ejemplo con algunos comentarios.

    import pygame as pg FPS = 60 ANCHO_PANTALLA = 500 ALTO_PANTALLA = 400 COLOR_PANTALLA = (0, 0, 0) COLOR_JUGADOR = (255, 255, 0) VELOCIDAD_JUGADOR = 8 GRAVITACIÓN = 0.18 class Jugador(pg.sprite.Sprite): def __init__(self): super().__init__() # Una simple superficie llena de un color self.image = pg.Surface((50, 50)) self.image.fill(COLOR_JUGADOR) self.rect = self.image.get_rect() self.saltando = False self.lista_saltos = [] def saltar(self, altura): if self.saltando: # Hay un salto en curso # No avanzamos más return self.altura_saltando = altura self.objetivo_salto = self.rect.y - altura self.lista_saltos.append(self.rect.y) self.saltando = -1 def izquierda(self): self.rect.x -= VELOCIDAD_JUGADOR def derecha(self): self.rect.x += VELOCIDAD_JUGADOR def actualizar(self): # Fase de ascenso if self.saltando == -1: dy = self.altura_saltando * GRAVITACIÓN self.altura_saltando -= dy self.rect.y -= dy # Añadimos el y a la lista para usarlo cuando # llegue la caída self.lista_saltos.append(self.rect.y) if self.rect.y <= self.objetivo_salto: # Añadir 5 veces el valor de la altura a alcanzar # para tener un efecto de "pesadez" en la caída self.lista_saltos.extend([self.objetivo_salto] * 5) # Indica que se pasa a la caída self.saltando = 1 # Fase de descenso elif self.saltando == 1: try: # Extraemos el último valor de la lista # que asignamos al valor y del jugador self.rect.y = self.lista_saltos.pop() except IndexError: # La lista está vacía, por lo tanto hemos vuelto al suelo # Detenemos la fase de salto e indicamos que el jugador puede # saltar de nuevo self.saltando = 0 pantalla = pg.display.set_mode((ANCHO_PANTALLA, ALTO_PANTALLA)) rect_pantalla = pantalla.get_rect() jugador = Jugador() # Colocamos al jugador en la parte inferior de la pantalla y a 30 px del borde izquierdo jugador.rect.bottomleft = 30, ALTO_PANTALLA # Creamos un grupo de sprites y añadimos nuestro jugador a este grupo. grupo_dibujo = pg.sprite.Group() grupo_dibujo.add(jugador) reloj = pg.time.Clock() corriendo = True while corriendo: for evt in pg.event.get(): if evt.type == pg.QUIT: corriendo = False teclas_pulsadas = pg.key.get_pressed() if teclas_pulsadas[pg.K_LEFT]: jugador.izquierda() elif teclas_pulsadas[pg.K_RIGHT]: jugador.derecha() if teclas_pulsadas[pg.K_UP]: jugador.saltar(100) # Permite que el jugador no salga de los límites de la pantalla jugador.rect.clamp_ip(rect_pantalla) pantalla.fill(COLOR_PANTALLA) # Actualización del grupo, por lo tanto de todos los sprites del grupo grupo_dibujo.update() # Luego se dibujan los sprites grupo_dibujo.draw(pantalla) pg.display.update() reloj.tick(FPS) pg.quit()

    Agrega algunos print en el método actualizar del jugador para entender bien si tienes un poco de dificultad para saber cuáles son las variables y atributos.

    0