python - 在特定时间内完成画圆
问题描述
我正在尝试用圆圈创建倒计时。圆圈将显示与给定时间相比已经过去了多少时间。因此,如果倒计时是 10 秒并且已经过了 5 秒,则将绘制半圈。我想出了这段代码:
from math import pi
import pygame
pygame.init()
(x, y) = (800, 600)
screen = pygame.display.set_mode((x, y))
clock = pygame.time.Clock()
radius = 50
# Just to place the circle in the center later on
top_left_corner = ((x / 2) - (radius / 2), (y / 2) - (radius / 2))
outer_rect = pygame.Rect(top_left_corner, (radius, radius))
countdown = 1000 # seconds
angle_per_frame = 2 * pi / (countdown * 60)
angle_drawn = 0
new_angle = angle_per_frame
while True:
if angle_drawn < 2 * pi:
new_angle += angle_drawn + angle_per_frame
pygame.draw.arc(screen, (255, 255, 255), outer_rect, angle_drawn, new_angle, 10)
angle_drawn += angle_per_frame
clock.tick(60)
pygame.display.update(outer_rect)
因此fps = 60
,在我正在绘制的每一帧中2 * pi / countdown * fps
,将一个完整的圆圈分成几帧。然后在每一帧中,画出圆圈的一部分。似乎可以很好地绘制圆圈,但它不能用于计时器,原因有两个:
这个圈子似乎比给定的时间更短。
在绘制圆圈时,似乎圆圈的最后一部分绘制得更快。
谁能指出我做错了什么?
解决方案
问题是你增加new_angle
了angle_drawn + angle_per_frame
,因为你添加angle_per_frame
到angle_drawn
它的每一帧都会更大。
我宁愿使用clock.tick
返回的增量时间,否则如果帧速率不是恒定的,可能会出现不准确的情况。然后将该angle_per_second
值乘以dt
得到该帧的正确值。
另外,因为pygame.draw.arc
如果角度之间的差异太小不起作用,我不得不从起始角度减去 0.2,并且必须在绘图开始之前添加一个短暂的延迟。
from math import pi
import pygame
from pygame import freetype
pygame.init()
x, y = 800, 600
screen = pygame.display.set_mode((x, y))
clock = pygame.time.Clock()
FONT = freetype.Font(None, 32)
WHITE = pygame.Color('white')
radius = 50
# Just to place the circle in the center later on
top_left_corner = (x/2 - radius/2, y/2 - radius/2)
outer_rect = pygame.Rect(top_left_corner, (radius, radius))
countdown = 10 # seconds
angle_per_second = 2*pi / countdown
angle = 0
dt = 0 # dt is the time since the last clock.tick call in seconds.
time = 0
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
time += dt
angle += angle_per_second * dt
# Delay the drawing a little bit, because draw.arc doesn't work
# with very small angle differences.
if angle > 0.2:
pygame.draw.arc(screen, WHITE, outer_rect, angle-0.2, angle, 10)
rect = pygame.draw.rect(screen, (50, 50, 50), (400, 340, 100, 50))
FONT.render_to(screen, (410, 350), str(round(time, 2)), WHITE)
dt = clock.tick(60) / 1000 # / 1000 to convert it to seconds.
pygame.display.update([outer_rect, rect])
推荐阅读
- r - 关于在 R 中使用 sample() 函数为 ML 设置训练和测试集的清晰性。
- javascript - 无论如何都读不出来
- php - 如果按赞排序,则 MySQL 分页
- node.js - Node.js - 观察特定文本的子节点输出
- php - json_encode() 将大数转换为科学计数法
- python - 如何保留在 tkinter 的弹出式顶层窗口中获取的输入字段的值?
- github - GitHub 选项在 PyCharm VCS 中不可用 | 从版本控制中签出
- android - 游戏循环是否应该放在 AsyncTask 中
- python - pyttsx 错误:没有名为“引擎”的模块
- c++ - 在 C++ 中,WriteProcessMemory 不会在 VisualStudio 之外更改值