当前位置:   article > 正文

Pygame入门_需要使用到pygame模块,即在pycharm终端输入

需要使用到pygame模块,即在pycharm终端输入

一、初始化pygame环境

(一)在pycharm中新建一个工程

新建一个名为learn_pygame的工程

(二)安装pygame

(三)测试安装是否成功

在pycharm终端中输入
python -m pygame --version
显示pygame版本
在pycharm运行演示程序。
在pycharm终端中输入:python -m pygame.examples.aliens
pygame测试小游戏

二、pygame基础

(一)pygame初始化

导入pygame

import pygame # 导入pygame
  • 1

pygame初始化

pygame.init()
  • 1

将pygame.init()赋值给一个变量,并打印它。

n = pygame.init()
print(n)
  • 1
  • 2

pycharm初始化
n返回一个元组,(5,0)中的5个模块初始化成功,0个模块初始化失败

(二)设置显示界面

pygame绘图思路
在这里插入图片描述
1.设置窗口尺寸
我们使用pygame.display.set_mode(size,flags,depth)来初始化窗口并将其传递给变量,将获得一个surface对象。size是一对元组,用以表示宽度和高度。

screen = pygame.display.set_mode((400,400)) # 第一个400是宽度,单位是像素,第二个400是高度
  • 1

flags用于设置主窗口样式

pygame.FULLSCREEN 创建一个全屏窗口。
pygame.HWSURFACE 创建一个硬件加速窗口,必须和 FULLSCREEN 同时使用。
pygame.OPENGL 创建一个 OPENGL 渲染窗口。
pygame.RESIZABLE 创建一个可以改变大小的窗口。
pygame.DOUBLEBUF 创建一个双缓冲区窗口,建议在 HWSURFACE 或者 OPENGL 时使用。
pygame.NOFRAME 创建一个没有边框的窗口。

2.设置窗口标题
设置窗口的标题,即游戏名称

pygame.display.set_caption('hello world')
  • 1

3.更新画面
我们可以将显示界面理解为电影中的画面。在电影中随着时间的推进,画面会不断发生变化。为了将每一幅图像显示到画面上,需要不断的更新页面上显示的内容。
更新屏幕方法一

pygame.display.flip()
  • 1

pygame.display.flip()的作用是更新整个屏幕的内容。

Update the full display Surface to the screen

在完成以上代码,点击运行会有一闪而过的画面,原因是没有设置任何动作。
下面,我们通过定义事件循环及动作捕获。
完整代码:

import pygame

pygame.init()

screen = pygame.display.set_mode((400, 400))

pygame.display.set_caption('hello world')

while True:
    for event in pygame.event.get():
        pass
    pygame.display.flip()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Alt
更新屏幕方法二:

pygame.display.update()
  • 1

与flip()的区别是可以通过传递rect值指定更新的区域,如果不传递参数其效果和flip()一样。

如果仅仅是几个物体在移动,那么他只重绘其中移动的部分,没有变化的部分,并不进行重绘。update比flip速度更快。因此在一般的游戏中,如果不是场景变化非常频繁的时候,我们建议使用update函数,而不是flip函数。
4.设置背景
现在的窗口默认使用的是黑色背景,我们可以通过以下两种方式来设置背景样式。
(1)为画面添加一个纯色背景

# 设置背景
screen.fill((255,209,220))
# 或者
screen.fill('pink')
  • 1
  • 2
  • 3
  • 4

Alt
(2)设置图片背景

background = pygame.image.load('./image/plane/background.png').convert_alpha()
screen.blit(background, (0, 0))
  • 1
  • 2

blit(source, dest, area=None, special_flags = 0) -> Rect

Surface对象的blit方法,是将一个surface对象绘制在另一个surface对象的上面,就想油画一样,上面的颜色将把下面的颜色盖住。
source为放在上层的Surface对象;
dest是放置的坐标元组(left,top);如果left和top都为0,则图片的左上角点与背景的左上角点重合;
area:是一个可选参数,通过该参数可设置矩形区域。若设置的矩形区域小于source所设置Surface对象的区域,那么仅绘制Surface对象的部分内容。

ALT
5.添加文字

pygame.font.SysFont()。使用系统字体。
name字体名称,size字体大小,bold是否加粗,italic是否斜体

create a Font object from the system fonts
SysFont(name, size, bold=False, italic=False) -> Font

系统可用字体使用以下语句查询,将获得所有可用字体的列表。

print(pygame.font.get_fonts())
  • 1

使用下面语句将获得一个字体对象

# 设置字体样式
scores_font = pygame.font.SysFont('仿宋gb_2312', 25)
  • 1
  • 2

在pygame中使用render方法将文本变成一个贴图,然后再将图片贴到背景上显示。

draw text on a new Surface
render(text, antialias, color, background=None) -> Surface
text是需要插入的字符串;
antialias设置抗锯齿;
值为True或False;
color是文字的颜色;
background是背景的颜色,默认为无背景。

# 
scores_caption = scores_font.render(f'得分{score}', True, (255, 255, 255), (0, 0, 0))
  • 1
  • 2

使用和之前贴背景图片一样的方法blit,将文字surface贴上去。

screen.blit(scores_capiton,(100,100))
  • 1

Alt

(三)定义事件循环

前面为了让游戏窗口正常显示,我们定义一个while循环。

while True:
    # 循环获取事件,监听事件状态
    for event in pygame.event.get():
        pass
    pygame.display.update()
  • 1
  • 2
  • 3
  • 4
  • 5

pygame.event.get()函数用于捕获用户使用键盘、鼠标设备的任何操作。
在for循环中只有一个pass语句,没有设置任何实际动作。
通过添加一个print(event),我们可以观察到捕捉了哪些动作。

while True:
    # 循环获取事件,监听事件状态
    for event in pygame.event.get():
    	print(event)
    pygame.display.update()
  • 1
  • 2
  • 3
  • 4
  • 5

Alt
实际上,我们目前的代码一直有一个Bug,就是在程序运行后,没办法通过点击窗口坐上角的x来关闭窗口。接下来我们对程序进行一些改动来解决这个问题。

while True:
    # 循环获取事件,监听事件状态
    for event in pygame.event.get():
    	if event.type == pygame.QUIT:
    	    pygame.quit()
    	    sys.exit()
    pygame.display.update()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

event.type用以返回事件的类型,在pygame中定义了以下基础事件类型。
pygame.QUIT用以判断是否按下了窗口坐上方的x按钮。如果“是”的话,则会执行pygame.quit(),它与pygame.init()的作用相反,用于停止Pygame库的工作,之后再执行sys.exit()关闭程序。

QUIT              none
ACTIVEEVENT       gain, state
KEYDOWN           key, mod, unicode, scancode
KEYUP             key, mod, unicode, scancode
MOUSEMOTION       pos, rel, buttons, touch
MOUSEBUTTONUP     pos, button, touch
MOUSEBUTTONDOWN   pos, button, touch
JOYAXISMOTION     joy (deprecated), instance_id, axis, value
JOYBALLMOTION     joy (deprecated), instance_id, ball, rel
JOYHATMOTION      joy (deprecated), instance_id, hat, value
JOYBUTTONUP       joy (deprecated), instance_id, button
JOYBUTTONDOWN     joy (deprecated), instance_id, button
VIDEORESIZE       size, w, h
VIDEOEXPOSE       none
USEREVENT         code
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

再举例说明:KEYDOWN、KEYUP分别指的是键盘按钮的按下和释放两种状态;MOUSEMOTION指的是鼠标的移动;JOYAXISMOTION手柄移动;JOYBALLMOTION手柄滚球移动;VIDEORESIZE窗口缩放。
然而,以上只是事件类型的冰山一角,在后面的实例中我们还将丰富对这一部分的了解。你也可以在pygame官网文档查询更多的内容:https://www.pygame.org/docs/ref/event.html

(四)事件实例

实例1:在窗口中显示动态时间
如下图所示在窗口中动态显示时间
在这里插入图片描述
游戏初始化

import pygame
import sys
import time

pygame.init() # pygame初始化

fpsclock = pygame.time.Clock() # 创建一个对象用于追踪时间

screen = pygame.display.set_mode((400, 400)) # 初始化一个屏幕用以显示

pygame.display.set_caption('hello world') # 设置窗口标题

background = pygame.image.load('./image/plane/background.png').convert_alpha() # 载入背景图片

screen.blit(background, (0, 0)) # 将背景图片放到屏幕上

clock_font = pygame.font.SysFont('仿宋gb_2312', 25) # 创建一个文字对象
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

设置更新动作

def clock_update():
    clock = time.strftime("%Y-%m-%d %H-%M-%S", time.localtime()) # 将本地时间按照年-月-日 时:分:秒的格式存入clock
    clock_caption = clock_font.render(f'现在时间:{clock}', True, (255, 0, 0), (0, 0, 0)) # 将文本绘制到一个新的Surface对象上
    clock_caption_rect = clock_caption.get_rect() # 获得文本所在Surface对象的rect
    clock_caption_rect.center = screen.get_rect().center # 将文本Surface对象的rect中心与屏幕的中心对齐
    screen.blit(clock_caption, clock_caption_rect.topleft) # 将文本Surface绘制到屏幕上
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设置循环事件

