rechteck drehen funktioniert nicht.

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

dieses rechteck soll sich um 45 grad drehen.
tut es aber nicht. es kommt auch keine fehlermeldung.
und das rechteck erscheint nicht gedreht.
was ist falsch ?

Code: Alles auswählen

import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode([320, 240], 0, 16)

viereck = pygame.Surface([30, 50])
viereck.fill([255,255,0])

pygame.transform.rotate(viereck,45)
screen.blit(viereck,(100,10))
pygame.display.flip()


pygame.time.wait(2000)
pygame.quit()

BlackJack

Ein Blick in die Dokumentation verrät, dass die `rotate()`-Funktion ein `Surface` zurück gibt. Die Funktion verändert also nicht das Argument.
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

das programm funktioniert jetzt .

die rotatefunktion ist zwar schon aktiv und wird durchgeführt.
bloss pygame nimmt automatisch als hintergrundfarbe für das surface die gesetzte farbe.

wenn ich einen drawbefehl dort drauf ausgeführt habe (rote ellipse zeichnen), wird dieser ellipse gedreht dargestellt. das heisst, das surface viereck wird mit meinem befehlen gedreht.

mein fehler war: das surface habe ich nicht als behälter gesehen wo erst was draufgezeichnet werden muss, sondern schon gleich als zeichnung gesehen. der behälterumriss(surface) bleibt immer ungedreht als viereck.
Ein Blick in die Dokumentation verrät, dass die `rotate()`-Funktion ein `Surface` zurück gibt. Die Funktion verändert also nicht das Argument.
danke für deine mühe.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Meine Panzerlösung

so ich hab das ganze mal animiert und in eine klasse gepackt
der Panzer springt noch etwas beim 90grad übergang

oder eine bessere idee
image
Panz.png Panza
BildBild

Code: Alles auswählen

import sys, os
import pygame
from pygame.locals import *

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

class Panzer(pygame.sprite.Sprite):
    speed = 10
    images = []
    animcycle = 3
    frame = 0
    angle = 0
    def __init__(self):
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.images.append(pygame.image.load('Panz.png').convert_alpha())
        self.images.append(pygame.image.load('Panza.png').convert_alpha())
        self.original_a = pygame.image.load('Panz.png').convert_alpha()
        self.original_b = pygame.image.load('Panza.png').convert_alpha()
        self.image = self.images[0]
        self.rect = self.image.get_rect(midleft=SCREENRECT.midleft)
        self.rect = self.image.get_rect(center = (SCREENRECT.centerx,SCREENRECT.centery))
    def move_vertical(self, moving_vertical):
        self.rect.move_ip(0 ,moving_vertical*self.speed)
        self.rect = self.rect.clamp(SCREENRECT)
        self.frame += 1
        self.imind = self.frame/self.animcycle%2
        self.image = self.images[self.imind]
    def move_horizontal(self, moving_horizontal):
        self.rect.move_ip(moving_horizontal*self.speed, 0)
        self.rect = self.rect.clamp(SCREENRECT)
    def rotate(self,rotate_left,rotate_right):
        center = self.rect.center
        if rotate_left == 2:
            self.angle += 5
        if rotate_right == 2:
            self.angle -= 5
        if self.angle == 360 or self.angle == 0:angle = 0
        self.images[0] = pygame.transform.rotate(self.original_a,self.angle)
        self.images[1] = pygame.transform.rotate(self.original_b,self.angle)
        self.rect = self.images[0].get_rect()
        self.rect.center = center

def main():
    pygame.init()
    pygame.display.set_caption('Panzer move')
    pygame.mouse.set_visible(0)
    screen = pygame.display.set_mode(SCREENRECT.size)
    background = pygame.Surface(screen.get_size())
    background.fill([0,0,255])
    clock = pygame.time.Clock()
    all = pygame.sprite.RenderUpdates()
    panzer = pygame.sprite.Group()
    Panzer.containers = all
    player = Panzer()
    while True:
        clock.tick(60)
        all.clear(screen, background)
        all.update()
        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
        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_UP]
        rotate_right = keystate[K_RIGHT] + keystate[K_LEFT] 
        player.move_vertical(moving_vertical)
        player.move_horizontal(moving_horizontal)
        player.rotate(rotate_left,rotate_right)
        screen.blit(background, (0, 0))
        dirty = all.draw(screen)
        pygame.display.update(dirty)
        pygame.display.flip()
        pygame.time.wait(50)
    pygame.quit()

if __name__ == '__main__': main()

DREHUNG MIT PFEILTASTEN doppelt left-Right up-Down
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also wäre es nicht sinnvoll in einem Spiel die Animationen vorher zu berechnen? So habe ich das bisher immer gesehen ... spart eben viel Rechenzeit.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Hyperion hat geschrieben:Also wäre es nicht sinnvoll in einem Spiel die Animationen vorher zu berechnen? So habe ich das bisher immer gesehen ... spart eben viel Rechenzeit.
laufzeitberechnung ist schneller als alle positionen mitzuschleppen
BlackJack

