#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. Это прекрасно, спасибо!