随着玩家移动旋转三角形会导致三角形在没有输入的情况下移动

rotating triangle with player movement causes the triangle to move without input

我用这个函数得到了三角形的向下旋转

def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = (dx * scale / len, dy * scale / len) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts

但后来我使用另一个函数用公式 (Ax + Bx + Cx)/3

得到三角形的中间
def getCenter(self):
        # formula: (Ax + Bx + Cx)/3
        x = (self.x1 + self.x2 + self.x3)/3
        y = (self.y1 + self.y2 + self.y3)/3
        return (x, y)

这里是调用两个函数的地方

def update(self):
        # point to mouse
        mouseP = pygame.mouse.get_pos()
        center = self.getCenter(mouseP)
        points = self._rotate(center, 12, mouseP)
        self.x1 = points[0][0]
        self.x2 = points[1][0]
        self.x3 = points[2][0]
        self.y1 = points[0][1]
        self.y2 = points[1][1]
        self.y3 = points[2][1]

和移动函数

def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x1 -= self.vel
            self.x2 -= self.vel
            self.x3 -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x1 += self.vel
            self.x2 += self.vel
            self.x3 += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y1 -= self.vel
            self.y2 -= self.vel
            self.y3 -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y1 += self.vel
            self.y2 += self.vel
            self.y3 += self.vel

所有这一切都发生了 https://streamable.com/1mfibu 我正在使用 pygame

因此您使用位置值计算中心。然后使用该中心旋转点并将结果分配回位置值。这使得值随着时间的推移而增加。您需要将这些旋转点保存在与存储原始位置值的变量不同的变量中。这是一个工作示例。它直接returns旋转的点并绘制它们。

import pygame, math

class Tri:
    def __init__(self):
        self.x1 = self.x2 = self.x3 = 300
        self.y1 = self.y2 = self.y3 = 300
        self.vel = 0.05
    
    def getCenter(self):
        # formula: (Ax + Bx + Cx)/3
        x = (self.x1 + self.x2 + self.x3)/3
        y = (self.y1 + self.y2 + self.y3)/3
        return (x, y)

    def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x1 -= self.vel
            self.x2 -= self.vel
            self.x3 -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x1 += self.vel
            self.x2 += self.vel
            self.x3 += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y1 -= self.vel
            self.y2 -= self.vel
            self.y3 -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y1 += self.vel
            self.y2 += self.vel
            self.y3 += self.vel

    def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = ((dx / len) * scale, (dy / len) * scale) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts

    def update(self):
        # point to mouse
        mouseP = pygame.mouse.get_pos()
        center = self.getCenter()
        points = self._rotate(center, 12, mouseP)
        return points
        
    def getpoints(self):
        return self.update()

window = pygame.display.set_mode((600, 600))
tri = Tri()

while True:
    pygame.event.pump()
    
    tri.move()

    window.fill((255, 255, 255))
    pygame.draw.polygon(window, (0, 0, 0), tri.getpoints())
    pygame.display.flip()

问题是,(0, 0) 不是三角形的中心点:

[(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]

(0, 0)是等边三角形的圆心:

a = math.sqrt(3)/2 # ~ 0.866 
[(-0.5, -a), (-0.5, a), (1.0, 0.0)]

或三角形的中心

[(-0.525, -0.866), (-0.525, 0.866), (1.05, 0.0)]

因为你计算了每一帧的三角形的中心,所以三角形从 (0, 0) 到每一帧的点 [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)] 的三角形的中心移动了距离。


不需要移动三角形的三个角点和计算三角形的中心。保存并仅移动三角形的中心。 (self.xself.y)。 3个角点可以从中心点和三角形的方向计算:

import pygame
import math

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

class Triangle:
    def __init__(self, x, y):
        self.x, self.y = x, y 
        self.vel = 5
        self.points = []

    def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = (dx * scale / len, dy * scale / len) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts
    
    def update(self):
        mouseP = pygame.mouse.get_pos()
        self.points = self._rotate((self.x, self.y), 12, mouseP)

    def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y += self.vel
    def draw(self, surf):
        pygame.draw.polygon(surf, (255, 255, 255), self.points)

triangle = Triangle(200, 200)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False      
    
    triangle.update()
    triangle.move()

    window.fill(0)
    triangle.draw(window)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
exit()