Frage zu Pygame (Zielkoordianten)

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Frage zu Pygame (Zielkoordianten)

Beitragvon Schildi » Samstag 5. August 2006, 14:15

Hallo!

Ich hab mal eine Fragen zu Pygame. Sagen wir ich habe ein Bild, das die Koordinaten x = 100, y = 100 hat. Was muss ich anstellen, dass sich das Bild z.B. zu x = 200, y = 200 bewegt? Damit meine ich jetzt nicht sowas hier:

Code: Alles auswählen

bildrect.move_ip(200, 200)


sondern ich möchte das in der While-Schleife drin haben, sodass man die Bewegung praktisch sieht. Ich hab's zwar hinbekommen, dass sich das Bild z.B. von rechts nach links bewegt, mit speed = [-1, 0] beispielsweise. Aber das ist ja nicht direkt das, was ich suche.

Man muss ja auch beachten, das das Beispiel jetzt recht einfach ist. Also ich meine x = 100, y = 100 -> x = 200, y = 200. Aber es müsste nachher auch gehn, dass sich das Bild von 100, 100 nach 531, 344 bewegt, nur so als Beispiel. Hättet ihr ne Idee, wie man das lösen könnte?

Danke im Voraus :)

MfG, Schildi
by: Schildi
BlackJack

Beitragvon BlackJack » Samstag 5. August 2006, 15:17

Wenn es eine Bewegung auf einer Linie sein soll, dann ist das ganz einfach. Du musst vorher nur noch festlegen in wievielen Schritten die Bewegung passieren soll. Dann lässt sich einfach ausrechnen, wieviele Pixel Du pro Schritt verschieben musst. Einfach die Differenz von alter und neuer X-Koordinate durch die Anzahl der Schritte teilen. Mit der Y-Koordinate machst Du das gleiche. Also von 100,100 nach 200,200 in 10 Schritten musst Du in jedem Schritt um 10,10 verschieben.
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Beitragvon Schildi » Samstag 5. August 2006, 17:15

also erstmal: klingt logisch :wink:
aber so flüssig läuft das leider nicht...hier mal der gesamte code:

Code: Alles auswählen

import sys, pygame
from pygame.locals import *

pygame.init()

size = width, height = 640, 480
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Test')
black = 0, 0, 0

surface = pygame.Surface((100, 100))
farbe = 255, 0, 0
surface.fill(farbe)

x = 100
y = 100

x1 = 345
y1 = 233

j = 0

schritte = 100

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == KEYDOWN:
             if event.key == K_ESCAPE:
                 sys.exit()
             elif event.key == K_SPACE:
                 j = 1

    if j == 1:
        y += (y1-y)/schritte
        x += (x1-x)/schritte
   
    screen.fill(black)
    screen.blit(surface, (x, y))
    pygame.display.flip()


hab das jetzt mal so gemacht, wie du gesagt hast. Und ich will nicht bestreiten, dass es das macht, was es soll, aber wie gesagt, es läuft nicht direkt flüssig. denn: bei mir erreicht das bild die y-koordiante (y1) eher als die x-koordinate (x1), d.h. es läuft erst auf einer linie diagonal nach unten rechts und wenn y dann mit y1 übereinstimmt, läuft es nur noch nach rechts, solange bis auch beide x-werte übereinstimmen. verstehst du wie ich das meine? woran liegt das? weißt du da auch eine Lösung für?

danke, schildi
by: Schildi
BlackJack

Beitragvon BlackJack » Samstag 5. August 2006, 22:24

Du teilst die Distanz immer wieder durch die Gesamtzahl der Schritte. Die Distanz wird aber nach jedem Schritt kleiner. Wenn Du z.B. schon 75 Schritte gemacht hast, dann teilst Du die Reststrecke immer noch in 100 Teile auf statt 25.
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Beitragvon Schildi » Sonntag 6. August 2006, 11:55

...und was muss ich ändern? Sry, das ich so doof frage, aber ich kapier das iwie net, wie ich das machen muss :wink:

MfG, Schildi
by: Schildi
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Beitragvon Joghurt » Sonntag 6. August 2006, 12:06

Code: Alles auswählen

