pygame环境搭建+基础组件

article/2024/3/2 10:46:25

一、初始化pygame环境
(一)在pycharm中新建一个工程

(二)安装pygame

(三)测试安装是否成功
在pycharm终端中输入
python -m pygame --version

在pycharm运行演示程序。
在pycharm终端中输入:python -m pygame.examples.aliens

二、pygame基础
(一)pygame初始化
导入pygame

import pygame # 导入pygame
1
pygame初始化

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

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

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

更新屏幕方法二:

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

(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对象的部分内容。

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

(三)定义事件循环
前面为了让游戏窗口正常显示,我们定义一个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

实际上,我们目前的代码一直有一个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() # 重新显示


http://www.ngui.cc/article/show-738568.html

相关文章

五大理由告诉你:为什么2023上半年软考要尽早开始备考了

上半年软考考试通常在5月份进行,现在距离考试只有将近6个月的时间,其实复习的时间并不是很长了。为什么推荐你尽早开始备考呢?接下来就从以下几点为大家解析。 01、假期备考快人一步 上班忙、没时间,这是大部分在职备考的同学都…

美食杰项目(七)菜谱大全

本文目录前言:1.具体样式2.实现的具体功能和代码思路3.element ui具体样式的网址4.相关代码5.总结:前言: 本文给大家讲的是美食杰项目中菜谱大全项目的具体样式,代码思路和具体代码,希望能帮助到你 1.具体样式 2.实现…

Win11开始菜单里面的推荐项目怎么全部关闭教学

Win11开始菜单里面的推荐项目怎么全部关闭教学分享。在Win11系统的开始菜单中,有一些推荐的功能程序。这些程序用户平时并没有使用到,所以想要去将它们进行关闭。那么这些程序如何彻底的关闭显示呢?一起来看看关闭的方法吧。 操作方法&#x…

【JavaScript】字符串方法汇总(方法最新至ES7~)

目的是自己做一个笔记,方便以后查~ 1. 字符串 1. 查 方法一: indexOf() 查找某个字符,有则返回第一次匹配到的位置,否则返回-1 let str abccefg; let res str.indexOf(c); // 2方法二: charAt() 返回第n个位置…

java计算机毕业设计ssm洗浴管理系统l9omz(附源码、数据库)

java计算机毕业设计ssm洗浴管理系统l9omz(附源码、数据库) 项目运行 环境配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。…

OutOfMemory内存溢出问题排查

OutOfMemory内存溢出问题排查 错误 2022-12-06 00:43:53.296[,] [registrationTask1] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler.handleError96 - Unexpected error occurred in scheduled task. java.lang.OutOfMemoryError: Java heap space 2022-12-06 00:42:49.…

【React高级技术】代码分割技术在React的高级使用[基于路由的代码分割]

代码分割 // app.js import {add } from ./math.js;console.log(add(16, 26)); // 42大多数React应用程序将使用Webpack、Rollup或Browserify等构建工具来打包文件。打包是将文件引入并合并到单个文件中,最后形成一个“包”的过程。然后在页面上引入捆绑包,整个应

【Android - 技术期刊】第005期

技术文章 雪Android app秒开实践Android 老兵翻车了,竟拿不到 Application Context?Android代码检查规则Lint的自定义与应用 - 掘金Android修炼系列(35),内存监控技术方案(下) - 掘金内核线程和…

leetcode1775:通过最少操作次数使数组的和相等(12.7日每日一题)

题目表述: 给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。 每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包…

Linux条件变量

一、条件变量函数 1,条件变量 条件变量:用来描述某种临界资源是否就绪的一种数据化描述。通常要配合mutex一起使用。 2,初始化 pthread_connd_init: 同样有一个静态的和一个动态的。 其中cond是需要初始化的条件变量,attr传…