利用python和pygame模块实现飞机大战

背景提要

我学习Python三天了,基础的语法和面向对象已经有了初步的了解,下一步急需一个实践项目来检验学习的成果,因此选择了很多人做过的飞机大战项目,这个项目我最终做完只写了200行不到的代码,在入门中算是比较轻松的了。

软硬件版本

win10
pycharm pro 2018 win版本

项目流程

初步框架准备

首先导入pygame模块,如果你还没有安装,可以在网上查一下如何安装
然后写出基本的main函数框架

import pygame
if __name__ == '__main__':
	# 创建游戏对象
	#TODO
	# 开始游戏
	#TODO

数字常量化

在导入模块后,添加一些全局变量,去替换之后要用到的一些魔法数字

# 屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新的帧率
UPDATE_FPS = 60
# 创建敌人飞机的事件
CREATE_ENEMY_EVENT = pygame.USEREVENT

游戏对象的框架

python的完全面向对象的语言,因此游戏本身也是一个对象,因此整个main函数中,先创建游戏对象,再调用该对象的开始游戏方法即可
首先定义一个游戏类,继承自祖先类,然后再明确初始化过程要做什么工作
重写父类的初始化方法,按照套路,先初始化python的所有模块,然后再把游戏窗口给整出来

# 定义一个游戏类
class GameClass(object):
# 游戏的初始化
    def __init__(self):
        pygame.init()                       # 初始化所有的 pygame 模块
        self.__screen_init()                # 窗口初始化

# 游戏窗口初始化
    def __screen_init(self):
        # 创建游戏窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")

值得一提的是,创建游戏窗口的时候,需要传入一个窗口的长*宽,它是一个元祖对象
另外就是可以设置窗口的名字“飞机大战”
实现窗口初始化函数后,接下来就是如何调用,让程序运行时生成一个游戏界面
再写一个开始游戏函数,这个函数中,用while True做游戏循环,保证程序不会运行完就关闭

# 启动游戏
def start_game(self):
    while True:
        pass

这样一个初步的框架就已经实现了,我们先看一下效果,运行后效果如下图,windows会提示游戏界面没有响应,要不要关闭,这是正常的,在pycharm的右上角点击红色的停止方块即可
游戏界面实现

背景的绘制

游戏界面已经有了,接下来需要我们把背景图片放进去
在一般的其它的游戏中,背景一般不是一成不变的,因此在这里,我们用图片的滚动,来实现即使飞机不动,你也会感觉一直往前飞的效果
实现的原理是用两张图片,在y轴上贴合到一起,组成一张长图片,在游戏开始的时候,一张图片完全与游戏框重合,另外一张在游戏框上面,当图片持续下移,最终有一张图片完全跑到游戏框下面的时候,我们立马把它放到游戏框的上方,这样用户就无法分辨其实背景其实是两张图片一直滚动播放了
滚动背景实现
整个游戏中的要显示的对象,有以下几种,背景、英雄飞机、敌人飞机、英雄子弹,(暂时没有做敌人子弹,因此实现起来稍微复杂一点) 他们的共同特征是,能移动有速度,需要加载图片,因此,先做一个父类,然后根据需求的不同,派生出不同的子类,再去创建背景、飞机对象
该类的代码如下,继承自pygame提供的精灵类,然后一定要先调用父类的init方法,然后加载指定路径的图片,通过get_rect函数,我们可以从加载的图片中获取它的尺寸数据
然后需要指定该对象的速度(默认值设置为1),然后实现它的更新方法,就是在y轴上,根据速度值,改变它的y坐标

# 定义一个游戏精灵类,继承自模块的精灵类
class GameSprite(pygame.sprite.Sprite):
    # 重写init方法
    def __init__(self, image_path, speed=1):
        super().__init__()    							# 先调用父类的方法
        self.image = pygame.image.load(image_path)      # 加载指定路径的图片
        self.rect = self.image.get_rect()               # 获取图片的尺寸
        self.speed = speed                              # 指定精灵对象的速度

    # 更新方法
    def update(self):
        self.rect.y += self.speed                       # 每次更新时,精灵对象在y方向移动

接下来就要去实现一个背景类,该类负责实现背景的交替显示
先重写父类GameSprite的init方法,然后调用父类的方法,加载背景图片,然后根据是第几张图片,判断是放在游戏框之中,还是之上,然后重写更新方法,当背景对象的y值超过范围,也就是图片向下移动到场外时,需要及时移动到游戏画面最上面

# 定义一个背景类,继承自精灵类
class BackGround(GameSprite):
    def __init__(self, isAlt = False):
        # 调用父类方法完成加载图片、尺寸获取、速度指定
        super().__init__("./image/background.png")
        # 判断是不是第二张图片
        if isAlt:
            self.rect.y = -self.rect.height

    # 通过两张图片的滚动播放实现动画效果
    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:          # y值移动到边界时
            self.rect.y = -SCREEN_RECT.height           # 让该图片重新回到游戏界面上方

实现了这两个类之后,就要在游戏初始化的方法中,实现背景初始化了
由于继承自pygame的精灵类,所以无论背景、还是飞机,都属于精灵类,因此,需要一个初始化函数,去显示这些精灵
在创建背景精灵后,将这两个背景精灵添加进背景精灵组,通过精灵组,可以对组内的对象统一操作

# 创建初始时的精灵
def __create_sprites(self):
    # 创建背景精灵
    self.bg1 = BackGround(False)
    self.bg2 = BackGround(True)

    # 创建精灵组
    self.back_group = pygame.sprite.Group(self.bg1, self.bg2)

由于需要不断的滚动,因此还要实现更新位置的方法,通过精灵组,调用两个方法,即可实现位置的更新

# 更新精灵
def __update_sprites(self):
     # 更新坐标
     self.back_group.update()
     # 绘制
     self.back_group.draw(self.screen)

位置更新后,还要调用update方法,才能显示出来

# 启动游戏
def start_game(self):
    while True:
        # 更新位置
        self.__update_sprites()
        # 更新显示
        pygame.display.update()

最终的代码如下:

import pygame

# 定义一个游戏精灵类,继承自模块的精灵类
class GameSprite(pygame.sprite.Sprite):

    # 重写init方法
    def __init__(self, image_path, speed=1):
        super().__init__()    # 先调用父类的方法
        self.image = pygame.image.load(image_path)      # 加载指定路径的图片
        self.rect = self.image.get_rect()              # 获取图片的尺寸
        self.speed = speed                              # 指定精灵对象的速度

    # 更新方法
    def update(self):
        self.rect.y += self.speed                      # 每次更新时,精灵对象在y方向移动


# 定义一个背景类,继承自精灵类
class BackGround(GameSprite):
    def __init__(self, isAlt = False):
        # 调用父类方法完成加载图片、尺寸获取、速度指定
        super().__init__("./image/background.png")
        # 判断是不是第二张图片
        if isAlt:
            self.rect.y = -self.rect.height

    # 通过两张图片的滚动播放实现动画效果
    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:          # y值移动到边界时
            self.rect.y = -SCREEN_RECT.height          # 让该图片重新回到游戏界面上方



# 定义一个游戏类
class GameClass(object):

# 游戏的初始化
    def __init__(self):
        pygame.init()                      # 初始化所有的 pygame 
  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值