Nette Behauptung. Vielleicht solltest Du das mal nachmessen. ;-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Am Ende wird PyGame doch sicherlich alles durch eine Transformationsmatrix jagen (oder durch einen Stack von Transformationsmatrizen), da kommt es auf eine Rotation dann auch nicht mehr drauf an.
BlackJack

Was meinst Du mit "am Ende" und "alles"? PyGame macht im Grunde nur das was man mittels Methoden sagt, und zwar *sofort*. Und in der Regel sind das einfache "blit"-Operationen, also rechteckige Bereiche von einem `Surface` in ein Anderes kopieren und dabei eventuell noch Alphakanäle berücksichtigen. Da ist nichts mit Transformationen. Sowohl skalieren als auch rotieren sind für die darunter liegende SDL "Fremdkörper", das gehört nicht zum Grundfunktionsumfang.

Und ob ich nun die Rotationen vorberechne und dann immer nur rechteckige Bereiche "blitt"e, wo dank MMX & Co auch mehrere Pixel auf einmal bewegt werden können, oder ob ich jedesmal die Drehung von vielen Pixeln berechne, inklusive der Speicherverwaltung weil dabei immer ein neues `Surface` erstellt wird, sollte schon einen Unterschied machen.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

damit ich euch richtig verstehe

ich soll zB bei 5Grad rotation 360/5 72 images auf der platte erzeugen
ODER
72 images in meiner images LISTE rotierend erzeugen

ind dann mittels variable self.angle das richtige anzeigen

und nur vertical und horizontal verfahren

was auch die colide funktion wesentlich erleichtern würde
denn das mit dem drehen an der WAND ist nicht so ohne
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn PyGame an dieser Stelle nicht optimiert, finde ich das schon sehr seltsam. Mittlerweile werden eigentlich alle 2D-Anwendungen einfach auf 3D abgebildet. Und dort kostet eine Rotation im Prinzip nichts mehr, da lediglich Texturkoordinaten verschoben werden.
BlackJack

PyGame setzt auf SDL und SDL verwendet simpelste Framebuffer-Technik weil es eben auch auf den simpelsten Geräten und Betriebssystemen laufen soll. Also zum Beispiel DOS oder Handhelds und Mobiltelefone mit 2D-Grafikhardware. SDL selbst bietet wie gesagt nicht einmal Rotation als Funktion an.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

sea-live hat geschrieben:damit ich euch richtig verstehe

ich soll zB bei 5Grad rotation 360/5 72 images auf der platte erzeugen
ODER
72 images in meiner images LISTE rotierend erzeugen
Äh ... ja :-) Wobei es fast egal ist, ob Du die gedrehten Bilder vor Spielstart oder eben beim Start berechnest. Guck Dir doch mal Sprites aus bekannten Spielen an. Die haben oftmals nur ein Bild pro Einheit, in welchem dann alle Animationsstufen drin stehen. Du blittest dann nur den Bereich der Grafik, der angezeigt werden soll.
Man kann aber natürlich auch 72 Bilder auf die Platte hauen :-)
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Mit rechteckigen objecten ist das nicht so einfach merk ich mitlerweile
der panzer ist doppelt so lang wie breit
sieht blöd aus wenn die granate ihn schon halb auserhalb trifft

und ein cube panzer sieht mies aus !

mal sehen wie ich das hinbiege
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

allen anschein geht es doch auch ohne 72 Blider

im draufsicht 2d spiel wäre nach reiflicher überlegung das die lösung

Code: Alles auswählen

    def move_vertical(self, moving_vertical):
        self.rect.move_ip(0 ,moving_vertical*self.speed)
        self.frame += 1
        self.imind = self.frame/self.animcycle%2
        self.image = self.images[self.imind]
        self.rect = self.rect.clamp(PLAYRECT)
        if self.rect.collidelist(blocked_tile_list) != -1:
            self.rect.move_ip(0 ,(moving_vertical*-1)*self.speed)
    def move_horizontal(self, moving_horizontal):
        self.rect.move_ip(moving_horizontal*self.speed, 0)
        self.rect = self.rect.clamp(PLAYRECT)
        if self.rect.collidelist(blocked_tile_list) != -1:
            self.rect.move_ip((moving_horizontal*-1)*self.speed, 0)
    def rotate(self,rotate_left,rotate_right):
        rotate = 0
        center = self.rect.center
        if rotate_left == 2:rotate = 5
        if rotate_right == 2:rotate = -5
        if self.angle == 360 or self.angle == 0:angle = 0
        if rotate :
            self.angle += rotate
            self.images[0] = pygame.transform.rotate(self.original_a,self.angle)
            self.images[1] = pygame.transform.rotate(self.original_b,self.angle)
            self.rect = self.images[0].get_rect()
            self.rect.center = center
            if self.rect.collidelist(blocked_tile_list) != -1:
                self.angle -= rotate
                self.images[0] = pygame.transform.rotate(self.original_a,self.angle)
                self.images[1] = pygame.transform.rotate(self.original_b,self.angle)
                self.rect = self.images[0].get_rect()
                self.rect.center = center
Qwellcode Komplett hier
http://paste.pocoo.org/show/52787/

bei mir läuft es jetzt zumindestens
Antworten