Pygame教程系列一:快速入门篇

【简介】

Pygame 是python用来开发视频游戏的游戏引擎,底层主要是SDL库实现,算是目前利用python开发小游戏的一个性能比较高的一个游戏框架

一、安装pygame

使用pip下载安装

pip install pygame

二、入门案例详析

1、示例效果

Pygame教程系列一:快速入门篇

; 2、示例代码

import os
import pygame

exitFlag = False

FPS = 10

pygame.init()

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 25)

surface = pygame.display.set_mode((800, 500))

pygame.display.set_caption("pygame教程")

icon = pygame.image.load('E:\AS-workspace\pygameTest\drawable\icon.png').convert_alpha()
pygame.display.set_icon(icon)

bgSurface = pygame.image.load('E:\AS-workspace\pygameTest\drawable\BG.jpg').convert()

clock = pygame.time.Clock()

scaleImg = pygame.transform.scale(icon, (400, 400))

rect = scaleImg.get_rect()

step = 10

surface.blit(bgSurface,(0,0))

newRect = None
while not exitFlag:
    clock.tick(FPS)

    if rect:
        surface.blit(bgSurface, rect,rect)

    newRect = rect.move(step, 0)

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            exitFlag = True

    surface.blit(scaleImg,newRect)

    if newRect.x > 800 - newRect.w:
        step = -10
    elif newRect.x < 0:
        step = 10

    pygame.display.update([rect,newRect])
    rect = newRect

if __name__ == '__main__':
    pass

3、代码分析

1)pygame窗口保持一直显示的前提是: python进程持续地在运行,要实现这个目的,需要有一个循环体在不停地运行,所以需要一个全局变量标识是否退出循环,结束进程,比如:上面声明 exitFlag这个变量来记录当前是否退出循环,当 exitFlag=True就退出游戏

2)游戏界面变化的频率,对应的是画面刷新的帧率,即画面每秒刷新多少次,这个刷新帧率设置太快,假如设备的GPU刷新跟不上也是没效果的,所以一般设置1秒刷新30次就可以达到看视频那样流畅的效果了,比如:上面代码设置 FPS = 10是为了不让刷新太快,否则动画移动太快,看不清图片,其中,pygame时钟是控制游戏画面刷新的帧率,通过 clock = pygame.time.Clock()获取到时钟对象,然后在 &#x5FAA;&#x73AF;&#x4F53;中设置指定的帧率即可: clock.tick(FPS)

3)pygame初始化是调用 pygame.init(),这句代码需要在所有设置pygame属性之前调用,先初始化再做其他操作

4) os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 25) , 指定pygame窗口的左上角显示在坐标(0,25)上,即距离屏幕左边0像素,距离屏幕上边25像素;不设置的话,窗口 &#x9ED8;&#x8BA4;&#x663E;&#x793A;&#x5C4F;&#x5E55;&#x6B63;&#x4E2D;&#x592E;

5) surface = pygame.display.set_mode((800, 500)),设置游戏窗口大小为:宽800像素,高500像素;

  • 当然,你还可以设置 surface = pygame.display.set_mode((0, 0)),这样就是全屏显示,
    不过单纯这样设置全屏的话,你会发现窗口的大小是固定的,没法缩小
  • 那么要达到默认显示全屏,但是又可以随意调节的目的,可以这样设置: surface = pygame.display.set_mode((0, 0),pygame.RESIZABLE)
  • 上面两种方式显示的全屏都有一个问题,那就是还看到游戏窗口的标题栏与桌面的任务栏,不算是严格意义的全屏,要想游戏画面铺满整个屏幕,需要这样设置: surface = pygame.display.set_mode((0, 0),pygame.FULLSCREEN)

6) pygame.display.set_caption("pygame&#x6559;&#x7A0B;"),设置游戏窗口标题栏显示的标题名称或者说软件名也可以

Pygame教程系列一:快速入门篇

7) pygame.image.load('E:\AS-workspace\pygameTest\drawable\icon.png').convert_alpha(),复制本地图片的像素数据到一个 Surface对象中储存,为后续绘制到屏幕做准备

  • 因为是png图片,需要额外处理alpha通道,所以需要使用 convert_alpha()转换成与我们的屏幕显示器相同的像素格式,这样能获得最快渲染速度;
  • 如果是jpg格式图片,没有alpha通道,也就是没有透明背景的图片,可以直接用 convert()转换为pygame最快的渲染格式即可
  • 注意: 最好每张图片都调用一下 covert方法,这样可以提高渲染速度,否则,pygame每次绘制时候也会自动根据屏幕显示器的像素格式进行转换,会降低渲染速度,可能会出现卡顿现象

8) pygame.display.set_icon(icon),设置指定图片的surface对象作为该程序的图标

9) scaleImg = pygame.transform.scale(icon, (400, 400)) ,缩小/放大图片到指定宽高,并返回缩小/放大之后的图片surface对象

10) rect = scaleImg.get_rect(),获取图片的矩形区域,即(left, top, width, height),也就是返回图片左上角的坐标,宽,高,不过默认返回的左上角坐标都是(0,0)

11) surface.blit(bgSurface,(0,0)),将图片绘制到指定的surface对象中,左上角的坐标为(0,0),注意:这里仅仅只是将图片绘制到surface上而已,并没有渲染到屏幕上,也就是说只做了这一步,屏幕上是看不到新绘制的内容的,还需要调用 pygame.display.update() 或者 pygame.display.flip()才会把新绘制的内容更新渲染到屏幕上

12) rect = rect.move(step, 0),将rect沿着x轴移动 step像素,沿着y轴移动0像素,即 step为整数时,向右移动step像素, step为负数时,向左移动step像素

13) PyGames通过事件队列来处理其所有事件消息传递,但是事件队列是有上限的,标准的 SDL 1.2声明的队列长度是 128,如果事件队列的事件超出了限制,那么后续的事件都会被丢弃,你的程序就会显示 &#x65E0;&#x6CD5;&#x54CD;&#x5E94;卡死,所以一定要在每一帧中都用以下其中一个方法来处理事件: pygame.event.get(), pygame.event.pump(), pygame.event.wait(), pygame.event.peek() 或者 pygame.event.clear()

 for event in pygame.event.get():

        if event.type == pygame.QUIT:
            exitFlag = True

14)由于pygame是一帧一帧绘制的,那么图片在移动时候,假如没有对上一帧绘制的图片做擦除,就会出现一堆图片重叠的现象,这就是所谓的”脏图片”,所以上面代码可以看到在每一帧刷新中,都对背景的指定区域rect做了擦除动作: surface.blit(bgSurface, rect,rect),即重新绘制一遍背景图的指定区域,以达到覆盖脏图片的效果,当然,你也可以把整个背景图重新绘制一遍的,但是这样太耗费性能

15)同时,我们更新绘制内容到屏幕显示器时,也不要一股脑地调用 pygame.display.update()更新整个屏幕,因为据测算,在性能比较一般的机器,每次调用update更新整个屏幕的耗时接近 35ms, 那么1秒内最大只能刷新: 1000/35 = 28帧,但是这里还没有计算游戏逻辑、绘制、获取输入输出等操作所耗费时间,仅仅是update,就最多只能一秒刷新28帧,那么这样算下来,就很容易出现卡顿现象了,那么有什么解决办法吗?看看上面代码,我们是对图片有改变的区域进行刷新即可,这样可以获得最高的刷新速率: pygame.display.update([rect,newRect]),换句话说,我们可以用list集合记录每一帧图片变化的区域,然后只对这些区域进行刷新即可

Original: https://blog.csdn.net/qq_43278826/article/details/113250012
Author: 潇曜
Title: Pygame教程系列一:快速入门篇

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/780743/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球