stepx = (x1-x)/schritte
stepy = (y1-y)/schritte
vor die Schleife schreiben, und dann

Code: Alles auswählen

y += stepy
x += stepx
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Beitragvon Schildi » Samstag 26. August 2006, 17:40

etwas verpätet, sry, aber DANKE! hat mich sehr viel weiter gebracht.

Und weil ich jetzt keinen neuen Thread öffnen will, schreib ich meine nächste frage gleich mal hierhin. :lol:

und zwar geht es um

Code: Alles auswählen

bild = pygame.transform.rotate(bild, 45)

(als Beispiel)

wenn ich also ein bild drehen möchte. bei mir kommt da dann was ganz komisches raus. also auf jeden fall kein bild, was um 45° gedreht wurde... :? also ich könnte mir gut vorstellen, das es irgendwas mit

Code: Alles auswählen

screen.blit(bild, (x, y))

am ende zu tun haben könnte, also das da irgendwas falsch 'geblittet' wird. weiß aber nicht, ob das stimmt, oder gar, wie ich das lösen kann. könnt ihr mir da auch wieterhelfen? danke im voraus schon mal :wink:

MfG, Schildi
by: Schildi
Benutzeravatar
Michael Schneider
User
Beiträge: 566
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Beitragvon Michael Schneider » Samstag 26. August 2006, 17:46

Die Frage würde doch hervorragend ins PyGame-Forum passen, oder? ;-)
http://www.python-forum.de/topic-6769.html?highlight=

Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Michael Schneider
User
Beiträge: 566
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Beitragvon Michael Schneider » Sonntag 27. August 2006, 19:09

Hi Schildi,

ich habe mal eben das Chimp-Tutorial beim Abschreiben angepasst und das läuft eigentlich einwandfrei:

Code: Alles auswählen

import os, pygame
from pygame.locals import *

def load_image(name, colorkey=None):
    fullname = name
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'Cannot load image:', fullname
        raise SystemExit, message
    image = image.convert()
    return image, image.get_rect()

class Smile(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("borg.jpg", -1)
        self.original = self.image
        screen = pygame.display.get_surface()
        self.area = screen.get_rect()
        self.rect.topleft = 70, 70
        self.spin = 230
        self.spinSpeed = 0
        self.increment = 1

    def update(self):
        if self.spinSpeed > 15 or self.spinSpeed < -15:
            self.increment = -self.increment
        self.spinSpeed += self.increment
        self._spin()

    def _spin(self):
        center = self.rect.center
        self.spin += self.spinSpeed
        if self.spin >= 360:
            self.spin -= 360
        if self.spin <0:
            self.spin += 360
        self.image = pygame.transform.rotate(self.original, self.spin)
        self.rect = self.image.get_rect()
        self.rect.center = center

def main():
    ##  Initialize Everything
    pygame.init()
    screen = pygame.display.set_mode((200, 200))
    pygame.display.set_caption("Borgsmile Twist")

    ##  prepare game objects
    clock = pygame.time.Clock()
    smile = Smile()
    allsprites = pygame.sprite.RenderPlain((smile))
    pygame.display.flip()

    ##  main loop
    while 1:
        clock.tick(60)

        ##  handle input events
        for event in pygame.event.get():
            if event.type in (QUIT, KEYDOWN, K_ESCAPE):
                return
        allsprites.update()

        ##  draw next smile
        allsprites.draw(screen)
        pygame.display.flip()

main()


Wenn mir noch jemand sagen könnte, wie ich meinen Borg-Smiley irgendwo hochladen kann... :D

[EDIT] Man ist ja erfinderisch und für einen Ingenieur ist nichts zu schwör. ;-)
BildDas Bild bitte als borg.jpg im Verzeichnis mit dem Code speichern.[/EDIT]

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Michael Schneider
User
Beiträge: 566
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Beitragvon Michael Schneider » Donnerstag 31. August 2006, 18:26

Also bei mir funktioniert das problemlos...

Code: Alles auswählen

import os, pygame
from pygame.locals import *

def load_image(name, colorkey=None):
    fullname = name
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'Cannot load image:', fullname
        raise SystemExit, message
    image = image.convert()
    return image, image.get_rect()

##  Initialize Everything
pygame.init()
screen = pygame.display.set_mode((200, 200))
image, rect = load_image("borg.jpg", -1)
rect.topleft = 70, 70
image = pygame.transform.rotate(image, 45)
screen.blit(image, rect)

pygame.display.flip()

while 1:
    ##  handle input events
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN, K_ESCAPE):
            raise SystemExit()


Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 31. August 2006, 18:46

Michael Schneider hat geschrieben:Die Frage würde doch hervorragend ins PyGame-Forum passen, oder? ;-)

Absolut! Deswegen habe ich den Thread ins passende Forum verschoben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Beitragvon Schildi » Samstag 2. September 2006, 12:24

Morgen!

Na gut, ich hab jetzt herausgefunden, woran das die ganze zeit lag, das es nicht funktioniert hat, bevor du das beispiel gepostet hast. und zwar hab ich herausgefunden, dass mein problem nur bei bilden "ohne rand" auftreten, also dein smiley ist ja auf weißem grund, aber ich hatte immer bilder (rechtecke bzw. quadrate zum testen), die das ganze bild ausfüllten. das gleiche würde also mit "surface" passieren. auf jeden fall noch mal DANKE! :wink:

naja, und weils so schön ist gleich noch eine andere frage:

gibt es eine möglichkeit, 2 oder mehr rects zusammen zu fassen? also es geht mir darum, das ich z.b. ein "hintergrundrect" habe (welches dann mit der bg-farbe gefüllt wird und halt den hintergrund darstellt) und eine anzahl von anderen rects, die irgendwo gezeichnet werden. diese möchte ich dann mit dem hintergrundrect zusammenfassen, weil wenn ich nachher 40-50 rects habe, lahmt das ganze verständlicher weise. so bräuchte ich dann gar nicht alle 40 oder 50 rects zeichnen, sondern die einfach dem hintergrundrect "hinzufügen" und nur das zeichnen.

versteht ihr was ich meine?

mfg schildi

ps:

Code: Alles auswählen

bgRect = bgRect.union(aRect)

hab ich schon ausprobiert, aber damit bin ich iwie nich klar gekommen :?: :oops:
by: Schildi
BlackJack

Beitragvon BlackJack » Samstag 2. September 2006, 12:52

Du verwechselst `Rect` und `Surface`. `Rect` sind nur die "Masse" von einem Rechteck, ein `Rect` enthält keine Grafik.

Was Du wahrscheinlich möchtest ist eine Kopie von Deinem Hintergrund (`Surface.copy()`) und dann die kleinen `Surface` Objekte auf diese Kopie "blitten".
Schildi
User
Beiträge: 30
Registriert: Freitag 19. Mai 2006, 22:23
Kontaktdaten:

Beitragvon Schildi » Samstag 2. September 2006, 18:10

hm..also ich kann am besten mal ein theoretisches beispiel nennen zur verdeutlichung:

ich hab ein hintergrund bild, welches ich weiss mache:

Code: Alles auswählen

bg = pygame.Surface((800, 600))
bg.fill((255, 255, 255))


dann hab ich mehere quadrate, die ich rot mache:

Code: Alles auswählen

q1 = pygame.Surface((20, 20))
q1.fill((255, 0, 0))


so, ich möchte jetz nich immer

Code: Alles auswählen

screen.blit(bg, (0, 0))
screen.blit(q1, (x1, y1))
screen.blit(q2, (x2, y2))
screen.blit(q3, (x3, y3))
...


schreiben, sondern die quadrate jeweils dem hintergrund "hinzufügen", so, dass ich zum schluss nur

Code: Alles auswählen

screen.blit(bg, (0, 0))

schreiben muss, und trotzdem die roten quadrate mit geblittet werden, weil sie ja praktisch dann zum hintergrund gehören.

mfg schildi
by: Schildi
BlackJack

Beitragvon BlackJack » Samstag 2. September 2006, 19:18

Naja, dann machst Du genau das was ich geschrieben habe: Du machst vom weissen Hintergrund eine Kopie, blittest da die roten Quadrate drauf und benutzt das als neuen Hintergrund den Du auf den Bildschirm blittest. Die `blit()` Methode ist nicht nur auf dem sichtbaren `Surface` definiert sondern auf jedem `Surface`.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder