Pygame. Rotate object

Masai

Вопрос по поводу Rotate (башню на танке поворачивать и сам корпус и т.д). В sfml я это делал вознёй с origin, а потом поворачивал. А в Пайгейме как-то иначе это делается. pygame.transform.rotate поворачивает объект не по своему центру личному, ещё и коверкает изображение. Допустим вот у меня Tower_tank = загрузил изображение. Есть angle переменная. И надо поворачивать башню. Заранее спасибо!В ютубе я видел какие-то схемы с вспомогательными rect, но не совсем понял...
9 ответов

Masai

Функция поворота вокруг центра
def rot_center(image, rect, angle):
        rot_image = pygame.transform.rotate(image, angle)
        rot_rect = rot_image.get_rect(center=rect.center)
        return rot_image,rot_rect
сам поворот
rect = image.get_rect(center=(точка где должно отрисовываться изображение)) 
surf, r = rot_center(image, rect, angle)
screen.****(surf, r)


Masai

Благодарю. =) Правда не совсем выходит так как надо. Хоть Башня и остаётся на своей позиции, не улетает куда-то, но крутиться она не по центру своего люка. И как раз в SFML Origin делал эту работу уточняющую. Я даже зашёл в VS в свой тот С++ код и нашёл эти строки.
Body_Corpus.setOrigin(Vector2f(Body_Corpus.getSize().x/2, Body_Corpus.getSize().y/2));
Body_Tower.setOrigin(Body_Tower.getSize().x/2, Body_Tower.getSize().y - (Body_Tower.getSize().y / 100.f) * 21.3f);
И из-за них всё не только находилось в нужном периметре при повороте, но и поворачивалось исходя из некой точки оси указанной. А в pygame тот rect как я понял он просто уточняет центр нахождения фигуры, вроде немного другое это...П.С Вообще как ни странно, в pygame уже раза 3 напарываюсь на проблемы на простых вещах где нужно заморочиться. В SFML как-то эти рубежи проходились проще, может пока так показалось...


Masai

Прошу прощения, забыл наглядно показать. Вот как это происходит. Т.е всё происходит в Рамках и правда заданных координат, в этом прямоугольнике, но сама ось вращения тем самым rect не настраивается, а просто уточняется где центр нахождения объекта.


Masai

Вот тут пример пушки http://fivedots.coe.psu.ac.th/Softwa...0Games/Cannon/


Masai

ТабуретY, не хочу показаться злоупотребляющим, но не могли бы Вы свой тот верхний пример (пост номер два) адаптировать для поворота пушки по своей оси?Вот клянусь, часа 2-3 потратил, пробовал разобраться в том коде, адаптировать свой, что-то всё равно не совсем выходит. Просто я уж что-то заколебался, а впереди новые проблемы (которых не было в SFML): обработка 2+ клавиш одновременно. Уже мысли возникают зачем мне эти запары на Pythone, который в принципе меньше подходит для игр (особенно если баловаться с гружённостью), ежели есть С++ с SFML где как-то худо бедно продвигался куда дальше чем тут.


Masai

Вот пример. вращение изображения вокруг указанной точки
import pygame
from pygame.locals import *
 
def rotate(img, pos, angle):
    w, h = img.get_size()
    img2 = pygame.Surface((w*2, h*2), pygame.SRCALPHA)
    img2.****(img, (w-pos[0], h-pos[1]))
    return pygame.transform.rotate(img2, angle)
 
pygame.init()
screen = pygame.display.set_mode([640,480])
screen.fill((135, 206, 250))
pygame.display.set_caption("Вращение")
 
imagec = pygame.image.load("gun.png").convert_alpha()
pivot = (200, 200) # положение центра вращения на экране
angle = 0
center_image = (30,22.5) # положение центра вращения на изображении
 
clock = pygame.time.Clock()
 
