OK,到该讲显示的时候了。没人可以否定好的画面是一款游戏吸引人最直接最诱人的因素,虽说滥画面高游戏度的作品也有,但优秀的画面无疑是一张过硬的通行证,可以让你争取到更多的机会。
其实上两回也已经打开过显示了,不过没有特别说明而已,pygame.display.set_mode(xxx)就是创建一个游戏窗口,也就是显示的意思。
全屏显示
我们在第一个程序里使用了如下的语句
screen = pygame.display.set_mode((640, 480), 0, 32)
也讲述了各个参数的意思,当我们把第二个参数设置为FULLSCREEN时,就能得到一个全屏窗口了
screen = pygame.display.set_mode((640, 480), FULLSCREEN, 32)
注意:如果你的程序有什么问题,很可能进入了全屏模式就不太容易退出来了,所以最好先用窗口模式调试好,再改为全屏模式。
在全屏模式下,显卡可能就切换了一种模式,你可以用如下代码获得您的机器支持的显示模式:
>>> import pygame
>>> pygame.init()
>>> pygame.display.list_modes()
看一下一个实例:
background_image_filename = 'sushiplate.jpg'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(background_image_filename).convert()
Fullscreen = False
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_f:
Fullscreen = not Fullscreen
if Fullscreen:
screen = pygame.display.set_mode((640, 480), FULLSCREEN, 32)
else:
screen = pygame.display.set_mode((640, 480), 0, 32)
screen.blit(background, (0,0))
pygame.display.update()
运行这个程序,默认还是窗口的,按“f ”,显示模式会在窗口和全屏之间切换。程序也没有什么难度,应该都能看明白。
可变尺寸的显示
虽然一般的程序窗口都能拖边框来改变大小,pygame的默认显示窗口是不行的,而事实上,很多游戏确实也不能改变显示窗口的大小,我们可以使用一个参数来改变这个默认行为。
background_image_filename = 'sushiplate.jpg'
import pygame
from pygame.locals import *
from sys import exit
SCREEN_SIZE = (640, 480)
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)
background = pygame.image.load(background_image_filename).convert()
while True:
event = pygame.event.wait()
if event.type == QUIT:
exit()
if event.type == VIDEORESIZE:
SCREEN_SIZE = event.size
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)
pygame.display.set_caption("Window resized to "+str(event.size))
screen_width, screen_height = SCREEN_SIZE
# 这里需要重新填满窗口
for y in range(0, screen_height, background.get_height()):
for x in range(0, screen_width, background.get_width()):
screen.blit(background, (x, y))
pygame.display.update()
当你更改大小的时候,后端控制台会显示出新的尺寸,这里我们学习到一个新的事件VIDEORESIZE,它包含如下内容:
- size — 一个二维元组,值为更改后的窗口尺寸,size[0]为宽,size[1]为高
- w — 宽
- h — 一目了然,高;之所以多出这两个,无非是为了方便
注意:在我的Windows 7 64bit上运行的时候,一改变窗口大小就非法退出;在Linux机器上很正常,应该是系统的兼容性问题(Pygame还只支持32位),不过想来平时都不会更改游戏窗口大小,问题不大。
至于无边框的窗口等,看一看本教程的第一篇就能知道了,不再赘述。
其他、复合模式
我们还有一些其他的显示模式,但未必所有的操作系统都支持(放心windows、各种比较流行的Linux发行版都是没问题的),一般来说窗口就用0全屏就用FULLSCREEN,这两个总是OK的。
如果你想创建一个硬件显示(surface会存放在显存里,从而有着更高的速度),你必须和全屏一起使用:
screen = pygame.display.set_mode(SCREEN_SIZE, HWSURFACE | FULLSCREEN, 32)
当然你完全可以把双缓冲(更快)DOUBLEBUF也加上,这就是一个很棒的游戏显示了,不过记得你要使用pygame.display.flip()来刷新显示。pygame.display.update()是将数据画到前面显示,而这个是交替显示的意思。
稍微说一下双缓冲的意思,可以做一个比喻:我的任务就是出黑板报,如果只有一块黑板,那我得不停的写,全部写完了稍微Show一下就要擦掉重写,这样一来别人看的基本都是我在写黑板报的过程,看到的都是不完整的黑板报;如果我有两块黑板,那么可以挂一块给别人看,我自己在底下写另一块,写好了把原来的换下来换上新的,这样一来别人基本总是看到完整的内容了。双缓冲就是这样维护两个显示区域,快速的往屏幕上换内容,而不是每次都慢慢地重画。
还有OPENGL模式,这是一个得到广泛应用的3D加速显示模式。不过一旦使用了这个模式,pygame中的2D图像函数就不能用了,我们会在以后讲详细的内容。
这次的东西不是很多,基本就是讲了一个显示参数,如果基础比较好,一看就明白了。不过还是建议实际的输入写一下巩固认识。下一回讲字体模块(游戏没图可以,没字咋整?)~尽请期待
第一个全屏切放 我win7下编译 好像没有通过 有时候感觉开启程序后 关闭不了 只能到任务管理器里面去关掉 这跟系统应该关系不大吧
你应该是quit没有加载正确哦,可以检查下
pygame和Python都是用的Tkinter的循环,有的命令会冲突导致关闭不了的问题,可以选择把文件保存后直接双击文件运行
@tangly: 我的可以比较正常的执行,如果是偶发性的不正常,我也说不清原因,可能和现在显卡高级了而pygame利用的借口还是陈旧的有关吧。但个人觉得这种切换操作在实际游戏中是非常少的,所以不用在意。
@xishui:
嗯 谢谢
for y in range(0, screen_height, background.get_height()):
for x in range(0, screen_width, background.get_width()):
screen.blit(background, (x, y))
楼主这两句FOR 看不懂,教教我
就是横向和纵向的填充,用背景图片的高和宽当步长,从零增长到窗口的高和宽,每次增长都把背景图片画一次(不用担心会画过界,不会出错的)。
如果您是不明白range(start, end, step)的用法的话,只好请你自行再修炼。“妈妈再也不用担心我的编程,手持《Python核心编程》那里不会翻哪里……”
填充为什么不直接用screen.fill()呢
因为程序在我电脑跑起来时,拖拽窗口之后,又恢复到原来的形状所以我改了下代码,即可实现拖拽后留在当前形状:
if event.type == VIDEORESIZE:
SCREEN_SINZE = event.size
screen = pygame.display.set_mode(event.size,RESIZABLE,32)
pygame.display.set_caption(“window resized to”+str(event.size))
#前面需定义全局变量screen_width和screen_height
screen_width,screen_height = event.size
for y in range(0,screen_height,background.get_height()):
for x in range(0,screen_width,background.get_width()):
screen.blit(background,(x,y))
@77: 额 竟然没有空格。。。if语句后面的5句是并列的 第二个for和最后一句逐步缩进
多谢楼主你的无私分享,这个系列我一定会看完,在此感谢你的资料
向博主致敬…
你好 请问你的代码点亮是用什么做的呀?
32位 resize 的时候挂掉、、、、 囧
2.6的py 1.9.1的pygame o(╯□╰)o
Win7 python2.7 pygame1.9.1当尺寸比最开始的大就会发生错误,是为什么?
一个有点题外话的问题:在resizable之后,怎么让窗口变大变小的同时图像跟随窗口尺寸缩放啊?
@xumaomao:自问自答个。用pygame.transform.scale()
1
楼主为什么不更新了啊
@tangly: Ctrl+C搞定一切
我认为博主第一个例程(全屏与窗口切换那个)第18行的缩进有问题,不知道大家怎么看的?
没错。按第一次f一定执行第一条,但再按第二次后Fullscreen变False,然后执行第二条,变回全屏,以此类推,这样达到按F来回切换。
将屏幕拉大到大于SCREEN_SIZE时出项如下错误Fatal Python error: (pygame parachute) Segmentation Fault
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application’s support team for more information.
我最近在写代码的时候也遇到了这个问题,请问你是怎么解决的?
@goonafly:
在20行前加一行就行:
pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)
没弄明白为什么会这样
在 可变尺寸显示中的26-28表示窗口扩大一点,就再画一张图片…
如何才能达到这样的效果: 窗口增大的同时, 图片也跟着增大?
Okay, I got it.
把26-28换成backgound=background = pygame.transform.scale(background, screen_size) 更换位置即可
1
不是替换, 是后面加上
可以替换,不过要把第29行改为
screen.blit(background, (0, 0))
py2.7+pygame1.9.1release,调整窗口大小是错误退出,这里http://stackoverflow.com/questions/18838464/pygame-crashes-when-i-try-to-resize-window 说:Try removing the color depth on the resize mode setting:
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE)。把”32″去掉后正常了。。。
我按照您的代码编辑好之后,只能从窗口切换到全屏,无法切换回窗口,请问是什么原因
当,刚看到可以全屏的时候,立马改写了代码fullscreen,立即运行。结果,结果,全屏了!(很是高兴中)
咦,突然发现退不出来了,退不出来了(由于linux,没有像win下的神码任务管理器)。最后,只能借用电脑远程进来,kill掉!否则得按下重启键了。噢,下次要想清楚了再运行(不知道有没有跟 木头 一样的呢,嘿嘿)。
我是在mac上运行的,写完set_mode((800*600))并且fill了一个颜色,但是显示出来的状态是,窗口大小确实是800*600,但是填充的大小却只占窗口的1/4并且在做一些鼠标事件的时候,鼠标的位置也会映射到填充的区域而不是直接在整个窗口中工作
请问这是为什么呢
mac下你可以全屏?应该点击键盘的什么触发啊?
tranform.scale 会导致图片变形
smoothscale 要好一点
试了下,无论是SCALE还是SMOOTHSCALE,多次拖拽屏幕,还是会失真严重。
解决方法,我尝试在每次SCALE之前,重新加载一次图片,就是再加一句
background = pygame.image.load(background_image_filename).convert()。每次SCALE都是对原始图片,所以效果好了很多:)
mark
图片拖拽变形是正常的啊, 比例改变了嘛,
加这一句没有任何作用.
不知道你说的是什么意思
每次都是未响应啊,配置好low
检查keydown的if部分被我放在for循环中了。
case1. 放在while下,每次循环while的时候都要检查一次key.type==keydown。|| 也就是说每次while循环,检查两次key.type。
case2. 放在for下,就只有发生事件的时候才会检查key.type。|| 每次while循环,检查一次key.type。
我这样理解应该没错吧?
测试了一下,两种都没有问题。
==================
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
#####################
if event.type == KEYDOWN:
if event.key == K_f:
Fullscreen = not Fullscreen
if Fullscreen:
screen = pygame.display.set_mode((640, 480), FULLSCREEN, 32)
else:
screen = pygame.display.set_mode((640, 480), 0, 32)
####################
screen.blit(background, (0,0))
pygame.display.update()
================
“case1. 放在while下,每次循环while的时候都要检查一次key.type==keydown。|| 也就是说每次while循环,检查两次##### key.type ######。
case2. 放在for下,就只有发生事件的时候才会检查key.type。|| 每次while循环,检查一次key.type。”
措辞有点问题,就是想表达case1的成本高于case2.
Pingback: 用Python和Pygame写游戏-从入门到精通(3)-演道网
为什么我的窗口只能拉大一点点,再拉大就出现黑色边框了
看了下官方文档,最新版本的pygame里面,update()和flip()的区别似乎已经基本没有了。不管哪个都会根据显示模式自动调整刷新模式,唯一的区别是update可以选择刷新区域
谢谢告知
Pingback: 用Python和Pygame写游戏-从入门到精通(3) – 易可信blog系统
为什么我汉字是2个方框飘过??
灰鹰是个好游戏:)
再一次提醒大家,别乱进全屏:)真是惨痛的教训
为何我把key.type==keydown放到外部做成函数后,能全屏但不能缩小
我设置可变尺寸的窗口时,在while True循环之前就写了一个标题名,但是运行的时候没有显示,直接显示的“”Window resized to ” + str(event.size)”,这是为什么?
我就想知道楼主这是什么主题,感觉看着好舒服,望楼主分享
页面最下面就有的
event = pygame.event.wait()
这一行, 之前学的时候都是 for event in pygame.event.get():
万分感谢楼主的资料!!!
Pingback: PyOpenGL之3D界面详解(三)-识荒者
棒棒的
Fullscreen、FULLSCREEN、K_f 的大小写必须严格按楼主的来啊,受教了