「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
本系列专栏将通过不断编写游戏的方式,带你夯实 Python 知识。
这篇博客的目的
通过 pygame 内置的函数绘制各种简单的线条图形。
简单的图形包括,矩形、圆形、椭圆形、线条。
先测试最终效果。
import pygame
import sys
from pygame.locals import *
pygame.init()
SCREEN = pygame.display.set_mode((300, 300), 0, 32)
pygame.display.set_caption("图形绘制")
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
SCREEN.fill(WHITE)
# 绘制多边形
pygame.draw.polygon(SCREEN, GREEN, ((0, 0), (100, 0), (100, 150)))
# 绘制直线
pygame.draw.line(SCREEN, RED, (50, 50), (100, 100), 5)
# 默认一个像素宽度的直线
pygame.draw.line(SCREEN, BLUE, (60, 50), (110, 100))
# 绘制一个圆形,最后一个参数取值为 0 时,表示实心圆
pygame.draw.circle(SCREEN, BLACK, (90, 90), 20, 0)
pygame.draw.circle(SCREEN, BLACK, (200, 20), 20, 1)
# 绘制一个椭圆形
pygame.draw.ellipse(SCREEN, BLUE, (170, 200, 50, 70), 1)
# 绘制一个矩形
pygame.draw.rect(SCREEN, RED, (150, 150, 30, 40), 1)
# 无最后一个参数,默认填充矩形
pygame.draw.rect(SCREEN, RED, (210, 210, 30, 40))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.init()
sys.exit()
pygame.display.update()
运行绘制之后的图形如下所示。
代码分析
.fill(color)
是 pygame.Surface
对象的一个方法,核心功能是使用 color 参数指定的颜色来填充整个 Surface
对象,理解成画板中的油漆桶即可。
pygame.draw.polygon(surface, color, pointlist, width)
绘制多边形的形状,Surface
和 color
参数一个是绘制的目标,另一个是填充的颜色,pointlist
参数是一个点的元组或者点的列表,具体格式为 ((1,2),(3,4))
。
多边形绘制会按照提供的点元组进行绘制,在点之间绘制线条,然后,从最后的点到第一个点绘制一个线条。
width
参数是可选的,如果未填写(或填写 0),表示填充多边形。
pygame.draw
相关函数,最后都有一个参数 width
,使用方式都一样。
pygame.draw.line(surface, color, start_point, end_point, width)
绘制直线,起始坐标是 start_point
,终点坐标是 end_point
。
line
函数还存在一个重载函数,函数原型:
pygame.draw.lines(surface, color, closed, pointlist, width)
该函数从一个点到下一个点进行线条的绘制,与多边形绘制非常类似,区别在 closed
,如果给该参数设置了 FALSE,那该形状不会闭合,就是一条长长的折线了。
pygame.draw.circle(surface, color, center_point, radius, width)
绘制一个圆,center_point
为圆心,radius
参数是半径,width
为线条的宽度。
pygame.draw.ellipse(surface, color, bounding_rectangle, width)
绘制一个椭圆, 必须指定的参数是 bounding_rectangle
,叫做椭圆的边界矩形,边界矩形的含义是围绕椭圆所绘制的最小矩形。
bounding_rectangle
参数是一个 pygame.Rect
对象或者是 4 个整数的元组。
pygame.draw.rect(surface, color, rectangle_tuple, width) 绘制矩形,该函数比较容易理解,不做过多说明。
帧速率和 pygame.time.Clock 对象 帧速率(frame rate) 也叫做刷新速率 (refresh rate)是程序每秒钟绘制的图像数目,一般用 FPS 来表示,单位是赫兹,玩游戏的朋友会比较清楚,例如一般显示器的帧速率是 60Hz,电竞屏是 144 Hz,大概这个含义,游戏丢帧也是常见的术语,一般戏称卡成幻灯片,就是每秒钟帧数变的很低。
pygame.time.Clock
对象在 pygame 中用来实现这个帧速率。
使用方式是先创建一个 Clock
对象,然后在游戏的每次迭代之后,调用 tick()
方法。
rate = pygame.time.Clock()
FPS = 60
while True:
# do something
rate.tick(FPS)
注意 tick
方法调用要放在 pygame.display.update()
之后,值设置的越高,程序运行的越快。
pygame.image.load()
图片通过该函数进行加载,返回一个图像的 Surface 对象,该对象与游戏窗口的 Surface 对象不同,如果需要渲染,一定要将图像 Surface 绘制到 游戏窗口的 Surface 对象上,实现这个步骤的函数是 blit
。
因此在后续的编程中,你会经常发现 SCREEN.blit(img_surface,(x,y))
,这样的代码。
第一个参数是待绘制的图像,第二个参数是绘制的位置。
pygame 中的字体
在 pygame 中,使用 pygame.font.Font
函数来实现文字,渲染的文字需要转换成图片,绘制到目标 Surface 对象上。
import pygame
import sys
from pygame.locals import *
pygame.init()
SCREEN = pygame.display.set_mode((300, 300), 0, 32)
pygame.display.set_caption("图形绘制")
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
SCREEN.fill(WHITE)
font_obj = pygame.font.Font("simfang.ttf",32)
font_surface = font_obj.render("橡皮擦",True,RED,BLACK)
font_rect = font_surface.get_rect()
font_rect.center = (100,100)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.init()
sys.exit()
SCREEN.blit(font_surface,font_rect)
pygame.display.update()
上文使用的是 pygame.font.Font("simfang.ttf",32)
,尤其注意第一个参数,它是字体文件的名称,这个字体文件的路径是你本地的字体文件路径,所以你需要提前准备好字体文件。
pygame.font.Font.render()
,在一个新 Surface 对象上绘制文本,函数原型为:
render(text, antialias, color, background=None) -> Surface
该函数返回一个新的 Surface 对象,并在该对象上渲染指定的文本。
pygame
没有提供直接的方式在一个现有的 Surface 对象上绘制文本,而使用 Font.render()
函数创建一个渲染了文本的图像(Surface 对象),然后将这个图像绘制到目标 Surface 对象上。
参数一,文本;参数二,是否开启抗锯齿;参数三,文字颜色;参数四,背景颜色。
参数二 antialias
:为 True 时文本图像显示更光滑,为 False 时文本图像显示有锯齿状。
除了使用自定义字体以外,还可以使用系统字体,函数对应如下:
my_font = pygame.font.SysFont("arial", 10)
在使用之前,可以先通过 pygame.font.get_fonts()
获取系统可用字体,比如微软雅黑字体,修改代码为:
print(pygame.font.get_fonts())
font_obj = pygame.font.SysFont("microsoftjhengheimicrosoftjhengheiui",40)
本系列专栏属于番外篇,希望你能学到新知识。 有任何疑问,都可以联系橡皮擦进行解决,一起做游戏吧 本专栏每天的练习量大概在 1 小时左右,整篇博客节奏会比较快,毕竟咱们是有基础的人。