Day9.10.11——打飞机小游戏续

一、项目规划

玩家控制一搜最初出现在屏幕底部中央的飞船。通过按键左右控制飞船,空格键进行射击。游戏开始时,一群外小飞机出现在天空中,他们向屏幕下面移动。在玩家消灭一波后下一波的速度会更快。小飞机撞到玩家或者到底屏幕底部就会掉一滴血一共三滴

二、详细项目

1.窗口

1.1创建窗口以及响应用户的输入

文件名为alien_invasion.py

import sys
import pygame
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    screen=pygame.display.set_mode((1200,800))
    pygame.display.set_caption("标题")
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            #让最近绘制的屏幕可见 让画面变成一帧一帧丝滑
        pygame.display.flip()
run_game()

1.2设置背景色

在上面文件中添加背景色功能

import sys
import pygame
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    screen=pygame.display.set_mode((1200,800))
    pygame.display.set_caption("标题")
    #在这里设置背景颜色
    bg_color=(230,230,250)
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            #颜色填充
            screen.fill(bg_color) #要放在循环内 不然只会刷新一次
            pygame.display.flip()
run_game()

1.3创建设置类 settings.py类

给游戏添加小功能的时候用settings的模块来存储在一起 

class Settings():
    #存储游戏中所有的设置选项
    def __init__(self):
        #屏幕设置
        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,250)

这时候要把alien——invasion.py修改一下

import sys
import pygame
from settings import Settings
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #在这里设置背景颜色
    bg_color=(230,230,250)
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            #颜色填充
            screen.fill(ai_settings.bg_color)
            pygame.display.flip()
run_game()

2.添加飞船图像

游戏中 可以用任何形式图像,pygame中默认加载.bmp

用blit()加载

2.1创建飞船的ship类来控制飞船的行为

import pygame
class Ship():
    def __init__(self,screen):
        #初始化飞船并且进行设置它的起始位置
        self.screen=screen
        #加载飞船图像并且获取它的外接矩形
        self.image=pygame.image.load("ship.bmp")
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #将每搜飞船重新放到屏幕底部中央
        self.rect.centerx=self.screen_rect.cenerx
        self.rect.bottom=self.screen_rect.bottom
    def blitme(self):
        #在指定位置绘制飞船 将图像画到矩形位置上
        self.screen.blit(self.image,self.rect)

2.2在屏幕上绘制飞船

更新alien——invasion.py创建一艘飞船并调用blitme()

import sys
import pygame
from settings import Settings
from ship import Ship
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(screen)
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            #颜色填充
            screen.fill(ai_settings.bg_color)
            ship.blitme()#将飞船绘制到屏幕上确保它出现在背景前面
            pygame.display.flip()
run_game()

3.重构:模块game_functions

以打包的方式需要的时候使用

3.1函数check_events()

把管理事件的代码移到一个名为check_events()的函数中,以简化run_game()

将check_events()放在一个名为game_functions的模块中:game_functions.py

import sys
import pygame
def check_events():
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()

下面修改ailin——invasion.py使其导入game_functions并将事件循环替换为对函数check_events()的调用:

import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(screen)
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
            gf.check_events()
            #颜色填充
            screen.fill(ai_settings.bg_color)
            ship.blitme()#将飞船绘制到屏幕上确保它出现在背景前面
            pygame.display.flip()
run_game()

3.2函数update_screen()

将更新屏幕代码移到这个函数里面放在模块game_functions.py中

import sys
import pygame
def check_events():
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
def update_screen(ai_settings,screen,ship):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

对alien_invasion.py进行更新

import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(screen)
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events()
        gf.update_screen(ai_settings,screen,ship)

run_game()

对代码进行重构后更容易扩展,可以处理游戏的动态方面。

4.驾驶功能

4.1响应按键

在检测到→飞船就向右 我们就增加rect.centerx的值

game_functions.py

import sys
import pygame
def check_events(ship):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            if event.key==pygame.K_RIGHT:
                #向右移动飞船
                ship.rect.centerx=ship.rect.centerx+20
def update_screen(ai_settings,screen,ship):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

更新alien_invasion

   while True:
        gf.check_events(ship)
        gf.update_screen(ai_settings,screen,ship)

run_game()

4.2运行不断移动

按右键不松的时候飞船一直向右直到松开。对Ship类

