旋轉的代碼是:如何在不使用旋轉命令的情況下在Pygame中旋轉我的曲面?
pygame.transform.rotate(surface, angle)
但我不希望使用的代碼。我想寫一個自己旋轉曲面的代碼。我怎樣才能做到這一點?
旋轉的代碼是:如何在不使用旋轉命令的情況下在Pygame中旋轉我的曲面?
pygame.transform.rotate(surface, angle)
但我不希望使用的代碼。我想寫一個自己旋轉曲面的代碼。我怎樣才能做到這一點?
import pygame
SIZE = 1000, 900
pygame.init()
screen = pygame.display.set_mode(SIZE)
a=0
done = False
screen.fill((0, 0, 0))
other1 = pygame.image.load("image.jpg")
screen.blit(other1, (0, 0))
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
a=a+90
other2 = pygame.transform.rotate(other1, a)
screen.blit(other2, (0, 0))
if event.key == pygame.K_RIGHT:
a=a-90
other2 = pygame.transform.rotate(other1, a)
screen.blit(other2, (0, 0))
screen.fill((0,0,0))
pygame.display.flip()
這個答案不會試圖回答這個問題。你剛纔複製了[你的問題]的代碼(http://stackoverflow.com/questions/42153719/how-can-i-rotate-an-image-in-pygame-with-out-current-commandwith-out -pygame-tr),這是這個問題的重複。 –
有解決這個問題很多不同的方式,但我的解讀是,它應該通過旋轉度,逆時針旋轉圖像,並根據需要調整圖像大小。我還包括一個crop
功能,以消除過度的噪音。雖然,我的實現仍然存在問題,主要是它的aliased。要解決它,你可以看看this答案。
要旋轉圖像,首先需要將圖像轉換爲矩陣。這可以在pygame.surfarray.array3d
的幫助下完成,但它需要你安裝numpy。然後我們需要一個rotation matrix和一個新的矩陣,我們將從我們的圖像複製所有像素。將位置矢量與旋轉矩陣相乘時,您將獲得一個新的位置矢量。因此,我們所做的只是遍歷圖像的x-y座標,將旋轉矩陣應用於每個座標,然後在新矩陣中的新座標處添加像素。
import numpy as np
from math import sin, cos, radians
import pygame
pygame.init()
SIZE = WIDTH, HEIGHT = 720, 480
FPS = 30
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
def crop(array, background=(0, 0, 0)):
rows, cols, _ = array.shape
left, right, top, bottom = 0, cols, 0, rows
for row in range(rows):
if not np.all(array[row] == background):
top = row
break
for row in range(rows - 1, top, -1):
if not np.all(array[row] == background):
bottom = row
break
np.transpose(array, axes=(1, 0, 2))
for col in range(cols):
if not np.all(array[col] == background):
left = col
break
for col in range(cols - 1, left, -1):
if not np.all(array[col] == background):
right = col
break
np.transpose(array, axes=(1, 0, 2))
return array[top:bottom+1, left:right+1]
def rotate(surface, angle):
rect = surface.get_rect()
width, height = surface.get_size()
image_array = pygame.surfarray.array3d(surface)
angle = radians(angle)
# Rotation matrix: https://en.wikipedia.org/wiki/Rotation_matrix
rotation = np.array(
((cos(angle), -sin(angle)),
(sin(angle), cos(angle))
), dtype=np.float16
)
# Rotates the corners of the image because the distance between 2 opposite corners will always be the furthest
# distance. This helps us calculate the new width and height of our new rotated image.
y_list, x_list = zip(*(
(position @ rotation) for position in (rect.topleft, rect.topright, rect.bottomleft, rect.bottomright)
))
min_x, min_y = min(x_list), min(y_list)
new_width = int(abs(min_x - max(x_list))) + 1
new_height = int(abs(min_y - max(y_list))) + 1
# Since we're rotating the image at the topleft corner and not in the center it'll be moved. By adding the offset
# we just move it back in place.
offset = -int(min_y), -int(min_x)
rotated_image_array = np.zeros(shape=(new_height, new_width, 3), dtype=np.uint8)
for row in range(height): # Not the newly calculated height, but the original image's height.
for col in range(width):
y, x = (row, col) @ rotation + offset
rotated_image_array[int(y), int(x)] = image_array[row, col]
rotated_image_array = crop(rotated_image_array)
return pygame.surfarray.make_surface(rotated_image_array)
def main():
running = True
original_image = pygame.Surface((200, 200))
original_image.fill(pygame.Color('red'))
image = original_image
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_1:
print('Reset image.')
image = original_image
elif event.key == pygame.K_2:
print('Starting rotating.')
time = pygame.time.get_ticks()
image = rotate(image, 20)
time = pygame.time.get_ticks() - time
print('Finished rotating in {:.4E} s.'.format(time/1000))
screen.fill((255, 255, 255))
screen.blit(image, image.get_rect(center=(WIDTH // 2, HEIGHT // 2)))
pygame.display.update()
if __name__ == '__main__':
main()
你的第一步是告訴我們爲什麼你不想使用該命令......否則,我們不知道你想要什麼,也不知道爲什麼你想要它! – Douglas
你爲什麼要那樣做?這個問題不是很好... – XCode
要自己旋轉曲面,最好的選擇是將其轉換爲[surfarray](http://www.pygame.org/docs/ref/surfarray.html)並應用變換矩陣(更具體地說是[旋轉矩陣](https://en.wikipedia.org/wiki/Rotation_matrix))。 Pygame不擅長手動操作像素,所以它很可能會很慢。使用'pygame.transform.rotate'是你的最佳選擇,但是如果主要關注的是你想學習的內容,那麼你可能需要研究線性代數和矩陣計算。目前的問題太廣泛了。 –