此篇为游戏实现前所用的基础知识介绍
完整的游戏实现和全部代码详见下一篇:
Python飞机大战项目终篇
项目准备
- 新建 飞机大战 项目
- 导入 游戏素材图片
; 需要调用的方法
方法说明 pygame.init()
导入并初始化所有 pygame
模块,使用其他模块之前,必须先调用 init
方法 pygame.quit()
卸载所有 pygame
模块,在游戏结束之前调用! pygame.display.set_mode()
初始化游戏显示窗口 pygame.display.update()
刷新屏幕内容显示,稍后使用
游戏背景图像绘制
要在屏幕上 看到某一个图像的内容,需要按照三个步骤:
- 使用
pygame.image.load()
加载图像的数据 - 使用 游戏屏幕 对象,调用
blit
方法 将图像绘制到指定位置 - 调用
pygame.display.update()
方法更新整个屏幕的显示
实现代码
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
pygame.display.update()
while True:
pass
pygame.quit()
效果图

; 绘制英雄图像
- 加载
me1.png
创建英雄飞机 - 将 英雄飞机 绘制在屏幕的
(200, 500)
位置 - 调用屏幕更新显示飞机图像
实现代码
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
hero = pygame.image.load('./images/me1.png')
screen.blit(hero, (200, 500))
pygame.display.update()
while True:
pass
pygame.quit()
效果图

; 更新英雄位置(让飞机动起来丫)
游戏循环的作用
- 保证游戏 不会直接退出
- 变化图像位置 —— 动画效果
- 每隔
1 / 60 秒
移动一下所有图像的位置 - 调用
pygame.display.update()
更新屏幕显示
游戏时钟
pygame
专门提供了一个类pygame.time.Clock
可以非常方便的设置屏幕绘制速度 —— 刷新帧率- 要使用 时钟对象 需要两步:
- 1)在 游戏初始化 创建一个 时钟对象
- 2)在 游戏循环 中让时钟对象调用
tick(帧率)
方法 tick
方法会根据 上次被调用的时间,自动设置 游戏循环 中的延时
英雄的简单动画实现
- 在 游戏初始化 定义一个
pygame.Rect
的变量记录英雄的初始位置 - 在 游戏循环 中每次让 英雄 的
y - 1
—— 向上移动 y <= 0< code> 将英雄移动到屏幕的底部<!--=-->
实现代码
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
hero = pygame.image.load('./images/me1.png')
screen.blit(hero, (200, 500))
pygame.display.update()
clock = pygame.time.Clock()
hero_rect = pygame.Rect(150, 300, 102, 126)
while True:
clock.tick(60)
hero_rect.y -= 1
screen.blit(bg, (0, 0))
screen.blit(hero, hero_rect)
pygame.display.update()
pygame.quit()
效果图

ps:文件夹是我初学时候创建的把python拼错了,哈哈哈哈哈!一直没改是为了激励自己,把一个名字都能叫错的东西学到熟练也没要多久嘛!
; 英雄循环飞行
(飞机从顶消失后又从底部冒上来)
- 英雄向上飞行,当 英雄完全从上方飞出屏幕后
- 将飞机移动到屏幕的底部
if hero_rect.y + hero_rect.height 0:
hero_rect.y = 700
提示
Rect
的属性bottom = y + height
if hero_rect.bottom 0:
hero_rect.y = 700
实现代码
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
hero = pygame.image.load('./images/me1.png')
screen.blit(hero, (200, 500))
pygame.display.update()
clock = pygame.time.Clock()
hero_rect = pygame.Rect(150, 300, 102, 126)
while True:
clock.tick(60)
hero_rect.y -= 1
if hero_rect.y -126:
hero_rect.y =700
screen.blit(bg, (0, 0))
screen.blit(hero, hero_rect)
pygame.display.update()
pygame.quit()
效果图

; 事件监听
事件 event
- 就是游戏启动后, 用户针对游戏所做的操作
- 例如: 点击关闭按钮, 点击鼠标, 按下键盘…
监听
- 在 游戏循环 中,判断用户 *具体的操作
只有 捕获 到用户具体的操作,才能有针对性的做出响应
代码实现
pygame
中通过pygame.event.get()
可以获得 用户当前所做动作 的 事件列表- 用户可以同一时间做很多事情
- 提示: 这段代码非常的固定,几乎所有的
pygame
游戏都 大同小异!
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("退出游戏...")
pygame.quit()
exit()
退出事件监听
实现代码
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
hero = pygame.image.load('./images/me1.png')
screen.blit(hero, (200, 500))
pygame.display.update()
clock = pygame.time.Clock()
hero_rect = pygame.Rect(150, 300, 102, 126)
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print('游戏退出...')
pygame.quit()
exit()
hero_rect.y -= 1
if hero_rect.y -126:
hero_rect.y = 700
screen.blit(bg, (0, 0))
screen.blit(hero, hero_rect)
pygame.display.update()
pygame.quit()
效果图
当你点击运行中游戏的叉号后 系统监听游戏退出。

; 演练精灵(添加敌机)
- 在刚刚完成的案例中, 图像加载、 位置变化、 绘制图像 都需要程序员编写代码分别处理
- 为了简化开发步骤,
pygame
提供了两个类 pygame.sprite.Sprite
—— 存储 图像数据 image 和 位置 rect 的 对象pygame.sprite.Group
精灵
- 在游戏开发中,通常把 显示图像的对象 叫做精灵
Sprite
- 精灵 需要 有 两个重要的属性
image
要显示的图像rect
图像要显示在屏幕的位置- 默认的
update()
方法什么事情也没做 - 子类可以重写此方法,在每次刷新屏幕时,更新精灵位置
- 注意:
pygame.sprite.Sprite
并没有提供image
和rect
两个属性 - 需要程序员从
pygame.sprite.Sprite
派生子类 - 并在 子类 的 初始化方法 中,设置
image
和rect
属性
精灵组
- 一个 精灵组 可以包含多个 精灵 对象
- 调用 精灵组 对象的
update()
方法 - 可以 自动 调用 组内每一个精灵 的
update()
方法 - 调用 精灵组 对象的
draw(屏幕对象)
方法 - 可以将 组内每一个精灵 的
image
绘制在rect
位置
Group(*sprites) -> Group
注意:仍然需要调用
pygame.display.update()
才能在屏幕看到最终结果
派生精灵子类
- 新建
plane_sprites.py
文件 - 定义
GameSprite
继承自pygame.sprite.Sprite
注意
- 如果一个类的 父类 不是
object
- 在重写 初始化方法 时, 一定要 先
super()
一下父类的__init__
方法 - 保证父类中实现的
__init__
代码能够被正常执行
image
精灵图像,使用image_name
加载rect
精灵大小,默认使用图像大小speed
精灵移动速度,默认为1
方法
update
每次更新屏幕时在游戏循环内调用- 让精灵的
self.rect.y += self.speed
提示
image
的get_rect()
方法,可以返回 pygame.Rect(0, 0, 图像宽, 图像高) 的对象
import pygame
class GameSprite(pygame.sprite.Sprite):
"""游戏精灵基类"""
def __init__(self, image_name, speed=1):
super().__init__()
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed
def update(self, *args):
self.rect.y += self.speed
使用 游戏精灵 和 精灵组 创建敌机
需求
- 使用刚刚派生的 游戏精灵 和 精灵组 创建 敌机 并且实现敌机动画
步骤
- 使用
from
导入plane_sprites
模块 from
导入的模块可以 直接使用import
导入的模块需要通过 模块名. 来使用- 在 游戏初始化 创建 精灵对象 和 精灵组对象
- 在 游戏循环中 让 精灵组 分别调用
update()
和draw(screen)
方法
职责
- 精灵
- 封装 图像 image、 位置 rect 和 速度 speed
- 提供
update()
方法,根据游戏需求, 更新位置 rect - 精灵组
- 包含 多个 精灵对象
update
方法,让精灵组中的所有精灵调用update
方法更新位置draw(screen)
方法,在screen
上绘制精灵组中的所有精灵
实现步骤
- 导入
plane_sprites
模块
from plane_sprites import *
- 修改初始化部分代码
enemy1 = GameSprite("./images/enemy1.png")
enemy2 = GameSprite("./images/enemy1.png", 2)
enemy2.rect.x = 200
enemy_group = pygame.sprite.Group(enemy1, enemy2)
- 修改游戏循环部分代码
enemy_group.update()
enemy_group.draw(screen)
pygame.display.update()
实现代码
import pygame
from plane_sprites import *
pygame.init()
screen = pygame.display.set_mode((480, 700))
bg = pygame.image.load('./images/background.png')
screen.blit(bg, (0, 0))
hero = pygame.image.load('./images/me1.png')
screen.blit(hero, (200, 500))
pygame.display.update()
clock = pygame.time.Clock()
hero_rect = pygame.Rect(150, 300, 102, 126)
enemy = GameSprite("./images/enemy1.png")
enemy1 = GameSprite("./images/enemy1.png", 2)
enemy_group = pygame.sprite.Group(enemy, enemy1)
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print('游戏退出...')
pygame.quit()
exit()
hero_rect.y -= 1
if hero_rect.y -126:
hero_rect.y = 700
screen.blit(bg, (0, 0))
screen.blit(hero, hero_rect)
enemy_group.update()
enemy_group.draw(screen)
pygame.display.update()
pygame.quit()
效果图

图片素材:
链接:https://pan.baidu.com/s/1LKoVQCRApscxpgg4MYznyw
提取码:chui
此项目为学习python时笔记
来源于:黑马程序员python教程
Original: https://blog.csdn.net/weixin_51313763/article/details/124866413
Author: 张大锤锤不秃头
Title: Python飞机大战项目前篇(一步一步实现—最全笔记)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/780309/
转载文章受原作者版权保护。转载请注明原作者出处!