标志moving_right在飞船不动的时候为False,按下右键的时候为True,松开的时候重新设置为False

import pygame
class Ship():
    def __init__(self,screen):
        #初始化飞船并且进行设置它的起始位置
        self.screen=screen
        #加载飞船图像并且获取它的外接矩形
        self.image=pygame.image.load("ship.bmp")
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #将每搜飞船重新放到屏幕底部中央
        self.rect.centerx=self.screen_rect.centerx
        self.rect.bottom=self.screen_rect.bottom
        #移动标志
        self.moving_right=False
    def update(self):
        #根据移动标志来调整飞船的位置
        if self.moving_right:
            self.rect.centerx+=20
    def blitme(self):
        #在指定位置绘制飞船 将图像画到矩形位置上
        self.screen.blit(self.image,self.rect)

修改gamefunction

import sys
import pygame
def check_events(ship):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            if event.key==pygame.K_RIGHT:
                ship.moving_right=True
        elif event.type==pygame.KEYUP:
            if event.key==pygame.K_RIGHT:
                ship.moving_right=False

def update_screen(ai_settings,screen,ship):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

最后在修改alien中while 循环使得每次执行循环的时候都调用飞船的update方法:

import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(screen)
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events(ship)
        ship.update()
        gf.update_screen(ai_settings,screen,ship)

run_game()

4.3左右移动

修改ship类和函数check——events

import pygame
class Ship():
    def __init__(self,screen):
        #初始化飞船并且进行设置它的起始位置
        self.screen=screen
        #加载飞船图像并且获取它的外接矩形
        self.image=pygame.image.load("ship.bmp")
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #将每搜飞船重新放到屏幕底部中央
        self.rect.centerx=self.screen_rect.centerx
        self.rect.bottom=self.screen_rect.bottom
        #移动标志
        self.moving_right=False
        self.moving_left=False
    def update(self):
        #根据移动标志来调整飞船的位置
        if self.moving_right:
            self.rect.centerx+=1
        if self.moving_left:
            self.rect.centerx-=1
    def blitme(self):
        #在指定位置绘制飞船 将图像画到矩形位置上
        self.screen.blit(self.image,self.rect)

再对check——events game——function

import sys
import pygame
def check_events(ship):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            if event.key==pygame.K_RIGHT:
                ship.moving_right=True
            elif event.key==pygame.K_LEFT:
                ship.moving_left=True
        elif event.type==pygame.KEYUP:
            if event.key==pygame.K_RIGHT:
                ship.moving_right=False
            elif event.key==pygame.K_LEFT:
                ship.moving_left=False

def update_screen(ai_settings,screen,ship):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

4.4调整飞船的速度

settings.py中

class Settings():
    #存储游戏中所有的设置选项
    def __init__(self):
        #屏幕设置
        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,250)
        self.ship_speed_factor=1.5 #速度设置

对ship类修改

import pygame
class Ship():
    def __init__(self,ai_settings,screen):
        #初始化飞船并且进行设置它的起始位置
        self.screen=screen
        #加载飞船图像并且获取它的外接矩形
        self.ai_settings=ai_settings
        self.image=pygame.image.load("ship.bmp")
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #将每搜飞船重新放到屏幕底部中央
        self.rect.centerx=self.screen_rect.centerx
        self.rect.bottom=self.screen_rect.bottom
        self.center=float(self.rect.centerx)
        #移动标志
        self.moving_right=False
        self.moving_left=False
    def update(self):
        #根据移动标志来调整飞船的位置
        #更新飞船的center值而不是rect
        if self.moving_right:
            self.rect.centerx+=self.ai_settings.ship_speed_factor
        if self.moving_left:
            self.rect.centerx-=self.ai_settings.ship_speed_factor
            #根据self.center更新rect对象
            self.rect.centerx=self.center
    def blitme(self):
        #在指定位置绘制飞船 将图像画到矩形位置上
        self.screen.blit(self.image,self.rect)

对alien中创建ship实例

import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings()
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(ai_settings,screen)
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events(ship)
        ship.update()
        gf.update_screen(ai_settings,screen,ship)

run_game()

4.5限制飞船的活动范围

飞船到达边缘后会停止移动 修改ship中的update  

self.rect.centerx=self.center

