Python游戏开发(二)
2021/5/5 20:28:41
本文主要是介绍Python游戏开发(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
pygame屏幕与事件
pygame屏幕绘制机制
指的是控制游戏的屏幕变化的机制。
pygame绘制机制简介
使用pygame.display来控制游戏的屏幕,在pygame游戏中只有一个屏幕,只有关闭一个屏幕才能使用另一个屏幕。
屏幕使用的是笛卡尔坐标系。左上角为(0,0 )。
通常而言,屏幕控制都有以下的若干需求:
- 游戏全屏
- 游戏屏幕大小可调节
- 游戏屏幕无边框
- 更改游戏标题栏内容
- 更改游戏图标
pygame提供了三组屏幕控制的函数:
- 屏幕模式和尺寸的控制
pygame.display.set_mode() 设置屏幕的相关模式
pygame.display.info() 生成屏幕的信息 - 窗口标题和图标
pygame.display.set_caption() 设置标题信息
pygame.display.set_icon() 设置图标信息
pygame.display.get_caption() 获得图标 - 窗口感知和刷新
pygame.display.get_active()
pygame.display.flip()
pygame.display.update()
pygame甚至还支持openGL和硬件加速,但一般来说不会用到。
pygame游戏屏幕尺寸和模式设置
- pygame.display.set_mode( r=(0, 0), flags = 0)
r 是屏幕游戏的分辨率,采用(width,height)的方式输入
flags用来控制显示类型,可以通过 “|” 组合使用,常用标记如下:
标记 | 说明 |
---|---|
pygame.RESIZABLE | 窗口大小可调 |
pygame.NOFRAME | 窗口无边框 |
pygame.FULLSCREEN | 窗口全屏 |
对于pygame.RESIZABLE可能出现窗口扩大而游戏图像仍局限在原本大小的情况;
对于pygame.NOFRAMW可能出现没有退出键,无法退出的情况;
对于pyagme.FULLSCREEN可能出现屏幕分辨率不协调的情况。
-
pygame.display.Info()
这个函数用来产生一个VideoInfo对象,这个对象用来存储当前的屏幕参数信息。
如果在set_mode()之前调用,则显示当前系统的参数。
其中有两个重要的参数:
.current_w:游戏窗体的宽
.current_h:游戏窗体的高 -
如果窗口大小改变:
会产生一个pygame.VIDEORESIZE,通过event.size元组返回了新的窗口的大小。
可以用event.size[0], event.size[1]分别获得改变后的窗口大小
pygame的窗口标题和图标设置
-
pygame.set_caption(title, icontitle=NONE)
title设置窗口标题
icontitle设置窗口图标标题,有些系统不支持这一设置所以一般不设置。 -
pygame.get_caption()
返回一个元组类型,其中第一个元素为title第二个元素为icontitle。
该函数可以增加游戏情节,通过交互是的游戏的标题发生变化。 -
pygame.set_icon(surface)
surface对象即之前获取小球图像的图标的对象。
可以设置图标。
注意需要在屏幕创建前设置好。
pygame窗口感知和刷新功能
-
pygame.display.get_active()
当窗口在系统中未被图标化(最小化到状态栏)则返回True,反之则返回False。
通过感应游戏是否被最小化来改变游戏的逻辑。 -
pygame.display.flip()
会将整个窗口重新绘制 -
pygame.display.update()
只重绘窗口中有变化的部分。
pygame事件处理机制
在游戏中,事件的处理是很重要的,它能响应用户的输入。
能够操作键盘以及鼠标等各种外设。
pygame事件处理机制
游戏响应外部的输入(如鼠标、键盘等等),以及在游戏运行中,一些情节的触发也可以通过事件系统进行实现。游戏本身也可以产生一些事件来实现游戏剧情的推进。
逻辑上,pygame有一个叫事件队列的结构,可以缓存pygame接受的所有事件,之后逐一取出事件来操作。
本质上数据是一种数据结构,pygame.even.EventType只有属性,没有方法。
用户也可以定义新的事件类型。
pygame主要包含六大类事件:鼠标、键盘、游戏手柄、系统、窗口以及用户定义事件。
pygame还有事件处理机制来对事件队列进行规范处理。
pygame键盘事件类型与使用
pygame支持两种键盘事件,分别是键盘按下事件pygame.event.KEYDOWN和键盘释放事件pygame.event.KEYUP(只在按下的情况下会触发)。
- 当键盘按下时事件会返回三个属性:
event..key 键盘值
event.unicode 键盘值对应的unicode但是可能会随系统而变化。
event.mod 按键修饰符组合值 - 而键盘释放事件不返回unicode属性。
- 按键的常量名称
基本上就是pygame.K_a...也即下划线后跟按键名称。
注意字母是小写的,大写字母的输入需要通过按键修饰符来实现。 - 按键的修饰符
修饰符:按键事件发生时,除了按键以外,其他修饰符按键的状态。
event.mod是一个按键修饰符的或运算组合值。
例如:KMOD_LSHIFT, KMOD_LCTRL, KMOD_LALT...
event.mod = KMOD_LSHIFT | KMOD_LALT
鼠标事件以及类型的基本使用
- pygame.event.MOUSEMOTION
该事件表示鼠标移动,只要鼠标在移动就会产生这个事件。
总共有三个返回值
event.pos 返回(X,Y)即鼠标此时的位置,相对于源点即左上角
event.rel 返回(X,Y)即鼠标相对于上一个事件运动的距离
event.buttons 返回(a, b, c)即鼠标此时三个键的状态。如果鼠标处于按下状态对应位置值为1,否则为0 - pygame.event.MOUSEBUTTONUP
该事件表示鼠标的键释放的事件。
共有两个返回值
event.pos
event.button 返回表示鼠标释放键的编号,左键为1,右键为3。 - pygame.event.MOUSEBUTTONDOWN
event.pos
event.button
壁球小游戏鼠标型
通过鼠标左键拜访壁球;
按下鼠标左键时,壁球随鼠标移动,释放鼠标时,壁球自己移动。
import sys, pygame pygame.init() size = width, height = (600, 400) speed = [1, 1] black = 0, 0, 0 fps = 300 still = False icon = pygame.image.load("滑稽球1.jpg") pygame.display.set_icon(icon) screen = pygame.display.set_mode(size) pygame.display.set_caption("壁球小游戏鼠标版") ball = pygame.image.load("滑稽球1.jpg") ballrect = ball.get_rect() fclock = pygame.time.Clock() while True: 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] - 1 elif event.key == pygame.K_UP: speed[1] = speed[1] + 1 if speed[1] > 0 else speed[1] - 1 elif 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.MOUSEBUTTONDOWN: if event.button == 1: still = True elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: still = False ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top) elif event.type == pygame.MOUSEMOTION: if event.buttons[0] == 1: ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top) if ballrect.left < 0 or ballrect.right > width: speed[0] = -speed[0] if ballrect.right > width and ballrect.right + speed[0] > ballrect.right: # 因为对于鼠标的控制而言,我们是设置的鼠标位置为矩形框的左上角,所以只考虑右下方突破边界的情况 speed[0] = -speed[0] elif ballrect.top < 0 or ballrect.bottom > height: speed[1] = -speed[1] if ballrect.bottom > height and ballrect.bottom + speed[1] > ballrect.bottom: speed[1] = -speed[1] if pygame.display.get_active(): if not still: ballrect = ballrect.move(speed[0], speed[1]) screen.fill(black) screen.blit(ball, ballrect) pygame.display.update() fclock.tick(fps)
但是可以注意到:小球移动到下边缘和右边缘(鼠标对应的时ballrect对象的左上角),则小球无法成功反弹,因为当小球处在边缘时会频繁取反,导致小球无法逃离边缘。当引入鼠标处理时,鼠标具有灵活性,要有对应的处理机制。
pygame事件处理函数
- 处理事件函数
(1) pygame.event.get()
用于从事件队列中获取一系列事件并删除,其中,同时也可以添加类型参数,用于获取某一类或者某些类的函数:pygame.event.get(type/typelist)
(2)pygame.event.poll()
用于从事件队列中获取一个事件,获取完即删除。
若事件队列为空,则返回:event.NOEVENT事件。
(3)pygame.event.clear()
类似于get()函数,只是区别于get函数它并不对事件进行处理,只是对时间进行删除。
同时可以增加参数,用于删除某一类或某些类的事件:
pygame.event.clear(type)
pygame.event.clear(typelist)
队列只能储存128个事件,一旦超过了队列存储的容量,新的事件只会被丢弃掉,所以一定要进行处理或者清除,同时做好事件队列的管理也非常重要 - 事件队列操作函数
(1)pygame.event.set_blocked(type or typelist)
用于设置哪个或哪些事件类型不允许进入事件队列。
(2)pygame.event.set_allowed(type or typelist)
用于设置哪个或哪些事件类型允许进入事件队列
(3)pygame.event.get_blocked(type)
用于判断某个事件类型是否被事件队列禁止,是返回True,否则False - 生成事件函数
可以用于生成事件并将产生的事件放到事件队列中。
(1)pygame.event.post(Event)
产生一个事件,并将其放入事件队列之中;
一般用于产生用户自定义类型的事件(event.USEREVENT)
也可用于放置系统事件,如鼠标/键盘相关事件,给定参数
(2)pygame.event.Event(type, dict)
创建一个给定类型的事件;
事件的属性用字典类型的键值对模式来表示;
如果创建的是已有类型的事件,需要保证属性一致。
import sys, pygame pygame.init() size = width, height = (600, 400) screen = pygame.display.set_mode(size) fps = 1 num = 1 fclock = pygame.time.Clock() while True: uevent = pygame.event.Event(pygame.KEYDOWN, {"unicode": "123", "key":pygame.K_SPACE, "mod":pygame.KMOD_ALT}) pygame.event.post(uevent) num = num + 1 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.unicode == "": print("[KEYDOWN {}]".format(num), "#", event.key, event.mod) else: print("[KEYDOWN {}]".format(num), event.unicode, event.key, event.mod) pygame.display.update() fclock.tick(fps)
以上内容来自北京理工大学嵩天老师及其团队的《Python游戏开发入门》课程第三周的内容。
非常感谢嵩天老师及其团队给我们带来这样优质的课程。
这篇关于Python游戏开发(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-03用FastAPI掌握Python异步IO:轻松实现高并发网络请求处理
- 2025-01-02封装学习:Python面向对象编程基础教程
- 2024-12-28Python编程基础教程
- 2024-12-27Python编程入门指南
- 2024-12-27Python编程基础
- 2024-12-27Python编程基础教程
- 2024-12-27Python编程基础指南
- 2024-12-24Python编程入门指南
- 2024-12-24Python编程基础入门
- 2024-12-24Python编程基础:变量与数据类型