Найти - Пользователи
Полная версия: pygame. Проблема с вращением изображения.
Начало » Python для новичков » pygame. Проблема с вращением изображения.
1
luckmaster
Всем привет!
Я недавно начал осваивать python, так что сразу прошу прощения если вопрос тупой.

Задача: отрисовывать на экране маленькую картинку (50*50 пикселов), картинка должна вращаться и центр картинки должен всегда оставаться в одной позиции.

В общем я кое-как решил данную задачу, только при вращении картинка немного дрожит (грешу на функцию pygame.transform.rotate).
Может кто посоветует как избавится от дрожания?
Вот мой код:

# -*- coding: UTF-8 -*-
import pygame

class Sprite:
def __init__(self, filename):
self.image = pygame.image.load(filename)
def render(self, screen, pos = (0, 0), angle = 0):
#Поворачиваю картинку
rot_im = pygame.transform.rotate(self.image, angle)

#Вычисляю новую позицию, иначе центр картинки сместится
ow, oh = self.image.get_size()
rw, rh = rot_im.get_size()
scale_x, scale_y = float(rw) / ow, float(rh) / oh
dx = round((ow / 2.0) * scale_x - (ow / 2.0))
dy = round((oh / 2.0) * scale_y - (oh / 2.0))
new_pos = pos - dx, pos - dy

#Отрисовываю повернутую картинку
screen.blit(rot_im, new_pos)
image = 0

pygame.init()
screen = pygame.display.set_mode((800, 600))

sprite = Sprite('box.png')
angle = 0.0

clk = pygame.time.Clock()
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT: exit(0)
if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE: exit(0)

screen.fill((255, 255, 255))
sprite.render(screen, (0, 0), angle)
angle += 0.5
pygame.display.update()

clk.tick_busy_loop(30)
Андрей Светлов
Координаты new_pos у тебя целые. А дрожание получается как раз на отброшенную дробную часть.
bw
Для этого нужно избавиться от изменения размера результирующего изображения (разрешение всегда должно быть одинаковым). И, соответственно, вычисления смещения координат (это смещение, другими словами, должно быть фиксировано). Как так сделать, подумай сам. Теоретически - должно помочь.

А зачем такая сложная формула для позиционирования? Почему бы не сделать так:
new_pos = round(pos[0] - rw / 2.0), round(pos[1] - rh / 2.0)
..bw
luckmaster
Андрей Светлов
Координаты new_pos у тебя целые. А дрожание получается как раз на отброшенную дробную часть.
Я тоже так сразу подумал, но в таком случае дрожание должно быть максимум на 1 пиксел, а на сколько я могу оценить визуально - оно дрожит больше чем на пиксел. Хотя конечно сложно подсчитать это визуально :)

Ради эксперимента я исключил из функции Sprite.render весь код, который может приводить к смещению.
#Сделал так
def render(self, screen, pos = (0, 0), angle = 0):
rot_im = pygame.transform.rotate(self.image, angle)
screen.blit(rot_im, pos)
И даже так немного дрожит, значительно меньше, но всеже дрожит. Из этого я делаю вывод что что-то не так с функцией pygame.transform.rotate
И уже к этому добавляется проблема с потерянной дробной частью, и дрожание усиливается.

bw
А зачем такая сложная формула для позиционирования? Почему бы не сделать так:
new_pos = round(pos - rw / 2.0), round(pos - rh / 2.0)
Сделаю так, спасибо :)


Интиресно, а может в pygame уже есть готовое решение этой задачи?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB