python - 如何在 pygame 中围绕枢轴点旋转 Element?

标签 python python-3.x pygame pygame-surface pygame-tick

我正在尝试围绕枢轴点旋转 pygame 中的元素(在我的例子中为字体),我的代码如下:

    import pygame, time

    pygame.init()

    display_width = 800
    display_height = 800

    window = pygame.display.set_mode((display_width, display_height))
    pygame.display.set_caption("Dials")

    black = (0, 0, 0)
    white = (255, 255, 255)
    red = (255, 0, 0)
    green = (0, 255, 0)
    blue = (0, 0, 255)


clock = pygame.time.Clock()

font = pygame.font.SysFont('Arial', 50, True)

#All Images of Dials

tutorial = [pygame.image.load('Dial_Images/tutorial_base.png')]

tutorialInputs = [[1,4,3,4], [1,4,3,2], [1,4,3,2], [1,4,3,4]]

class Dial:
    def __init__(self, x, y, radius, inputs):
        self.x = x
        self.y = y
        self.radius = radius
        self.inputs = inputs
        self.columns = len(self.inputs)
        self.rows = len(self.inputs[0])

    def drawDial(self):
        for i in range(0, self.columns):
            pygame.draw.circle(window, red, (self.x, self.y), self.radius)
            pygame.draw.circle(window, black, (self.x, self.y), self.radius, 1)

        if self.rows == 4:
            input_1 = font.render(str(self.inputs[0][0]), 1, black)
            input_2 = font.render(str(self.inputs[0][1]), 1, black)
            input_3 = font.render(str(self.inputs[0][2]), 1, black)
            input_4 = font.render(str(self.inputs[0][3]), 1, black)

            window.blit(input_1, (self.x - 4, self.y - self.radius + 10))
            window.blit(input_2, (self.x + self.radius - 35, self.y - 15))
            window.blit(input_3, (self.x - 4, self.y + self.radius - 40))
            window.blit(input_4, (self.x - self.radius + 20, self.y - 15))




def level_1():
   window.fill(white)
   dial1.drawDial()


#all Dials Instantiated

dial1 = Dial(int(display_width/2), int(display_height/2), int((display_width/2) - 100), tutorialInputs)

score = 0

run = True
level1 = True

while run:
    keys = pygame.key.get_pressed()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    pygame.display.update()
    clock.tick(100)

    if level1:
        level_1()



pygame.quit()   

下面将创建一个窗口和一个带有黑色边框的圆圈,并在 12 点钟、3 点钟、6 点钟和 9 点钟位置有 4 个数字。

我想围绕圆心旋转输入。任何允许我旋转 input_1 - 输入的 pygame 函数 _4 绕圆心90度?我在 pygame 上看到了一些函数,例如 pygame.math.vector 和其他一些 .rotate 函数,但我想要最好的方法。

此外,如果有一种方法可以清理我对输入位置进行编码的方式,以便它们在 12 点钟、3 点钟、6 点钟和 9 点钟方向对齐,那将会很有帮助.

最佳答案

仅在图像/表面中保留文本,以便您可以使用 pygame 的函数就地旋转图像(围绕图像中心)

image = pygame.transform.rotate(image, -angle)

然后使用从圆心开始的半径角度将其移动到圆的边界

angle = 0 # 90, 180, 270
x = dial_center_x
y = dial_center_y
x += radius * sin(radians(angle))
y += radius * cos(radians(angle))

最好使用 pygame.Rect() 来保持位置和大小 - 它具有诸如 .x.y 之类的属性,但是还有.center.centerx.centery,这样很容易将号码放在拨号盘的中心

image_rect = image.get_rect()

image_rect.center = dial_rect.center

然后你可以使用radiusangle将其移动到12点钟、3点钟、6点钟和9点钟位置甚至 1 点、2 点等

angle = 0 # 90, 180, 270
image_rect.centerx += radius * sin(radians(angle))
image_rect.centery += radius * cos(radians(angle))
<小时/>

enter image description here

<小时/>
import pygame
import time
import math

# --- constants --- (UPPER_CASE_NAMES)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)

DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 800

# --- classes ---

class Dial:

    def __init__(self, x, y, radius, inputs, angle_step=45):
        self.rect = pygame.Rect(x-radius, y-radius, 2*radius, 2*radius)
        self.radius = radius
        self.radius2 = radius - 30 # position for digits
        self.inputs = inputs
        self.angle_step = angle_step

    def draw(self): # no need to add prefix/postfix 'Dial' to name `draw`
        #for i in range(0, self.columns):
        # `Dial` means single object so it should draw only one circle 
        pygame.draw.circle(window, RED, self.rect.center, self.radius)
        pygame.draw.circle(window, BLACK, self.rect.center, self.radius, 1)

        angle = 0
        for number in self.inputs:
            text = font.render(str(number), 1, BLACK)

            # rotate image
            text = pygame.transform.rotate(text, -angle)

            # center image on circle
            text_rect = text.get_rect(center=self.rect.center)

            # move to border using `angle` and `radius`
            angle_rad = math.radians(180-angle)
            text_rect.centerx += self.radius2 * math.sin(angle_rad)
            text_rect.centery += self.radius2 * math.cos(angle_rad)

            window.blit(text, text_rect)

            angle += self.angle_step


# --- functions ---

def level_1():
   window.fill(WHITE)
   dial1.draw()
   dial2.draw()
   dial3.draw()

# --- main ---

pygame.init()

window = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
window_rect = window.get_rect()

pygame.display.set_caption("Dials")

clock = pygame.time.Clock()

font = pygame.font.SysFont('Arial', 50, True)

#tutorial = [pygame.image.load('Dial_Images/tutorial_base.png')]

tutorial_inputs = [[1,4,3,4], [1,4,3,2], [1,4,3,2], [1,4,3,4]]

dial1 = Dial(window_rect.centerx, window_rect.centery, window_rect.centerx-250, tutorial_inputs[0], 45)
dial2 = Dial(window_rect.centerx-250, window_rect.centery-250, window_rect.centerx-250, tutorial_inputs[1], 90)
dial3 = Dial(window_rect.centerx+250, window_rect.centery-250, window_rect.centerx-250, tutorial_inputs[2], 30)

score = 0

run = True
level1 = True

while run:
    #keys = pygame.key.get_pressed()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    pygame.display.update()
    clock.tick(100)

    if level1:
        level_1()

pygame.quit()   

关于python - 如何在 pygame 中围绕枢轴点旋转 Element?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59902716/

相关文章:

python - 使用 SQLAlchemy 计算结果集中包含的值实例

Python-将字节地址(从ReadProcessMemory)转换为字符串?

python - 如何在 python 中将图像 block 传输到特定图像的区域内?

image - pygame问题加载图像( Sprite )

python - 使用 NLP 从文本中提取关联值

python - Discord.py 赋予用户角色 - 'User' 对象没有属性 'guild'

Python 线程/多处理不需要 Mutex?

python - Python PEG 中 bitwise_or 的目的是什么?

python - 如何在 python 3 中禁用 SSL 身份验证

python - Pyinstaller EXE 在启动时崩溃