Collision Detection

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Sonnenblume
User
Beiträge: 7
Registriert: Sonntag 20. Juli 2008, 11:42

Hallo,

ich habe ein kleines Problem mit meiner Collision Detection: Sie funktioniert nicht.


Teil des Codes, der relevant ist:

Code: Alles auswählen

class Raumschiff(pygame.sprite.Sprite):
        def __init__(self, x, y, image):
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.image.load(image).convert_alpha()
                self.rect = pygame.image.load(image).get_rect()
                self.x = x
                self.y = y
                
        
               

class Enemy(pygame.sprite.Sprite):
        def __init__(self, x, y , image):
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.image.load(image).convert_alpha()
                self.rect = pygame.image.load(image).get_rect()
                self.x = x
                self.y = y
                self.next_update_time = 0

spieler = Raumschiff(x = startx, y = 550, image = schiffimage)

enemies = pygame.sprite.Group()

while True:
        
        screen.fill([0,0,0])	
	screen.blit(spieler.image, (spieler.x, spieler.y))

        time = pygame.time.get_ticks()
        
        enemies.update(time)
        for gegner in enemies.sprites():
                screen.blit(gegner.image, (gegner.x, gegner.y))

        for sprite in pygame.sprite.spritecollide(spieler, enemies, 1):
                spieler.kill()

Habe ich den Boolean bei spritecollide auf "1" stehen, sind die Gegner sofort weg, habe ich ihn auf "0" stehen passiert absolut gar nix, keine Collision Detection. Für Ideen wäre ich sehr dankbar.

Edit (Leonidas): Code in Python-Tags gesetzt. Kaputte Umlaute so stehen gelassen.
BlackJack

@Sonnenblume: Die Kollisionserkennung funktioniert wunderbar wenn alle Gegner verschwinden. Position und Grösse eines Sprites werden über das `rect`-Attribut festgelegt und nicht wie Du das machst über zusätzliche `x`- und `y`-Attribute. Wenn Du das `rect`-Attribut nicht veränderst, dann sollte die linke obere Ecke aller Sprites (0, 0) sein, d.h. die kollidieren *alle* miteinander.

Schau Dir mal die Doku und die Beispiele an. Da Sprites ihre Position kennen, solltest Du sie sich auch selbst zeichnen lassen. Gleiches gilt für die Gruppe. Beide haben eine `draw()`-Methode.
Sonnenblume
User
Beiträge: 7
Registriert: Sonntag 20. Juli 2008, 11:42

Danke für die schnelle Antwort. Das die alle miteinander kollidieren hatte ich schon vermutet.
Allerdings ist genau das mein Problem, ich habe Stundenlang im Netz nach vernünftigen Tutorials gesucht, habe aber nichts genaueres bezüglich dem rect - attribut gefunden, was mir weiterhelfen würde, bzw. ich bin einfach zu bescheuert. Ich suche eine einfache Möglichkeit das Bild eines Sprites und dessen Maße und Position mit seinem rect - Attribut gleichzusetzten, so dass ich eine einfache Kollisionsabfrage machen kann. Ich nehme an, dass das irgendwie relativ einfach gehen muss, weiß aber nicht wie.
BlackJack

Und ich weiss jetzt nicht so recht wo das Problem liegt. Das `image`-Attribut bestimmt das Aussehen und das `rect`-Attribut die Position an der das `image` gezeichnet wird. Die Doku zu `Rect`-Objekten kennst Du?
Sonnenblume
User
Beiträge: 7
Registriert: Sonntag 20. Juli 2008, 11:42

Ich habe meinen Code jetzt so verändert, dass es einigermaßen funktioniert. Allerdings sieht es grauenhaft aus, weil ich einige Werte hardcoden musste:

Code: Alles auswählen

class Raumschiff(pygame.sprite.Sprite):
        def __init__(self, x, y, image):
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.image.load(image).convert_alpha()
                self.x = x
                self.y = y
                self.rect = pygame.rect.Rect(self.x, self.y, self.x+80, self.y+80)
                
                
class Enemy(pygame.sprite.Sprite):
        def __init__(self, x, y , image):
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.image.load(image).convert_alpha()
                self.x = x
                self.y = y
                self.rect = pygame.rect.Rect(self.x, self.y, self.x+80, self.y+80)
                self.next_update_time = 0
Wie kann ich sagen umfang rect = umfang image? Dafür gibt es doch bestimmt eine Funktion. Ich kenne nur die Dokumentation auf http://www.pygame.org/docs/ die ich allerdings recht unvollständig finde. Ich kann z.B. keinerlei Beschreibung zu der von dir angesprochenen draw() Funktionen eines Sprites finden. Gruß und danke.

Edit (Leonidas): Code wieder in Tags gesetzt. Kaputte Umlaute immer noch stehen gelassen.
BlackJack

Natürlich gibt es eine Methode um ein `Rect` von einem `Surface` zu bekommen, die hast Du sogar selbst schon verwendet: Surface.get_rect(). Und wenn Du Dir die Doku dazu durch liest, siehst Du, dass das man auch Schlüsselwort-Argumente angeben kann. Welche das sind steht bei der Doku zu Rect-Objekten.

`Sprite` hat tatsächlich keine `draw()`-Methode, aber `Group`-Exemplare haben eine.
Sonnenblume
User
Beiträge: 7
Registriert: Sonntag 20. Juli 2008, 11:42

Nach einigem herumwursteln funktioniert jetzt alles so wie es soll, danke fuer die Hilfe. Wenn ich allerdings die Group.draw() Methode aufrufe, zeigt er mir einen "Group object has no attribute draw" Fehler an, was seltsam ist, da add(), etc. alles geht. Ist allerdings nicht weiter dramatisch, ich mache es halt ueber eine Schleife. Besten dank noch mal.
Antworten