pygame.ransform.rotate

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Hallo Community,

bei der im Titel genannten Funktion trat bei mir ein Bug auf, der darin resultierte, dass das Bild das ichrotieren lassen wollte verschwand und ein schwarzer (je nach Bild auch anderstfarbig) Fleck immer weiter ausbreitete und immer mehr RAM frass. Also las ich mir den Abschnitt um rotate in der Doku nochmal genau durch und stellte fest, dass das kein Bug ist sonder ganz normal: http://www.pygame.org/docs/ref/transfor ... orm.rotate
Weiß jemand wie ich das umgehen kann?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Imperator hat geschrieben:Weiß jemand wie ich das umgehen kann?
Ja, das habe ich in meinem Pygame-Talk mal angesprochen. Du darfst ein Bild nicht mehrmals rotieren. Du musst das Ursprungsbild mit immer anderem Winkel jeweils neu rotieren.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Äh, meinst du damit, ich soll das Bild immer bevor es gedreht wird nochmal reseten?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Imperator hat geschrieben:Äh, meinst du damit, ich soll das Bild immer bevor es gedreht wird nochmal reseten?
Du speichers immer ein mal das Ursprungsbild. Dieses rotierst du dann um sagen wie mal 1°. Dann willst du noch ein mal rotieren, wieder 1°. Statt jetzt das rotierte Bild nochmal zu rotieren, nimmst du das Ursprungsbild und rotierst es um 2°. In ``screensaw.py`` habe ich sowas in der ``AXE`` Demo implementiert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Danke, war mir zuerst nur nicht sicher ob ich es auch richtig verstanden habe.
Jetzt gehts dem Spieler mit einem tollen roteirenden Geschützturm an den Kragen :twisted:
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Heureka!
Habe selbiges Problemchen. Wenn das so ist, weiß man ja nun bescheid. Nur, um ehrlich zu sein: so ganz klar ist es mir noch nicht!
Ich meine: wie kann ich ein Bild rotieren und wenn ich es noch mals rotieren will, vom ursprünglichen Punkt wieder rotieren?
Brauche ich dazu eine Art "Hilfsrect"?

Köntte mir das jemand noch ein wenig "ausdeutschen"? Danke.
Gruß!
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Hallo,

erstelle doch einfach einmal die Surface 'image' und eine Surface 'image_backup' (mit image.copy()).
Nun rotierst du immer mit image = pygame.transform.rotate(image_backup, winkel). image_backup ist also immer das Bild in Originalausrichtung, nur image änderst du.
Ich hoffe, das ist verständlich ;)

Gruß Fred
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

C4S3 hat geschrieben:Ich meine: wie kann ich ein Bild rotieren und wenn ich es noch mals rotieren will, vom ursprünglichen Punkt wieder rotieren?
Brauche ich dazu eine Art "Hilfsrect"?
Nein. Du hast einfach zwei Bilder. Das Ursprüngliche, das speicherst du ab. Wenn du etwas rotieren willst, dann nimmst du das unrotierte Ursprungsbild und rotierste es. Wenn du nun aber noch einmal rotieren willst, nimmst du statt dem bereits rotierten einfach das ursprüngliche, unrotierte und rotierst das.

Kurz zusammengefasst: du darfst ein Bild nicht mehr als ein mal rotieren. Sonst kommt Müll raus.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

OK, soweit habe ich das ja nun durch rumprobieren hinbekommen, denke ich. Was jetzt noch fehlt, ist folgendes (das hatte ich anfangs gar nicht bedacht):
Zum Testen hatt ich ein Bild mit 128x128px gemacht.
Wenn ich das Bild jetzt aber Rotiere, ändert sich ja die Bildgröße, bzw. das Rect-Objekt, wenn ich richtig liege.
Wenn ich aber beim Blitten, die X/Y-Koordinaten angebe, kommt wieder Müll dabei raus, weil der Mittelpunkt meines Objektes nicht mehr stimmt.

Gibt es da noch eine nette Möglichkeit, bzw. kann mir bitte jemand einen Denkanstoß geben? Irgendwie muss ich den Mittelpunkt meines Objekts immer an die gleiche Stelle bekommen, egal welche Größe es hat.

Danke.

Code: Alles auswählen

import pygame
from pygame.locals import *
import sys

img = "cross.png"

pygame.init()

screen = pygame.display.set_mode((320,240), 0, 32)
pygame.display.set_caption("transform.rotate - Test")

