Pygame:编写一个小游戏

大学最后的考试终于结束了,迎来了暑假和大四的漫长的“自由”假期。当然要自己好好“玩玩”了。
我最近在学习Python,本意是在机器学习深度学习上使用Python进行编程的而学习的。偶然接触了pygame,觉得很感兴趣,所以打算使用pygame制作一个小游戏作为对Python学习和练习。
废话不多说了,先介绍一下pygame。

简要介绍:

请原谅本人比较懒,直接上百度百科进行介绍:(点我打开链接
这里写图片描述

Pygame是跨平台Python模块,专为电子游戏设计。
包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。基于这样一个设想,所有需要的游戏功能和理念都(主要是图像方面)都完全简化为游戏逻辑本身,所有的资源结构都可以由高级语言提供,如Python。
Pygame 原为代替突然停止的 pySDL
Pygame 作者是 Pete Shinners 协议为 GNU Lesser General Public License

简单点概括,pygame是个专门用来做游戏开发的库,提供了一些较方便的API。

设计目标:

1、设计一个飞机大战的游戏,玩家能控制一架飞机在游戏界面内通过界面上下左右移动;
2、飞机能发射子弹,自动前进,当走出游戏界面之外时,其自动删除;
3、敌机随机产生,并自动前进,当走出游戏界面之外时,其自动删除;
4、如果敌机碰到子弹则,敌机破坏;
5、如果敌机碰到我方飞机,则游戏结束;

游戏运行截图:
这里写图片描述

源码下载:

网友分享的打飞机小游戏源码:打开链接(不需要积分)
我自己写的小游戏源码:打开链接(功能稍微要简单一些,收1分的积分做辛苦费╮(╯▽╰)╭)

环境搭建:

我是在Ubuntu环境下进行开发的,所以使用以下指令既可以自动安装配置好环境:

sudo apt-get install python-pygame

安装完成后,为检验是否配置成功。先进入Python交互环境,试着import pygame看看会不会报错。
这里写图片描述

程序架构构思:

1、首先,可以想到程序中可以分为3个类,即:玩家的飞机、敌机、子弹,所以功能都可以在这几个类中定义方法来实现;
2、背景可以调用pygame中的相关类和方法读出图片,随后在其上添加飞机、敌机、子弹的贴图即可,效果音也可以调用相关类和方法实现;
3、由于存在复数个敌机和子弹,所以分别建立一个列表变量来管理,比如说,如果发生碰撞就要破坏,即从列表中删除对应的元素;
4、建立一个死循环不断重复检测状态并刷新显示,为了控制帧率,还需要适当的延时,而不是一直运行程序。

代码讲解:

我在上传的程序中分为了两个文件:
这里写图片描述
myGame.py:主程序
myGameRole.py:定义相关的类,供myGame.py调用
resources:使用到的图片以及音频文件

myGame.py:

1、音频文件的初始化:
这里写图片描述
a、首先是对pygame进行初始化。

pygame.init()

b、随后调用pygame.mixer中的方法读入音频wav文件。

bullet_sound = pygame.mixer.Sound('resources/sound/bullet.wav')
enemy_down_sound = pygame.mixer.Sound('resources/sound/enemy1_down.wav')
game_over_sound = pygame.mixer.Sound('resources/sound/game_over.wav')

c、设置音量大小,参数范围从0~1。

bullet_sound.set_volume(0.3)
enemy_down_sound.set_volume(0.3)
game_over_sound.set_volume(0.3)

d、游戏背景音载入后循环播放。还有pygame.mixer.music.play()中第一个参数表示播放次数,选择-1表示循环播放,其后的参数表示播放起始和结束位置,可以用它预设的参数,即全部播放。

# 载入游戏音乐并循环播放
pygame.mixer.music.load('resources/sound/game_music.wav')
pygame.mixer.music.play(-1, 0)
pygame.mixer.music.set_volume(0.25)

2、图片的初始化
这里写图片描述

这里写图片描述

这里写图片描述
以上的程序实现创建窗口并贴图上去和显示刷新。

a、创建一个窗口,SCREEN_WIDTHSCREEN_HEIGHT 指定窗口大小,后面的图片都在这个窗口内显示。

SCREEN_WIDTH = 480
SCREEN_HEIGHT = 800
# 创建窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

b、指定图片存放的路径,读出图片。

# 读出背景图片
background = pygame.image.load('resources/image/background.png').convert()

c、指定图片的位置,将之前读出的图片贴在指定位置上,坐标表示图片的左上角位置。程序中放在死循环内,让其不断刷新。

screen.blit(background,(0, 0))

d、更新图片显示,把所有贴图后最后的结果显示。

# 整个界面刷新
pygame.display.update()

3、按键检测:
这里写图片描述

从下面的方法中可以得到返回值,其中包含了按键的键值。

pygame.event.get()

程序中通过遍历比较得到的键值是多少,一系列的if…elif…就是这个目的。如果检测到了对应的按键,就调用类中的相关方法执行相应的操作。

myGameRole.py

1、飞机类:(截图太大了,所以直接贴上代码了)

# 玩家飞机类
class Player(object):
    def __init__(self, screen):
        # 储存子弹列表
        self.bulletList = []

        # 飞机图片
        planeImageName = 'resources/image/hero1.png'
        # 导入飞机图片
        self.image = pygame.image.load(planeImageName)

        # 图片大小
        self.image_width = 100
        self.image_height = 124

        # 设置默认坐标
        self.x = 180
        self.y = 600

        # 设置速度
        self.speed = 20

        self.window =  screen

        # 设置飞机名称
        self.name = 'player'

    def getPos(self):
        return [self.x, self.y, self.image_width, self.image_height]

    def crash(self):
        # 图片
        crashImageName = 'resources/image/hero_blowup_n3.png'
        # 导入图片
        self.image = pygame.image.load(crashImageName)

    # 发射子弹,创建一个新的子弹对象
    def shoot(self):
        bullet = Bullet(self.window, self)
        self.bulletList.append(bullet)

    # 清除不使用的子弹列表元素
    def bulletClear(self):
        num = len(self.bulletList)
        for i in range(0,num):
            if self.bulletList[i].y <= 0:
                del  self.bulletList[i]
                break

    # 飞机上移
    def moveUp(self):
        if self.y <= 0:
            self.y = 0
        else:
            self.y -= self.speed

    # 飞机下移
    def moveDown(self):
        if self.y >= SCREEN_HEIGHT - self.image_height:
            self.y = SCREEN_HEIGHT - self.image_height
        else:
            self.y += self.speed

    # 飞机左移
    def moveLeft(self):
        if self.x <= 0:
            self.x = 0
        else:
            self.x -= self.speed

    # 飞机右移
    def moveRight(self):
        if self.x >= SCREEN_WIDTH - self.image_width:
            self.x = SCREEN_WIDTH - self.image_width
        else:
            self.x += self.speed

    # 绘制图形
    def draw(self):
        self.window.blit(self.image, (self.x, self.y))

    # 按键操作处理
    def keyHandle(self, keyValue):
        if keyValue == 'left':
            self.moveLeft()
        elif keyValue == 'right':
            self.moveRight()
        elif keyValue == 'up':
            self.moveUp()
        elif keyValue == 'down':
            self.moveDown()
        elif keyValue == 'space':
            # bullet = Bullet(self.x, self.y)
            self.shoot()

一个一个方法来介绍,不重复贴太多代码了,可以在前面查看:

a、其中建立了一些初始化用的变量,比如用来保存读入的图片,初始的坐标位置等等,其中都有注释。传入的screen参数就是之前创建的游戏运行的窗口,为方便操作,建立玩家类时就传入,以后直接在内部方法中调用而不需从外部获取。

def __init__(self, screen):

b、返回当前的位置坐标。

def getPos(self):

c、飞机破坏,读取对应图片,并贴在窗口中响应的位置上。

def crash(self):

d、实际中就是新建一个子弹类的对象,并添加到一个列表中,此后对于子弹对象通过列表管理。

# 发射子弹,创建一个新的子弹对象
def shoot(self):

e、检测子弹列表中的所有子弹对象是否出界,若出界直接从列表中删除。

# 清除不使用的子弹列表元素
def bulletClear(self):

f、飞机上下左右移动,实质就是操作该player对象的x,y坐标。

# 飞机上移
def moveUp(self):
# 飞机下移
def moveDown(self):
# 飞机左移
def moveLeft(self):
# 飞机右移
def moveRight(self):

g、绘制player对象,即调用前面所说的screen.blit方法更新(这里的screen代表前面实例化的窗口)。

# 绘制图形
def draw(self):

h、根据键值处理,调用前面的几个方法,诸如:上下左右移动、发射子弹等等方法。

# 按键操作处理
def keyHandle(self, keyValue):

2、子弹类:

# 子弹类
class Bullet(object):
    def __init__(self, screen, plane):
        # 子弹图片
        bulletImageName = 'resources/image/bullet1.png'
        # 导入子弹图片
        self.image = pygame.image.load(bulletImageName)

        # 图片大小
        self.image_width = 9
        self.image_height = 21

        # 图片位置
        self.x = plane.x + plane.image_width // 2 - self.image_width // 2
        self.y = plane.y + self.image_height 

        # 设置速度
        self.speed = 12

        self.window = screen

    def getPos(self):
        return [self.x, self.y, self.image_width, self.image_height]

    def move(self):
        self.y -= self.speed

    def draw(self):
        self.window.blit(self.image, (self.x, self.y))

a、设置一些变量和参数,screen是窗口的实例化对象,plane表示飞机对象。

def __init__(self, screen, plane):

b、获取子弹对象的坐标(图片的左上角位置坐标)

def getPos(self):

c、子弹移动,实际操作它的位置坐标变化。不断在程序的循环中调用,使其创建后自动移动。

def move(self):

d、绘制bullet对象,即调用前面所说的screen.blit方法更新(这里的screen代表前面实例化的窗口)。

def draw(self):

3、敌机类:

class Enemy(object):
    def __init__(self, screen, x=0, y=0):
        # 图片
        enemyImageName = 'resources/image/enemy1.png'
        # 导入图片
        self.image = pygame.image.load(enemyImageName)

        # 图片大小
        self.image_width = 51
        self.image_height = 39

        self.speed = 3

        # 图片位置
        self.x = x
        self.y = y

        self.window =  screen

        self.direction = 'right'

        self.name = 'enemy'

    def getPos(self):
        return [self.x, self.y, self.image_width, self.image_height]

    # 检测是否出界
    def checkOut(self):
        if self.y >= SCREEN_HEIGHT - self.image_height:
            return True
        else:
            return False

    def move(self):
        self.y += self.speed

    def crash(self):
        # 图片
        crashImageName = 'resources/image/enemy1_down3.png'
        # 导入图片
        self.image = pygame.image.load(crashImageName)

    def draw(self):
        self.window.blit(self.image, (self.x, self.y))

a、screen跟前面一样,是为了后续程序调用方便而传入的;x、y表示敌机的坐标,默认都取0。

def __init__(self, screen, x=0, y=0):

b、获取位置坐标

def getPos(self):

c、判断是够移动出了窗口的界面范围,若出去了返回True;若否,则返回False。

# 检测是否出界
def checkOut(self):

d、实际是操作enemy对象的坐标变化,以使其移动。不断调用,实现自动移动。

def move(self):

e、与前面一样,飞机破坏时导入图片,并刷新,表示爆炸效果。

def crash(self):

f、在窗口上刷新enemy对象的图片。

def draw(self):

小结:

就介绍这么多了,这里只是大概介绍了一下程序大概的思想和一些需要注意的地方。编写程序时的思路与此完全不同,随着功能的不断实现,类的方法、成员等等都是同步改变的。在我上传的程序中也有注释,可以到其中查看完整的程序。(打开链接

PythonPygame游戏-从入门到精通 中文pdf版本 部分目录如下: 系统学习部分 用PythonPygame游戏-从入门到精通(1) Pygame的历史,安装Pygame,第一个Pygame脚本 用PythonPygame游戏-从入门到精通(2) 理解游戏中的事件 用PythonPygame游戏-从入门到精通(3) Pygmae的屏幕显示 用PythonPygame游戏-从入门到精通(4) 使用字体模块,Pygame 的错误处理 用PythonPygame游戏-从入门到精通(5) 像素和颜色 用PythonPygame游戏-从入门到精通(6) 使用图像,理解Surface 用PythonPygame游戏-从入门到精通(7) 绘制图形 用PythonPygame游戏-从入门到精通(8) 产生动画和控制帧率 用PythonPygame游戏-从入门到精通(9) 向量基础 用PythonPygame游戏-从入门到精通(10) 用户输入 用PythonPygame游戏-从入门到精通(11) 使用鼠标控制精灵。一个在鼠标旁不断游动的小鱼的例程。 用PythonPygame游戏-从入门到精通(12) 手柄操作,暂无 用PythonPygame游戏-从入门到精通(13) AI初探 用PythonPygame游戏-从入门到精通(14) 状态机 用PythonPygame游戏-从入门到精通(15) 开始AI编程 用PythonPygame游戏-从入门到精通(16) AI编程总结。一个蚂蚁采集食物,攻击蜘蛛的系统模拟例程。 用PythonPygame游戏-从入门到精通(17) 3D基础 用PythonPygame游戏-从入门到精通(18) 3D中的概念 用PythonPygame游戏-从入门到精通(19) 第一个 3D 程序(伪)。一个空间中的3D立方体的例程。 用PythonPygame游戏-从入门到精通(20) 声音原理 用PythonPygame游戏-从入门到精通(21) 使用声音,播放音效。一个重力模拟金属球碰撞的例程。 用PythonPygame游戏-从入门到精通(22) 播放长时间的背景音乐。一个建议播放器的例程。 额外提高部分 用PythonPygame游戏-从入门到精通(py2exe编) 使用py2exe将pygame脚本转换为exe可执行文件 用PythonPygame游戏-从入门到精通(Sprite篇) 介绍Pygame中不是必须但又很重要的Sprite模块,游戏中的角色实现,大多都要靠它。 实践部分 用PythonPygame游戏-从入门到精通(实战一:涂鸦画板1) 一个类似于Windows画图板的小玩意儿,精简了很多功能但是有更帅的笔刷。这一次主要是将笔刷的实现。 用PythonPygame游戏-从入门到精通(实战一:涂鸦画板2) 加上了按钮,我们的涂鸦画板可以用了! 用PythonPygame游戏-从入门到精通(实战二:恶搞俄罗斯方块1) 俄罗斯方块,却有不是普通的俄罗斯方块。 用PythonPygame游戏-从入门到精通(实战二:恶搞俄罗斯方块2) 代码构架 用PythonPygame游戏-从入门到精通(实战二:恶搞俄罗斯方块3) 实现说明 用PythonPygame游戏-从入门到精通(实战二:恶搞俄罗斯方块4) 完成,提供下载 用PythonPygame游戏-从入门到精通(实战三:植物大战僵尸1)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值