[英]How to draw a moving circle in Pygame with a small angle at a low speed and blinking?
下面的代碼在屏幕上移動兩個球。 第一個以低速移動10度角,繪圖質量好。 第二個球以 1 度的角度移動,為了尊重該角度,速度必須高得多,並且繪圖不令人滿意,閃爍很多。 有沒有辦法減慢第二個球的繪制速度並避免過度眨眼?
import pygame, sys, math
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((1000, 600))
pygame.display.set_caption('Bouncing Ball with position and angle')
# Set our color constants
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
# Create the ball class
class Ball():
def __init__(self,
screen,
color,
radius,
startX,
startY,
speed,
angle=45):
super().__init__()
self.screen = screen
self.color = color
rectSize = radius * 2
self.rect = pygame.Rect(startX, startY, rectSize, rectSize)
self.speed = speed
self.angle = math.radians(angle)
def update(self):
delta_x = self.speed * math.cos(self.angle)
delta_y = self.speed * math.sin(self.angle)
self.rect = self.rect.move(delta_x, delta_y)
if self.rect.right >= self.screen.get_width() or self.rect.left <= 0:
self.angle = math.pi - self.angle
if self.rect.top <= 0 or self.rect.bottom >= self.screen.get_height():
self.angle = -self.angle
def draw(self):
'''
Draw our ball to the screen with position information.
'''
pygame.draw.circle(self.screen, self.color, self.rect.center, int(self.rect.width / 2))
# Create a new Ball instance named 'myball'
myball = Ball(screen=DISPLAYSURF, color=YELLOW, startX=100, startY=100, radius=150, speed=8, angle=10)
mySmaLlAngleball = Ball(screen=DISPLAYSURF, color=YELLOW, startX=100, startY=500, radius=150, speed=58, angle=-1)
run = True
clock = pygame.time.Clock()
# Display loop
while run:
# Handle events
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Update ball position
myball.update()
mySmaLlAngleball.update()
# Draw screen
DISPLAYSURF.fill(BLACK)
myball.draw()
mySmaLlAngleball.draw()
pygame.display.update()
clock.tick(30)
問題是因為pygame.Rect
存儲積分坐標:
Rect 對象的坐標都是整數。 [...]
delta_x
和delta_y
的小數部分在self.rect.move(delta_x, delta_y)
處丟失。
您必須使用浮點數進行計算。 添加一個屬性self.pos
,它是一個包含 2 個組件的元組,用於存儲球的中心點:
self.pos = self.rect.center
以最大浮點精度計算 position:
delta_x = self.speed * math.cos(self.angle)
delta_y = self.speed * math.sin(self.angle)
self.pos = (self.pos[0] + delta_x, self.pos[1] + delta_y)
通過round()
ed position 更新self.rect.center
。
self.rect.center = round(self.pos[0]), round(self.pos[1])
self.pos
是“內部”position 並負責 position 的精確計算。 self.rect.center
是積分 position 負責抽球。 self.pos
在每一幀中略有變化。 self.rect.center
只有在坐標的 a 分量改變 1 時才會改變。
Class Ball
:
class Ball():
def __init__(self,
screen,
color,
radius,
startX,
startY,
speed,
angle=45):
super().__init__()
self.screen = screen
self.color = color
rectSize = radius * 2
self.rect = pygame.Rect(startX, startY, rectSize, rectSize)
self.speed = speed
self.angle = math.radians(angle)
self.pos = self.rect.center
def update(self):
delta_x = self.speed * math.cos(self.angle)
delta_y = self.speed * math.sin(self.angle)
self.pos = (self.pos[0] + delta_x, self.pos[1] + delta_y)
self.rect.center = round(self.pos[0]), round(self.pos[1])
if self.rect.right >= self.screen.get_width() or self.rect.left <= 0:
self.angle = math.pi - self.angle
if self.rect.top <= 0 or self.rect.bottom >= self.screen.get_height():
self.angle = -self.angle
def draw(self):
'''
Draw our ball to the screen with position information.
'''
pygame.draw.circle(self.screen, self.color, self.rect.center, int(self.rect.width / 2))
使用此解決方案,您可以擴大每秒的觸發器 ( clock.tick()
) 並將速度縮小相同的比例。 這會導致平穩的運動而不會眨眼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.