cross = pygame.image.load(img).convert_alpha()
toRotate = pygame.Surface((128,128))
toRotate = cross.copy()
angle = 0

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        elif event.type == pygame.KEYUP and event.key == pygame.K_q:
            sys.exit()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            angle += 1
            toRotate = pygame.transform.rotate(cross, angle)

    x,y = 50,50
    screen.fill((0,0,255))
    screen.blit(toRotate,(x,y))
    pygame.display.update()
Gruß!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dafür hat ja auch jedes Rect eine ``center``-Koordinate, die du verwenden kannst um das Rect wieder an die richtige Stelle zu positionieren.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Mein Bild ist ja ein Surface und kein Rect! Wie bekomme ich die zur Kooperation? Ich habe es versucht, komme aber auf keinen grünen Zweig. :(
Gruß!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

``Surfaces`` haben ``get_rect()``, wo du auch etwa ``center`` definieren kannst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

:roll:

Pfff...
Kennt ihr das Gefühl, wenn ihr euch absolut nicht sicher seid, und raten müsst, wie denn etwas gehen könnte!? So ist es mir gegangen, weil mir einige Zusammenhänge unklar waren. Teile der Doku lesen, probieren, ärgern. Nächsten Teil der Doku lesen, probieren, ... usw.
Naja, macht nix.

Danke Leonidas, dass du mir nur die Denkanstöße gegeben hast und keine fertige Lösung. Ich habe mich zwar geärgert, aber im Endeffekt war das der bessere Weg. Danke nochmal.

Sollte doch noch mal jemand danach suchen, hier mal mein erster funktionierender Versuch:

Code: Alles auswählen

import pygame
from pygame.locals import *
import sys

img = "cross.png"

pygame.init()

screen = pygame.display.set_mode((320,240), 0, 32)
pygame.display.set_caption("transform.rotate - Test")

cross = pygame.image.load(img).convert_alpha()
toRotate = pygame.Surface((128,128))
toRotate = cross.copy()
angle = 0

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        elif event.type == pygame.KEYUP and event.key == pygame.K_q:
            sys.exit()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            angle += 1
            toRotate = pygame.transform.rotate(cross, angle)

    rect = toRotate.get_rect(center=(100,100))
    screen.fill((0,0,255))
    screen.blit(toRotate,rect)
    pygame.display.update()
Gruß!
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

hier ein drehendes rechteck, welches nach rechts wandert:

Code: Alles auswählen

import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode([320, 240], 0, 16)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill([255,255,0])

bild_rect = pygame.Surface([50,50])
bild_rect.fill([255,0,255])
bild_rect.set_colorkey((255,0,255), RLEACCEL)
pygame.draw.rect(bild_rect, (255,0,0), (10,0,30,50),1)

clock = pygame.time.Clock()
b=10  

for angle in xrange(0, 600, 2):
    clock.tick(60)
    
    b=b+1
    
    screen.blit(background, (0, 0))
    
    bild = pygame.transform.rotate(bild_rect, angle)
    bild1=bild.get_rect(center=(b,120))  
    screen.blit(bild,bild1 )  
    
    pygame.display.flip()
    
#while pygame.event.poll().type != pygame.KEYDOWN:
 #       pygame.time.delay(10)
        
pygame.quit()
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

müsste das surface beim drehen eines quadrates nicht grösser werden

PYTHAGORAS

Code: Alles auswählen

class Rechteck(pygame.sprite.Sprite):
    speed = 5
    angle = 90
    def __init__(self):
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.images = pygame.Surface([50,50])
        self.images.fill([255,0,255])
        self.image = self.images
        self.rect = self.image.get_rect(center=(160,120))
        
    def move(self,moving_vertical,moving_horizontal,rotate_left,rotate_right):
        if moving_vertical and rotate_left != 2 and rotate_right != 2:
            self.rect[1] += moving_vertical*self.speed
            self.rect = self.rect.clamp(SCREENRECT)
        if moving_horizontal and rotate_left != 2 and rotate_right != 2:
            self.rect[0] += moving_horizontal*self.speed
            self.rect = self.rect.clamp(SCREENRECT)
        if rotate_left == 2:
            oldCenter = self.rect.center
            self.angle += 2
            self.image = pygame.transform.rotate(self.images, self.angle)
            self.rect = self.image.get_rect()
            self.rect.center = oldCenter
        if rotate_right == 2:
            oldCenter = self.rect.center
            self.angle -= 2
            self.image = pygame.transform.rotate(self.images, self.angle)
            self.rect = self.image.get_rect()
            self.rect.center = oldCenter

BlackJack

Was ist denn das für eine haarsträubende API!? Man kann nur um zwei Grad drehen, aber nicht bewegen wenn gedreht wird, wobei die "keine Drehung" durch alles ausser dem Wert 2 für die beiden "Drehargumente" angezeigt wird? Und je ein Argument für links und rechts drehen statt *einem* was dann halt auch negativ sein kann!?
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

müsste das surface beim drehen eines quadrates nicht grösser werden
ist bei pygame total überflüssig, weil es intern von pygame durchgeführt wird. wenn du mein viereck drehst und vorher die transparens ausgeschaltest, ist es beim drehen gut sichtbar, wie die hintergrundfläche angepasst wird.

pygame nimmt hier einem die arbeit ab.
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

bzw. erzeugt pygame.transform.rotate ein neues Surface-Objekt.

Übrigens, sicher, dass dein Code funktioniert?
self.image = self.images
bedeutet nämlich, dass self.image und self.images dasselbe Objekt sind.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

es läuft einfach nicht move left right top bottem geht aber rotieren nicht

Code: Alles auswählen

import pygame
from pygame.locals import *

SCREENRECT = Rect(0, 0, 320, 240)

class Rechteck(pygame.sprite.Sprite):
    speed = 5
    angle = 90
    def __init__(self):
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.image = pygame.Surface([50,50])
        self.image.fill([255,0,255])
        self.original = pygame.Surface([50,50])
        self.original.fill([255,0,255])
        self.rect = self.image.get_rect(center=(160,120))
        self.speed = 5
        self.angle = 90
        
    def update(self):
        keystate = pygame.key.get_pressed()  

        moving_vertical = keystate[K_DOWN] - keystate[K_UP]
        moving_horizontal = keystate[K_RIGHT] - keystate[K_LEFT] 
        rotate_left = keystate[K_DOWN] + keystate[K_LEFT]
        rotate_right = keystate[K_DOWN] + keystate[K_RIGHT]

        if moving_vertical and rotate_left != 2 and rotate_right != 2:
            self.rect[1] += moving_vertical*self.speed
            self.rect = self.rect.clamp(SCREENRECT)
        if moving_horizontal and rotate_left != 2 and rotate_right != 2:
            self.rect[0] += moving_horizontal*self.speed
            self.rect = self.rect.clamp(SCREENRECT)
        if rotate_left == 2:
            self.oldCenter = self.rect.center
            self.angle += 5
            if self.angle == 180:
                self.angle = 90
            self.image = pygame.transform.rotate(self.original, self.angle)
            self.rect = self.image.get_rect()
            self.rect.center = self.oldCenter
        if rotate_right == 2:
            self.oldCenter = self.rect.center
            self.angle -= 5
            if self.angle == 0:
                self.angle = 90
            self.image = pygame.transform.rotate(self.original, self.angle)
            self.rect = self.image.get_rect()
            self.rect.center = self.oldCenter
        
def main():
        
    pygame.init()
    try:
        os.environ['SDL_VIDEO_CENTERED'] = '1'
    except:
        pass

    #pygame.display.set_icon(pygame.image.load(os.path.join('data', 'icones1.gif')))

    pygame.display.set_caption('RECHTECK move')
    pygame.mouse.set_visible(0)
    screen = pygame.display.set_mode(SCREENRECT.size)

    background = pygame.Surface(screen.get_size())
    background.fill([255,255,0])
     
    clock = pygame.time.Clock()

    all = pygame.sprite.RenderUpdates()
    Rechteck.containers = all

    rechteck = Rechteck()

    weiter = True

    while weiter:
        clock.tick(60)
        
        event = pygame.event.poll()
        if event.type == QUIT or \
           (event.type == KEYDOWN and event.key == K_q):
            break
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            break

        screen.blit(background, (0, 0))
        all.draw(screen)
        all.update()
        pygame.display.flip()
        pygame.time.wait(50)
    pygame.quit()

if __name__ == '__main__': main()
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

wenn du dieses änderst: "if rotate_left == 2"
in : "if rotate_left " dann geht es und du siehst deutlich wie der hintergrund sich dem drehenden viereck anpasst bzw grösser und kleiner wird.
du musst dem surface noch einen andere farbe geben , damit sich dein viereck und das surface unterscheiden , du siehst ja nicht die drehung.
Antworten