Compilation of core knowledge points about "Python" 41

Table of contents

scoreboard.py

game_functions.py

game_functions.py

14.3.8 Display level

game_stats.py

scoreboard.py

scoreboard.py

scoreboard.py

game_functions.py

game_functions.py

alien_invasion.py

14.3.9 Display the number of remaining ships

ship.py

scoreboard.py


 

We rounded the highest score to the nearest multiple of 10 (1) and added a thousandth separator represented by a comma (see 2). We then generate an image based on the highest score (see 3), center it horizontally (see 4), and set its top property to that of the current scoring image (see 5).

Now, the method show_score() needs to display the current score in the upper right corner of the screen and the highest score in the top center of the screen:

scoreboard.py

 def show_score(self):
 """在屏幕上显示当前得分和最高得分"""
 self.screen.blit(self.score_image, self.score_rect)
 self.screen.blit(self.high_score_image, self.high_score_rect) 

To check whether a new high score has been generated, we add a new function check_high_ score() in game_functions.py:

game_functions.py

The function check_high_score() contains two formal parameters: stats and sb. It uses stats to compare the current score with the highest score, and sb to modify the highest score image if necessary. At , we compare the current score with the highest score. If the current score is higher, we update the value of high_score and call prep_high_score() to update the image containing the highest score. In check_bullet_alien_collisions(), whenever an alien is destroyed, check_high_score() needs to be called after updating the score:

game_functions.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
 aliens, bullets):
 --snip--
 if collisions:
 for aliens in collisions.values():
 stats.score += ai_settings.alien_points * len(aliens)
 sb.prep_score()
 check_high_score(stats, sb)
 --snip-- 

When the dictionary collisions exists, we update the score based on how many aliens were destroyed, and then call check_high_score(). The first time you play the game, the current score is the highest score, so the current score is displayed in both places. But when you start the game again, the highest score appears in the center and the current score appears on the right, as shown in Figure 14-4.

14.3.8 Display level

In order to display the player's level in the game, you first need to add an attribute to GameStats that represents the current level. To ensure that the level is reset every time you start a new game, initialize it in reset_stats():

game_stats.py
 def reset_stats(self):
 """初始化随游戏进行可能变化的统计信息"""
 self.ships_left = self.ai_settings.ship_limit
 self.score = 0
 self.level = 1

To allow Scoreboard to display the current level below the current score, we call a new method prep_level() in __init__():

scoreboard.py
 def __init__(self, ai_settings, screen, stats):
 --snip--
 # 准备包含得分的初始图像
 self.prep_score()
 self.prep_high_score()
 self.prep_level() 

The code of prep_level() is as follows:

scoreboard.py
 def prep_level(self):
 """将等级转换为渲染的图像"""
1 self.level_image = self.font.render(str(self.stats.level), True,
 self.text_color, self.ai_settings.bg_color)
 # 将等级放在得分下方
 self.level_rect = self.level_image.get_rect()
2 self.level_rect.right = self.score_rect.right
3 self.level_rect.top = self.score_rect.bottom + 10

The method prep_level() creates an image based on the value stored in stats.level (see ) and sets its right attribute to the score's right attribute (see ). Then, set the top property to be 10 pixels larger than the bottom property of the score image to allow some space between the score and the level (see ). We also need to update show_score():

scoreboard.py
 def show_score(self):
 """在屏幕上显示飞船和得分"""
self.screen.blit(self.score_image, self.score_rect)
self.screen.blit(self.high_score_image, self.high_score_rect)
 self.screen.blit(self.level_image, self.level_rect)

In this method, a line of code is added that displays the level image on the screen. We raise the level in check_bullet_alien_collisions() and update the level image: game_functions.py

def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
 aliens, bullets):
 --snip--
 if len(aliens) == 0:
 # 如果整群外星人都被消灭,就提高一个等级
 bullets.empty()
 ai_settings.increase_speed()
 # 提高等级
1 stats.level += 1
2 sb.prep_level()
 create_fleet(ai_settings, screen, ship, aliens)

If the entire group of aliens is destroyed, we increment the value of stats.level by 1 (see ) and call prep_level() to ensure that the new level is displayed correctly (see ). To ensure that the score and level images are updated when starting a new game, trigger a reset when the Play button is clicked:

