欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Pygame:事件

程序员文章站 2022-07-13 08:29:20
...

????大家好!我是近视的脚踏实地,虽然近视,但是脚踏实地,这一篇来谈谈Pygame的事件。

事件的概念

从上一篇的例子可以看到,其实游戏就是一个死循环,如果我们不去干预他的话,他就一直自己玩得不亦说乎,而事件就是Pygame 提供给我们去干预它的机制,比如我们点击关闭游戏的窗口,就会产生QUIT事件,而处理quit事件的方法就是调用sys.exit() 来退出整个程序。

事件随时都可能发生,比如说你在窗口上边移动鼠标,点击鼠标,或者敲击键盘的按键,这些都会产生事件并且信息量是非常大的,Pygame 的做法就是将这所有产生的事件都放在一个叫做事件队列里,然后我们通过for语句去迭代取出每一个事件,对我们关注的事件进行处理就好了,不关注就忽略它,不管它,拿出来扔掉,拿出来扔掉。

※写一个代码将程序运行过程中产生的所有事件记录到文件中

import pygame
import sys

# 初始化Pygame
pygame.init()

size = width, height = 600, 400

# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")

f = open("record.text","w")


while True:
    for event in pygame.event.get():
        f.write(str(event)+ '\n')
         
        if event.type == pygame.QUIT:
            f.close()
            sys.exit()

Pygame:事件
(解析:f = open(“record.text”,“w”)就是以写的方式打开文件,文件名叫record,然后在迭代事件队列时,把他们写入到文件中,最后要记得关闭文件,位置就是就是当我们点击关闭程序的时候,触发了处理QUIT事件的方法,退出程序之前就把文件关闭,因为write是写到内存的缓冲区中,他还没有写入到硬盘,那么调用f.close的时候才会写入到硬盘,数据才不会丢失

当运行后就是一块黑屏,然后在上面随便滚动一下鼠标,然后在键盘上敲击字母,关闭窗口后,在这个源文件的当前文件夹下就会record文件,打开如上图,挺多的,虽然说没有操作什么事情,但是也产生了非常多的事件了,每一行就是一个事件们可以看到,最多的就是MouseMotion,鼠标移动事件,因为你鼠标在上面晃荡一下,他就产生若干条事件,

可以看到MouseMion后面的buttons,后边其实就是个字典,而buttons后面的(0,0,0,)就是表示False,False,False,表示左键,中间键,右键没有被点下,如pos就是他在窗口中的位置,

然后其实下面还有KeyDown事件,这里没截取到,这个就是表示按下键盘按键,KeyUp就表示释放键盘按键)

※使用到 font 模块的 render() 方法将事件打印到屏幕

如果希望将这些事件显示在 屏幕上,这就涉及到要在屏幕上显示文本的功能,或者说要求我们在Surface对象上面打印文字,但是Pygame并没有直接在一个Surface对象上边绘制你想要的文字。

但是Pygame 也提供了可以达到同样效果的途径,我们使用 font字体模块里边的 render() 渲染方法就可以了,render() 方法就是将显示的文字活生生的渲染成一个 Surface 对象,这样你就可以调用 blit() 方法将一个 Surface 对象复制到另一个Surface 上面。

import pygame
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
 
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Python Demo")
bg = (0, 0 , 0)
 
position = 0
#实例化Font对象
font = pygame.font.Font(None, 20)
line_height = font.get_linesize()
 
screen.fill(bg) #背景画布填充为黑色
 
while True:
    for event in pygame.event.get():  #迭代每一个事件
        if event.type == pygame.QUIT:            
            sys.exit()
 
        screen.blit(font.render(str(event), True, (0, 255, 0)), (0, position))
        position += line_height
 
        if position > height:
            position = 0
            screen.fill(bg)
 
    pygame.display.flip()

Pygame:事件
(解析:bg = (0, 0 , 0)这里先设置了一个背景色颜色,都是0那么就是黑色,接着font = pygame.font.Font(None, 20)就是实例化Font对象,第一个参数是font的字体,这里填None默认,20是他的尺寸,然后就得到一个font对象。

接着先把屏幕刷成黑色screen.fill(bg) #背景画布填充为黑色,然后就可以调用render方法将文本渲染成一个Surface对象,font.render(str(event), True, (0, 255, 0)),他的第一个参数是要渲染的文本,那就获得的事件,先把他变成字符串,第二个参数是否消除锯齿,我们知道如果文字放大的话会发现有马赛克的一个脚,设置为True他会自动消除锯齿,第三个参数就是设置他的字体的颜色,绿色就(0,255,0),然后这里调用screen的blit方法把渲染好的文本,渲染好就是Surface对象了,那就把这个Surface对象放到这个screen的Surface对象上面去,

screen.blit(font.render(str(event), True, (0, 255, 0)), (0, position))然后后面再加上一个位置,位置是从左侧打印过去,那就说x值永远是从0开始,y值要设置一个变量来存放position,这个变量在前面初始化就好了,position = 0,那么就是从第0行开,每打印一行,那么我们就再往下走一行,那就要知道一行是多高,所以再加个line_height = font.get_linesize(),就可以获取行高了,

因此我们显示完了行高,在循环中位置就显示到下一行就好了, position += line_height,然后就是如果position大于了高度if position > height:,就来清屏,屏幕清掉,重新来,先刷成黑色,最后再调用display.flip()把页面来更新一下

运行后当鼠标在里边移动就会打印鼠标移动事件,当按下键盘上的字母和松开时都会打印出相应的事件,并且超过了画布大小就会清屏,然后从头开始再来,)

Pygame常用的事件及含义

(这个表列列举了所有pygame比较常用的事件含义)
Pygame:事件
列举一个MOUSEMOTION,鼠标移动事件,他有三个属性,pos:表示当前的坐标,以像素为单位,rel:距离上一个位置的相对距离,x相差多少,y相差多少,button是一个三元组,表示你按下了哪个按钮,分别是左键,中键,右键,按下了哪一个,哪一个就为True即1。

MOUSEBUTTONDOWN 和 MOUSETTONUP和上面那个也是一样的,只是少了个rel而已,然后还有KEYDOWN 和 KEYUP

※使用keyDOWN等事件来完成控制老污龟的移动方向

要想让老污龟受控,那就不止要关注QUIT事件了,还要关注KEYDOWN,表示键盘被按下,下面将第一篇的代码改造一下

import pygame
import sys
from pygame.locals import *

# 初始化Pygame
pygame.init()

size = width, height = 600, 400
speed = [-2, 1]
bg = (255, 255, 255) # RGB

#实例化Clock对象
clock = pygame.time.Clock()

# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")

# 加载图片 Surface
turtle = pygame.image.load("turtle.png")
# 获得图像的位置矩形
position = turtle.get_rect()

l_head = turtle
r_head = pygame.transform.flip(turtle, True, False)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                 turtle = l_head
                 speed = [-1,0]
            if event.key == K_RIGHT:
                 turtle = r_head
                 speed = [1,0]
            if event.key == K_UP:
                 speed = [0,-1]
            if event.key == K_DOWN:
                 speed = [0,1]
                 
                    

    # 移动图像
    position = position.move(speed)

    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False)
        # 反方向移动
        speed[0] = -speed[0]

    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]

    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    
    clock.tick(200)

Pygame:事件

(解析:首先就是在迭代中增加对KEYDOWN事件的响应,if event.key == K_LEFT 表示的是按下键盘上的方向键的左键,K_a 表示按下键盘的字母a,K_b表示字母b,这里就是说,如果有检索到方向左键被按下了,就把speed(他的方向速度)更改为[-1,0]表示水平往左,后面的类似,改为向右,向上,向下,最后,from pygame.locals import *把所有的常量名都导入,就是刚刚LEFT,KEYDOWN啊,这样就不会在前面加前置pygame了,即pygame.KEYDOWN直接写成KEYDOWN就OK 了

这样的话,按下左右的时候他不会自己调头,所以还需要改进,先在循环外面多加两个变量l_head = turtle,这个表示向左转,刚开始进入的时候就默认是向左边了,所以给turtle就好了,然后再来个r_head = pygame.transform.flip(turtle, True, False)向右的,调用图片翻转的方法就好了,接着在if判断里边,如果是按了向左,就turtle = l_head,向右就turtle = r_head接可以了)

本篇博客到这就完啦,非常感谢您的阅读????,如果对您有帮助,可以帮忙点个赞或者来波关注鼓励一下喔???? ,嘿嘿????

相关标签: Python