running = True    
while running:
    clock.tick(60)
 
    for event in pygame.event.get():
        if event.type == QUIT: 
            running = False
 
    screen.fill((135, 206, 250))
 
    image = rotate(imagec, center_image , angle)
    rect = image.get_rect()
    rect.center = pivot
    screen.****(image, rect)
 
    angle += 1 % 360
 
    pygame.display.update()
 
pygame.quit()


Masai

Спасибо добрый человек! Подкорректировал циферки в centre_image под свой случай и работает!А можно уточнить? В SFML я там поворачивая башню, мог расчитать, зная угол поворота башни and координаты башни, положение снаряда и так же угол его направления после выстрела. Тут тоже в данном случае ничто не мешает вычислить где быть снаряду и куда смотреть? Я не прошу кода, просто сразу уточнить. --- А так анализирую код. Со своим пока слабым пониманием. На этот раз используется Surface - поверхность некая вспомогательная. Что интересно, у Surface есть собственный метод **** (а image мы совали в **** окна). Т.е мы создаём этот Сюрфейс, задавая размер его ориентируясь на размер нашей картинки (но зачем-то ещё умножаем на 2). Так же передаём некий флаг SCRALPHA - как я понял чтоб показывалось только изображение на поверхности, остальное чтоб было скрыто. И вот тут ещё один моментик непонятный. В функции поворота строка: img2.****(img, (w-pos[0], h-pos[1])) Т.е рисуем нашу башню в функции. (Не совсем понял строку (w-pos[0], h-pos[1])))Затем мы возвращаем результат поворота. И рисуем опять уже в нашем главном цикле: screen.****(image, rect) И ещё используем pivot, но вот не совсем понял зачем он нужен. И почему он 200-200. Я экспериментирую и меняю числа, вижу как это всё влияет, но так как тут и pivot, и center_image влияет на результат, немного запутался. Прошу прощения, что загрузил... Но я думаю эту тему кто-то позже увидит и кому-то это тоже будет полезно (в т.ч и эти прояснения).


Masai

В SFML я там поворачивая башню, мог расчитать, зная угол поворота башни and координаты башни, положение снаряда и так же угол его направления после выстрела. Тут тоже в данном случае ничто не мешает вычислить где быть снаряду и куда смотреть?
В pygame это все можно вычислять, выше я привел ссылку там в примере с пушкой можете посмотреть
Что интересно, у Surface есть собственный метод **** (а image мы совали в **** окна).
У всех surface есть метод ****, после загрузки картинки тоже превращаются в surface, так что можно сделать **** картинки в картинку
но так как тут и pivot, и center_image влияет на результат
center_image - это точка вокруг которой будет вращаться изображение, отсчитывается от левого верхнего угла изображения pivot - это место на экране где будет отрисовано изображение, отсчитывается от левого верхнего ушла экрана
Т.е мы создаём этот Сюрфейс, задавая размер его ориентируясь на размер нашей картинки (но зачем-то ещё умножаем на 2).В функции поворота строка: img2.****(img, (w-pos[0], h-pos[1])) Т.е рисуем нашу башню в функции. (Не совсем понял строку (w-pos[0], h-pos[1])))
создаем вспомогательный surface в 2 раза больше размера изображения для удобства расчетов, если размер (w*2, h*2), то центр в точке (w,h) в функцию **** передаются координаты левого верхнего угла pos = center_image, поэтому img2.****(img, (w-pos[0], h-pos[1])) отрисует пушку в центре вспомогательного surface, затем вращаем вспомогательный surface и выводим его на экран в точке pivot


Masai

Большое спасибо! Хоть и помучился, но смог интегрировать всё это в свои танки. По поводу понимания, надо будет ещё поразмыслить. Конечно было бы проще если бы у изображения был бы set_origin в pygame. Чтоб обойтись без доп. поверхности. Без дополнительных манипуляций. Т.е сделали переменную с изображением и ей и орудуем. А так приходится создавать временную поверхность, на неё отрисовывать наше изображаение (imagec), результат передавать дополнительной новой переменной (image) и лишь после этого осуществится эта операция. Ещё раз большое спасибо!