Loading... # 外星人入侵项目 了解到了项目的基本实现方式,属于一看就会,一学就废 使用Flag来进行基本的通信,使用settings来存放基本数据/变动的全局数据 ```python def run_game(self): """开始游戏的主循环""" while True: self._check_events() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_alien() # self._update_screen() self._update_screen() ``` ## 游戏分为三个部分 检查与处理输入 更新游戏内容 输出图像 ### 检查与处理输入 ```python def _check_events(self): """响应键盘和鼠标事件""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) elif event.type == pygame.KEYDOWN: # 修改标签来实现移动 self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) ``` 这个游戏通过修改标签来确定状态,比如游戏是否正在进行,飞船移动方向,等等。 ### 更新游戏内容 基本上绝大部分工作是ALienInvasion在做。 self.ship.update() 在用Flag进行通信后,就可以通过ship的update()方法来实现飞船的移动 self._update_bullets() 显而易见 ```python def _update_bullets(self):# 为什么这些函数前面都有'_'呢? self.bullets.update() # 删除消失的子弹 for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() ``` self._update_alien() ```python def _update_alien(self): self._check_fleet_edges() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_aliens_bottom() ``` ## 渲染屏幕 pygame通过把所有图像blit到screen上,最后实现绘制 例: ```python def __init__(self): """初始化游戏并创建资源""" pygame.init() self.settings = Settings() # 创建显示窗口 self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_height))# 创建屏幕 pygame.display.set_caption("Alien Invasion")# 标题 self.stats = GameStatus(self) self.sb = Scoreboard(self) self.ship = Ship(self)# 下级对象可以通过这个获取上级对象的内容 self.bullets = pygame.sprite.Group() # Container class for many sprites. self.aliens = pygame.sprite.Group() self._create_fleet() self.play_button = Button(self, "PLAY") ``` 以ship.py为例,子对象只做了两件事 1. 更新(重置)对象 2. 绘制/更新图像,并绘制图像到屏幕上 ```python import pygame from pygame.sprite import Sprite class Ship(Sprite): """管理飞船的类""" def __init__(self, ai_game): super().__init__() self.screen = ai_game.screen self.settings = ai_game.settings self.screen_rect = ai_game.screen.get_rect() # 加载飞船图像并获取其外接矩形. self.image = pygame.image.load("images/ship.bmp")# 像文字等复杂一点的要重构成函数获取图像。 self.rect = self.image.get_rect() # 对于每艘新飞船,都将其放在屏幕底部的中央 self.rect.midbottom = self.screen_rect.midbottom # 新建飞船的属性x,其中存储小数值 self.x = float(self.rect.x) # 移动标志 self.moving_right = False self.moving_left = False def update(self): """根据移动标志调整飞船的位置""" if self.moving_right and self.rect.right < self.screen_rect.right: # 更新飞船而不是对象x的值 self.x += self.settings.ship_speed if self.moving_left and self.rect.left > 0: self.x -= self.settings.ship_speed self.rect.x = self.x # 依据self.x 更新rect对象 def blitme(self): """在指定位置绘制飞船""" self.screen.blit(self.image, self.rect) def center_ship(self): self.rect.midbottom = self.screen_rect.midbottom self.x = float(self.rect.x) ``` 文字处理 ```python import pygame.font from pygame.sprite import Group from ship import Ship class Scoreboard: def __init__(self, ai_game): self.ai_game = ai_game self.screen = ai_game.screen self.screen_rect = self.screen.get_rect() self.settings = ai_game.settings self.stats = ai_game.stats self.text_color = (30, 30, 30) self.font = pygame.font.SysFont(None, 48) self.prep_score() self.prep_high_score() self.prep_level() self.prep_ships() def prep_score(self): rounded_score = round(self.stats.score, -1) score_str = "{:,}".format(rounded_score) self.score_image = self.font.render(score_str, True, self.text_color, self.settings.bg_color) self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right - 20 self.score_rect.top = 20 def prep_high_score(self): # 说是prep实际每次都要调用 high_score = round(self.stats.high_score, -1) high_score_str = "{:,}".format(high_score) self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.settings.bg_color) self.high_score_rect = self.high_score_image.get_rect() self.high_score_rect.centerx = self.screen_rect.centerx self.high_score_rect.top = self.score_rect.top def prep_level(self): level_str = str(self.stats.level) self.level_image = self.font.render(level_str, True, self.text_color, self.settings.bg_color) self.level_rect = self.level_image.get_rect() self.level_rect.right = self.score_rect.right self.level_rect.top = self.score_rect.bottom + 10 def prep_ships(self): self.ships = Group() for ship_number in range(self.stats.ships_left): ship = Ship(self.ai_game) ship.rect.x = 10 + ship_number * ship.rect.width ship.rect.y = 10 self.ships.add(ship) 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) self.ships.draw(self.screen) def check_high_score(self): if self.stats.score > self.stats.high_score: self.stats.high_score = self.stats.score self.prep_high_score() ``` Last modification:January 11, 2023 © Allow specification reprint Like 如果觉得我的文章对你有用,请留下评论。