python - 如何使 Sprite 沿着pygame中的曲线移动到点

标签 python pygame

我正在做一个 pygame 项目进行练习,我需要一个 Sprite 移动到屏幕上的某个点,我做到了,但它沿直线移动,我想学习如何让它移动到同一条直线曲线上的点。

def move_to_point(self, dest_rect, speed, delta_time):

        #  Calculates relative rect of dest
        rel_x = self.rect.x - dest_rect[0]
        rel_y = self.rect.y - dest_rect[1]
        
        # Calculates diagonal distance and angle from entity rect to destination rect
        dist = math.sqrt(rel_x**2 + rel_y**2)
        angle =  math.atan2( - rel_y,  - rel_x)
        
        # Divides distance to value that later gives apropriate delta x and y for the given speed
        # there needs to be at least +2 at the end for it to work with all speeds
        delta_dist = dist / (speed * delta_time) + 5
        print(speed * delta_time)
        
        # If delta_dist is greater than dist entety movement is jittery
        if delta_dist > dist:
            delta_dist = dist
        
        # Calculates delta x and y
        delta_x = math.cos(angle) * (delta_dist)
        delta_y = math.sin(angle) * (delta_dist)
        

        if dist > 0:
            self.rect.x += delta_x 
            self.rect.y += delta_y 

这个 Action 看起来像

this

我希望它像

this

最佳答案

有很多方法可以实现您想要的目标。一种可能性是 Bézier curve :

def bezier(p0, p1, p2, t):
    px = p0[0]*(1-t)**2 + 2*(1-t)*t*p1[0] + p2[0]*t**2
    py = p0[1]*(1-t)**2 + 2*(1-t)*t*p1[1] + p2[1]*t**2   
    return px, py

p0p1p2 是控制点,t 是范围 [0 ,0, 1,0]表示沿曲线的位置。 p0 是曲线的起点,p2 是曲线的终点。如果t = 0,则贝塞尔函数返回的点等于p0。如果t=1,则返回的点等于p2

另请参阅PyGameExamplesAndAnswers - Shape and contour - Bezier


最小示例:

import pygame

pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock() 

def bezier(p0, p1, p2, t):
    px = p0[0]*(1-t)**2 + 2*(1-t)*t*p1[0] + p2[0]*t**2
    py = p0[1]*(1-t)**2 + 2*(1-t)*t*p1[1] + p2[1]*t**2   
    return px, py

dx = 0
run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    pts = [(100, 100), (100, 400), (400, 400)]

    window.fill(0)
    for p in pts:
        pygame.draw.circle(window, (255, 255, 255), p, 5)
    for i in range(101):
        x, y = bezier(*pts, i / 100)
        pygame.draw.rect(window, (255, 255, 0), (x, y, 1, 1))

    p = bezier(*pts, dx / 100)
    dx = (dx + 1) % 101
    pygame.draw.circle(window, (255, 0, 0), p, 5)
    pygame.display.update()

pygame.quit()
exit()

关于python - 如何使 Sprite 沿着pygame中的曲线移动到点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74070512/

相关文章:

python - 安装 Python lineprofiler 时出错

python - Pygame:如何改变背景颜色

python - Pygame 音频断断续续和滞后

python - Pygame - 我如何 blit 图像但改变它的颜色?

python - 在 UNIX 网络共享上从 Windows 创建硬链接(hard link)/符号链接(symbolic link)

python - 对 3d numpy 数组进行子集化

python - 为 Django 表单中的只读字段动态创建 clean_* 方法

python - Ubuntu 16.04 中 pip3 在哪里下载 .whl 文件?

Python Pygame 字体 x 坐标

python - 想要在 X 和 O 之间交替