pygame模块
安装方式
01通过在线安装的方式
在pycharm中左下角有一个Terminal
可以查看有哪些安装好的模块与包
通过命令
pip list
如果我们需要安装pygame
使用命令
pip install pygame
02离线安装
对于anaconda来说
安装在
C:\Users\用户名\Anaconda3\Lib\site-packages
因此, 如果我们有了离线的包文件夹
可以直接把文件夹拷备到这个目录
如果当前使用的解释器是pycharm给我们生成的一个纯净的解释器
那么我们直接把pygame的文件夹,粘到 site-packages
体验pygame的游戏效果
在pycharm中的Terminal中
python -m pygame.examples.aliens
在命令提示符下也可以使用
前提条件就是
我们的项目用的是anaconda目录下的python解释器
函数的定义与调用
- 定义函数的时候,有默认值的形参
def func(name="zs", age=18):
print(name)
print(age)
func()
# 有默认值的形参,我们在调用的时候是不用传参,不报错的
调用时,如果需要传参,有两种方式传
-
位置传参
def func(name="zs", age=18): print(name) print(age) func("李四", 28)
-
指名传参(关键词传参)
def func(name="zs", age=18): print(name) print(age) func(age=16, name="ww")
扩展出来的传参方式
位置传参与关键词传参,同时
def func(name="zs", age=18):
print(name)
print(age)
func("zl", age=88)
创造游戏屏幕对象
pygame.display.set_mode()
set_mode 方法说明
set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
- 作用 —— 创建游戏显示窗口
- 参数
resolution
指定屏幕的宽
和高
,默认创建的窗口大小和屏幕大小一致flags
参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递depth
参数表示颜色的位数,默认自动匹配
- 返回值
- 暂时 可以理解为 游戏的屏幕,游戏的元素 都需要被绘制到 游戏的屏幕 上
- 注意:必须使用变量记录
set_mode
方法的返回结果!因为:后续所有的图像绘制都基于这个返回结果
创建游戏主窗口
screen = pygame.display.set_mode((480, 700))
time模块
引入
import time
有一个延迟功能,睡眠
time.sleep(秒数)
让游戏窗口不要秒退
使用time模块来延迟下一行代码的执行
while True:
pygame.display.set_mode((400,600))
time.sleep(10)
break
绘制图象三步曲
- 在游戏中,能够看到的 游戏元素 大多都是 图像
- 图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存
- 要在屏幕上 看到某一个图像的内容,需要按照三个步骤:
- 使用
pygame.image.load()
加载图像的数据 - 使用 游戏屏幕 对象,调用
blit
方法 将图像绘制到指定位置 - 调用
pygame.display.update()
方法更新整个屏幕的显示
- 使用
提示:要想在屏幕上看到绘制的结果,就一定要调用
pygame.display.update()
方法
游戏中的座标系
飞机的定位
飞机定位在右下的的训练
矩形对象的创建
矩形对象 = pygame.Rect(x,y,width,heigh)
用途:
通过矩形对象来存储数据
需要修改数据时,直接对矩形对象进行操作
动画效果实现的原理
实际上是多张图片快速的翻页
翻页速度越快,动画越流畅
让英雄移动
实现方式
在循环中,修改飞机的x与y的数据
问题,出现了残影
解决办法
重新绘制图片
重新绘制飞机
游戏时钟
创建游戏时钟对象
时钟对象 = pygame.time.Clock()
控制帧率
时钟对象.tick(帧率)
显示当前的时间戳
time.time()
练习让飞机不越界
思路,进行边界判断
flag_x = True # 控制x方向的开关
flag_y = True # 控制y方向的开关
while True:
# print(hero_rect.x, '英雄的x')
# 绘制背景图,更新显示
screen.blit(bg, (0,0))
# 对象.属性 = 值
if flag_x == True:
hero_rect.x += 2
else:
hero_rect.x -= 2
if flag_y == True:
hero_rect.y += 2
else:
hero_rect.y -= 2
if hero_rect.x >= 400-69:
flag_x = False
elif hero_rect.x <=0:
flag_x = True
if hero_rect.y >= 600-99:
flag_y = False
elif hero_rect.y <=0:
flag_y = True
# 绘制飞机
screen.blit(hero, (hero_rect.x, hero_rect.y))
# 更新显示
pygame.display.update()
clock.tick(60)
事件
获得事件列表
事件列表 = pygame.event.get()
事件类型
鼠标左击
[<Event(5-MouseButtonDown {'pos': (134, 489), 'button': 1, 'window': None})>, <Event(6-MouseButtonUp {'pos': (134, 489), 'button': 1, 'window': None})>, <Event(4-MouseMotion {'pos': (142, 481), 'rel': (8, -8), 'buttons': (0, 0, 0), 'window': None})>]
鼠标右击
[<Event(5-MouseButtonDown {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(6-MouseButtonUp {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(5-MouseButtonDown {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(6-MouseButtonUp {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(5-MouseButtonDown {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(6-MouseButtonUp {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(5-MouseButtonDown {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(6-MouseButtonUp {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(5-MouseButtonDown {'pos': (58, 430), 'button': 3, 'window': None})>, <Event(6-MouseButtonUp {'pos': (58, 430), 'button': 3, 'window': None})>]
点击空格
[<Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(3-KeyUp {'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>, <Event(2-KeyDown {'unicode': ' ', 'key': 32, 'mod': 0, 'scancode': 57, 'window': None})>]
关闭按钮
[<Event(12-Quit {})>, <Event(12-Quit {})>, <Event(12-Quit {})>]
继承的复习
使用继承的场景
如果需要类会频繁的用到另一个类的属性或方法时,可以考虑继承
目的是减少代码重复
子类继承父类的情况
-
父类的方法,子类可以直接使用
-
如果子类的方法与父类方法完全不一样,那么我们可以重写子类中的方法
-
如果子类的方法会在父类方法中有新增和拓展,保留父类中的方法的功能,调用父类的方法
super().父类方法名(参数)
精灵
pygame.sprite.Sprite
精灵组
pygame.sprite.Group
导入模块的顺序
python内置的模块,放最顶层
第三方模块,放其次
自定义的模块,其次
重写时调用父类方法
父类的实例方法一定是这样子定义的
def 父类方法名(self, 形参1, 形参n):
调用的时候:
super().父类方法(实参1,实参n)
上面的代码相当于
对象.方法名(实参1,实参n)
通过对象调方法,不用管实例方法中的self参数
因为,通过对象来调的时候,会自动的传参给self