game_functions.py
def check_play_button(ai_settings, screen, stats, sb, play_button, ship, 
 aliens, bullets, mouse_x, mouse_y):
 """在玩家单击Play按钮时开始新游戏"""
 button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
 if button_clicked and not stats.game_active:
 --snip--
 # 重置游戏统计信息
 stats.reset_stats()
 stats.game_active = True
 # 重置记分牌图像
1 sb.prep_score()
 sb.prep_high_score()
 sb.prep_level()
 # 清空外星人列表和子弹列表
 aliens.empty()
 bullets.empty()
 --snip-- 

The definition of check_play_button() needs to contain the object sb. To reset the scoreboard image, we call prep_score(), prep_high_score(), and prep_level() after resetting the relevant game settings (see ). In check_events(), you now need to pass sb to check_play_button() so that it can access the scoreboard object:

game_functions.py
def check_events(ai_settings, screen, stats, sb, play_button, ship, aliens,
 bullets):
 """响应按键和鼠标事件"""
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
 --snip--
 elif event.type == pygame.MOUSEBUTTONDOWN:
 mouse_x, mouse_y = pygame.mouse.get_pos()
1 check_play_button(ai_settings, screen, stats, sb, play_button,
 ship, aliens, bullets, mouse_x, mouse_y) 

The definition of check_events() needs to include the formal parameter sb, so that when calling check_play_button(), sb can be passed to it as an actual parameter (see ). Finally, update the code in alien_invasion.py that calls check_events() to also pass sb to it:

alien_invasion.py
 # 开始游戏主循环
 while True:
 gf.check_events(ai_settings, screen, stats, sb, play_button, ship,
 aliens, bullets)
 --snip--

Now you can know how many levels you have upgraded to, as shown in Figure 14-5.


Notice

In some classic games, scores are labeled, such as Score, High Score and Level. We don't show these labels because it will be obvious what each number means once you start playing the game. To include these labels, simply add them to the score string before calling font.render() in Scoreboard.


14.3.9 Display the number of remaining ships

Finally, let's show how many ships the player has left, but using a graph instead of a number. To do this, we drew an image of a ship in the upper left corner of the screen to indicate how many ships were left, just like in many classic arcade games. First, you need to let Ship inherit Sprite so that you can create ship groups:

ship.py
import pygame
from pygame.sprite import Sprite
1 class Ship(Sprite):
 def __init__(self, ai_settings, screen):
 """初始化飞船,并设置其起始位置"""
2 super(Ship, self).__init__()
 --snip-- 

Here, we imported Sprite, let Ship inherit Sprite (see 1), and called super() at the beginning of __init__() (see 2).

Next, you need to modify the Scoreboard to create a group of ships for display. The following are the import statements and method __init__(): scoreboard.py

import pygame.font
from pygame.sprite import Group
from ship import Ship
class Scoreboard():
 """报告得分信息的类"""
 def __init__(self, ai_settings, screen, stats):
 --snip--
 self.prep_level()
 self.prep_ships()
 --snip-- 

Since we want to create a ship group, we import the Group and Ship classes. After calling prep_level(), we called prep_ships(). The code for prep_ships() is as follows:

scoreboard.py

 def prep_ships(self):
 """显示还余下多少艘飞船"""
1 self.ships = Group()
2 for ship_number in range(self.stats.ships_left):
 ship = Ship(self.ai_settings, self.screen)
3 ship.rect.x = 10 + ship_number * ship.rect.width
4 ship.rect.y = 10
5 self.ships.add(ship) 

The method prep_ships() creates an empty group self.ships for storing ship instances (see 1). To fill this group, a loop is run a number of times depending on how many ships the player has left (see 2). In this loop, we create a new ship and set its x-coordinate so that the entire group of ships is on the left side of the screen, and each ship has a left margin of 10 pixels (see 3). We also set the y coordinate to 10 pixels from the top edge of the screen so that all ships are aligned with the score image (see 4). Finally, we add each new ship to the grouping ships (see 55). Now it's time to draw the ship on the screen:

scoreboard.py
def show_score(self):
 --snip--
 self.screen.blit(self.level_image, self.level_rect)
 # 绘制飞船
 self.ships.draw(self.screen)

Guess you like

Origin blog.csdn.net/lzy302810/article/details/135173074