第十二章—武装飞船
12-1 蓝色天空 :创建一个背景为蓝色的Pygame窗口。
1 import sys 2 import pygame 3 def run_game(): 4 #初始化游戏并创建一个屏幕对象 5 pygame.init() 6 screen=pygame.display.set_mode((1200,800)) 7 pygame.display.set_caption("Alien Invasion") 8 #设置背景颜色 9 bg_color=(0,0,255) 10 #开始游戏的主循环 11 while True: 12 #监视键盘和鼠标事件 13 for event in pygame.event.get(): 14 if event.type==pygame.QUIT: 15 sys.exit() 16 #每次循环时都会重绘屏幕 17 screen.fill(bg_color) 18 #让最近绘制的屏幕可见 19 pygame.display.flip() 20 run_game()
输出:
12-2 游戏角色 :找一幅你喜欢的游戏角色位图图像或将一幅图像转换为位图。创建一个类,将该角色绘制到屏幕中央,并将该图像的背景色设置为屏幕背景色,或将 屏幕背景色设置为该图像的背景色。
alien_invasion1.py
1 import sys 2 import pygame 3 from rocket import Rocket 4 5 def run_game(): 6 #初始化游戏并创建一个屏幕对象 7 pygame.init() 8 screen=pygame.display.set_mode((800,600)) 9 pygame.display.set_caption("Alien Invasion") 10 11 #创建一艘火箭 12 rocket=Rocket(screen) 13 14 #设置背景颜色 15 bg_color=(0,0,255) 16 #开始游戏的主循环 17 while True: 18 #监视键盘和鼠标事件 19 for event in pygame.event.get(): 20 if event.type==pygame.QUIT: 21 sys.exit() 22 #每次循环时都会重绘屏幕 23 screen.fill(bg_color) 24 rocket.blitme() 25 #让最近绘制的屏幕可见 26 pygame.display.flip() 27 run_game()
rocket.py
1 import pygame 2 class Rocket(): 3 def __init__(self,screen): 4 '''初始化火箭并设置其初始位置''' 5 self.screen=screen 6 #加载火箭图像图像并获取其外接矩形 7 self.image=pygame.image.load('image/rocket.bmp') 8 self.rect = self.image.get_rect() 9 self.screen_rect = screen.get_rect() 10 11 #将每艘新火箭放在屏幕中央 12 self.rect.centerx = self.screen_rect.centerx 13 self.rect.centery = self.screen_rect.centery 14 # 在飞船的属性center中存储小数值 15 self.center = float(self.rect.centerx) 16 17 def blitme(self): 18 # 在指定位置绘制飞船 19 self.screen.blit(self.image, self.rect)
输出:
12-3 火箭 :编写一个游戏,开始时屏幕中央有一个火箭,而玩家可使用四个方向键上下左右移动火箭。请务必确保火箭不会移到屏幕外面。
alien_invasion1.py
1 import sys 2 import pygame 3 import game_functions1 as gf 4 from settings1 import Settings 5 from rocket import Rocket 6 7 def run_game(): 8 #初始化游戏并创建一个屏幕对象 9 pygame.init() 10 ai_settings=Settings() 11 screen=pygame.display.set_mode( 12 (ai_settings.screen_width,ai_settings.screen_height))#窗口尺寸 13 pygame.display.set_caption("Rocket") 14 #创建一个火箭 15 rocket=Rocket(ai_settings,screen) 16 #开始游戏主循环 17 while True: 18 #监视键盘和鼠标事件 19 gf.check_events(rocket) 20 rocket.update() 21 gf.update_screen(ai_settings,screen,rocket) 22 run_game()
输出:
12-4 按键 :创建一个程序,显示一个空屏幕。在事件循环中,每当检测到pygame.KEYDOWN 事件时都打印属性event.key。运行这个程序,并按各种键,看看Pygame如何响应。
1 import sys 2 import pygame 3 def run_game(): 4 pygame.init() 5 screen=pygame.display.set_mode((1000,600)) 6 pygame.display.set_caption('kong') 7 bg_color = (230, 230, 230) 8 while True: 9 for event in pygame.event.get(): 10 if event.type==pygame.QUIT: 11 sys.exit() 12 elif event.type == pygame.KEYDOWN: 13 if event.key==pygame.K_DOWN: 14 bg_color = (255, 0, 0) 15 else : 16 bg_color = (0, 255, 0) 17 screen.fill(bg_color) 18 pygame.display.flip() 19 20 run_game()
输出:
点击运行后键盘无操作:
键盘向下键:
键盘其他键:
12-5 侧面射击 :编写一个游戏,将一艘飞船放在屏幕左边,并允许玩家上下移动飞船。在玩家按空格键时,让飞船发射一颗在屏幕中向右穿行的子弹,并在子弹离开 屏幕而消失后将其删除。
settings2.py
1 class Settings(): 2 #存储《外星人入侵》的所有设置的类 3 def __init__(self): 4 #初始化游戏的设置 5 #屏幕设置 6 self.screen_width=1000 7 self.screen_height=500 8 self.bg_color=(230,230,230) 9 #飞船的设置 10 self.ship_speed_factor=1.5 11 12 #子弹的设置 13 self.bullet_speed_factor=1 14 self.bullet_width=15 15 self.bullet_height=3 16 self.bullet_color=(60,60,60) 17 self.bullets_allowed=6
ship2.py
1 import pygame 2 class Ship(): 3 def __init__(self,ai_settings,screen): 4 #初始化飞船并设置其初始位置 5 self.screen=screen 6 self.ai_settings=ai_settings 7 #加载飞船图像并获取其外接矩形 8 self.image=pygame.image.load('image/ship.bmp') 9 self.rect=self.image.get_rect() 10 self.screen_rect=screen.get_rect() 11 #将每艘新飞船放在屏幕左侧中央 12 self.rect.left=self.screen_rect.left 13 self.rect.centery=self.screen_rect.centery 14 #在飞船的属性center中存储小数值 15 self.centery=float(self.rect.centery) 16 17 #移动标志 18 self.moving_up=False 19 self.moving_down = False 20 def update(self): 21 """根据移动标志调整飞船位置""" 22 #更新飞船的center值,而不是rect 23 if self.moving_up and self.rect.top>0: 24 self.centery-=self.ai_settings.ship_speed_factor 25 if self.moving_down and self.rect.bottom<self.screen_rect.bottom: 26 self.centery+=self.ai_settings.ship_speed_factor 27 28 #根据self.centery更新rect对象 29 self.rect.centery=self.centery 30 31 def blitme(self): 32 #在指定位置绘制飞船 33 self.screen.blit(self.image,self.rect)
bullet2.py
1 import pygame 2 from pygame.sprite import Sprite 3 4 class Bullet(Sprite): 5 '''一个对飞船发射的子弹进行管理的类''' 6 def __init__(self,ai_settings,screen,ship): 7 """在飞船所处的位置创建一个子弹对象""" 8 super(Bullet,self).__init__() 9 self.screen=screen 10 #在(0,0)处创建一个表示子弹的矩形,再设置正确的位置 11 self.rect=pygame.Rect(0,0,ai_settings.bullet_width, 12 ai_settings.bullet_height) 13 self.rect.centery=ship.rect.centery 14 self.rect.left=ship.rect.left 15 #存储用小数表示的子弹位置 16 self.x=float(self.rect.x) 17 self.color= ai_settings.bullet_color 18 self.speed_factor=ai_settings.bullet_speed_factor 19 def update(self): 20 """向右移动子弹""" 21 #更新表示子弹位置的小数值 22 self.x+=self.speed_factor 23 #更新表示子弹的rect的位置 24 self.rect.x=self.x 25 26 def draw_bullet(self): 27 """在屏幕上绘制子弹""" 28 pygame.draw.rect(self.screen,self.color,self.rect)
game_functions2.py
1 import sys 2 import pygame 3 from bullet2 import Bullet 4 def check_keydown_events(event,ai_settings,screen,ship,bullets): 5 """响应按键""" 6 if event.key == pygame.K_UP: 7 # 向上移动飞船 8 ship.moving_up = True 9 elif event.key == pygame.K_DOWN: 10 # 向下移动飞船 11 ship.moving_down = True 12 elif event.key==pygame.K_SPACE: 13 fire_bullet(ai_settings, screen, ship, bullets) 14 15 def fire_bullet(ai_settings,screen,ship,bullets): 16 """如果还没有到达限制,就发射一颗子弹""" 17 # 创建一颗子弹,并将其加入到编组bullets中 18 if len(bullets) < ai_settings.bullets_allowed: 19 new_bullet = Bullet(ai_settings, screen, ship) 20 bullets.add(new_bullet) 21 22 def check_keyup_events(event,ship): 23 """响应松开""" 24 if event.key == pygame.K_UP: 25 # 向上移动飞船 26 ship.moving_up = False 27 elif event.key == pygame.K_DOWN: 28 # 向上移动飞船 29 ship.moving_down = False 30 def check_events(ai_settings,screen,ship,bullets): 31 for event in pygame.event.get(): 32 if event.type == pygame.QUIT: 33 sys.exit() 34 elif event.type==pygame.KEYDOWN: 35 check_keydown_events(event, ai_settings,screen,ship,bullets) 36 37 elif event.type==pygame.KEYUP: 38 check_keyup_events(event, ship) 39 40 def update_screen(ai_settings,screen,ship,bullets): 41 """更新屏幕上的图像,并切换到新屏幕上""" 42 #每次循环时都重绘屏幕 43 screen.fill(ai_settings.bg_color) 44 #在飞船和外星人后面重绘所有子弹 45 for bullet in bullets.sprites(): 46 bullet.draw_bullet() 47 ship.blitme() 48 #让最近绘制屏幕可见 49 pygame.display.flip() 50 def update_bullets(bullets): 51 # 更新子弹位置,删除已消失的子弹 52 #更新子弹位置 53 bullets.update() 54 #删除已消失的子弹 55 for bullet in bullets.copy(): 56 if bullet.rect.left >= 1000: 57 bullets.remove(bullet) 58 # print(len(bullets))
alien_invasion2.py
1 import sys 2 import pygame 3 from pygame.sprite import Group 4 import game_functions2 as gf 5 from settings2 import Settings 6 from ship2 import Ship 7 8 def run_game(): 9 #初始化游戏并创建一个屏幕对象 10 pygame.init() 11 ai_settings=Settings() 12 screen=pygame.display.set_mode( 13 (ai_settings.screen_width,ai_settings.screen_height))#窗口尺寸 14 pygame.display.set_caption("Alien Invasion") 15 #创建一个飞船 16 ship=Ship(ai_settings,screen) 17 #创建一个用于存储子弹的编组 18 bullets=Group() 19 20 #开始游戏主循环 21 while True: 22 gf.check_events(ai_settings,screen,ship,bullets) 23 ship.update() 24 gf.update_bullets(bullets) 25 gf.update_screen(ai_settings,screen,ship,bullets) 26 run_game()
输出: