<电子幽灵>Pygame入门笔记

Pygame入门笔记

介绍

费曼学习法最重要的部分,即把知识教给一个完全不懂的孩子——或者小白。
为了更好的自我学习,也为了让第一次接触某个知识范畴的同学快速入门,我会把我的学习笔记整理成电子幽灵系列。
提示:文章的是以解释-代码块-解释的结构呈现的。当你看到代码块并准备复制复现的时候,最好先保证自己看过了代码块前后的解释。

Pygame介绍

Pygame是用来做页面游戏的一个开源Python库。通过Pygame可以很方便地制作出一个交互界面,进而创作页面游戏。

官方Github:https://github.com/pygame

官方文档:https://www.pygame.org/docs/

本文档内容总结自Pygame官方文档及其中译版本、BiliBili相关教程

下载

  1. 下载:python3 -m pip install -U pygame --user
    最新版本:python -m pip install -U pygame==2.5.2 --user

常用模块

模块一览
模块名称模块功能
cdrom播放/回放
cursors加载光标图像,包括标准指针
Color填充颜色
display控制显示窗口或屏幕
draw在Surface对象上绘制简单的形状、线或点
event管理事件和事件队列
fontcreate和render TrueType字体
image保存和加载图像
joystick管理操纵杆设备
key管理键盘
mixer管理声音
mouse管理鼠标
movie播放视频
music播放音频
overlay访问高级视频叠加
rect管理矩形区域
scrap本地剪切板访问
sndarray用numpy操纵声音
sprite操纵移动图像sprite(精灵)
surfarray用numpy操纵图像
surface管理图像和屏幕
time控制时间
transform缩放,旋转和翻转图像
#导入、初始化、退出
import pygame as pg
pg.init()#初始化pygame界面
pg.get_init()#如果已经初始化,返回True
pg.quit()#退出pygame界面

虽然我比较习惯于把pygame缩写成pg,但是并没有发现其他人有这个习惯…

'''以下是官网的例子'''
# Example file showing a basic pygame "game loop"
import pygame

# pygame setup
pygame.init()
screen = pygame.display.set_mode((1280, 720))
clock = pygame.time.Clock()

while 1:
    # poll for events
    # pygame.QUIT event means the user clicked X to close your window
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # fill the screen with a color to wipe away anything from last frame
    screen.fill("purple")

    # RENDER YOUR GAME HERE

    # flip() the display to put your work on screen
    pygame.display.flip()

    clock.tick(60)  # limits FPS to 60
某些需要注意的点
  1. blit(我也忘记我为什么要写这个?)
    BLIT意味着把一个图像复制到另一个图像(相当于图层覆盖)
    (更正式的定义是将 数据数组 复制到 位映射数组 (bitmapped array)的目的地)
    具体细节就是为目标图像上的像素点重新赋值。
  2. 屏幕坐标
    pygame的坐标轴是以左上角为原点的,以向右和向下为X、Y正方向。
  3. 特殊数据结构:Rect
    在pygame中有一个特殊的容器,叫做Rect。它是一个包含四个数的元组,结构是(左、上、宽、高)。前两个数字确定Rectangle的左上角,后两个确定它的宽和高。
    pygame中很多函数都需要且接受Rect参数,传入即可。比如blit函数就可以接受一个Rect参数,但是只使用前两个参数作为图像的左上角。因此可以只输入一个二元/三元组作为Rect容器的一部分。
常用模块&常用函数(本笔记后来要用到的部分)
display模块
'''display模块常用函数'''
from pygame import display
display.init()
display.get_init()
''''''
screen=display.set_mode((680,720))#输入一个二元组,初始化一个相应长宽的界面
#这个页面可以赋值给一个对象,使得我们能够在之后面向他编程
print(screen)
surface=display.get_surface()#获取当前surface对象
print(surface)
display.flip()#更新并在屏幕上显示当前的surface对象
#display.update(rectangle=None)#更新部分内容并在屏幕上显示。如果参数为空(rectangle=None),则与flip功能相同
'''update函数可以传递一个rectangle_list,可以同时传递多个rect参数,效率更高'''
display.quit()

输出:

<Surface(680x720x32 SW)>
<Surface(680x720x32 SW)>
draw 模块
'''draw模块常用函数'''
import pygame as pg
from pygame import draw
color=(255,255,255)
width=8#注意,如果这里width为0,绘制的图形就是实心的
'''画一条线,参数顺序为:哪个Surface对象、颜色、起始坐标、终点坐标、宽度(像素级)'''
draw.line(screen, color, (35, 35), (135, 135), width)
'''画一个圆,参数顺序为:哪个Surface对象、颜色、圆心坐标、半径、边缘宽度(像素级)'''
draw.circle(screen,color,(200,200),30,width)
'''画一个长方形,参数顺序为:哪个Surface对象、颜色、Rect容器、边缘宽度(像素级)'''
draw.rect(screen, color, (500, 100, 40, 80), width)
'''画一个椭圆,参数顺序为:哪个Surface对象、颜色、Rect容器、边缘宽度(像素级)'''
draw.ellipse(screen, color, (600,300,100,50),width)
key模块
'''key模块常用函数'''
import pygame
from pygame import key
'''返回一个按键布尔列表,哪个键被按下了,相应的按键就会变为True'''
pressed=key.get_pressed()
'''返回一个按键布尔字典,如果相应的键被按下,就会返回True'''
keys=key.get_key_pressed()
'''设置一个重复事件,参数顺序为:按键后多少ms后开始重复、每次重复间隔多少ms'''
key.set_repeat(1000,10)
key.set_repeat(None)#参数为None将禁用重复。
'''返回当前键盘重复事件的延迟时间和间隔时间,以毫秒为单位。'''
delay, interval = pygame.key.get_repeat()
print(delay, interval)  # 输出当前的延迟时间和间隔时间
'''返回给定按键名称'''
key_name = key.name(pygame.K_LEFT)
print(key_name)  # 输出:LEFT
'''返回给定修饰键的状态。
修饰键:Shift、Ctrl、Alt'''
mod=key.get_mods()
'''设置当前按下的修饰键的状态。
可以将修饰键的组合作为参数传递给该函数,以设置修饰键的状态。'''
key.set_mods(pygame.KMOD_SHIFT | pygame.KMOD_CTRL)#这里是同时按下Shift和Ctrl

上述模块和函数已经足以完成一些基础控制了。接下来,我们要用这些函数实现一些功能。

基础控制

接下来将用pygame中的各种库函数完成一系列基础控制。比如创建一个窗口、给这个窗口涂一些颜色,可以移动窗口中的某些图像等等。

创建窗口
'''ver0.1'''
import pygame as pg
pg.init()
pg.display.set_mode()

问题:

  1. 窗口最大化全屏,无法进行其他操作
  2. 窗口只会闪一下,之后无法再响应
'''ver0.2'''
import pygame as pg
pg.init()
size=wideth,length=(360,240)#size会自动转化为元组
pg.display.set_mode(size)
while 1:
    continue

ver0.2解决了0.1的问题,
但是由于此处为死循环,没有退出条件,所以程序会一直进行下去,关闭窗口时,就会出现"无法响应"的类似报错的问题。

'''ver0.3'''
import pygame as pg
pg.init()
size=width,length=720,680
pg.display.set_mode(size)
while 1:
    for event in pg.event.get():#遍历所有事件
        if event.type==pg.QUIT:#如果点击了关闭窗口按钮  
            pg.quit()#执行退出操作

至此,解决了0.2的问题,构成了一个相对完整、健全的页面。

为窗口涂色

在这里,我们用上面“创建窗口”中已经有的基础,继续更高级的控制。

import pygame as pg
pg.init()
screen=pg.display.set_mode((1280,720))
print(screen)
'''pygame.display.set_mode会产生一个图像表面(surface)对象screen,构成screen页面上的每一个像素都有自己的颜色。
每一个像素的颜色color是一个三元整数组,范围是0~255。
用fill函数可以让整个页面现实一种颜色(由参数决定)'''
color=(123,0,0)
screen.fill(color)
pg.display.flip()
running = True
while 1:
    for event in pg.event.get():#遍历所有事件
        if event.type==pg.QUIT:#如果点击了关闭窗口按钮  
            running = False#执行退出操作
print(screen)
pg.quit()

输出:

< Surface(1280x720x32 SW) >

代表screen是一个图像表面对象(surface),分辨率为1280x720个像素,用32位存储每个像素的颜色,SW代表用软件渲染。(相对的,HW代表硬件渲染)

pygame中也可以自己直接创建一个Surface对象而不直接显示到窗口中,就是pg.surface()。

现在我们要改变窗口中一个像素点的颜色。

  • set_at()方法

Surface对象的set_at方法可以将某个像素点变为我们想要的颜色。

用法:set_at(坐标位置,颜色)

坐标位置是一个二元组(Rect前两位),颜色可以是三元组(R,G,B),也可以是四元组(R,G,B,A)。

import pygame as pg
pg.init()
screen=pg.display.set_mode((1280,720))
color=(123,0,0)
screen.fill(color)
screen.set_at((640,360),(255,255,255))#把某个像素变为某个颜色
pg.display.flip()
running=True
while running:
    for event in pg.event.get():#遍历所有事件
        if event.type==pg.QUIT:#如果点击了关闭窗口按钮  
            running=False#执行退出操作
pg.quit()
移动简单图像

移动一个已经被加载进来的图片显然简单很多,但是移动画出的图形可以和上面的操作连接起来。

  • 注:在操作的时候如果打开输入法,会在输入字母的时候隐藏地唤起输入法,输入法会阻碍界面捕捉按键状态。如果打开输入法后敲击字母按键后无法移动,按下Enter即可脱离卡死。
    接下来,画一个实心圆,并且用方向键使它移动。
'''version 1.0'''
import pygame as pg
pg.init()
color = (255,255,255)
size = wideth,length = (1280,640)
circle = {
    'center' : (640,320),
    'radius' : 50,
    'color' : color
}
screen = pg.display.set_mode(size)
running = True
while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
    keys = pg.key.get_pressed()
    if keys[pg.K_LEFT] :
        circle['center'] = (circle['center'][0] - 1, circle['center'][1])
    elif keys[pg.K_RIGHT] :
        circle['center'] = (circle['center'][0] + 1, circle['center'][1])
    elif keys[pg.K_UP] :
        circle['center'] = (circle['center'][0], circle['center'][1] - 1)
    elif keys[pg.K_DOWN] :
        circle['center'] = (circle['center'][0], circle['center'][1] + 1)
    screen.fill('black')
    pg.draw.circle(screen,circle['color'],circle['center'],circle['radius'],width = 0)
    pg.display.flip()

pg.quit()

ver1.0中,利用pygame.key模块,可以通过操控上下左右键控制圆的移动。

但是,圆会超出边框,所以接下来给圆加上边框,让它不会超出边框。

'''version 2.0'''
import pygame as pg
pg.init()
color = (255,255,255)
size = wideth,length = (1280,640)
circle = {
    'center' : (640,320),
    'radius' : 50,
    'color' : color
}
#clock = pg.time.Clock()
screen = pg.display.set_mode(size)
running = True
while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
    keys = pg.key.get_pressed()
    if keys[pg.K_LEFT] & (circle['center'][0] - circle['radius'] > 0) :
        circle['center'] = (circle['center'][0] - 1, circle['center'][1])
    elif keys[pg.K_RIGHT] & (circle['center'][0] + circle['radius'] < wideth) :
        circle['center'] = (circle['center'][0] + 1, circle['center'][1])
    elif keys[pg.K_UP] & (circle['center'][1] - circle['radius'] > 0) :
        circle['center'] = (circle['center'][0], circle['center'][1] - 1)
    elif keys[pg.K_DOWN] & (circle['center'][1] + circle['radius'] < length) :
        circle['center'] = (circle['center'][0], circle['center'][1] + 1)
    screen.fill('black')
    pg.draw.circle(screen,circle['color'],circle['center'],circle['radius'],width = 0)
    pg.display.flip()
    #clock.tick(60)
pg.quit()

ver2.0中,圆不会再超出边框了。至此,我们完成了一个相对结构化的小程序;尽管他只是让我们可以移动一个圆,但也是好的开始。

日志
  • 动笔:2024/5/1
  • 第一稿结束:2024/5/8
  • 第二稿更改:2024/5/9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

靈镌sama

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值