指的是控制游戏的屏幕变化的机制。
使用pygame.display来控制游戏的屏幕,在pygame游戏中只有一个屏幕,只有关闭一个屏幕才能使用另一个屏幕。
屏幕使用的是笛卡尔坐标系。左上角为(0,0 )。
通常而言,屏幕控制都有以下的若干需求:
pygame提供了三组屏幕控制的函数:
pygame甚至还支持openGL和硬件加速,但一般来说不会用到。
标记 | 说明 |
---|---|
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.set_caption(title, icontitle=NONE)
title设置窗口标题
icontitle设置窗口图标标题,有些系统不支持这一设置所以一般不设置。
pygame.get_caption()
返回一个元组类型,其中第一个元素为title第二个元素为icontitle。
该函数可以增加游戏情节,通过交互是的游戏的标题发生变化。
pygame.set_icon(surface)
surface对象即之前获取小球图像的图标的对象。
可以设置图标。
注意需要在屏幕创建前设置好。
pygame.display.get_active()
当窗口在系统中未被图标化(最小化到状态栏)则返回True,反之则返回False。
通过感应游戏是否被最小化来改变游戏的逻辑。
pygame.display.flip()
会将整个窗口重新绘制
pygame.display.update()
只重绘窗口中有变化的部分。
在游戏中,事件的处理是很重要的,它能响应用户的输入。
能够操作键盘以及鼠标等各种外设。
游戏响应外部的输入(如鼠标、键盘等等),以及在游戏运行中,一些情节的触发也可以通过事件系统进行实现。游戏本身也可以产生一些事件来实现游戏剧情的推进。
逻辑上,pygame有一个叫事件队列的结构,可以缓存pygame接受的所有事件,之后逐一取出事件来操作。
本质上数据是一种数据结构,pygame.even.EventType只有属性,没有方法。
用户也可以定义新的事件类型。
pygame主要包含六大类事件:鼠标、键盘、游戏手柄、系统、窗口以及用户定义事件。
pygame还有事件处理机制来对事件队列进行规范处理。
pygame支持两种键盘事件,分别是键盘按下事件pygame.event.KEYDOWN和键盘释放事件pygame.event.KEYUP(只在按下的情况下会触发)。
通过鼠标左键拜访壁球;
按下鼠标左键时,壁球随鼠标移动,释放鼠标时,壁球自己移动。
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对象的左上角),则小球无法成功反弹,因为当小球处在边缘时会频繁取反,导致小球无法逃离边缘。当引入鼠标处理时,鼠标具有灵活性,要有对应的处理机制。
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游戏开发入门》课程第三周的内容。
非常感谢嵩天老师及其团队给我们带来这样优质的课程。