@websec007
2020-05-31T14:22:17.000000Z
字数 21705
阅读 1729
pygame
(1)pygame 安装
pygame 直接使用pip进行安装你会发现很难安装成功,其主要原因主要是因为其安装包默认要求国外官方站点下载,由于我天朝的网络管理原因,下载速度极其缓慢,这里我们使用参数 --index-url 来指定国内的pypi镜像进行快速安装,具体命令如下。(百试不爽)
# pip install pygame --index-url https://mirrors.aliyun.com/pypi/simple/或# pip install pygame -i https://mirrors.aliyun.com/pypi/simple/
(2)pygame 模块测试
pygame 安装是否成功,可以使用如下模块调用进行测试,游戏运行成功,即表明模块安装OK.
# python -m pygame.examples.alien
import pygame, sys# 1. pygame模块初始化pygame.init()# 2. 屏幕设置size = width, height = 360, 480screen = pygame.display.set_mode(size)pygame.display.set_caption("pygame最小代码框架测试")bg_color = (233, 233, 233)# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()"""(2) Game Update"""screen.fill(bg_color)"""(3) Render"""pygame.display.update()
(1)知识点
(2)核心点
import pygame, sys# 1. pygame模块初始化pygame.init()# 2. 屏幕设置size = width, height = 360, 480screen = pygame.display.set_mode(size)pygame.display.set_caption("pygame最小代码框架测试")bg_color = (233, 233, 233)''' 弹力球 image 载入'''ball_image= pygame.image.load(r"F:\My_Learn\PygameCourses\images\PYG02-ball.gif")ball_rect = ball_image.rect_get()speed = [1, 1]# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()"""(2) Game Update"""'''设置弹力球反弹的边界范围'''ball_rect = ball_rect.move(speed)if ball_rect.left < 0 or ball_rect.right > width:speed[0] = - speed[0]if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = - speed[1]"""(3) Render"""screen.fill(bg_color)screen.blit(ball_image, ball_rect)pygame.display.update()
(1)知识点
(2)核心点
import pygame, sys# 1. pygame模块初始化pygame.init()# 2. 屏幕设置size = width, height = 720, 420screen = pygame.display.set_mode(size)pygame.display.set_caption("pygame 最小代码框架测试")bg_color = (233, 233, 233)ball_image = pygame.image.load(r"F:\My_Learn\PygameCourses\images\PYG02-ball.gif")ball_rect = ball_image.get_rect()speed = [1, 1]"""创建clock对象,为设置屏幕刷新做准备"""fps = 300clock = pygame.time.Clock()# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()"""(2) Game Update"""ball_rect = ball_rect.move(speed)if ball_rect.left < 0 or ball_rect.right > width:speed[0] = - speed[0]if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = - speed[1]"""(3) Render"""clock.tick(fps)screen.fill(bg_color)screen.blit(ball_image, ball_rect)pygame.display.update()
(1)知识点
(2)核心点
import pygame, sys# 1. pygame模块初始化pygame.init()# 2. 屏幕设置size = width, height = 720, 420screen = pygame.display.set_mode(size)pygame.display.set_caption("pygame 最小代码框架测试")bg_color = (233, 233, 233)ball_image = pygame.image.load(r"F:\My_Learn\PygameCourses\images\PYG02-ball.gif")ball_rect = ball_image.get_rect()speed = [1, 1]"""创建clock对象,为设置屏幕刷新做准备"""fps = 200clock = pygame.time.Clock()# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()"""通过键盘类型-键盘值的调整实现对speed值的横坐标与纵坐标进行重新赋值"""elif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:speed[0] = speed[0] if speed[0] == 0 else (abs(speed[0] - 1)*int(speed[0]/abs(speed[0])))elif event.key == pygame.K_RIGHT:speed[0] = speed[0] + 1 if speed[0] > 0 else speed[0] - 1elif event.key == pygame.K_UP:speed[1] = speed[1] + 1 if speed[1] > 0 else speed[1] - 1elif event.key == pygame.K_DOWN:speed[1] = speed[1] if speed[1] == 0 else (abs(speed[1] - 1)*int(speed[1]/abs(speed[1])))"""(2) Game Update"""print(speed)ball_rect = ball_rect.move(speed)if ball_rect.left < 0 or ball_rect.right > width:speed[0] = - speed[0]if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = - speed[1]"""(3) Render"""clock.tick(fps)screen.fill(bg_color)screen.blit(ball_image, ball_rect)pygame.display.update()
(1)屏幕简介
(2)屏幕尺寸控制
i)屏幕尺寸控制
pygame.display.set_mode(size)pygame.display.Info()ii)窗口类函数
pygame.display.set_caption()pygame.display.set_icon()pygame.display.get_caption()iii)窗口动态感知与刷新
pygame.display.get_active()pygame.display.flip() pygame.display.update()pygame.display.set_mode(r=(0,0), flags=0)
屏幕无边界显示
代码:对键盘类型“按下事件”进行监控,并判断其值是否是ESC,如果是则退出。
elif event.type == pygame.KEYDOWN:if pygame.key == pygame.K_ESCAPE:sys.exit()
# 2. 屏幕模式设置size = width, height = 720, 420print(pygame.display.Info())# screen = pygame.display.set_mode(size, pygame.RESIZABLE)# screen = pygame.display.set_mode(size, pygame.NOFRAME)# screen = pygame.display.set_mode(size, pygame.FULLSCREEN)screen = pygame.display.set_mode(size)print(pygame.display.Info())pygame.display.set_caption("pygame 最小代码框架测试")bg_color = (233, 233, 233)ball_image = pygame.image.load(r"F:\My_Learn\PygameCourses\images\PYG02-ball.gif")ball_rect = ball_image.get_rect()speed = [1, 1]
vInfo = pygame.display.Info()size = width, height = vInfo.current_w, vInfo.current_h
pygame.display.Info() ,我们可以获取一个 “VIDEOInfo” 信息对象,此对象包含了当前屏幕显示多个信息参数,其中有2个是我们最关注的,即:
(1)current_w: 当前窗口像素的宽度(2)current_h: 当前窗口像素的高度
源码演示 - 屏幕大小改变后信息获取比较
通过在屏幕设置前后运行屏幕信息获取函数并打印比较,我们可以看到屏幕信息获取函数可以获取到的参数信息和变化;
-----------------------------以下为运行的源码部分--------------------------------
import pygame, sys# 1. pygame模块初始化pygame.init()# 2. 屏幕设置size = width, height = 360, 480"""屏幕大小感知:pygame.display.Info()"""print(pygame.display.Info())screen = pygame.display.set_mode(size)print(pygame.display.Info())pygame.display.set_caption("pygame最小代码框架测试")bg_color = (233, 233, 233)# 3. 游戏主循环while True:...
-----------------------------以下为源码运行打印输出部分--------------------------------
# 屏幕分辨率尺寸设置前:<VideoInfo(hw = 0, wm = 1,video_mem = 0blit_hw = 0, blit_hw_CC = 0, blit_hw_A = 0,blit_sw = 0, blit_sw_CC = 0, blit_sw_A = 0,bitsize = 32, bytesize = 4,masks = (16711680, 65280, 255, 0),shifts = (16, 8, 0, 0),losses = (0, 0, 0, 8),current_w = 1920, current_h = 1080# 屏幕分辨率尺寸设置后:<VideoInfo(hw = 0, wm = 1,video_mem = 0blit_hw = 0, blit_hw_CC = 0, blit_hw_A = 0,blit_sw = 0, blit_sw_CC = 0, blit_sw_A = 0,bitsize = 32, bytesize = 4,masks = (16711680, 65280, 255, 0),shifts = (16, 8, 0, 0),losses = (0, 0, 0, 8),current_w = 360, current_h = 480
通过源码运行演示打印,我们可以看到在 pygame.display.set_mode()前后,当前屏幕显示信息的变化;
pygame.VIDEORESIZE
源码示例演示
# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:speed[0] = speed[0] if speed[0] == 0 else (abs(speed[0] - 1)*int(speed[0]/abs(speed[0])))elif event.key == pygame.K_RIGHT:speed[0] = speed[0] + 1 if speed[0] > 0 else speed[0] - 1elif event.key == pygame.K_UP:speed[1] = speed[1] + 1 if speed[1] > 0 else speed[1] - 1elif event.key == pygame.K_DOWN:speed[1] = speed[1] if speed[1] == 0 else (abs(speed[1] - 1)*int(speed[1]/abs(speed[1])))elif event.key == pygame.K_ESCAPE:sys.exit()"""屏幕大小动态调整感知和自动调整实现"""elif event.type == pygame.VIDEORESIZE:size = width, height = event.size[0], event.size[1]screen = pygame.display.set_mode(size, pygame.RESIZABLE)"""(2) Game Update"""
icon = pygame.image.load('icon.png')pygame.display.set_icon(icon)
pygame.display.get_active()
.....if pygame.display.get_active():ball_rect = ball_rect.move(speed)if ball_rect.left < 0 or ball_rect.right > width:speed[0] = - speed[0]if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = - speed[1]
(1)什么是事件处理机制
(2)常见的事件类型
注:事件处置机制的核心内容就是事件队列的缓存,又称“事件队列”。
| 序号 | 事件 | 事件类型 | 事件属性 |
|---|---|---|---|
| 1 | 系统 | pygame.QUIT pygame.ACTIVEEVENT |
none gain, state |
| 2 | 键盘 | pygame.KEYDOWN pygame.KEYUP |
event.unicode event.key event.mod |
| 3 | 鼠标 | pygame.MOUSEMOTION pygame.MOUSEBOTTONDOWN pygame.MOUSEBOTTONUP |
pos,rel,button pos,button pos,button |
| 4 | 窗口 | pygame.VIDEORESIZE pygame.VIDEOEXPOSE |
size,w,h none |
| 5 | 游戏杆 | JOY ... | joy ... |
| 6 | 自定义 | USEREVENT | code |
(1)“键盘按下事件”与其“属性”
(2)“键盘释放事件”与其“属性”
(1)按键的常量名称(event.key)
(2)按键的修饰符(event.mod)
# Description: pygame.KEYDWON 键盘按键事件响应测试import pygame, sys...# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 对键盘按下事件进行测试学习:了解其3个属性,特别是event.unicodeelif event.type == pygame.KEYDOWN:if event.unicode == '':print("[KEYDOWN]: {}, {}, {}".format("#", event.key, event.mod))else:print("[KEYUP]: {}, {}, {}".format(event.unicode, event.key, event.mod))....."""(3) Render"""pygame.display.update()
(1)鼠标移动事件与其属性
(2)鼠标按下事件与其属性
(3)鼠标释放事件与其属性
# 3. 游戏主循环while True:"""(1) Input Process"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()# 对键盘按下事件进行测试学习:了解其3个属性,特别是event.unicodeelif event.type == pygame.KEYDOWN:if event.unicode == '':print("[KEYDOWN]: {}, {}, {}".format("#", event.key, event.mod))else:print("[KEYDOWN]: {}, {}, {}".format(event.unicode, event.key, event.mod))# 对鼠标3事件和其属性进行测试与学习elif event.type == pygame.MOUSEMOTION:print("[MOUSEMOTON]: {}, {}, {}".format(event.pos, event.rel, event.buttons))elif event.type == pygame.MOUSEBUTTONDOWN:print("[MOUSEBUTTONDOWN]: {}, {}".format(event.pos, event.button))elif event.type == pygame.MOUSEBUTTONUP:print("[MOUSEBUTTONUP]: {}, {}".format(event.pos, event.button))
(1)通过鼠标左键摆放壁球,按下按键时壁球停止移动;
(2)按键按下并且移动时,壁球跟随鼠标移动;
(3)当释放时,壁球继续移动;
# 3. 游戏主循环while True:"""(1) Input Process""".....# 增加对鼠标控制的响应# (1) 鼠标左键按下,壁球暂停移动(通过 still = True 配合默认移动条件实现)elif event.type == pygame.MOUSEBUTTONDOWN:if event.button == 1:still = True# (2) 鼠标按键释放,壁球移动到鼠标当前位置;elif event.type == pygame.MOUSEBUTTONUP:if event.button == 1:still = Falseball_rect = ball_rect.move(event.pos[0] - ball_rect.left, event.pos[1] - ball_rect.top)# (3) 鼠标移动,壁球跟着移动elif event.type == pygame.MOUSEMOTION:if event.buttons[0] == 1:ball_rect = ball_rect.move(event.pos[0] - ball_rect.left, event.pos[1] - ball_rect.top)"""(2) Game Update"""# 屏幕窗口最小化感知判断,从而决定是否要暂停壁球的移动if pygame.display.get_active() and not still:ball_rect = ball_rect.move(speed[0], speed[1])# 壁球的边界控制if ball_rect.left < 0 or ball_rect.right > width:speed[0] = - speed[0]if width < ball_rect.right < ball_rect.right + speed[0]:speed[0] = - speed[0]if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = - speed[1]if height < ball_rect.bottom < ball_rect.bottom + speed[1]:speed[1] = - speed[1]"""(3) Render"""
(1)处理事件函数
(2) pygame.event.get() 实例
for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()
pygame.Color() 绘制色彩方法
pygame.Color(r, g, b, a) 详解
alpha 通道
pygame.Color类
游戏需求说明
游戏实现源码
# 色彩控制bg_color = pygame.Color("grey")def RGBChannel(a):return 0 if a<0 else (255 if a>255 else int(a))# 3. 游戏主循环while True:....# 通过pygame.Color.r来绘制色彩bg_color.r = RGBChannel(ball_rect.left/width * 255)bg_color.g = RGBChannel(ball_rect.top/height * 255)bg_color.b = RGBChannel(min(speed)/ max(speed[0], speed[1], 1) * 255)bg_color.a = RGBChannel(ball_rect.left/width * 255)screen.fill(bg_color)
pygame.draw.xxx()方法 进行图形绘制过程,其就是在屏幕画布上直接进行图形绘制,然后返回一个pygame.Rect类表示该形状;
pygame.Rect 外接矩形对象
pygame.Rect 表达一个矩形区域的类,用于存储坐标和长度信息
pygame利用Rect类来操作图形/图像元素
pygame.Rect 属性
pygame.Rect 类提供了很多属性,可以返回一给数值或一个代表坐标的元组.
pygame.Rect 方法
pygame.Rect 参考
pygame.draw绘图类型简介
.line()
.lines()
.circle()
.ellipse()
.rect()
.polygon
.arc()
pygame.draw 绘图详解
(1)矩形绘制:pygame.draw.rect(surface, color, rect, width=0)
(2)椭圆绘制:pygame.draw.ellipse(surface, color, rect, width=0)
(3)多边形绘制:pygame.draw.polygon(Surface, color, pointlist, width=0)
(4)圆形绘制:pygame.draw.circle(Surface, color, pointlist, width=0)
(5)圆弧绘制:pygame.draw.arc(surface, color, rect, start_angle, stop_angle, width=0)
(6)直线条绘制:pygame.draw.line(surface, color, start_pos, end_pos, width=1)
(7)多线条绘制:pygame.draw.lines(surface, color, closed, pointlist, width=1)
(8)锯形线条绘制:pygame.draw.aalines(surface, color, closed, pointlist, blend=1)
import pygame,sysfrom math import pi# 1.初始化pygame.init()# 2. 屏幕初始化size = width, height = 720, 600# Vinfo = pygame.display.Info()# size = width, height = Vinfo.current_w, Vinfo.current_hscreen = pygame.display.set_mode(size)pygame.display.set_caption("多图形绘制学习")bg_color = pygame.Color('black')GOLD = 255, 251, 0RED = pygame.Color('red')WHITE = 255, 255, 255GREEN = pygame.Color('green')# # 多图绘制# e1rect = pygame.draw.ellipse(screen, GREEN, (50, 50, 500, 500), 3)# c1rect = pygame.draw.circle(screen, GOLD, (200, 180), 30, 5)# c2rect = pygame.draw.circle(screen, GOLD, (400, 180), 30)# r1rect = pygame.draw.rect(screen, RED, (170, 130, 60, 10), 3)# r2rect = pygame.draw.rect(screen, RED, (370, 130, 60, 10))# plist = [(295,170), (285,250), (260,280), (340,280), (315,250), (305 ,170)]# l1rect = pygame.draw.lines(screen, GOLD, True, plist, 2)# a1rect = pygame.draw.arc(screen, RED, (200, 220, 200, 100), 1.4*pi, 1.9*pi, 3)# 3. game loopwhile True:# process inputfor event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_ESCAPE:pygame.quit()elif event.type == pygame.VIDEORESIZE:size = width, height = event.size[0], event.size[1]screen = pygame.display.set_mode(size, pygame.RESIZABLE)# update gamescreen.fill(bg_color)# 多图绘制e1rect = pygame.draw.ellipse(screen, GREEN, (50, 50, 500, 500), 3)c1rect = pygame.draw.circle(screen, GOLD, (200, 180), 30, 5)c2rect = pygame.draw.circle(screen, GOLD, (400, 180), 30)r1rect = pygame.draw.rect(screen, RED, (170, 130, 60, 10), 3)r2rect = pygame.draw.rect(screen, RED, (370, 130, 60, 10))plist = [(295, 170), (285, 250), (260, 280), (340, 280), (315, 250), (305, 170)]l1rect = pygame.draw.lines(screen, GOLD, True, plist, 2)a1rect = pygame.draw.arc(screen, RED, (200, 220, 200, 100), 1.4 * pi, 1.9 * pi, 3)# renderpygame.display.update()
图形绘制过程:是直接在指定屏幕画布上进行作画的,图形会直接在屏幕画布中显示;(图形绘制过程与“图片”与“文字”绘制是不同的;
图形与文字的绘制过程是,先是由外部导入的一个对象并获得其矩形对象属性,然后通过surface.blit()方法绘制到屏幕画布上;
字符符集
Windows 系统自带的字符集
字符对象获取方法1:
模块2:pygame.font.Font()
字符集获取
Font 类的绘制方法
Font 类绘制方法 -1 (2步完成)
Font.render_to(surf, dest, text, fgcolor=None, bgcolor=None, rotation=0, size=0)
Font类绘制方法 - 2 (3步完成)
Font.render(text, fgcolor=None, bgcolor=None, rotation=0, size=0)
-> 获取 (font_Surface, font_Rect) 1个元组2个对象;
5.4.3 源码演示
方法1:
# 文字绘制 - 方法1Font = pygame.font.Font(r'F:\My_Learn\PygameCourses\fonts\msyh.ttc', 36)text_surface = Font.render('不要急,慢一点,少一点', True, GOLD)# print(text_surface)text_rect = text_surface.get_rect()# print(text_rect)# 文字图层移入主图层,显示出来screen.blit(text_surface, text_rect)
方法2:
# 文字绘制 - 方法2# 导入模块import pygame.freestyle# 字符绘制,并获取Rect对象;Font = pygame.freetype.Font(r'F:\My_Learn\PygameCourses\fonts\msyh.ttc', 36)text_surface, text_rect = Font.render('世界和平', fgcolor=pygame.Color('gold'), size=50)print(text_rect)# 文字图层移入主图层,显示出来screen.blit(text_surface, text_rect)
| 序号 | 函数 | 功能说明 |
|---|---|---|
| 1 | pygame.display.Info() | 屏幕信息获取 |
| 2 | pygame.display.set_mode(size, flags) | 屏幕尺寸与模式设置 |
| 3 | pygame.display.set_icon(icon_surface) | 屏幕图标设置 |
| 4 | pygame.display.set_caption('Title_Strings') | 设置屏幕标题 |
| 5 | pygame.display.get_caption() | 屏幕标题信息获取 |
| 6 | pygame.display.get_active() | 屏幕最小化感知判断 |
| 7 | pygame.display.flip() | 屏幕整个刷新 |
| 8 | pygame.display.update() | 仅刷新更新的内容 |
| 序号 | 事件 | 事件类型 | 事件属性 |
|---|---|---|---|
| 1 | 系统事件 | pygame.QUIT pygame.ACTIVEEVENT |
none gain, state |
| 2 | 键盘事件 | pygame.KEYDOWN pygame.KEYUP |
event.unicode event.key event.mod event.key event.mod |
| 3 | 鼠标事件 | pygame.MOUSEMOTION pygame.MOUSEBOTTONDOWN pygame.MOUSEBOTTONUP |
pos,rel,button pos,button pos,button |
| 4 | 窗口事件 | pygame.VIDEORESIZE pygame.VIDEOEXPOSE |
size,w,h none |
| 5 | 游戏杆事件 | JOY ... | joy ... |
| 6 | 自定义事件 | USEREVENT | code |
# 多图形绘制 (图形绘制与显示是1步完成的,无需在blit())e1rect = pygame.draw.ellipse(screen, GREEN, (50, 50, 500, 500), 3)c1rect = pygame.draw.circle(screen, GOLD, (200, 180), 30, 5)c2rect = pygame.draw.circle(screen, GOLD, (400, 180), 30)r1rect = pygame.draw.rect(screen, RED, (170, 130, 60, 10), 3)r2rect = pygame.draw.rect(screen, RED, (370, 130, 60, 10))plist = [(295,170), (285,250), (260,280), (340,280), (315,250), (305 ,170)]l1rect = pygame.draw.lines(screen, GOLD, True, plist, 2)a1rect = pygame.draw.arc(screen, RED, (200, 220, 200, 100), 1.4*pi, 1.9*pi, 3)# 3. game loopwhile True:# Process Input...# update game...# render# 报错的原因:# (1) 图形绘制与显示只需要指定screen后,1步就可以获取一个pygame.Rect了,无需在blit())# (2) pygame.Rect 对象即表示图形已经绘制完成,并且可以显示了,无需在blit()块移动;screen.blit(r1rect, (500, 500))pygame.display.update()
Traceback (most recent call last):File "F:/My_Learn/PygameCourses/PYG05/[Error]PYG05-03 多图形绘制.py", line 46, in <module>screen.blit(r1rect, (500, 500))TypeError: argument 1 must be pygame.Surface, not pygame.RectProcess finished with exit code 1
收获: 知识点认识与收获
pygame.Rect 对象
其是一个矩形对象属性,是实质就是在“主图层”(screen)上的一个矩形对象的区域坐标与大小的属性对象(left, top, width, height),通常被用于进行pygame.surface 对象在主图层的移动定位。
主图层生成(screen)
主图层即由pygame.diplay.set_mode()生成的 surface 绘图层。
size = width, height = 360, 480screen = pygame.display.set_mode(size)
其他图层的显示:screen.blit(surface, rect)
其它非主图层的surface的绘制显示,是必须移到“主图层”上才可以显示出来。(如:图片surface & 文字surface)
# surface_1: 图像绘制# 1) 载入图片对象image = pygame.image.load(r'F:\My_Learn\PygameCourses\images\Ball.png')# 2) 获取图片对象矩形属性(0,0, 200,200), 默认rect的坐标为(left.top) = (0,0)image_rect = image.get_rect()# 3) 图片surface 移动到主图层进行显示screen.blit(ball, ball_rect)