import pygame
class Ship():
    def __init__(self,ai_settings,screen):
        #初始化飞船并且进行设置它的起始位置
        self.screen=screen
        #加载飞船图像并且获取它的外接矩形
        self.ai_settings=ai_settings
        self.image=pygame.image.load("ship.bmp")
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #将每搜飞船重新放到屏幕底部中央
        self.rect.centerx=self.screen_rect.centerx
        self.rect.bottom=self.screen_rect.bottom
        self.center=float(self.rect.centerx)
        #移动标志
        self.moving_right=False
        self.moving_left=False
    def update(self):
        #根据移动标志来调整飞船的位置
        #更新飞船的center值而不是rect
        if self.moving_right and self.rect.right<self.screen_rect.right:
            self.rect.centerx+=self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left>0:
            self.rect.centerx-=self.ai_settings.ship_speed_factor
            #根据self.center更新rect对象

    def blitme(self):
        #在指定位置绘制飞船 将图像画到矩形位置上
        self.screen.blit(self.image,self.rect)

4.6重构check_events()

随着check越来越长 把部分代码放到keydown事件和keyup事件中

gamefunction

import sys
import pygame
def check_keydown_events(event,ship):
    #响应按键
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True
def check_keyup_events(event,ship):
    #响应松开
    if event.key==pygame.K_RIGHT:
        ship.moving_right=False
    elif event.key==pygame.K_LEFT:
        ship.moving_left=False
def check_events(ship):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ship)

        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)
           


def update_screen(ai_settings,screen,ship):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

写的想死 妈的 明天写了

4.7简单回顾

bullet文件添加设计功能

alieninvasion:文件的主循环在这里 创建了所有的对象,while中调用了check、shipupdate和screenupdate函数

setting:init初始化游戏外观和飞船速度

gamefaction:check中有keydown和keyup来检测事件的按和松。包含updatescreen函数在主循环中不断更新图片

ship:包含ship类

        init方法、管理飞船的位置例如起始在底部中心、获取rect对象、绘制飞船的blitme方法并且画到rect上

5.射击功能

按空格时候发射子弹(小矩形)的代码、子弹将闯过屏幕向上,低到屏幕上边缘后消失

5.1添加子弹设置

更新setting 在init后面存储新类bullet的值

class Settings():
    #存储游戏中所有的设置选项
    def __init__(self):
        #屏幕设置
        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,250)
        self.ship_speed_factor=1.5 #速度设置
        #子弹设置
        self.bullet_speed_factor=1
        self.bullet_width=3
        self.bullet_height=15
        self.bullet_color=60,60,60

5.2创建bullet类

创建bullet.py

import pygame
from pygame.sprite import Sprite#角色库,可以与场景以及其他角色进行交互
class Bullet(Sprite): #继承sprite类
    #对子弹管理的类
    def __init__(self,ai_settings,screen,ship):
        #在飞船所处的位置创建子弹
        super(Bullet,self).__init__() #调用父类sprite 确保bullet类继承了sprite
        self.screen=screen
        #在(0,0)处创建一个表示子弹的矩形
        self.rect=pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        #子弹不是图像是矩形所以要创建rect属性
        self.rect.centerx=ship.rect.centerx #子弹的位置在飞船的中心

        self.rect.top=ship.rect.top   #子弹从飞船顶部射出

        self.y=float(self.rect.y)#存储用小数表示的子弹位置 以便可以微调子弹速度
        self.color=ai_settings.bullet_color #将settings中子弹的颜色存储到self.color中
        self.speed_factor=ai_settings.bullet_speed_factor#将setting中子弹的速度存储到self.speed中

下面是bullet中的方法update和drawbullet

import pygame
from pygame.sprite import Sprite#角色库,可以与场景以及其他角色进行交互
class Bullet(Sprite): #继承sprite类
    #对子弹管理的类
    def __init__(self,ai_settings,screen,ship):
        #在飞船所处的位置创建子弹
        super(Bullet,self).__init__() #调用父类sprite 确保bullet类继承了sprite
        self.screen=screen
        #在(0,0)处创建一个表示子弹的矩形
        self.rect=pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        #子弹不是图像是矩形所以要创建rect属性
        self.rect.centerx=ship.rect.centerx #子弹的位置在飞船的中心

        self.rect.top=ship.rect.top   #子弹从飞船顶部射出

        self.y=float(self.rect.y)#存储用小数表示的子弹位置 以便可以微调子弹速度
        self.color=ai_settings.bullet_color #将settings中子弹的颜色存储到self.color中
        self.speed_factor=ai_settings.bullet_speed_factor#将setting中子弹的速度存储到self.speed中
    def update(self):
        '''向上移动子弹'''
        #更新表示子弹位置的小数值
        self.y-=self.speed_factor #子弹向上移动那么y坐标不断减小
        #更新表示子弹的rect的位置
        self.rect.y=self.y
    def draw_bullet(self):
        '''在屏幕上绘制子弹'''
