2024年最全Pygame教程(非常详细)(1),滴滴Golang面试

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

如果想创建一个包含图像的 surface 对象可以使用如下方法:

surface_image =pygame.image.load("图片路径") 

事件监听

游戏,在我们日常生活中经常接触到,无论是手游、还是电脑端游戏,已经成了信息社会中,不可或缺的一部分。

游戏大致来讲是由动画和人机交互的体验两部分构成,其中动画则是由一系列连续静止的图片,经过一定频率的刷新构成的,这个频率被称为 FPS,如果频率值越大则画面越流畅;如果频率值越小则画面会出现卡顿的感,在游戏过程中一般人能接受的最低 FPS 约为 30Hz,如果想要画面流畅则 FPS 要大于 60 Hz。

FPS 越高,细节越好,体验也越好,但是文件容量也越高

动画保证了玩家的视觉体验,而人机交互则是操作上的体验。通过移动和点击鼠标、按下键盘上的技能键,或是滑动手机屏幕等操作来实现人机交互,这些与游戏程序交互的操作被称为事件(Event)。

如果您接触过 JavaScript,那么您对于“事件”这一名词,一定不会陌生。

Pygame 作为一个游戏开发库,同样具有设置和监听事件的功能。它提供了一个 enevt 事件模块,这个模块中包含了所有常用到游戏事件。下面是退出游戏的代码示例(其他事件类型,后续会做介绍):

# 循环获取事件,监听事件状态,使用get()获取事件
for event in pygame.event.get():
    # 判断事件类型,用户是否点了"X"关闭按钮
    # pygame.QUIT 指点击右上角窗口的"X"号
    if event.type == pygame.QUIT:
        #点击后,卸载所有pygame模块
        pygame.quit()

游戏循环

当打我们游戏时可能会触发游戏中的各种事件,比如鼠标事件、键盘按键事件、摄像拍照事件等等,因此游戏程序需要一直循环监听玩家的操作,只有当用户点击了游戏“关闭”按钮时,监听才会结束。如果想要达到“循环监听”目的,此时就需要设置一个游戏循环(Game Loop)也称为游戏的主循环,这样才能保证人机交互的体验感。代码示例如下:

#游戏主循环(游戏循环)
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == pygame.QUIT:
            # 当用户关闭游戏窗口时执行以下操作
            # 这里必须调用quit()方法,退出游戏
            pygame.quit()
            #终止系统
            sys.exit()
    #更新并绘制屏幕内容
    pygame.display.flip() 

游戏主循环是每个 Pygame 游戏程序中必不可少的一部分,它主要承担着以下三个重要任务:

  • 处理游戏事件
  • 更新游戏状态
  • 把更新后的游戏状态绘制到屏幕上

pygame程序
图2:主循环示意图

游戏画面和游戏操作状态会因为动画效果和玩家的操作而改变,因此需要以循环的方式实时地更新主屏幕(screen)的显示内容。把下列代码放入游戏主循环中即可实现实时更新和绘制屏幕内容,如下所示:

#刷新界面显示pygame.display.flip() 

除了上述方法外,Pygame 还提供了另一个方法。如下所示:

pygame.display.update() 

这两个方法的主要区别是:后者可以根据选定的区域来更新部分内容,而前者则是更新整个待显示的内容。如果后者没有提供区域位置参数时,其作用和 display.flip() 相同。

通过上述学习,我们对 Pygame 程序有了基本的认识。下面对 Pygame 模块中的方法、属性做更加细致的讲解。

Pygame Display显示模块详解

Pygame 使用pygame.display显示模块中的方法创建游戏的主窗口:

screen = pygame.display.set_mode(size=(),flags=0)

上述函数有两个参数常用参数:

  • size:元组参数,用来设置主窗口的大小
  • flags:功能标志位,表示创建的主窗口样式,比如创建全屏窗口、无边框窗口等,flags 参数值见下表。
标志位功能
pygame.FULLSCREEN创建一个全屏窗口。
pygame.HWSURFACE创建一个硬件加速窗口,必须和 FULLSCREEN 同时使用。
pygame.OPENGL创建一个 OPENGL 渲染窗口。
pygame.RESIZABLE创建一个可以改变大小的窗口。
pygame.DOUBLEBUF创建一个双缓冲区窗口,建议在 HWSURFACE 或者 OPENGL 时使用。
pygame.NOFRAME创建一个没有边框的窗口。

体验过电脑游戏的朋友们都知道,当运行程序后会在电脑桌面上出现一个游戏的主窗口,这个主窗口的本质是一个 surface 对象,把理解为画布、画板、白纸在合适不过了,它相当于一个载体,用于承载一切游戏所用到的元素。假如您需要将一段文本方放置到主窗口中,那么您需要先创建一个包含文本的 surface 对象,之后再将它附加到主窗口上。简单的理解,就是将一张图 A 粘贴到另一张图 B 上。

主窗口(screen)相当于游戏程序中尺寸最大的 Surface 对象,在这个最大的“画布”中,我们还可以添加其他“小”的 Surface 对象,这些对象以矩形的形式存在于主窗口中,它们共同组成了一个游戏程序。通过下列方法可以将一个 Surface 对象粘贴至主窗口上:

scrren.blit(source, dest, area=None, special_flags = 0)

下面对上述参数做简单的介绍:

  • source:表示要粘贴的 Surface 对象。
  • dest:主窗口中的一个标识的坐标位置,可以接受一个 (x,y) 元组,或者 (x,y,width,height) 元组,也可以是一个 Rect 对象;
  • area:接受一个 Rect 对象,默认为 None,如果提供该参数则相当于抠图操作,即在屏幕的指定区域显示想要的内容;
  • special_flags:可选参数,它是 Pygame.1.8 版本新增的功能,用于指定对应位置颜色的混合方式,参数值有 BLEND_RGBA_ADD、BLEND_SUB 等。如果不提供该参数的情况下,默认使用 source 的颜色覆盖 screen 的颜色。

除了创建游戏的主窗口之外,display 模块还提供了许多的和“显示”相关的方法,比如设置游戏窗口的名称,如下表所示

import sys
import pygame
#使用pygame之前必须初始化
pygame.init()
#设置主屏窗口
screen = pygame.display.set_mode((400,400))
#填充主窗口的背景颜色,参数值RGB(颜色元组)
screen.fill((156,156,156))
#设置窗口标题
pygame.display.set_caption('c语言中文网')
# 如果没有下列主循环代码,运行结果会一闪而过
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == pygame.QUIT:
            #卸载所有模块
            pygame.quit()
            #终止程序
            sys.exit()
    #更新屏幕内容
    pygame.display.flip()

程序的运行结果如下所示:

pygame程序运行结果
图1:Pygame程序运行结果

pygame.display 模块还提供了一些和“显示”相关的其他方法,如下表所示:

方法名称说明
pygame.display.get_surface()获取当前显示的 Surface 对象。
pygame.display.flip()更新整个待显示的 Surface 对象到屏幕上。
pygame.display.update()更新部分软件界面显示。
pygame.display.Info()产生一个 VideoInfo 对象,包含了显示界面的相关信息。
pygame.display.set_icon()设置左上角的游戏图标,图标尺寸大小为 32*32。
pygame.display.iconify()将显示的主窗口即 Surface 对象最小化,或者隐藏。
pygame.display.get_active()当前显示界面显示在屏幕上时返回 True,如果窗口被隐藏和最小化则返回 False。

Pygame Surface创建图像

通过前面内容的介绍,我们对 Surface 对象有了大体上的认识。Pygame 针对文本、图像、颜色提供了不同模块来生成它们各自的 Surface 对象。Surface 模块是Pygame 中专门用来新建图像的,通过该模块可以创建一个 Surface 对象,语法格式如下:

Surface=pygame.Surface(size=(width,height),flags,depth)

参数函数如下:

  • size:表示 Surface 对象的矩形区域大小;
  • flags:功能标志位,有两个可选参数值 HWSURFACE 和 SPCALPHA,前者代表将创建的 Surface 对象存放于显存中,后者表示让图像的每一个像素都包含一个 alpha 通道
  • depth:指定像素的颜色深度,默认为自适应模式,由 Pygame 自动调节。

下面看一组简单的使用示例,如下所示:

import sys
import pygame
#使用pygame之前必须初始化
pygame.init()
#设置主屏窗口 ;设置全屏格式:flags=pygame.FULLSCREEN
screen = pygame.display.set_mode((400,400))
#设置窗口标题
pygame.display.set_caption('c语言中文网')
screen.fill('white')
#创建一个 50*50 的图像,并优化显示
face = pygame.Surface((50,50),flags=pygame.HWSURFACE)
#填充颜色
face.fill(color='pink')
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == pygame.QUIT:
            #卸载所有模块
            pygame.quit()
            #终止程序
            sys.exit()
    # 将绘制的图像添加到主屏幕上,(100,100)是位置坐标,显示屏的左上角为坐标系的(0,0)原点
    screen.blit(face, (100, 100))
    pygame.display.flip() #更新屏幕内容

最终的显示结果如下:

pygame surface对象
图1:程序运行结果

从上述运行结果可以看出,通过 Surface 模块,我们成功的在主屏幕上绘制一个 50 * 50 的矩形区域。注意,如果不设置尺寸,Surface 默认创建一个和主游戏屏幕同样大小的区域。

Surface 模块还提供了处理图像的其他方法,下表对它们做了简单的介绍。

方法说明
pygame.Surface.blit()将一个图像(Surface 对象)绘制到另一个图像上
pygame.Surface.convert()修改图像(Surface 对象)的像素格式
pygame.Surface.fill()使用纯色填充 Surface 对象
pygame.Surface.scroll()复制并移动 Surface 对象
pygame.Surface.set_alpha()设置整个图像的透明度
pygame.Surface.get_at()获取一个像素的颜色值
pygame.Surface.set_at()设置一个像素的颜色值
pygame.Surface.get_palette()获取 Surface 对象 8 位索引的调色板
pygame.Surface.map_rgb()将一个 RGBA 颜色转换为映射的颜色值
pygame.Surface.set_clip()设置该 Surface 对象的当前剪切区域
pygame.Surface.subsurface()根据父对象创建一个新的子 Surface 对象
pygame.Surface.get_offset()获取子 Surface 对象在父对象中的偏移位置
pygame.Surface.get_size()获取 Surface 对象的尺寸

除了使用 Surface 模块新建图像外,我们还可以使用另外一种方法从外部加载图像,如下所示:

pygame.image.load("图片路径").convert()  

上述方法将被加载的图像作为 Surface 对象来使用,因此它可以调用上述表格中所有方法。注意,此处之所以使用 convert()来转换被加载图片的像素格式,是为了提升 Pygame 对图片的处理速度,该操作能够保证图像的像素格式与图片的显示格式是相同的。

通过 image.load() 方法可以加载游戏的背景图,或者游戏中使用的其他元素,比如的人物、道具等等。

下面看一组简单的示例:

import pygame
#引入pygame中所有常量,比如 QUIT
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((500,250))
pygame.display.set_caption('c语言中文网')
#加载一张图片
image_surface = pygame.image.load("C:/Users/Administrator/Desktop/c-net.png").convert()
# rect(left,top,width,height)指定图片上某个区域
# special_flags功能标志位,指定颜色混合模式,默认为 0 表示用纯色填充
image_surface.fill((0,0,255),rect=(100,100,100,50),special_flags=0)
# 200,100 表示图像在水平、垂直方向上的偏移量,以左上角为坐标原点
image_surface.scroll(100,50)
# 无限循环,让窗口停留
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    # 将图像放置在主屏幕上
    screen.blit(image_surface,(0,0))
    pygame.display.update()

程序运行结果如下所示:

pygame运行程序
图2:程序运行结果

Pygame Transform图像变形

pygame.transform 模块允许您对加载、创建后的图像进行一系列操作,比如调整图像大小、旋转图片等操作,常用方法如下所示:

方法说明
pygame.transform.scale()将图片缩放至指定的大小,并返回一个新的 Surface 对象。
pygame.transform.rotate()将图片旋转至指定的角度。
pygame.transform.rotozoom()以角度旋转图像,同时将图像缩小或放大至指定的倍数。

下面看一组简单的演示示例:

import pygame
#引入pygame中所有常量,比如 QUIT
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((500,250))
pygame.display.set_caption('c语言中文网')
#加载一张图片(455*191)
image_surface = pygame.image.load("C:/Users/Administrator/Desktop/c-net.png").convert()
image_new = pygame.transform.scale(image_surface,(300,300))
# 查看新生成的图片的对象类型
#print(type(image_new))
# 对新生成的图像进行旋转至45度
image_1 =pygame.transform.rotate(image_new,45)
# 使用rotozoom() 旋转 0 度,将图像缩小0.5倍
image_2 = pygame.transform.rotozoom(image_1,0,0.5)
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    # 将最后生成的image_2添加到显示屏幕上
    screen.blit(image_2,(0,0))
    pygame.display.update()

程序的运行结果如下:

pygame程序运行结果
图1:程序运行结果

Pygame Time时间控制详解

pygame.time 时间控制模块,是 Pygame 中使用频率较高的模块,其主要功能是管理时间和游戏帧数率(即 FPS)。

时间在游戏开发中承担着非常重要的作用,比如释放某个技能所消耗的时间,或者播放动画、声音的持续时间,这些都需要时间来管理。time 模块另外一个重要作用是控制游戏帧数率(即 FPS),它是评价游戏画面是否流畅的关键指标。在一般情况下,计算机的 FPS 都能达到 60帧/s 的速度,这足够我们使用,如果当帧数小于 30 的时候,游戏画面就会变得卡顿。

注意,在 Pygame 中时间以毫秒为单位(1秒=1000毫秒),这样会使游戏的设计更为精细。

1) 游戏暂停

Pygame.time 模块提供了以下常用方法,如下表所示:

方法说明
pygame.time.get_ticks()以毫秒为单位获取时间
pygame.time.wait()使程序暂停一段时间
pygame.time.set_timer()创建一个定时器,即每隔一段时间,去执行一些动作
pygame.time.Clock()创建一个时钟对象来帮我们确定游戏要以多大的帧数运行

下面看一组简单的示例:

import pygame
pygame.init()
screen = pygame.display.set_mode((500,500))
pygame.display.set_caption('c语言中文网')
# 获取以毫秒为单位的时间
t = pygame.time.get_ticks() #该时间指的从pygame初始化后开始计算,到调用该函数为止
t1 =pygame.time.wait(3000) #暂停游戏3000毫秒
print(t1)
#暂停t1时间后,加载图片
image_surface = pygame.image.load("C:/Users/Administrator/Desktop/c-net.png")
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.blit(image_surface,(0,0))
    pygame.display.update()

上述程序在暂停 3 秒后才会加载图片,运行结果如下:

pygame程序
图1:程序运行结果

2) 设置游戏FPS

若想设置游戏的帧数率(FPS)可以通过 Clock() 方法来实现,该对象提供了以下常用方法:

方法说明
pygame.time.Clock.tick()更新clock对象
pygame.time.Clock.get_time()获取上一个tick中的时间
pygame.time.Clock.get_fps()计算clock对象的帧率

下面看一组简单的应用示例:

import pygame
pygame.init()
screen = pygame.display.set_mode((500,300))
pygame.display.set_caption('c语言中文网')
# 获取以毫秒为单位的时间
t = pygame.time.get_ticks() #该时间指的从pygame初始化后开始计算,到调用该函数为止
t1 =pygame.time.delay(3000) #暂停游戏3000毫秒
print(t1)
#暂停t1时间后,加载图片
image_surface = pygame.image.load("C:/Users/Administrator/Desktop/c-net.png")
#创建时钟对象(控制游戏的FPS)
clock = pygame.time.Clock()
while True:
    #通过时钟对象,指定循环频率,每秒循环60次
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.blit(image_surface,(0,0))
    pygame.display.update()

注意:FPS(游戏帧率)影响效果只有在动态图时才能显现出来,不过无论静态图还是动态图,它们的使用规则都是一样的。

Pygame Rect区域位置(图解)

Rect(rectangle)指的是矩形,或者长方形,在 Pygame 中我们使用 Rect() 方法来创建一个指定位置,大小的矩形区域。函数的语法格式如下:

rect =pygame.Rect(left,top,width,height) 

Rect 表示的区域必须位于一个 Surface 对象之上,比如游戏的主窗口(screen)。上述方法由四个关键参数值构成,分别是 left、top、width、height,为了方便大家理解这些距离的含义,下面给出了一张示意图:

pygame Rect区域

注意:在 Pygame 中以游戏主窗口的左上角为坐标原点。

下面看一组简单的使用示例,如下所示:

import pygame
pygame.init()
screen = pygame.display.set_mode((500,300))
pygame.display.set_caption('c语言中文网')
image_surface = pygame.image.load("C:/Users/Administrator/Desktop/c-net.png")
rect1 = pygame.Rect(50,50,100,100)
# 在原图的基础上创建一个新的子图(surface对象)
image_child= image_surface.subsurface(rect1)
rect2 = image_child.get_rect()
#输出的矩形大小为 100*100
print(rect2)
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    #在屏幕上显示子图的区域
    screen.blit(image_child,rect1)
    pygame.display.update()

程序的运行结果如下:

pygame游戏程序
图1:程序运行结果

从上述运行结果可以看出,我们在图片上截取了一个和 rect1 同样大小的矩形区域(100*100)。

Rect(矩形区域)对象还提供了一些常用方法。如下表所示:

方法说明
pygame.Rect.copy()复制矩形
pygame.Rect.move()移动矩形区域,接受一个列表参数
pygame.Rect.move_ip()移动矩形(无返回)
pygame.Rect.inflate()增大或缩小矩形大小
pygame.Rect.clamp()将矩形移到另一个矩形内
pygame.Rect.union()返回一个两个矩形合并后的矩形。
pygame.Rect.fit()按纵横比调整矩形的大小或移动矩形。
pygame.Rect.contains()测试一个矩形是否在另一个矩形内
pygame.Rect.collidepoint()测试点是否在矩形内
pygame.Rect.colliderect()测试两个矩形是否重叠

同时 Rect 对象也提供了一些关于矩形大小的常用的属性,如下所示:

x,y  表示矩形距离 x、y 轴的距离
top, left, bottom, right #在坐标系内描述矩形的大小
topleft, bottomleft, topright, bottomright #返回一个描述矩形大小的元组
midtop, midleft, midbottom, midright #返回一个描述矩形大小的元组
center, centerx, centery #(centerx,centery)表示矩形中央坐标(x,y)的值
size, width, height
w,h  #用于描述矩形的width、height

下面看一组简单的示例演示,如下所示:

import  pygame
# 对应left/top/width/height
rect1 = pygame.Rect(0,0,100,100)
print('x的值是{};y的值是{}'.format(rect1.x,rect1.y))
print('bottom的值是{};right的值是{}'.format(rect1.bottom,rect1.right))
# 设置居中的距离
print(rect1.center,rect1.centerx,rect1.centery)
# 返回值为 (centerx,top)
print(rect1.midtop)
# 返回值为 (right,centery)的元组
print(rect1.midright)
# 返回值为(left,bottom)
print(rect1.bottomleft)
# 返回矩形区域大小,元组格式
print(rect1.size)

输出结果如下:

x的值是0;y的值是0
bottom的值是100;right的值是100
#设置中心努力
(50, 50) 50 50
(50, 0)
#midright
(100, 50)
#bottomleft
(0, 100)
#size
(100, 100)

我们还可以通过属性对来设置,或者者更改矩形区域的大小,如下所示:

rect1.left = 30 
rect1.center = (70,70)

除了通过 Rect 对象来构造一个矩形区域之外,我们还可以使用rect属性来构建一个矩形区域。在 Pygame 中有许多函数都提供了rect属性,比如有下列函数:

surface.fill((0,0,255),rect=(100,100,100,50))

上述代码会在 surface 对象的区域内选定一个 rect 区域,并将该区域填充为蓝色(RGB(0,0,255))。

Pygame Event事件模块(详细示例)

事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢?

事件类型

Pygame 定义了一个专门用来处理事件的结构,即事件队列,该结构遵循遵循队列“先到先处理”的基本原则,通过事件队列,我们可以有序的、逐一的处理用户的操作(触发事件)。下述表格列出了 Pygame 中常用的游戏事件:

事件类型描述成员属性
QUIT用户按下窗口的关闭按钮none
ATIVEEVENTPygame被激活或者隐藏gain,state
KEYDOWN键盘按下unicode、key、mod
KEYUP键盘放开key、mod
MOUSEMOTION鼠标移动pos, rel, buttons
MOUSEBUTTONDOWN鼠标按下pos, button
MOUSEBUTTONUP鼠标放开pos, button
JOYAXISMOTION游戏手柄(Joystick or pad) 移动joy, axis, value
JOYBALLMOTION游戏球(Joy ball) 移动joy, axis, value
JOYHATMOTION游戏手柄(Joystick) 移动joy, axis, value
JOYBUTTONDOWN游戏手柄按下joy, button
JOYBUTTONUP游戏手柄放开joy, button
VIDEORESIZEPygame窗口缩放size, w, h
VIDEOEXPOSEPygame窗口部分公开(expose)none
USEREVENT触发一个用户事件事件代码

注意,当使用 Pygame 做游戏开发时,上述事件并非都会应用的到,因此在学习的过程中,我们要懂得触类旁通、举一反三。

事件处理方法

Pygame.event 模块提供了处理事件队列的常用方法,如下表所示:

方法说明
pygame.event.get()从事件队列中获取一个事件,并从队列中删除该事件
pygame.event.wait()阻塞直至事件发生才会继续执行,若没有事件发生将一直处于阻塞状态
pygame.event.set_blocked()控制哪些事件禁止进入队列,如果参数值为None,则表示禁止所有事件进入
pygame.event.set_allowed()控制哪些事件允许进入队列
pygame.event.pump()调用该方法后,Pygame 会自动处理事件队列
pygame.event.poll()会根据实际情形返回一个真实的事件,或者一个None
pygame.event.peek()检测某类型事件是否在队列中
pygame.event.clear()从队列中清除所有的事件
pygame.event.get_blocked()检测某一类型的事件是否被禁止进入队列
pygame.event.post()放置一个新的事件到队列中
pygame.event.Event()创建一个用户自定义的新事件

当我们使用 Pygame 处理事件时,逻辑一般都是相似的。首先是判断事件的类型,然后根据不同的事件操作,执行不同的游戏操作。因此这种情况非常适合使用 if … else 语句。如下所示:

while True:
    #等待事件发生
    event = pygame.event.wait()
    if event.type == pygame.QUIT:
        exit()
    if event.type == pygame.MOUSEBUTTONDOWN:
        print('鼠标按下',event.pos)
    if event.type == pygame.MOUSEBUTTONUP:
        print('鼠标弹起')
    if event.type == pygame.MOUSEMOTION:
        print('鼠标移动')
        # 键盘事件
    if event.type ==pygame.KEYDOWN:
        # 打印按键的英文字符
        print('键盘按下',chr(event.key))
    if event.type == pygame.KEYUP:
        print('键盘弹起')
    ....

下面应用上述方法对鼠标事件和键盘事件分别做简单的介绍。

处理键盘事件

键盘事件会涉及到大量的按键操作,比如游戏中的上下左右,或者人物的前进、后退等操作,这些都需要键盘来配合实现。

键盘事件提供了一个 key 属性,通过该属性可以获取键盘的按键。Pygame 将键盘上的字母键、数字键、组合键等按键以常量的方式进行了定义,下表列出了部分常用按键的常量:

常量名描述
K_BACKSPACE退格键(Backspace)
K_TAB制表键(Tab)
K_CLEAR清除键(Clear)
K_RETURN回车键(Enter)
K_PAUSE暂停键(Pause)
K_ESCAPE退出键(Escape)
K_SPACE空格键(Space)
K_0…K_90…9
K_a…Kza…z
K_DELETE删除键(delete)
K_KP0…K_KP90(小键盘)…9(小键盘)
K_F1…K_F15F1…F15
K_UP向上箭头(up arrow)
K_DOWN向下箭头(down arrow)
K_RIGHT向右箭头(right arrow)
K_LEFT向左箭头(left arrow)
KMOD_ALT同时按下Alt键

想要了解更多按键常量可参考官方文档,这里有您想要的更多知识 ———> 点击前往

下面通过“图片移动”示例来了解键盘事件的处理过程,如下所示:

import pygame
import sys
# 初始化pygame
pygame.init()
# 定义变量
size = width, height = 600, 400
bg = (255, 255, 255)
# 加载logo图
img = pygame.image.load("C:/Users/Administrator/Desktop/logo.jpg")
# 获取图像的位置
position = img.get_rect()
# 创建一个主窗口
screen = pygame.display.set_mode(size)
# 标题
pygame.display.set_caption("C语言中文网")
# 创建游戏主循环
while True:
    # 设置初始值
    site = [0, 0]
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        # 图像移动 KEYDOWN 键盘按下事件
        # 通过 key 属性对应按键
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                site[1] -= 8
            if event.key == pygame.K_DOWN:
                site[1] += 8
            if event.key == pygame.K_LEFT:
                site[0] -= 8
            if event.key == pygame.K_RIGHT:
                site[0] += 8
    # 移动图像
    position = position.move(site)
    # 填充背景
    screen.fill(bg)
    # 放置图片
    screen.blit(img, position)
    # 更新显示界面
    pygame.display.flip()

程序运行结果如下:

pygame event事件图像移动
图1:Pygame键盘事件——图像移动

处理鼠标事件

鼠标是计算机最重要外接设备之一,同时它也是游戏玩家必不可少的工具之一。

Pygame 提供了三个鼠标事件,分别是鼠标移动(MOUSEMOTION)、鼠标按下(MOUSEBUTTONDOWN)、鼠标释放(MOUSEBUTTONUP),不同事件类型对应着不同的成员属性。如下所示:

pygame.event.MOUSEMOTION鼠标移动事件

    event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
    event.rel 鼠标相对运动距离(X,Y),相对于上次事件
    event.buttons 鼠标按钮初始状态(0,0,0),分别对应(左键,滑轮,右键),移动过程中点击那个键,相应位置变会为1

pygame.event.MOUSEBUTTONUP鼠标键释放事件

    event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
    event.button 鼠标释放键编号(整数)左键为1,按下滚动轮2、右键为3

pygame.event.MOUSEBUTTONDOWN 鼠标键按下事件

    event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
    event.button 鼠标按下键编号(整数),左键为1,按下滚动轮2、右键为3,向前滚动滑轮4、向后滚动滑轮5

通过一组简单的示例对鼠标事件进行演示,示例代码如下:

import pygame
from random import randint
# 初始化程序
pygame.init()
screen = pygame.display.set_mode((450,400))
pygame.display.set_caption("c语言中文网")
# 更新显示
pygame.display.flip()
while True:
    #等待事件发生
    event = pygame.event.wait()
    if event.type == pygame.QUIT:
        exit("成功退出")
    if event.type == pygame.MOUSEBUTTONDOWN:
        # pos 获取鼠标当前位置
        print('鼠标按下',event.pos)
        mx,my = event.pos
        # 调用 pygame.draw 模块画圆
        pygame.draw.circle(screen,(255,255,0),(mx,my),50)
        # 处理完,更新显示
        pygame.display.update()
    if event.type == pygame.MOUSEBUTTONUP:
        print('鼠标弹起')
        pass
    if event.type == pygame.MOUSEMOTION:
        print('鼠标移动')
        mx, my = event.pos
        # 随机生成 RGB 颜色值
        r = randint(0,255)
        g = randint(0,255)
        b = randint(0,255)
        pygame.draw.circle(screen, (r,g,b,),(mx, my), 50)
        # 处理完,更新显示
        pygame.display.update()

程序运行结果如下:

pygame鼠标事件
图2:Pygame鼠标事件——鼠标移动

Pygame Draw绘图函数详解

Pygame 中提供了一个draw模块用来绘制一些简单的图形状,比如矩形、多边形、圆形、直线、弧线等。

pygame.draw模块的常用方法如下表所示:

方法说明
pygame.draw.rect()绘制矩形
pygame.draw.polygon()绘制多边形
pygame.draw.circle()根据圆心和半径绘制圆形
pygame.draw.ellipse()绘制一个椭圆形
pygame.draw.arc()绘制弧线(挥着椭圆的一部分)
pygame.draw.line()绘制线段(直线)
pygame.draw.lines()绘制多条连续的线段
pygame.draw.aaline()绘制一条平滑的线段(抗锯齿)
pygame.draw.aalines()绘制多条连续的线段

表格中的函数使用方法大同小异,它们都可以在 Surface 对象上绘制一些简单的形状,返回值是一个 Rect 对象,表示实际绘制图形的矩形区域。上述绘图函数都提供了一个 color 参数,我们可以通过以下三种方式来传递 color 参数值:

  • 使用 pygame.color 对象
  • RGB 三元组
  • RGBA 四元组

下面通对上述一些方法的参数进行详细说明:

1) 绘制矩形

绘制矩形的语法格式如下:

pygame.draw.rect(surface, color, rect, width)

参数说明如下:

  • surface:指主游戏窗口,无特殊情况,一般都会绘制在主屏幕上;
  • color:该参数用于该图形着色;
  • rect:绘制图形的位置和尺寸大小;
  • width:可选参数,指定边框的宽度,默认为 0,表示填充该矩形区域。

注意,当 width > 0 时,表示线框的宽度;而 width < 0 时,此时不会绘制任何图形。

2) 绘制多边形
pygame.draw.polygon(surface, color, points, width)

其中 points 一个列表参数,它表示组成多边形顶点的 3 或者多个 (x,y) 坐标,通过元组或者列表来表示这些多边形顶点。其余参数与上述函数相同。

3) 绘制圆形
pygame.circle(surface, color, pos, radius, width=0)

上述参数的含义如下:

  • pos:该参数用来指定的圆心位置;
  • radius:用来指定圆的半径;
4) 绘制椭圆形
pygame.draw.ellipse(surface, color, Rect, width=0)

绘制椭圆形的过程,其实就是在矩形区域内部(Rect)绘制一个内接椭圆形,其余参数与上述参数意思相同。

5) 绘制圆弧曲线

当需要绘制圆弧的曲线时,使用以下函数,语法格式如下:

pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1)

与 ellipse 函数相比,该函数多了两个参数:

  • start_angle是该段圆弧的起始角度;
  • stop_angle是终止角度;

这两个都是用弧度制来表示的,而原点就是矩形 Rect 的中心位置。

6) 绘制直线

Draw 模块提供了两类绘制直线的方法,即是否消除直线的锯齿,并且根据实际情况,我们还可以选择绘制一条或者多条直线。

pygame.draw.line(surface, color, start_pos, end_pos, width=1)

参数说明:

  • start_pos 和 end_pos 表示线段的起始位置,此处使用 [x,y] 来表示起始位置;
  • width =1 表示直线的宽度,默认为 1。

如果是绘制一条消除锯齿的平滑线,此时则使用 blend = 1 参数,如下所示:

pygame.aaline(surface, color, startpos, endpos, blend=1) 

blend 参数表示通过绘制混合背景的阴影来实现抗锯齿功能。

7) 绘制多条直接

当需要绘制多条直线的时候,我们可以使用以下方法:

pygame.lines(surface, color, closed, pointlist, width=1)

其中 pointlist 与 closed 含义如下:

  • pointlist:参数值为列表,包含了一些列点坐标的列表
  • closed:布尔值参数,如果设置为 True,表示直线的第一个端点和直线的最后一个端点要首尾相连;

如果绘制抗锯齿直线,使用以下方法:

pygame.draw.aalines(surface, color, closed, pointlist, blend=1)

除了指定了 blend = 1 之外,其余参数含义与上述函数相同。

下面通过一组简单的示例对上述绘图方法进行演示:

import pygame
from math import pi


![img](https://img-blog.csdnimg.cn/img_convert/bd2565b749a17125bed0767c57c3b06c.png)
![img](https://img-blog.csdnimg.cn/img_convert/042316432f69c4792478778d62e19c20.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

``
pygame.draw.line(surface, color, start_pos, end_pos, width=1)

参数说明:

  • start_pos 和 end_pos 表示线段的起始位置,此处使用 [x,y] 来表示起始位置;
  • width =1 表示直线的宽度,默认为 1。

如果是绘制一条消除锯齿的平滑线,此时则使用 blend = 1 参数,如下所示:

pygame.aaline(surface, color, startpos, endpos, blend=1) 

blend 参数表示通过绘制混合背景的阴影来实现抗锯齿功能。

7) 绘制多条直接

当需要绘制多条直线的时候,我们可以使用以下方法:

pygame.lines(surface, color, closed, pointlist, width=1)

其中 pointlist 与 closed 含义如下:

  • pointlist:参数值为列表,包含了一些列点坐标的列表
  • closed:布尔值参数,如果设置为 True,表示直线的第一个端点和直线的最后一个端点要首尾相连;

如果绘制抗锯齿直线,使用以下方法:

pygame.draw.aalines(surface, color, closed, pointlist, blend=1)

除了指定了 blend = 1 之外,其余参数含义与上述函数相同。

下面通过一组简单的示例对上述绘图方法进行演示:

import pygame
from math import pi


[外链图片转存中...(img-Q0z1ULgd-1715718916632)]
[外链图片转存中...(img-4PIUvzJm-1715718916633)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值