Pygame — Вторжение инопланетян; Как настроить стартовую позицию моих флотов?

#python #pygame #pygame-surface

Вопрос:

Я изо всех сил пытаюсь настроить свою игру так, чтобы мой флот инопланетян не начинался под моим лучшим пользовательским интерфейсом. Я знаю, что это как-то связано с настройкой моего первого поколения моего инопланетянина, прежде чем я создам флот, но я довольно новичок в кодировании в целом и просто не совсем уверен, что мне нужно настроить.

Эта игра, созданная во время прохождения вместе с ускоренным курсом Python 2-го издания.

Как вы можете видеть, мой флот находится под моим пользовательским интерфейсом корабля

Настройте некоторый код для отображения инопланетян поверх пользовательского интерфейса

Это предложение ставит моих инопланетян поверх моего пользовательского интерфейса, что, я думаю, лучше, но я все равно считаю, что это выглядит не очень хорошо.

alien_invasion.py

 def __init__(self):  """Initlize the game, and create game resources."""  pygame.init()  self.settings = Settings()  self.screen = pygame.display.set_mode((  self.settings.screen_width, self.settings.screen_height  ))  self.settings.screen_width = self.screen.get_rect().width  self.settings.screen_height = self.screen.get_rect().height   pygame.display.set_caption("Alien Invasion")   self.stats = GameStats(self)  self.sb = Scoreboard(self)   self.ship = Ship(self)   self.bullets = pygame.sprite.Group()   self.aliens = pygame.sprite.Group()  self._create_fleet()   #Set our background color  self.bg_color = (230, 230, 230)    self.play_button = Button(self, "Play")  def run_game(self):  """Start main loop for our game."""  while True:  self._check_events()   if self.stats.game_active:  self.ship.update()  self._update_bullets()  self._update_aliens()    self._update_screen()  def _check_events(self):  """Respond to kepresses and mouse events."""  #for each event in game capture that event  for event in pygame.event.get():  #if player preses close, quit game  if event.type == pygame.QUIT:  sys.exit()  # if event is a key press  elif event.type == pygame.KEYDOWN:  self._check_keydown_events(event)  elif event.type == pygame.KEYUP:  self._check_keyup_events(event)  elif event.type == pygame.MOUSEBUTTONDOWN:  mouse_pos = pygame.mouse.get_pos()  self._check_play_button(mouse_pos)  def _check_play_button(self, mouse_pos):  """start new game if player clicks play"""  button_clicked = self.play_button.rect.collidepoint(mouse_pos)  if button_clicked and not self.stats.game_active:  self.settings.initialize_dynamic_settings()  self.stats.reset_stats()  self.stats.game_active = True  self.sb.prep_score()  self.sb.prep_level()  self.sb.prep_ships()   self.aliens.empty()  self.bullets.empty()   self._create_fleet()  self.ship.center_ship()   pygame.mouse.set_visible(False)  def _check_keydown_events(self, event):  """respond to keydown events"""  if event.key == pygame.K_RIGHT:  self.ship.moving_right = True  elif event.key == pygame.K_LEFT:  self.ship.moving_left = True  elif event.key == pygame.K_ESCAPE:  sys.exit()  elif event.key == pygame.K_SPACE:  self._fire_bullet()  def _check_keyup_events(self, event):  if event.key == pygame.K_RIGHT:  self.ship.moving_right = False  elif event.key == pygame.K_LEFT:  self.ship.moving_left = False  def _fire_bullet(self):  """create a new bullet and add it to the bullets group"""  if len(self.bullets) lt; self.settings.bullets_allowed:  new_bullet = Bullet(self)  # add is simpler than append, but is only avaliable in pygame  self.bullets.add(new_bullet)   def _update_bullets(self):  """update bullets position and get rid of old bullets"""  #update bullets position  self.bullets.update()  # get rid of bullets that leave the window  for bullet in self.bullets.copy():  if bullet.rect.bottom lt;= 0:  self.bullets.remove(bullet)   self._check_bullet_alien_collisions()  def _check_bullet_alien_collisions(self):  """respond to bullet-alien collisions"""  collisions = pygame.sprite.groupcollide(  self.bullets, self.aliens, False, True  )   if collisions:  for aliens in collisions.values():  self.stats.score  = self.settings.alien_points * len(aliens)  self.sb.prep_score()  self.sb.check_high_score()   if not self.aliens:  self.bullets.empty()  self._create_fleet()  self.settings.increse_speed()   self.stats.level  = 1  self.sb.prep_level()  def _update_aliens(self):  """update the position of the aliens"""  self._check_fleet_edges()  self.aliens.update()   # look for alien ship collisions  if pygame.sprite.spritecollideany(self.ship, self.aliens):  self._ship_hit()   self._check_aliens_bottom()  def _ship_hit(self):  """respond to the ship being hit by alien"""  if self.stats.ships_left gt; 0:  # decrese ships left  self.stats.ships_left -= 1  self.sb.prep_ships()   # get rid of any remaining aliens and bullets  self.aliens.empty()  self.bullets.empty()   # create new fleet and recenter ship  self._create_fleet()  self.ship.center_ship()    # small pause for reset  sleep(0.5)  else:  self.stats.game_active = False  pygame.mouse.set_visible(True)  def _create_fleet(self):  """create our fleet of aliens"""  # creat an alien and fine the number that fits in a row  # spacing between each alien is equal to one alien  alien = Alien(self)  alien_width, alien_height = alien.rect.size  available_space_x = self.settings.screen_width - (2 * alien_width)  number_aliens_x = available_space_x // (2 * alien_width)   # determine the number of rows that fit on the screen  ship_height = self.ship.rect.height  available_space_y = (self.settings.screen_height -   (3 * alien_height) - ship_height)  number_rows = available_space_y // (2 * alien_height)   # create a full fleet of aliens  for row_number in range(number_rows):  for alien_number in range(number_aliens_x):  self._create_alien(alien_number, row_number)  def _create_alien(self, alien_number, row_number):  alien = Alien(self)  alien_width, alien_height = alien.rect.size  alien.x = alien_width   2 * alien_width * alien_number  alien.rect.x = alien.x  alien.rect.y = alien_height   2 * alien.rect.height * row_number  self.aliens.add(alien)  def _check_fleet_edges(self):  """respond if any aliens reach the edge"""  for alien in self.aliens.sprites():  if alien.check_edges():  self._change_fleet_direction()  break  def _check_aliens_bottom(self):  """check if any aliens have reached the bottom of the screen"""  screen_rect = self.screen.get_rect()  for alien in self.aliens.sprites():  if alien.rect.bottom gt;= screen_rect.bottom:  self._ship_hit()  break  def _change_fleet_direction(self):  """drop entire fleet and change direction"""  for alien in self.aliens.sprites():  alien.rect.y  = self.settings.fleet_drop_speed  self.settings.fleet_direction *= -1  def _update_screen(self):  """Update images on screen and flip to the new screen."""  #fill our background with our bg_color  self.screen.fill(self.settings.bg_color)  #draw ship to screen  self.ship.blitme()   for bullet in self.bullets.sprites():  bullet.draw_bullet()    # draw scoreboard to screen  self.sb.show_score()   self.aliens.draw(self.screen)     # draw play button if game is inactive  if not self.stats.game_active:  self.play_button.draw_button()   #Make the most recently drawn screen visible.  #this clears our previous screen and updates it to a new one  #this gives our programe smooth movemnt  pygame.display.flip()  