pygame.draw.rect(self.screen,self.color,self.rect) #语法是pygame.draw.rect(screen,color,rect)

5.3将子弹存储到编组中

定义好bullet类和必要设置后可以编写代码了。按空格射击

在alieninvasion中创建一个编组group用来存储所有有效的子弹,这个编组将是pygame.sprite.Group类中的一个示例,它类似于列表但是它能自动更新渲染和碰撞体积检测

alieninvasion

import pygame
from  pygame.sprite import Group #从文件模块中导入Group类
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings() ## 将settings中的值给了ai_settings
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(ai_settings,screen)
    #创建一个用于存储子弹的编组
    bullets=Group()
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events(ship) #操作飞船移动
        ship.update() #限制飞船不出界
        bullets.update()
        gf.update_screen(ai_settings,screen,ship)#模块函数的调用

run_game()

5.4开火设置

在function中我们需要修改checkkeydown,按空格的时候发一个子弹

修改updatescreen,确保在调用flip()前在屏幕上绘制每颗子弹

function:

import sys
import pygame
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    #响应按键
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True
    elif event.key==pygame.K_SPACE:#按空格的时候造一颗子弹
        new_bullet=Bullet(ai_settings,screen,ship)#对新子弹进行实例化,它的属性有设置、
        bullets.add(new_bullet) #新子弹加入到bullet组中方便进行碰撞检测
def check_keyup_events(event,ship):
    #响应松开
    if event.key==pygame.K_RIGHT:
        ship.moving_right=False
    elif event.key==pygame.K_LEFT:
        ship.moving_left=False
def check_events(ai_settings,screen,ship,bullets):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)

        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)



def update_screen(ai_settings,screen,ship,bullets):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #在飞船和外星人后面重新绘制所有的子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

5.5删除已消失的子弹

子弹穿过屏幕消失只是因为无法绘制但是还消耗内存

检测条件:子弹的rect的bottom属性为0

aline

import pygame
from  pygame.sprite import Group #从文件模块中导入Group类
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings() ## 将settings中的值给了ai_settings
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(ai_settings,screen)
    #创建一个用于存储子弹的编组
    bullets=Group()
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events(ai_settings,screen,ship,bullets) #操作飞船移动
        ship.update() #限制飞船不出界
        bullets.update()
        #删除已经消失的子弹
        for bullet in bullets.copy():#遍历副本修改bullets
            if bullet.rect.bottom<=0:
                bullets.remove(bullet)
        #print(len(bullets))#显示当前还有多少子弹
        gf.update_screen(ai_settings,screen,ship,bullets)#模块函数的调用

run_game()

5.6限制子弹的数量

setting

class Settings():
    #存储游戏中所有的设置选项
    def __init__(self):
        #屏幕设置
        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,250)
        self.ship_speed_factor=1.5 #速度设置
        #子弹设置
        self.bullet_speed_factor=1
        self.bullet_width=10
        self.bullet_height=15
        self.bullet_color=60,60,10
        self.bullet_allowed=10

gamefunction

import sys
import pygame
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    #响应按键
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True
    elif event.key==pygame.K_SPACE:#按空格的时候造一颗子弹
        if len(bullets)<ai_settings.bullets_allowed: #限制子弹的发射数量
            new_bullet=Bullet(ai_settings,screen,ship)
            bullets.add(new_bullet)
        new_bullet=Bullet(ai_settings,screen,ship)#对新子弹进行实例化,它的属性有设置、
        bullets.add(new_bullet) #新子弹加入到bullet组中方便进行碰撞检测
    
