www tutorial org games documentacion docs python pygame

tutorial - python pygame documentation



Proyecto Space Invaders (2)

Algunos consejos: su primer blit no tiene sentido. Ya que comienzas a bliting en el ciclo while.

Puede almacenar ship_left y ship_top en una tupla, por lo que habrá menos desorden en su código.

Usa funciones y dales nombres significativos, de esta manera será más fácil para ti y para otros que lean tu código.

Una cosa más: su función de movimiento toma un parámetro, pero no hace nada con él. Utiliza un evento, por lo que debe pasar esto en su lugar.

De vuelta a tu pregunta. Así es como normalmente se resuelve en juegos como estos.

Usted hace una lista de misiles. Cada evento KEYDOWN crearía un nuevo misil y lo agregaría a la lista. Si digamos que hay 10 misiles en la lista, el misil no se crea.

Lo mejor es crear un Misil de clase separado. Para cada objeto en la lista, debe hacer lo siguiente:

  1. Dibuja según su posición.
  2. Actualización - Mueva los misiles más cerca de la parte superior.
  3. Compruebe si hay algún misil fuera de la pantalla, de ser así, quítelos.

De esta forma, no hay necesidad de un temporizador, y puedes limitar los disparos para que el jugador no envíe spam al teclado. Si realmente quiere limitarlo según el tiempo, puede usar el valor de retorno de pygame.Clock.tick() para incrementar una variable time_since_last_shot. Cada pulsación de tecla verificará si el valor es lo suficientemente grande, y si es así, dispare y restablezca la variable a 0.

Estoy haciendo un juego similar a Space Invaders. ¿Hay alguna manera de verificar un evento como disparar con menos frecuencia? En este momento, si presiona la barra espaciadora lo suficientemente rápido, la toma superior desaparecerá antes de que llegue a la parte superior de la pantalla. Me preguntaba si podría verificar el evento de disparo como 2 / (cuánto tiempo lleva alcanzar la parte superior).

Aquí está mi código:

#-----!!!!SPACE INVADERS!!!!----- import pygame, sys from pygame.locals import * #-----MAIN FUNCTIONS----- def movement(move_x): if event.type == KEYDOWN: if event.key == K_LEFT: move_x = -5 if event.key == K_RIGHT: move_x = 5 if event.type == KEYUP: if event.key == K_LEFT: move_x = 0 if event.key == K_RIGHT: move_x = 0 return move_x #-----FFRAME RAEE / SCREEN SIZE----- clock = pygame.time.Clock() w,h = 800,800 screen = pygame.display.set_mode((w,h)) #-----SETTING IMAGES----- pygame.mouse.set_visible(0) ship = pygame.image.load("spaceship.png") ship = pygame.transform.scale(ship,(100,50)) ship_top = screen.get_height() - ship.get_height() ship_left = screen.get_width()/2 - ship.get_width()/2 screen.blit(ship, (ship_left,ship_top)) shot1 = pygame.image.load("SingleBullet.png") shot1 = pygame.transform.scale(shot1,(25,25)) shot2 = shot1 shot_count = 0 shot_y = 0 shot_y_2 = 0 #-----GLOBAL VARIABLES----- x = 0 resetShot = 0 move_x = 0 #-----MAIN GAME LOOP----- while True: clock.tick(60) screen.fill((0,0,0)) #x,y = pygame.mouse.get_pos() screen.blit(ship, (x-ship.get_width()/2,ship_top)) for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() move_x = movement(move_x) if event.type == KEYDOWN: if event.key == K_SPACE and shot_count == 0: shot_y = h-50 shot_x = x elif event.type == K_SPACE and shot_count == 1: shot_y_2 = h-50 shot_x_2 = x print(h, '' '', shot_y, shot_count) if event.type == KEYUP: if event.key == K_SPACE and shot_count == 0: resetShot = 0 elif event.type == K_SPACE and shot_count == 1: resetShot = 0 if shot_y > 0: screen.blit(shot1, (shot_x-shot1.get_width()/2,shot_y)) shot_y -= 15 if shot_y_2 > 0: screen.blit(shot2, (shot_x_2-shot1.get_width()/2,shot_y_2)) shot_y_2 -= 15 x+=move_x pygame.display.update()


Puede usar el contador para contar bucles en el bucle principal desde el último disparo - si es más grande que (por ejemplo) 10 que borrar el contador y disparar - en el juego más complicado puede usar pygame.time.get_ticks () para contar el tiempo en milisegundos desde el último disparo

Otro método es disparar solo si tiene menos de 2 disparos en la pantalla.

EDITAR:

Su código se vería así: simple ejemplo. Use las teclas: IZQUIERDA, DERECHA, ESPACIO, P (para pausa).

Todavía hay mucho por hacer. Por ejemplo, mejor detección de colisión - pygame.sprite.collide_rect ()

( Adjunté mis bitmaps al final )

#-----!!!!SPACE INVADERS!!!!----- import pygame from pygame.locals import * #---------------------------------------------------------------------- class Ship(): def __init__(self, screen_rect): #self.image = pygame.image.load("spaceship.png") self.image = pygame.image.load("ball1.png") self.image = pygame.transform.scale(self.image, (100,50)) self.rect = self.image.get_rect() # put ship bottom, center x self.rect.bottom = screen_rect.bottom self.rect.centerx = screen_rect.centerx self.move_x = 0 self.shots = [] self.shots_count = 0 self.max_shots = 2 #-------------------- def event_handler(self, event): #print "debug: Ship.event_handler" if event.type == KEYDOWN: if event.key == K_LEFT: self.move_x = -5 elif event.key == K_RIGHT: self.move_x = 5 elif event.key == K_SPACE: if len(self.shots) < self.max_shots: self.shots.append(Bullet(self.rect.centerx, self.rect.top)) if event.type == KEYUP: if event.key in (K_LEFT, K_RIGHT): self.move_x = 0 def update(self): #print "debug: Ship.update: move_x", self.move_x self.rect.x += self.move_x for s in self.shots: s.update() for i in range(len(self.shots)-1, -1, -1): print "debug: Ship.update: testing bullet ", i if not self.shots[i].is_alive: print "debug: Ship.update: removing bullet ", i del self.shots[i] #-------------------- def draw(self, screen): #print "debug: Ship.draw" screen.blit(self.image, self.rect.topleft) for s in self.shots: s.draw(screen) def bullet_detect_collison(self, enemy_list): for s in self.shots: for e in enemy_list: if pygame.sprite.collide_circle(s, e): s.is_alive = False e.is_alive = False #---------------------------------------------------------------------- class Bullet(): def __init__(self, x, y): #self.image = pygame.image.load("SingleBullet.png") self.image = pygame.image.load("ball2.png") self.image = pygame.transform.scale(self.image, (25,25)) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y self.is_alive = True #-------------------- def update(self): self.rect.y -= 15 if self.rect.y < 0: self.is_alive = False #-------------------- def draw(self, screen): screen.blit(self.image, self.rect.topleft) #---------------------------------------------------------------------- class Enemy(): def __init__(self, x, y): self.image = pygame.image.load("ball3.png") self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y self.is_alive = True #-------------------- def update(self): self.rect.y += 1 #~ if self.rect.y < 0: #~ self.is_alive = False #-------------------- def draw(self, screen): screen.blit(self.image, self.rect.topleft) #---------------------------------------------------------------------- class Game(): def __init__(self): pygame.init() w, h = 800, 800 self.screen = pygame.display.set_mode((w,h)) pygame.mouse.set_visible(False) self.ship = Ship(self.screen.get_rect()) self.enemies = [] for i in range(100, 800, 100): self.enemies.append(Enemy(i, 100)) font = pygame.font.SysFont("", 72) self.text_paused = font.render("PAUSED", True, (255, 0, 0)) self.text_paused_rect = self.text_paused.get_rect(center=self.screen.get_rect().center) #-----MAIN GAME LOOP----- def run(self): clock = pygame.time.Clock() RUNNING = True PAUSED = False while RUNNING: clock.tick(30) #--- events --- for event in pygame.event.get(): if event.type == pygame.QUIT: RUNNING = False if event.type == KEYDOWN: if event.key == K_ESCAPE: RUNNING = False if event.key == K_p: PAUSED = not PAUSED if not PAUSED: self.ship.event_handler(event) #--- changes --- if not PAUSED: self.ship.update() for e in self.enemies: e.update() self.ship.bullet_detect_collison(self.enemies) for i in range(len(self.enemies)-1, -1, -1): print "debug: Ship.update: testing bullet ", i if not self.enemies[i].is_alive: print "debug: Ship.update: removing bullet ", i del self.enemies[i] #--- draws --- self.screen.fill((0,0,0)) self.ship.draw(self.screen) for e in self.enemies: e.draw(self.screen) if PAUSED: self.screen.blit(self.text_paused, self.text_paused_rect) pygame.display.update() #--- quit --- pygame.quit() #--------------------------------------------------------------------- Game().run()

ball1.png ball2.png ball3.png

Captura de pantalla