alien.py

 def __init__(self, ai_game):  """initlize alien and set its starting position"""  super().__init__()  self.screen = ai_game.screen  self.settings = ai_game.settings  self.screen_rect = ai_game.screen.get_rect()   # load alien image at set its rect  self.image = pygame.image.load('images/alien.bmp')  self.rect = self.image.get_rect()   # start each new alien at the top left of the screen  self.rect.x = self.rect.width  self.rect.y = self.rect.height   # store aliens exact position (decimal)  self.x = float(self.rect.x)  def check_edges(self):  """return true if alien is at edge of screen"""  screen_rect = self.screen.get_rect()  if self.rect.right gt;= screen_rect.right or self.rect.left lt;= 0:  return True  def update(self):  """move the alien to the right or left"""  self.x  = (self.settings.alien_speed *  self.settings.fleet_direction)  self.rect.x = self.x  

Я хочу нарисовать своего первого инопланетянина на экране дальше по экрану, чтобы он вообще не мешал моему пользовательскому интерфейсу.

Насколько я понимаю, это проблема с тем, где первый инопланетянин выводится на экран.

 self.rect.x = self.rect.width self.rect.y = self.rect.height  

Это должно было дать первому инопланетянину пространство одного инопланетянина слева и сверху инопланетянина, но когда я отрегулирую себя.прямо.в любом случае, на самом деле ничего не меняется в том, как инопланетяне рисуются на экране.

Любая помощь в более глубоком понимании этой концепции была бы весьма признательна.

Комментарии:

1. Вещи, которые вы визуализируете позже, отображаются поверх предыдущих. Переместите код чертежа пользовательского интерфейса перед кодом чертежа флота. Таким образом, он сначала нарисует пользовательский интерфейс и нарисует флот поверх него. Возможно, сейчас у вас все наоборот.

2. Ну, вы были правы в том, что мой пользовательский интерфейс был нарисован до моего флота, и это действительно перемещает флот ПОВЕРХ пользовательского интерфейса, но я не хочу, чтобы мой флот каким-либо образом вмешивался в мой пользовательский интерфейс.

3. Привет, я автор PCC, и я просто хотел похвалить стиль вашей игры. Я видел много вариаций игры, и это одна из самых визуально привлекательных версий, которые я видел. 🙂

Ответ №1:

Вам необходимо адаптировать код в методах _create_fleet и _create_alien вашего первого класса, чтобы учесть пространство, занимаемое пользовательским интерфейсом в верхней части экрана. Я не знаю точно, какой размер вам там нужен, но я укажу, куда его поместить в приведенном ниже коде:

 def _create_fleet(self):  """create our fleet of aliens"""  # creat an alien and fine the number that fits in a row  # spacing between each alien is equal to one alien  alien = Alien(self)  alien_width, alien_height = alien.rect.size  available_space_x = self.settings.screen_width - (2 * alien_width)  number_aliens_x = available_space_x // (2 * alien_width)   # determine the number of rows that fit on the screen  ship_height = self.ship.rect.height  available_space_y = (self.settings.screen_height - # substract UI height here  (3 * alien_height) - ship_height)  number_rows = available_space_y // (2 * alien_height)   # create a full fleet of aliens  for row_number in range(number_rows):  for alien_number in range(number_aliens_x):  self._create_alien(alien_number, row_number)  def _create_alien(self, alien_number, row_number):  alien = Alien(self)  alien_width, alien_height = alien.rect.size  alien.x = alien_width   2 * alien_width * alien_number  alien.rect.x = alien.x  alien.rect.y = alien_height   2 * alien.rect.height * row_number # add UI height here  self.aliens.add(alien)  

Комментарии:

1. В этом есть полный смысл! Я смог вычесть дополнительную «высоту пришельца» в create fleet и добавить 2 дополнительных «высоты пришельца» в create_alien. Это прекрасно, спасибо!