猿问

在表面上绘制并使用 pygame 旋转

我试图在 Python 中使用命令 context.rotate(angle) 在 JS 中模拟一些可用的行为。


我有以下代码: import pygame import math import numpy as np


pygame.init()


CLOCK = pygame.time.Clock()

RED = pygame.color.THECOLORS['red']

WHITE = pygame.color.THECOLORS['white']

screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)

screen_width, screen_height = screen.get_size()

surface = pygame.Surface((50, 50), pygame.SRCALPHA)

surface.fill((0, 0, 0))

rotated_surface = surface

rect = surface.get_rect()

ax = int(screen_width / 2)

ay = int(screen_height / 2)

angle = 0

print("Size of the screen ({}, {})".format(screen_width, screen_height))

print("Center of the screen ({}, {})".format(ax, ay))

myfont = pygame.font.SysFont("monospace", 12)


pygame.display.set_caption("Test rotate")


main_loop = True

amplifier = 200



def calculate_angle(mouse_position):

    dx = mouse_position[0] - ax

    dy = mouse_position[1] - ay

    return np.arctan2(dy,dx)


while main_loop:

    for event in pygame.event.get():

        keys = pygame.key.get_pressed()

        if event.type == pygame.QUIT or keys[pygame.K_ESCAPE]:

            main_loop = False


    pos = pygame.mouse.get_pos()

    angle = (calculate_angle(pos) * 180)/math.pi

    screen.fill((255,255,255))

    rotated_surface = pygame.transform.rotate(surface, -angle)

    rect = rotated_surface.get_rect(center = (ax, ay))

    screen.blit(rotated_surface, (rect.x, rect.y))

    pygame.draw.line(rotated_surface, WHITE, (ax,ay), (ax+20, ay), 1)

    pygame.draw.line(rotated_surface, WHITE, (ax+10,ay-10), (ax+20, ay), 1)

    pygame.draw.line(rotated_surface, WHITE, (ax+10,ay+10), (ax+20, ay), 1)

    pygame.display.update()

    CLOCK.tick(30)



pygame.quit()

我正在绘制一个箭头并希望根据鼠标在屏幕上的位置旋转它。我当然可以在每次进行一些正弦、余弦计算时重新绘制线条,但这很痛苦。我认为表面可以在这里帮助我,事实上,它适用于完美旋转的矩形。但是将我的线条画到表面上是行不通的。


所以,我想我误解了表面的用途,或者我编码错误,有更好的方法来做到这一点。请注意,如果我在我的 draw.line 指令中用 screen 替换了 Rodated_surface,箭头确实会在屏幕上绘制,但永远不会旋转。


有什么想法(除了使用图像/精灵;))?


慕无忌1623718
浏览 170回答 1
1回答

忽然笑

问题是您在表面积外绘制箭头线。每个表面的左上角坐标为 (0, 0),因此它们都有自己的(本地)坐标系。由于您使用屏幕的中心坐标来绘制线条,因此不会在可见表面区域中绘制箭头。我会使用局部坐标在 while 循环之前的原始表面上绘制线条,然后旋转它并在循环内获得一个新的矩形。import mathimport pygamepygame.init()CLOCK = pygame.time.Clock()GRAY = pygame.color.THECOLORS['gray50']WHITE = pygame.color.THECOLORS['white']screen = pygame.display.set_mode((800, 600))screen_rect = screen.get_rect()  # A rect with the size of the screen.surface = pygame.Surface((50, 50), pygame.SRCALPHA)# surface.fill((0, 50, 150))  # Fill the surface to make it visible.# Use the local coordinate system of the surface to draw the lines.pygame.draw.line(surface, WHITE, (0, 0), (25, 0), 1)pygame.draw.line(surface, WHITE, (0, 0), (25, 25), 1)pygame.draw.line(surface, WHITE, (0, 0), (0, 25), 1)# I rotate it so that the arrow is pointing to the right (0° is right).surface = pygame.transform.rotate(surface, -135)rect = surface.get_rect()angle = 0# If you're using Python 3.6+, you can use f-strings.print(f"Size of the screen {screen.get_size()}")print(f"Center of the screen {screen_rect.center}")def calculate_angle(mouse_position):    dx = mouse_position[0] - screen_rect.centerx    dy = mouse_position[1] - screen_rect.centery    return math.atan2(dy, dx)main_loop = Truewhile main_loop:    for event in pygame.event.get():        # You shouldn't use `pygame.key.get_pressed` in the event loop.        if (event.type == pygame.QUIT            or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):            main_loop = False    pos = pygame.mouse.get_pos()    angle = math.degrees(calculate_angle(pos))    screen.fill(GRAY)    # Now just rotate the original surface and get a new rect.    rotated_surface = pygame.transform.rotate(surface, -angle)    rect = rotated_surface.get_rect(center=(screen_rect.center))    screen.blit(rotated_surface, rect)    pygame.display.update()    CLOCK.tick(30)pygame.quit()我还尝试改进了一些其他内容(查看评论)。
随时随地看视频慕课网APP

相关分类

Python
我要回答