while True:
    fpsclock.tick(60) # 调用时间对象的tick方法设置屏幕刷新屏幕,每秒循环的次数
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    clock_update() # 调用时间更新事件
    pygame.display.update() # 更新屏幕,实现动态显示
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

实例2:键盘操作移动图片到指定位置
如下图所示,程序运行后,小汽车位于窗口的左上角,通过键盘的上下左右按键操作小汽车移动,当小汽车移动到红色框框,屏幕提示“well done”。
在这里插入图片描述
1.游戏初始化

import pygame
import sys

pygame.init()  # pygame初始化

screen = pygame.display.set_mode((500,500))  # 设置窗口大小width,height都为500

pic = pygame.image.load('./image/driver/car1.png').convert_alpha() # 插入小车图片

pic = pygame.transform.scale(pic, (50, 50)) # 将图片大小缩放为width,height都为50

pic_rect = pic.get_rect() # 获得图片的rect对象

screen.blit(pic, (0, 0)) # 设置pic初始位置,(0,0)也可以缺省。如果不提供,默认就是插入到(0,0)

speed = 10  # 移动速度

fpsticks = pygame.time.Clock() # 创建一个时间对象

font = pygame.font.SysFont('仿宋gb_2312', 25) # 创建一个系统字体对象

msg = font.render('Go to the target...', True, (255, 255, 255)) # 生成文本Surface

msg_rect = msg.get_rect() # 获得msg的rect

msg_rect.topleft = (100, 100) # 设置msg信息的位置
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

pygame.Rect
Rect对象是pygame用于存储矩形坐标的对象,它决定了游戏中图像的位置和大小,是pygame中非常核心的内容。

pygame object for storing rectangular coordinates
Rect(left, top, width, height) -> Rect
Rect((left, top), (width, height)) -> Rect
Rect(object) -> Rect

Rect对象有许多虚拟属性用于移动和与对齐其他的Rect。

The Rect object has several virtual attributes which can be used to move and align the Rect

以下是Rect对象具有的属性

x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height
w,h
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

print(pic_rect)
# 当输出pic_rect时,将获得pic的rect值,(0, 0, 50, 50)
print(pic_rect.center)
# 同样,当输出pic_rect.center时,将获得这个矩形中心点的坐标,其他属性以此类推。
print(pic_rect.x,pic_rect.y)
# 背景的坐上角是原点的位置,x代表在水平方向上离原点的距离,y代表在垂直方向上离原点的距离。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
通过修改Rect将实现对图像的移动。

# 如上图所示,下面代码将把矩形向上刚好移除屏幕
pic_rect.y = - pic_rect.height
# 我们还可以先定义一个移动速度,然后使用一个循环使Rect的x或y值按一定的速度移动
speed = 1
while True:
    pic_rect.x += speed
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设置游戏循环

while True:
    fpsticks.tick(60) # 设置游戏刷新频率,每秒循环的次数
    for event in pygame.event.get():
        if pic_rect.topleft == (300, 200): # 判断小车是否进入目标区域
            msg = font.render('Well done', True, (255, 255, 255))
        else:
            msg = font.render('Go to the target...', True, (255, 255, 255))
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        keys = pygame.key.get_pressed() # 返回一个布尔值序列代表键盘上每个键被按下状态
        if keys[pygame.K_UP]:  # 意思是判断键盘上的Up键是否被按下
            pic_rect.y -= speed # 代表每按下一次,小车的y坐标减去速度,等同于小车按照speed向上移动一次
        elif keys[pygame.K_DOWN]:
            pic_rect.y += speed # 小车向下移动,小车的y坐标增大
        elif keys[pygame.K_LEFT]:
            pic_rect.x -= speed # 小车向左移动,小车的x坐标减小
        elif keys[pygame.K_RIGHT]:
            pic_rect.x += speed # 小车向右移动,小车的x坐标增大
    screen.fill((0, 0, 0))  # 背景不断刷行,从而隐藏小车移动过程中留下的痕迹
    screen.fill((255, 0, 0),(300, 200, 50, 50)) # 此处绘制的是目标位置,背景刷新的同时,刷新目标位置,如果不刷新,目标位置将被背景覆盖住
    screen.blit(msg, msg_rect.topleft) # 刷新消息框信息
    screen.blit(pic, pic_rect.topleft) # 刷新小车位置
    pygame.display.update() # 重新显示屏幕内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

本篇到此结束,在下一篇中将对上述代码的结构和方法进行优化,随后以实例引入精灵的相关介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/96843
推荐阅读
  

闽ICP备14008679号