def check_keyup_events(event,ship):
    #响应松开
    if event.key==pygame.K_RIGHT:
        ship.moving_right=False
    elif event.key==pygame.K_LEFT:
        ship.moving_left=False
def check_events(ai_settings,screen,ship,bullets):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)

        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)



def update_screen(ai_settings,screen,ship,bullets):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #在飞船和外星人后面重新绘制所有的子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数

5.7创建函数update_bullets()

创建updatebullet函数添加到function末尾来简化主程序

import sys
import pygame
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    #响应按键
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True
    elif event.key==pygame.K_SPACE:#按空格的时候造一颗子弹
        if len(bullets)<ai_settings.bullets_allowed: #限制子弹的发射数量
            new_bullet=Bullet(ai_settings,screen,ship)
            bullets.add(new_bullet)
        new_bullet=Bullet(ai_settings,screen,ship)#对新子弹进行实例化,它的属性有设置、
        bullets.add(new_bullet) #新子弹加入到bullet组中方便进行碰撞检测

def check_keyup_events(event,ship):
    #响应松开
    if event.key==pygame.K_RIGHT:
        ship.moving_right=False
    elif event.key==pygame.K_LEFT:
        ship.moving_left=False
def check_events(ai_settings,screen,ship,bullets):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)

        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)



def update_screen(ai_settings,screen,ship,bullets):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #在飞船和外星人后面重新绘制所有的子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数
def update_bullets(bullets):
    #更新子弹的位置,删除已经消失的子弹
    bullets.update() #更新子弹的位置
    #删除消失的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom<=0:
            bullets.remove(bullet)

allien中

import pygame
from  pygame.sprite import Group #从文件模块中导入Group类
from settings import Settings
from ship import Ship
import game_functions as gf
#可以使用gf.update_screen()来调用
#从settings文件中导入Settings类
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings=Settings() ## 将settings中的值给了ai_settings
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("标题")
    #创建一艘飞船
    ship=Ship(ai_settings,screen)
    #创建一个用于存储子弹的编组
    bullets=Group()
    #在这里设置背景颜色
    bg_color=(230,230,250)
    # 调整飞船的初始位置
    ship.rect.centery -= 50  # 向上调整50个像素
    #开始游戏的主循环
    while True:
        gf.check_events(ai_settings,screen,ship,bullets) #操作飞船移动
        ship.update() #限制飞船不出界
        gf.update_bullets(bullets) #从模块中调用update参数为bullets
        #删除已经消失的子弹
        for bullet in bullets.copy():#遍历副本修改bullets
            if bullet.rect.bottom<=0:
                bullets.remove(bullet)
        #print(len(bullets))#显示当前还有多少子弹
        gf.update_screen(ai_settings,screen,ship,bullets)#模块函数的调用

run_game()

5.8创建函数fire_bullet()

将发射子弹移到一个独立的函数中,这样在check_keydown_events()中只需要一行代码来发射子弹,让elif代码块变的非常简单

function

import sys
import pygame
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    #响应按键
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True
    elif event.key==pygame.K_SPACE:#按空格的时候造一颗子弹
        fire_bullet(ai_settings,screen,ship,bullets)
def fire_bullet(ai_settings,screen,ship,bullets):
        if len(bullets)<ai_settings.bullet_allowed: #限制子弹的发射数量
            new_bullet=Bullet(ai_settings,screen,ship)
            bullets.add(new_bullet)
        new_bullet=Bullet(ai_settings,screen,ship)#对新子弹进行实例化,它的属性有设置、
        bullets.add(new_bullet) #新子弹加入到bullet组中方便进行碰撞检测

def check_keyup_events(event,ship):
    #响应松开
    if event.key==pygame.K_RIGHT:
        ship.moving_right=False
    elif event.key==pygame.K_LEFT:
        ship.moving_left=False
def check_events(ai_settings,screen,ship,bullets):
    #响应键盘和鼠标事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)

        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)



def update_screen(ai_settings,screen,ship,bullets):
    #更新屏幕上的图形,并切换到新屏幕
    #每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #在飞船和外星人后面重新绘制所有的子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()
#新函数包含了三个参数
def update_bullets(bullets):
    #更新子弹的位置,删除已经消失的子弹
    bullets.update() #更新子弹的位置
    #删除消失的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom<=0:
            bullets.remove(bullet)

整个项目完成一半了 已经想死了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值