[英]How to make smooth movement in pygame
我和我的一個朋友剛剛開始學習在 repl.it 上使用 pygame 進行編程,對於我們的第一個“真實”項目,我們希望制作一個像點擊式冒險一樣的老派。
然而,我們在角色的移動上遇到了問題,如果我們點擊屏幕上的某個地方,角色只是“傳送”到那里,但我們希望它看起來盡可能流暢。
所以基本上,我們想要擺脫角色的“傳送”,而是從角色當前位置到鼠標位置平滑地逐幀過渡。
我們已經嘗試減慢 while 循環的速度,以便我們可以在每次執行 while 循環時投射角色,但這只會使整個站點崩潰,我們還嘗試在 repl.it 之外執行此操作,以防出現問題與網站,但它也沒有在那里工作。
#PMC = Character
#mpos = the mouse position
#mstate= the state of the mouse buttons (0 if nothing is pressed, 1 if a mouse
#button is pressed)
#charspeed = the speed at which the character moves (=1px)
```
#---PMC movement when mouse click-----------------------
#---x,y = mpos x2,y2 = characterpos
if mstate == (1,0,0):
#print('x: ', x, ' y: ', y, ' x2: ', x2, ' y2: ', y2) #debugging_positions
while x2 != x:
if x2>x:
x2-=charspeed
screen.blit(pmc, (x2-46, y2-184))
if x2<x:
x2+=charspeed
screen.blit(pmc, (x2-46, y2-184))
while y2 != y:
if y2>y:
y2 -= charspeed
screen.blit(pmc, (x2-46, y2-184))
if y2<y:
y2 += charspeed
screen.blit(pmc, (x2-46, y2-184))
你有一個游戲循環,所以使用它。 只需在每一幀中將角色移動某個位置即可。 例如,每幀step
角色:
step = 1
if x2 + step <= x:
x2 += step
elif x2 - step >= x:
x2 -= step
else:
x2 = x
if y2 + step <= y:
y2 += step
elif y2 - step >= y:
y2 -= step
else:
y2 = y
對於更復雜的解決方案,您必須計算從點到目標的歐幾里得距離。 使用pygame.math.Vector2
進行計算。
計算跟隨者和精靈之間的距離以及從 ( follower_x
, follower_y
) 到 ( mainsprite_x
, mainsprite_y
) 的單位方向向量。 單位向量可以通過將方向向量除以距離或通過歸一化( normalize()
)方向向量來計算:
target_vector = Vector2(mainsprite_x, mainsprite_y)
follower_vector = Vector2(follower_x, follower_y)
distance = follower_vector.distance_to(target_vector)
direction_vector = target_vector - follower_vector
if distance > 0:
direction_vector /= distance
現在你可以定義一個精確的step_distance
並移動到精靈的 follower int 方向:
if distance > 0:
new_follower_vector = follower_vector + direction_vector * step_distance.
定義一個maximum_distance
和一個minimum_distance
。 最小步距為:
min_step = max(0, distance - maximum_distance)
最大步距為
max_step = distance - minimum_distance
把它們放在一起:
minimum_distance = 0
maximum_distance = 10000
target_vector = Vector2(mainsprite_x, mainsprite_y)
follower_vector = Vector2(follower_x, follower_y)
new_follower_vector = Vector2(follower_x, follower_y)
distance = follower_vector.distance_to(target_vector)
if distance > minimum_distance:
direction_vector = (target_vector - follower_vector) / distance
min_step = max(0, distance - maximum_distance)
max_step = distance - minimum_distance
step_distance = min_step + (max_step - min_step) * LERP_FACTOR
new_follower_vector = follower_vector + direction_vector * step_distance
最小的例子: repl.it/@Rabbid76/PyGame-FollowMouseSmoothly
import pygame
LERP_FACTOR = 0.05
minimum_distance = 25
maximum_distance = 100
def FollowMe(pops, fpos):
target_vector = pygame.math.Vector2(*pops)
follower_vector = pygame.math.Vector2(*fpos)
new_follower_vector = pygame.math.Vector2(*fpos)
distance = follower_vector.distance_to(target_vector)
if distance > minimum_distance:
direction_vector = (target_vector - follower_vector) / distance
min_step = max(0, distance - maximum_distance)
max_step = distance - minimum_distance
step_distance = min_step + (max_step - min_step) * LERP_FACTOR
new_follower_vector = follower_vector + direction_vector * step_distance
return (new_follower_vector.x, new_follower_vector.y)
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
follower = (100, 100)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
player = pygame.mouse.get_pos()
follower = FollowMe(player, follower)
window.fill(0)
pygame.draw.circle(window, (0, 0, 255), player, 10)
pygame.draw.circle(window, (255, 0, 0), (round(follower[0]), round(follower[1])), 10)
pygame.display.flip()
我不建議使用 repl.it,因為它往往運行得很慢。
此外,您的代碼應該更像這樣:
while True:
screen.fill((0,0,0))
stuff happens
if x2>x:
x2-=charspeed
elif x2<x:
x2+=charspeed
elif y2>y:
y2 -= charspeed
elif y2<y:
y2 += charspeed
screen.blit(pmc, (x2-46, y2-184))
pygame.display.flip()
在顯示一直移動到 (x,y) 之前,您不會更新顯示
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.