2015-04-10 3 views
0

У меня все еще есть проблема с моим программным обеспечением для проверки столкновений между космическим кораблем и астероидами. Я понятия не имею, почему я столкнулся только в левом верхнем углу экрана.pygame collissions между двумя группами

любые идеи? любая помощь, пожалуйста?

import pygame, sys 
import random 
import math 
from pygame.locals import KEYDOWN, K_SPACE 

pygame.init() 
pygame.display.set_caption("ASTROCRASH version 0.1 >>> DKR103 <<<") 
clock = pygame.time.Clock() 

SCREENH = 600 
SCREENW = 800 
SCREEN = pygame.display.set_mode((SCREENW, SCREENH)) 

sGRAD = math.pi/180 

BLACK = (0,0,0) 
WHITE = (255,255,255) 
BBB = (0, 75, 230) 

ASTEROIDS = [] 
MISSILES = [] 
SPACESHIPS = [] 

class AsteroidSprite(pygame.sprite.Sprite): 
    def __init__(self,posX,posY): 
     pygame.sprite.Sprite.__init__(self)  
     self.image = pygame.image.load("img/asteroid3.png").convert() 
     self.rect = self.image.get_rect() 
     self.x = posX 
     self.y = posY 
     self.speed = 2 
     self.dx = random.choice([1,-1]) * self.speed * random.random() 
     self.dy = random.choice([1,-1]) * self.speed * random.random() 

    def update(self): 
     if self.y > SCREENH: 
      self.y = (0 - self.rect[3]) 
     if self.y < (0 - self.rect[3]): 
      self.y = SCREENH 
     if self.x > SCREENW: 
      self.x = (0 - self.rect[2]) 
     if self.x < (0 - self.rect[2]): 
      self.x = SCREENW 

     self.x += self.dx 
     self.y += self.dy 

class Ship(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     #load original image 
     self.imageMaster = pygame.image.load("img/spaceship.png") 
     self.imageMaster = self.imageMaster.convert() 
     ###self.imageMaster.set_colorkey(WHITE) 
     #set Sprite attribute 
     self.image = self.imageMaster 
     #get Sprite rect 
     self.rect = self.image.get_rect() 
     self.rect.center = ((SCREEN.get_width()/2),(SCREEN.get_height()/2)) 
     #initial rotation value 
     self.dir = 0 
     #ship movement speed 
     self.speed = 5 

    def rotation(self): 
     #set Sprite center before rotation 
     self.oldCenter = self.rect.center 
     #rotate Sprite 
     self.image = pygame.transform.rotate(self.imageMaster,self.dir) 
     self.rect= self.image.get_rect() 
     #set new Sprite center equal to old Center so it stays in place 
     self.rect.center = self.oldCenter 
     self.value = self.dir * math.pi/180 
    def update(self): 
     #move 
     key = pygame.key.get_pressed() 
     if key[pygame.K_UP]: 

      self.rect[0] -= self.speed * math.sin(self.value) 
      self.rect[1] -= self.speed * math.cos(self.value) 

     #rotate 
     if key[pygame.K_LEFT]: 
      self.dir += 5 
      if self.dir > 360: 
       self.dir = 15 
     if key[pygame.K_RIGHT]: 
      self.dir -= 5 
      if self.dir < 0: 
       self.dir = 355 
     #outside SCREEN conditions 
     if self.rect[1] > SCREENH: 
      self.rect[1] = (0 - self.rect[3]) 
     if self.rect[1] < (0 - self.rect[3]): 
      self.rect[1] = SCREENH 
     if self.rect[0] > SCREENW: 
      self.rect[0] = (0 - self.rect[2]) 
     if self.rect[0] < (0 - self.rect[2]): 
      self.rect[0] = SCREENW 

    def draw(self): 
     SCREEN.blit(self.image,(self.rect[0],self.rect[1])) 

def main(): 
    #spaceship 
    spaceship = Ship() 
    SPACESHIPS.append(spaceship) 
    for i in range(8): 
     ASTEROIDS.append(AsteroidSprite(300,300)) 

    runGame = True 
    while runGame: 

     clock.tick(60) 
     SCREEN.fill(BLACK)  

     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       runGame = False 

     #update asteroids 
     for i in range(8): 
      ASTEROIDS[i].update() 
      SCREEN.blit(ASTEROIDS[i].image,(ASTEROIDS[i].x,ASTEROIDS[i].y)) 
     for a in ASTEROIDS: 
      if pygame.sprite.spritecollide(a,SPACESHIPS,0): 
       SCREEN.fill(BBB) 

     spaceship.rotation()  
     spaceship.update() 
     spaceship.draw() 
     print spaceship.rect[0] 

     pygame.display.update()       
main() 
pygame.quit() 

ответ

1

pygame.sprite.groupcollide() функция находит столкновения между всеми спрайтами два прошедших спрайтами групп и возвращает словарь, содержащая информацию о столкновении, в документации государств.

Поскольку столкновение определяется сравнивающих sprite.rect атрибута каждого спрайт, каждый раз, когда вы вызываете update() метод экземпляра спрайта вам необходимо обновить положения self.rect объекта, вместо того, чтобы изменять свою self.x и self.y атрибутов.

Ваш Ship класс это нормально, потому что вы изменить self.rect объекта и его собственные .x или .y атрибуты. (например, self.rect[1] = (0 - self.rect[3])).
Но в вашем AsteroidSprite класса создать объект прямоугольника в методе __init__() и только изменить self.x и self.y атрибуты экземпляра при вызове метода .update().

Что вам нужно изменить:

  1. .update() метод AsteroidSprite класса, потому что вам нужно изменить положение self.rect объектов, который используется для обнаружения столкновений.
  2. Оператор if, где вы проверяете наличие столкновения, поскольку pygame.sprite.groupcollide() возвращает объект dict, а не логическое значение.

Я надеюсь, что это поможет вам немного :)

0

Большое спасибо. Ваш ответ помог мне решить проблему.

обновленный код:

import pygame, sys 
import random 
import math 
from pygame.locals import KEYDOWN, K_SPACE 

pygame.init() 
pygame.display.set_caption("ASTROCRASH version 0.1 >>> DKR103 <<<") 
clock = pygame.time.Clock() 

SCREENH = 600 
SCREENW = 800 
SCREEN = pygame.display.set_mode((SCREENW, SCREENH)) 

sGRAD = math.pi/180 

BLACK = (0,0,0) 
WHITE = (255,255,255) 
BBB = (0, 75, 230) 

ASTEROIDS = [] 
MISSILES = [] 
SPACESHIPS = [] 

class AsteroidSprite(pygame.sprite.Sprite): 
    def __init__(self,posX,posY): 
     pygame.sprite.Sprite.__init__(self)  
     self.image = pygame.image.load("img/asteroid3.png").convert() 
     self.rect = self.image.get_rect() 
     self.rect.x = posX 
     self.rect.y = posY 
     self.speed = 2 
     self.dx = random.choice([1,-1]) * self.speed * random.random() 
     self.dy = random.choice([1,-1]) * self.speed * random.random() 

    def update(self): 
     if self.rect.y > SCREENH: 
      self.rect.y = (0 - self.rect[3]) 
     if self.rect.y < (0 - self.rect[3]): 
      self.rect.y = SCREENH 
     if self.rect.x > SCREENW: 
      self.rect.x = (0 - self.rect[2]) 
     if self.rect.x < (0 - self.rect[2]): 
      self.rect.x = SCREENW 

     self.rect.x += self.dx 
     self.rect.y += self.dy 

class Ship(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     #load original image 
     self.imageMaster = pygame.image.load("img/spaceship.png") 
     self.imageMaster = self.imageMaster.convert() 
     ###self.imageMaster.set_colorkey(WHITE) 
     #set Sprite attribute 
     self.image = self.imageMaster 
     #get Sprite rect 
     self.rect = self.image.get_rect() 
     self.rect.center = ((SCREEN.get_width()/2),(SCREEN.get_height()/2)) 
     #initial rotation value 
     self.dir = 0 
     #ship movement speed 
     self.speed = 5 

    def rotation(self): 
     #set Sprite center before rotation 
     self.oldCenter = self.rect.center 
     #rotate Sprite 
     self.image = pygame.transform.rotate(self.imageMaster,self.dir) 
     self.rect= self.image.get_rect() 
     #set new Sprite center equal to old Center so it stays in place 
     self.rect.center = self.oldCenter 
     self.value = self.dir * math.pi/180 
    def update(self): 
     #move 
     key = pygame.key.get_pressed() 
     if key[pygame.K_UP]: 

      self.rect[0] -= self.speed * math.sin(self.value) 
      self.rect[1] -= self.speed * math.cos(self.value) 

     #rotate 
     if key[pygame.K_LEFT]: 
      self.dir += 5 
      if self.dir > 360: 
       self.dir = 15 
     if key[pygame.K_RIGHT]: 
      self.dir -= 5 
      if self.dir < 0: 
       self.dir = 355 
     #outside SCREEN conditions 
     if self.rect[1] > SCREENH: 
      self.rect[1] = (0 - self.rect[3]) 
     if self.rect[1] < (0 - self.rect[3]): 
      self.rect[1] = SCREENH 
     if self.rect[0] > SCREENW: 
      self.rect[0] = (0 - self.rect[2]) 
     if self.rect[0] < (0 - self.rect[2]): 
      self.rect[0] = SCREENW 

    def draw(self): 
     SCREEN.blit(self.image,(self.rect[0],self.rect[1])) 

def main(): 
    #spaceship 
    spaceship = Ship() 
    SPACESHIPS.append(spaceship) 
    for i in range(8): 
     ASTEROIDS.append(AsteroidSprite(300,300)) 

    runGame = True 
    while runGame: 

     clock.tick(60) 
     SCREEN.fill(BLACK)  

     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       runGame = False 

     #update asteroids 
     for i in range(8): 
      ASTEROIDS[i].update() 
      SCREEN.blit(ASTEROIDS[i].image,(ASTEROIDS[i].rect.x,ASTEROIDS[i].rect.y)) 
     for a in ASTEROIDS: 
      if pygame.sprite.spritecollide(a,SPACESHIPS,0): 
       SCREEN.fill(BBB) 

     spaceship.rotation()  
     spaceship.update() 
     spaceship.draw() 
     print spaceship.rect[0] 

     pygame.display.update()       
main() 
pygame.quit() 
Смежные вопросы