系列文章目录 

python从入门到实践12章答案

python从入门到实践14章答案


目录

前言

一、13-1星星

二、13-2更逼真的星星

三、13-3雨滴

四、13-4连绵细雨

五、13-5 侧面射击2

六、13-6游戏结束

总结


前言

这里是Python从入门到实践的练习答案,本人也是初学python,在这里把我的答案记录下来。如果有错误或者可以改进的地方欢迎在评论区留言。另外,所有代码均按照书上方式重构,便于阅读和理解。

后两题的答案是根据12章答案改进而来,感兴趣的uu们可以去专栏里找找看。

另外注意相对路径问题。


一、13-1星星

在网上找的图片 没找到合适大小的( 尺寸小就美观一些

图片命名为 star.png

新建star.py

import pygame
from pygame.sprite import Spriteclass Star(Sprite):"""表示单个星星的类"""def __init__(self, ai_game):"""初始化星星"""super().__init__()self.screen = ai_game#加载星星图像并设置其rectself.image = pygame.image.load('star.png')self.rect = self.image.get_rect()#每个星星一开始都在屏幕左上角附近self.rect.x = self.rect.width - 50self.rect.y = self.rect.height - 50#储存星星的精确位置self.x = float(self.rect.x)self.y = float(self.rect.y)

新建sky.py

import sys
import pygame
from star import Starclass Sky:"""管理天空的类"""def __init__(self):"""初始化界面"""pygame.init()self.screen = pygame.display.set_mode((1000, 800))self.screen_rect = self.screen.get_rect()pygame.display.set_caption("Star Sky")self.stars = pygame.sprite.Group()self._create_fleet()def _create_fleet(self):"""创建星云"""#计算一行可以容纳多少星星star = Star(self)star_width = star.rect.widthavailable_space_x = self.screen_rect.width - 100number_stars_x = available_space_x // (star_width * 2)for row_number in range(3):#创建一行星星for star_number in range(number_stars_x):#创建一个星星并加入当前行self._create_star(star_number, row_number)def _create_star(self, star_number, row_number):#创建一个星星star = Star(self)star_width = star.rect.widthstar_height = star.rect.heightstar.x = 50 + star_width * star_number * 2star.rect.x = star.xstar.y = 50 + star_height * row_number * 2star.rect.y = star.yself.stars.add(star)def _update_screen(self):"""绘制屏幕"""self.screen.fill((0, 190, 230))self.stars.draw(self.screen)pygame.display.flip()def run_game(self):"""主循环"""while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()self._update_screen()if __name__ == "__main__":ai = Sky()ai.run_game()

结果是这样的 星星小点就好了(


二、13-2更逼真的星星

只需对 sky.py 做少许修改

import sys
import pygame
from star import Star
from random import randintclass Sky:"""管理天空的类"""def __init__(self):"""初始化界面"""pygame.init()self.screen = pygame.display.set_mode((1000, 800))self.screen_rect = self.screen.get_rect()pygame.display.set_caption("Star Sky")self.stars = pygame.sprite.Group()self._create_fleet()def _create_fleet(self):"""创建星云"""#计算一行可以容纳多少星星star = Star(self)star_width = star.rect.widthavailable_space_x = self.screen_rect.width - 100number_stars_x = available_space_x // (star_width * 2)for row_number in range(3):#创建一行星星for star_number in range(number_stars_x):#创建一个星星并加入当前行star_number = randint(0, number_stars_x)self._create_star(star_number, row_number)def _create_star(self, star_number, row_number):#创建一个星星star = Star(self)star_width = star.rect.widthstar_height = star.rect.heightstar.x = 50 + star_width * star_number * 2star.rect.x = star.xstar.y = 50 + star_height * row_number * 2star.rect.y = star.yif star.rect.right < self.screen_rect.right:self.stars.add(star)def _update_screen(self):"""绘制屏幕"""self.screen.fill((0, 190, 230))self.stars.draw(self.screen)pygame.display.flip()def run_game(self):"""主循环"""while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()self._update_screen()if __name__ == "__main__":ai = Sky()ai.run_game()

结果是这样的:


三、13-3雨滴

雨滴和星星差不多,这里直接修改 star.py 将星星都换成雨滴就行

将背景改为白色

在 raindrop.py里直接设置速度,就不新建settings.py文件专门储存设置了

另外稍微修改raindrop.py

raindrop.py

import pygame
from pygame.sprite import Spriteclass Raindrop(Sprite):"""表示单个雨滴的类"""def __init__(self, ai_game):"""初始化雨滴"""super().__init__()self.screen = ai_game#加载雨滴图像并设置其rectself.image = pygame.image.load('raindrop.png')self.rect = self.image.get_rect()#每个雨滴一开始都在屏幕左上角附近self.rect.x = self.rect.width - 50self.rect.y = self.rect.height - 50#储存雨滴的精确位置self.x = float(self.rect.x)self.y = float(self.rect.y)#雨滴下降速度self.speed = 0.3def update(self):"""向下移动雨滴"""self.y += self.speedself.rect.y = self.y

sky.py

import sys
import pygame
from raindrop import Raindropclass Sky:"""管理天空的类"""def __init__(self):"""初始化界面"""pygame.init()self.screen = pygame.display.set_mode((1000, 800))self.screen_rect = self.screen.get_rect()pygame.display.set_caption("Star Sky")self.raindrops = pygame.sprite.Group()self._create_fleet()def _create_fleet(self):"""创建大雨"""#计算一行可以容纳多少雨滴raindrop = Raindrop(self)raindrop_width = raindrop.rect.widthavailable_space_x = self.screen_rect.width - 100number_raindrop_x = available_space_x // (raindrop_width * 2)for row_number in range(3):#创建一行雨滴for raindrop_number in range(number_raindrop_x):#创建一个雨滴并加入当前行self._create_raindrop(raindrop_number, row_number)def _create_raindrop(self, raindrop_number, row_number):#创建一个雨滴raindrop = Raindrop(self)raindrop_width = raindrop.rect.widthraindrop_height = raindrop.rect.heightraindrop.x = 50 + raindrop_width * raindrop_number * 2raindrop.rect.x = raindrop.xraindrop.y = 50 + raindrop_height * row_number * 2raindrop.rect.y = raindrop.yself.raindrops.add(raindrop)def _update_raindrops(self):"""更新所有雨滴的位置"""self.raindrops.update()def _update_screen(self):"""绘制屏幕"""self.screen.fill((255, 255, 255))self.raindrops.draw(self.screen)pygame.display.flip()def run_game(self):"""主循环"""while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()self._update_raindrops()self._update_screen()if __name__ == "__main__":ai = Sky()ai.run_game()

结果是这样的:


四、13-4连绵细雨

修改 raindrop.py

import pygame
from pygame.sprite import Spriteclass Raindrop(Sprite):"""表示单个雨滴的类"""def __init__(self, ai_game):"""初始化雨滴"""super().__init__()self.screen = ai_game.screen#加载雨滴图像并设置其rectself.image = pygame.image.load('raindrop.png')self.rect = self.image.get_rect()#每个雨滴一开始都在屏幕左上角附近self.rect.x = self.rect.width - 50self.rect.y = self.rect.height - 50#储存雨滴的精确位置self.x = float(self.rect.x)self.y = float(self.rect.y)#雨滴下降速度self.speed = 0.3def update(self):"""向下移动雨滴"""self.y += self.speedself.rect.y = self.ydef check_edge(self):"""如果位于屏幕边缘则返回 True"""screen_rect = self.screen.get_rect()if self.rect.bottom > screen_rect.bottom:return True

sky.py

import sys
import pygame
from raindrop import Raindropclass Sky:"""管理天空的类"""def __init__(self):"""初始化界面"""pygame.init()self.screen = pygame.display.set_mode((1000, 800))self.screen_rect = self.screen.get_rect()pygame.display.set_caption("Star Sky")self.raindrops = pygame.sprite.Group()self._create_fleet()def _create_fleet(self):"""创建星云"""#计算一行可以容纳多少星星raindrop = Raindrop(self)raindrop_width = raindrop.rect.widthavailable_space_x = self.screen_rect.width - 100number_raindrop_x = available_space_x // (raindrop_width * 2)for row_number in range(3):#创建一行星星for raindrop_number in range(number_raindrop_x):#创建一个星星并加入当前行self._create_raindrop(raindrop_number, row_number)def _create_raindrop(self, raindrop_number, row_number):#创建一个星星raindrop = Raindrop(self)raindrop_width = raindrop.rect.widthraindrop_height = raindrop.rect.heightraindrop.x = 50 + raindrop_width * raindrop_number * 2raindrop.rect.x = raindrop.xraindrop.y = 50 + raindrop_height * row_number * 2raindrop.rect.y = raindrop.yself.raindrops.add(raindrop)def _check_rain_edge(self):"""有雨滴到达边缘时采取相应的措施"""for raindrop in self.raindrops.sprites():if raindrop.check_edge():raindrop.y = 0def _update_raindrops(self):"""更新所有雨滴的位置"""self.raindrops.update()def _update_screen(self):"""绘制屏幕"""self.screen.fill((255, 255, 255))self.raindrops.draw(self.screen)pygame.display.flip()def run_game(self):"""主循环"""while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()self._check_rain_edge()self._update_raindrops()self._update_screen()if __name__ == "__main__":ai = Sky()ai.run_game()

结果是这样的


五、13-5 侧面射击2

外星人图片放在这里啦

命名为 enemy1.png

遗漏的外星人到达边缘以后不会消失,只是看不见

长时间这样运行肯定不好

所以有一个额外任务:删除到达边缘的外星人

settings.py

class Settings:"""储存游戏《外星人入侵》中所有设置的类"""def __init__(self):"""初始化游戏的设置"""# 屏幕设置self.screen_width = 1000self.screen_height = 600self.bg_color = (0, 200, 255)#飞船设置self.ship_speed = 0.5#子弹设置self.bullet_speed = 1.0self.bullet_width = 5self.bullet_hight = 15self.bullet_color = (60, 60, 60)#外星人设置self.alien_speed = 0.3

alien.py

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""表示单个外星人的类"""def __init__(self, ai_game):"""初始化外星人并设置起始位置"""super().__init__()self.screen = ai_game.screenself.screen_rect = self.screen.get_rect()self.settings = ai_game.settings#加载外星人图像并设置其 rect 属性self.image = pygame.image.load('enemy1.png')self.rect = self.image.get_rect()#每个外星人都在屏幕右上角附近self.rect.right = self.screen_rect.rightself.rect.y = 30#储存外星人的精确位置self.x = float(self.rect.x)def update(self):"""更新外星人的位置"""self.x -= self.settings.alien_speedself.rect.x = self.xdef check_edge(self):"""如果外星人到达边缘就返回 True """if self.rect.left < 0:return True

mygame1.0.py

import sys
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from random import randintclass MyGame:"""管理游戏资源和行为的类"""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("MyGame 1.0")self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()def _check_fleet_edge(self):"""到达边缘时对外星人的处理"""for alien in self.aliens.sprites():if alien.check_edge():self.aliens.remove(alien)def _create_fleet(self):"""创建外星人舰队"""if 200 == randint(1, 300):for alien_num in range(8):if 8 == randint(0, 20):num = randint(0, 7)alien = Alien(self)alien.y = 30 + num * (alien.rect.height + 10)alien.rect.y = alien.yself.aliens.add(alien)def _update_screen(self):"""更新屏幕上的图像,并切换到新图像"""self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self._check_fleet_edge()self.aliens.draw(self.screen)# 让最近绘制的屏幕可见pygame.display.flip()def _update_bullets(self):"""更新子弹的位置并删除消失的子弹"""self.bullets.update()# 删除消失的子弹for bullet in self.bullets.copy():if bullet.rect.x > self.settings.screen_width:self.bullets.remove(bullet)#子弹和外星人碰撞collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)def _fire_bullet(self):"""创建一颗子弹,并将其加入编组bullets中"""new_bullet = Bullet(self)self.bullets.add(new_bullet)def _check_events(self):"""相应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:self._check_keydown_events(event)elif event.type == pygame.KEYUP:self._check_keyup_events(event)def _check_keydown_events(self, event):"""响应按键"""if event.key == pygame.K_UP:# 向上移动角色self.ship.moving_up = Trueelif event.key == pygame.K_DOWN:# 向下移动角色self.ship.moving_down = Trueelif event.key == pygame.K_q:#按 q 退出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 = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falseelif event.key == pygame.K_UP:self.ship.moving_up = Falseelif event.key == pygame.K_DOWN:self.ship.moving_down = Falsedef run_game(self):""""开始游戏的主循环"""while True:self._create_fleet()self._check_events()self.ship.update()self._update_bullets()self.aliens.update()self._update_screen()if __name__ == '__main__':ai = MyGame()ai.run_game()

来看看结果吧:


六、13-6游戏结束

我的游戏规则:

玩家有三艘飞船,与外星人碰撞会损失一艘并停顿0.5秒,没有飞船时游戏结束

外星人飞出屏幕不会损失飞船

增加了一点设置

settings.py

class Settings:"""储存游戏《外星人入侵》中所有设置的类"""def __init__(self):"""初始化游戏的设置"""# 屏幕设置self.screen_width = 1000self.screen_height = 600self.bg_color = (0, 200, 255)#飞船设置self.ship_speed = 0.5self.ship_limit = 3#子弹设置self.bullet_speed = 0.75self.bullet_width = 5self.bullet_hight = 15self.bullet_color = (60, 60, 60)#外星人设置self.alien_speed = 0.3

新建game_stats.py

class GameStats:"""跟踪游戏的统计信息"""def __init__(self, ai_game):"""初始化统计信息"""self.settings = ai_game.settingsself.reset_stats()#游戏刚开始时处于活动状态self.game_active = Truedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ship_left = self.settings.ship_limit

mygame1.0.py

import sys
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from random import randint
from game_stats import GameStats
from time import sleepclass MyGame:"""管理游戏资源和行为的类"""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("MyGame 1.0")# 创建一个用于游戏储存的统计信息的实例self.stats = GameStats(self)self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()def _check_fleet_edge(self):"""到达边缘时对外星人的处理"""for alien in self.aliens.sprites():if alien.check_edge():self.aliens.remove(alien)def _create_fleet(self):"""创建外星人舰队"""if 100 == randint(1, 250):for alien_num in range(8):if 8 == randint(0, 20):num = randint(0, 7)alien = Alien(self)alien.y = 30 + num * (alien.rect.height + 10)alien.rect.y = alien.yself.aliens.add(alien)def _update_screen(self):"""更新屏幕上的图像,并切换到新图像"""self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self._check_fleet_edge()self.aliens.draw(self.screen)# 让最近绘制的屏幕可见pygame.display.flip()def _update_bullets(self):"""更新子弹的位置并删除消失的子弹"""self.bullets.update()# 删除消失的子弹for bullet in self.bullets.copy():if bullet.rect.x > self.settings.screen_width:self.bullets.remove(bullet)#子弹和外星人碰撞collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)def _update_aliens(self):"""更新外星人的类"""self._create_fleet()self.aliens.update()#检测飞船和外星人的碰撞if pygame.sprite.spritecollideany(self.ship, self.aliens):if self.stats.ship_left > 0:self.stats.ship_left -= 1#暂停sleep(0.5)#清空余下的外星人和子弹self.aliens.empty()self.bullets.empty()else:self.stats.game_active = Falsedef _fire_bullet(self):"""创建一颗子弹,并将其加入编组bullets中"""new_bullet = Bullet(self)self.bullets.add(new_bullet)def _check_events(self):"""相应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:self._check_keydown_events(event)elif event.type == pygame.KEYUP:self._check_keyup_events(event)def _check_keydown_events(self, event):"""响应按键"""if event.key == pygame.K_UP:# 向上移动角色self.ship.moving_up = Trueelif event.key == pygame.K_DOWN:# 向下移动角色self.ship.moving_down = Trueelif event.key == pygame.K_q:#按 q 退出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 = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falseelif event.key == pygame.K_UP:self.ship.moving_up = Falseelif event.key == pygame.K_DOWN:self.ship.moving_down = Falsedef run_game(self):""""开始游戏的主循环"""while True:self._check_events()if self.stats.game_active:self.ship.update()self._update_bullets()self._update_aliens()self._update_screen()if __name__ == '__main__':ai = MyGame()ai.run_game()

结果跟上一题看不出差别

但是测试撞击、结束是成功的

接下来做记分系统

先对游戏画面做点优化

换掉子弹和背景

图片放在这里 背景命名为 background.png 子弹命名为 bullet0.png

为了便于管理,新建一个image文件夹存放照片

这次改动较大,我把所有文件都贴一下 目录如下图所示

alien.py

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""表示单个外星人的类"""def __init__(self, ai_game):"""初始化外星人并设置起始位置"""super().__init__()self.screen = ai_game.screenself.screen_rect = self.screen.get_rect()self.settings = ai_game.settings#加载外星人图像并设置其 rect 属性self.image = pygame.image.load('image/enemy1.png')self.rect = self.image.get_rect()#每个外星人都在屏幕右上角附近self.rect.right = self.screen_rect.rightself.rect.y = 30#储存外星人的精确位置self.x = float(self.rect.x)def update(self):"""更新外星人的位置"""self.x -= self.settings.alien_speedself.rect.x = self.xdef check_edge(self):"""如果外星人到达边缘就返回 True """if self.rect.left < 0:return True

bullet.py

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):"""管理飞船所发射子弹的类"""def __init__(self, ai_game):"""在飞船当前位置创建一个子弹对象"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settings#在(0,0)处创建一个表示子弹的矩形,再设置正确的位置self.buImg = pygame.image.load('image/bullet0.png')self.rect = self.buImg.get_rect()self.rect.midleft = ai_game.ship.rect.midleftself.rect.x = ai_game.ship.rect.right#使用小数表示的子弹的位置self.x = float(self.rect.x)def draw_bullet(self):"""在屏幕上绘制子弹"""self.screen.blit(self.buImg, (self.rect.x, self.rect.y))def update(self):"""向右移动子弹"""#更新表示子弹位置的小数值self.x += self.settings.bullet_speed#更新表示 rect 的位置self.rect.x = self.x

gamestats.py

class GameStats:"""跟踪游戏的统计信息"""def __init__(self, ai_game):"""初始化统计信息"""self.settings = ai_game.settingsself.reset_stats()#游戏刚开始时处于活动状态self.game_active = Truedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ship_left = self.settings.ship_limitself.score = 0

mygame1.0.py

import sys
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from random import randint
from game_stats import GameStats
from time import sleep
from scoreboard import Scoreboardclass MyGame:"""管理游戏资源和行为的类"""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("MyGame 1.0")# 创建一个用于游戏储存的统计信息的实例self.stats = GameStats(self)self.sb = Scoreboard(self)self.ship = Ship(self)self.bullets = pygame.sprite.Group()self.aliens = pygame.sprite.Group()def _check_fleet_edge(self):"""到达边缘时对外星人的处理"""for alien in self.aliens.sprites():if alien.check_edge():self.aliens.remove(alien)def _check_bullet_alien_collision(self):#子弹和外星人碰撞collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)if collisions:self.stats.score += self.settings.alien_pointsself.sb.prep_score()def _create_fleet(self):"""创建外星人舰队"""if 1 == randint(1, 15):for alien_num in range(8):if 8 == randint(0, 20):num = randint(0, 5)alien = Alien(self)alien.y = 30 + num * (alien.rect.height + 10)alien.rect.y = alien.yself.aliens.add(alien)def _update_screen(self):  """更新屏幕上的图像,并切换到新图像"""bmImg = pygame.image.load('image/background.png')self.screen.blit(bmImg, (0, 0))self.sb.show_score()self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self._check_fleet_edge()self.aliens.draw(self.screen)# 让最近绘制的屏幕可见pygame.display.flip()def _update_bullets(self):"""更新子弹的位置并删除消失的子弹"""self.bullets.update()# 删除消失的子弹for bullet in self.bullets.copy():if bullet.rect.x > self.settings.screen_width:self.bullets.remove(bullet)self._check_bullet_alien_collision()def _update_aliens(self):"""更新外星人的类"""self._create_fleet()self.aliens.update()#检测飞船和外星人的碰撞if pygame.sprite.spritecollideany(self.ship, self.aliens):if self.stats.ship_left > 0:#暂停sleep(0.5)self.stats.ship_left -= 1self.sb.prep_ships()#清空余下的外星人和子弹self.aliens.empty()self.bullets.empty()else:self.stats.game_active = Falsedef _fire_bullet(self):"""创建一颗子弹,并将其加入编组bullets中"""new_bullet = Bullet(self)self.bullets.add(new_bullet)def _check_events(self):"""相应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:self._check_keydown_events(event)elif event.type == pygame.KEYUP:self._check_keyup_events(event)def _check_keydown_events(self, event):"""响应按键"""if event.key == pygame.K_UP:# 向上移动角色self.ship.moving_up = Trueelif event.key == pygame.K_DOWN:# 向下移动角色self.ship.moving_down = Trueelif event.key == pygame.K_q:#按 q 退出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 = Falseelif event.key == pygame.K_LEFT:self.ship.moving_left = Falseelif event.key == pygame.K_UP:self.ship.moving_up = Falseelif event.key == pygame.K_DOWN:self.ship.moving_down = Falsedef run_game(self):""""开始游戏的主循环"""while True:self._check_events()if self.stats.game_active:self.ship.update()self._update_bullets()self._update_aliens()self._update_screen()if __name__ == '__main__':ai = MyGame()ai.run_game()

scoreboard.py

import pygame.fontclass Scoreboard:"""显示得分信息的类"""def __init__(self, ai_game):"""初始化显示得分涉及的属性"""self.ai_game = ai_gameself.screen = ai_game.screenself.screen_rect = self.screen.get_rect()self.stats = ai_game.statsself.settings = ai_game.settings#显示得分信息时使用的字体设置self.color = (251, 255, 242)self.font = pygame.font.SysFont("./STCAIYUN.ttf", 33)#准备初始得分图像self.prep_score()self.prep_ships()def prep_ships(self):"""显示还余下多少飞船"""ship_left_str = str(self.stats.ship_left)self.ship_left_image = self.font.render("LEFT: " + ship_left_str,True, self.color)self.ship_left_rect = self.ship_left_image.get_rect()self.ship_left_rect.top, self.ship_left_rect.right = 10, 700def prep_score(self):"""将得分转换为一幅渲染的图像"""rounded_score = round(self.stats.score, -1)score_str = "{:,}".format(rounded_score)self.score_image = self.font.render("SCORE: " + score_str,True, self.color)self.score_rect = self.score_image.get_rect()self.score_rect.bottom, self.score_rect.right = 480, 700def show_score(self):"""在屏幕上显示得分"""self.screen.blit(self.score_image, self.score_rect)self.screen.blit(self.ship_left_image, self.ship_left_rect)

settings.py

class Settings:"""储存游戏《外星人入侵》中所有设置的类"""def __init__(self):"""初始化游戏的设置"""# 屏幕设置self.screen_width = 700self.screen_height = 480#飞船设置self.ship_speed = 4.0self.ship_limit = 3#子弹设置self.bullet_speed = 5.0# def initialize_dynamic_settings(self):"""游戏动态数据"""#飞船设置self.ship_left = 3#外星人设置self.alien_speed = 2.0self.alien_points = 50

ship.py

import pygame
from pygame.sprite import Spriteclass Ship(Sprite):"""管理角色的类"""def __init__(self, ai_game):"""初始化角色并设置其初始位置"""super().__init__()self.screen = ai_game.screenself.settings = ai_game.settingsself.screen_rect = ai_game.screen.get_rect()#加载角色图像并获取其外接矩形self.image = pygame.image.load('image/me.png')self.rect = self.image.get_rect()#绘制到屏幕中央self.rect.midleft = self.screen_rect.midleft# 在飞船的属性 x,y 中储存小数值self.y = float(self.rect.y)#移动标志self.moving_up = Falseself.moving_down = Falsedef update(self):"""根据移动标志调整角色的位置"""#更新角色而不是rect对象的y值if self.moving_up and self.rect.top > 0:self.y += -1 * self.settings.ship_speedelif self.moving_down and self.rect.bottom < self.screen_rect.bottom:self.y += self.settings.ship_speed#更新rect对象self.rect.y = self.ydef blitme(self):"""在指定的位置绘制飞船"""self.screen.blit(self.image, self.rect)

来看看结果吧:


总结

学习pygame能让我们对如何管理一个项目有一个初认识,这对于初学者来说绝对是难得的体验,希望大家都能从中体会编程的乐趣。

看完了记得点个赞~ 

python从入门到实践13章答案相关推荐

  1. python从入门到实践19章答案

    目录 前言 一.博客 1.建立项目 2.创建应用程序 3.Django管理网站 4.让用户输入数据 二.博客账户 1.应用程序users 2.登录页面 3.注销 4.注册页面 三.重构 四.保护页面n ...

  2. python从入门到实践18章答案

    目录 前言 一.新项目 二.简短的条目 三.Django API 四.比萨店 1.创建虚拟环境.安装Django.创建项目.创建数据库.创建应用程序 2.定义模型 3.激活模型 4.向管理网站注册模型 ...

  3. python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 用户输入和while循环 课后练习...

    题目: 7-8 熟食店 :创建一个名为sandwich_orders 的列表,在其中包含各种三明治的名字:再创建一个名为finished_sandwiches 的空列表.遍历列 表sandwich_o ...

  4. python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 while循环 课后练习...

    题目: 7-4 比萨配料 :编写一个循环,提示用户输入一系列的比萨配料,并在用户输入'quit' 时结束循环.每当用户输入一种配料后,都打印一条消息,说我们会在比萨 中添加这种配料. 7-5 电影票 ...

  5. python从入门到实践课后题答案第7章_【《Python编程: 从入门到实践》习题答案--第七章:】...

    #本章节代码中暂不涉及try-catch,所以默认为用户输入的符合所需要的输入类型 # 7-1 汽车租赁 : 编写一个程序, 询问用户要租赁什么样的汽车, 并打印一条消息, 如"Let me ...

  6. python 数据挖掘 简书_[Python数据挖掘入门与实践]-第一章开启数据挖掘之旅

    1.数据挖掘简介(略) 2.使用Python和IPython Notebook 2.1.安装Python 2.2.安装IPython 2.3.安装scikit-learn scikit-learn是用 ...

  7. python从入门到实践15章的几个自己的小程序

    练习15-1自己的答案 #加入python画图的库 pyplot import matplotlib.pyplot as plt #生成一个list input_values= list(range( ...

  8. python数据挖掘入门与实践-第一章-用最简单OneR算法对Iris植物分类

    前言: 这本书其实有配套代码的来着,但是有点坑的是,里面的代码对应的版本是有点旧的,用的时候会警告或者已经报错.甚至有些代码书里提了但是却没有写进去,要自己去摸索.我是每一章都跟着代码示例,把每一个步 ...

  9. python从入门到实践18章django存在问题_第18章 Django入门 P371

    声音简介-感谢粉丝NN娜娜小天使的打赏,此音频即日起以24小时/天,1次/小时的速度更新,直至完结~ 特别说明: 此音频仅作为更好地阅读此书的辅助工具,请大家购买正版书籍. 所有音频全部免费供大家试听 ...

最新文章

  1. 今天已经算一下过来有一个礼拜了,还是感觉是在熬日子似的
  2. 搭建通用性多用户后台-思路
  3. php饿死,男网红出租屋内活活饿死宠物:不尊重生命的人有多可怕?
  4. boost::hana::lexicographical_compare用法的测试程序
  5. P2446 [SDOI2010]大陆争霸
  6. 多层陶瓷电容器用处_陶瓷电容器的用途有哪几种?
  7. 观、砺、破——我的算法之道
  8. NOR Flash擦写和原理分析 (二)
  9. 【博主推荐】html好看的个人主页(附源码)
  10. 【USACO19FEB】Mowing Mischief P(决策单调性)(线段树辅助分治)
  11. html5页面交互,H5的交互原型设计
  12. C++单元测试框架Gtest的配置与使用过程
  13. UISlider实现背景图
  14. 手机设备的唯一标识:IMSI、IMEI、ESN、MEID
  15. 《20个月赚130亿-YouTube创始人陈士骏自传》- 简评
  16. TUANDUIZUOYE
  17. 解决问题:使用nvm use出现exit status 1与exit status 145乱码
  18. Enable密码丢失的解决方法
  19. python安装paddlex(虚拟环境快速安装)
  20. 技嘉 linux设置u盘启动项,技嘉u盘启动,教您技嘉主板怎么设置u盘启动

热门文章

  1. 乡村调研笔记----乡村振兴,实现城乡融合发展新局面
  2. c++简易颓废小说的小程序
  3. pyppeteer Chrome无响应问题解决
  4. 使用gnvm管理多个版本的node应用
  5. ORACLE 计算某个变量的同比环比
  6. 网络请求 - 收藏集 - 掘金
  7. C#,弗洛伊德-瑞文斯特(Floyd-Rivest)算法与源代码
  8. 在华为写了十几年代码,一个程序员的自我修养
  9. ML—AdaBoost(二)—MATLAB代码
  10. 个人如何发表国家级期刊