2017-05-19 73 views
1

我知道有近5或6個問題類似於我正在做的這個,但沒有一個答案幫助了我(他們可能會,如果我不是完成noob),所以我會試着展示我的具體情況。我試圖在PyGame(Python庫)做一個精靈碰撞測試,但我不能得到它的工作,所有我碰到時是「假」,它根本不會工作,我可以'不知道爲什麼,一直在尋找連續兩天。PyGame中的雪碧碰撞測試(嘗試:rect和組)

在我的遊戲中,我有對象玩家(我稱之爲「夥計」)和對象敵人(我稱之爲「敵人」)。兩者上的__init__非常相似,並且都產生了rects。

這是__init__玩家:

class dude(pygame.sprite.Sprite): 
def __init__(self): 
    pygame.sprite.Sprite.__init__(self) 
    self.image = self.load_image(SPRITE_PLAYER) 
    self.X = randint(34,ALTURA-10) 
    self.Y = randint(34,LARGURA-10) 
    self.rect = pygame.Rect(self.X,self.Y,25,25) #currently testing this 
    #self.rect = self.image.get_rect()   already tried this 
    self.speed = SPEED_PLAYER 
    self.clock = pygame.time.Clock() 

敵人,我有這樣的:

class enemy(pygame.sprite.Sprite): 
def __init__(self): 
    pygame.sprite.Sprite.__init__(self) 
    self.image = self.load_image(SPRITE_ENEMY) 
    self.X = randint(34,ALTURA-10) 
    self.Y = randint(34,LARGURA-10) 
    self.rect = pygame.Rect(self.X,self.Y,25,25) 
    self.speed = SPEED_ENEMY 
    self.clock = pygame.time.Clock() 
    self.xis=1 
    self.yps=1 

當測試碰撞,這是兩個方法,返回的東西(至極已經真棒對我來說,因爲還有其他的嘗試只會返回錯誤),但即使我碰撞然後遊戲時它們總是返回0。 當玩家(由鍵盤輸入控制)觸及敵人精靈或圖像(在舞臺上隨機移動)時發生碰撞。

這些測試方法,我有:

print pygame.sprite.collide_rect(player, enemy),pygame.sprite.collide_rect(player, enemy2) 
print pygame.sprite.collide_rect(player, enemy),player.rect.colliderect(enemy2) 
print player.rect.colliderect(enemy),player.rect.colliderect(enemy2) 

我已經爲導向,以顯示更多的代碼,所以這個問題可以發現(EDIT) ,所以它 (我也要去在全球加載精靈,將它們作爲參數傳遞給對象,提示坦克)。

播放器目標:

# -*- coding: cp1252 -*- 
import pygame, os 
from pygame.locals import * 
from Configs import * 
from random import randint 

class dude(pygame.sprite.Sprite): 
def __init__(self): 
    pygame.sprite.Sprite.__init__(self) 
    self.image = self.load_image(SPRITE_PLAYER) 
    self.X = randint(34,ALTURA-10) 
    self.Y = randint(34,LARGURA-10) 
    self.rectBox() 
    self.speed = SPEED_PLAYER 
    self.clock = pygame.time.Clock() 

def load_image(self,image_loaded): 
    try: 
     image = pygame.image.load(image_loaded) 
    except pygame.error, message: 
     print "Impossivel carregar imagem: " + image_loaded 
     raise SystemExit, message 
    return image.convert_alpha() 

def rectBox(self): 
    self.rect = self.image.get_rect() 
    self.image_w, self.image_h = self.image.get_size() 
    self.rect.move(self.X, self.Y)   
    self.rect.topleft = (self.X, self.Y) 
    self.rect.bottomright = (self.X + self.image_w, self.Y + self.image_h) 

def update(self,xis,yps,screen): 
    time_passed = self.clock.tick() 
    time_passed_seconds = time_passed/1000.0 
    distance_moved = time_passed_seconds * (self.speed +100) #Distancia = tempo * velocidade 

    self.X +=xis*distance_moved 
    self.Y +=yps*distance_moved 

    screen.blit(self.image, (self.X,self.Y)) 

    if self.X>ALTURA-52: 
     self.X-=2 

    elif self.X<30: 
     self.X+=2 

    if self.Y>LARGURA-52: 
     self.Y-=2 

    elif self.Y<30: 
     self.Y+=2 

敵方目標:

# -*- coding: cp1252 -*- 
import pygame, os 
from pygame.locals import * 
from Configs import * 
from random import randint 

class enemy(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = self.load_image(SPRITE_ENEMY) 
     self.X = randint(34,ALTURA-10) 
     self.Y = randint(34,LARGURA-10) 
     self.rectBox() 
     self.speed = SPEED_ENEMY 
     self.clock = pygame.time.Clock() 
     self.xis=1 
     self.yps=1 

    def load_image(self,image_loaded): 
     try: 
      image = pygame.image.load(image_loaded) 
     except pygame.error, message: 
      print "Impossivel carregar imagem: " + image_loaded 
      raise SystemExit, message 
     return image.convert_alpha() 

    def rectBox(self): 
     self.rect = self.image.get_rect() 
     self.image_w, self.image_h = self.image.get_size() 
     self.rect.move(self.X, self.Y)   
     self.rect.topleft = (self.X, self.Y) 
     self.rect.bottomright = (self.X + self.image_w, self.Y + self.image_h) 

    def update(self,screen): 
     time_passed = self.clock.tick() 
     time_passed_seconds = time_passed/1000.0 
     distance_moved = time_passed_seconds * (self.speed +100) 

     self.X +=self.xis*distance_moved 
     self.Y -=self.yps*distance_moved 

     screen.blit(self.image, (self.X,self.Y)) 

     #Maquina de estados finitos para inteligência da movimentação 
     if self.X>ALTURA-50: 
      self.X-=2 
      self.xis=-1 
     elif self.X<30: 
      self.X+=2 
      self.xis=1 

     if self.Y>LARGURA-50: 
      self.Y-=2 
      self.yps=1 
     elif self.Y<30: 
      self.Y+=2 
      self.yps=-1 

主要腳本:

# -*- coding: cp1252 -*- 
import pygame, os 
from pygame.locals import * 
from Configs import * 
from Enemy import enemy as e 
from Player import dude 
from sys import exit 

pygame.init() 

#Função para carregar imagens 
def load_image(image_loaded): 
     try: 
      image = pygame.image.load(image_loaded) 
     except pygame.error, message: 
      print "Impossivel carregar imagem: " + image_loaded 
      raise SystemExit, message 
     return image.convert() 

#Funções do Pause 
def pause(): 
    drawpause() 
    while 1: 
     p = pygame.event.wait() 
     if p.type in (pygame.QUIT, pygame.KEYDOWN): 
      return 

def drawpause(): 
    font = pygame.font.Font(None, 48) 
    text1 = font.render("PAUSE", 1, (10, 10, 10)) 
    text1pos = text1.get_rect() 
    text1pos.centerx = screen.get_rect().centerx 
    text1pos.centery = screen.get_rect().centery 
    screen.blit(text1, text1pos) 
    font = pygame.font.Font(None, 36) 
    text2 = font.render("Pressione qualquer tecla para continuar", 1, (10, 10, 10)) 
    text2pos = text2.get_rect() 
    text2pos.centerx = screen.get_rect().centerx 
    text2pos.centery = screen.get_rect().centery + 50 
    screen.blit(text2, text2pos) 
    pygame.display.flip() 

#Inicializa tela principal  
os.environ["SDL_VIDEO_CENTERED"] = "1" 
screen = pygame.display.set_mode((ALTURA, LARGURA),0,32) 
bg = load_image(BACKGROUND) 
pygame.display.set_caption("Jogo teste para TCC - Top-Down") 

#Inicialização do personagem 
move_x, move_y = 0, 0 
player = dude() 

#Inicialização dos inimigos 
enemy = e() 
enemy2 = e() 

#Atribuição de grupos de entidades 
inimigos = pygame.sprite.Group() 
inimigos.add(enemy) 
inimigos.add(enemy2) 

personagem = pygame.sprite.Group() 
personagem.add(player) 

#Objeto clock 
clock = pygame.time.Clock() 

#Loop principal sprite.get_height() sprite.get_width() 
while True: 

    #Eventos do jogo 
    for event in pygame.event.get(): 
     #SAIR DO JOGO 
     if event.type == QUIT: 
      pygame.quit() 
      exit() 
     if event.type == KEYDOWN: 
      if event.key == K_ESCAPE: 
       pygame.quit() 
       exit() 
      elif event.key == K_p: 
       pause() 

     #TECLAS DE MOVIMENTAÇÃO PERSONAGEM 
     if event.type == KEYDOWN: 
      if event.key == K_LEFT: 
       move_x = -1 
      elif event.key == K_RIGHT: 
       move_x = +1 
      elif event.key == K_UP: 
       move_y = -1 
      elif event.key == K_DOWN: 
       move_y = +1 
     elif event.type == KEYUP: 
      if event.key == K_LEFT: 
       move_x = 0 
      elif event.key == K_RIGHT: 
       move_x = 0 
      elif event.key == K_UP: 
       move_y = 0 
      elif event.key == K_DOWN: 
       move_y = 0 

    #Posicionamento do background 
    screen.blit(bg, (0,0)) 

    #Movimentação do personagem 
    player.update(move_x,move_y,screen) 

    #Movimentação inimigos 
    enemy.update(screen) 
    enemy2.update(screen) 

    #Teste colisão 
    #print pygame.sprite.collide_rect(player, enemy),pygame.sprite.collide_rect(player, enemy2) 
    #print pygame.sprite.collide_rect(player, enemy),player.rect.colliderect(enemy2) 
    #print player.rect.colliderect(enemy),player.rect.colliderect(enemy2) 

    #Refresh (por FPS) 
    pygame.display.update() 

完蛋了,感謝在我的崗位反饋!

+1

你的代碼示例是不完整的,足以發現其中的錯誤。所提到的碰撞檢測功能應能正常工作。請編輯您的帖子並提供一個[最小,完整且可驗證的示例](http://stackoverflow.com/help/mcve),我們可以複製並執行。 ---旁註:不要在你的類中加載圖像,因爲每次創建新實例時都必須重新加載它們。在主循環開始之前全局加載它們,然後重新使用它們。 – skrx

+1

修正了它,謝謝! –

回答

0

如果碰撞檢測有問題,通常會幫助打印精靈的rect,例如, print(player.rect)。它會告訴你rects永遠不會更新,並且它們保持在同一個位置,並且因爲它們用於碰撞檢測,所以你的sprite不會碰撞。

要解決你的問題,你必須精靈的設定self.rect.center(或self.rect.topleft),以當前self.Xself.Yupdate方法座標。

self.rect.center = self.X, self.Y 

我建議採取看看pygame.sprite.spritecollide方法。把你的敵人變成一個獨立的精靈羣體,然後獲得相撞精靈這樣:

collided_enemies = pg.sprite.spritecollide(player, enemies, False) 
for collided_enemy in collided_enemies: 
    # Do something with the collided_enemy. 

這裏有一個最小的,完整的例子:

import sys 
import pygame as pg 


class Player(pg.sprite.Sprite): 

    def __init__(self, pos, color): 
     super().__init__() 
     self.image = pg.Surface((50, 30)) 
     self.image.fill(color) 
     self.rect = self.image.get_rect(center=pos) 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 
    player = Player((100, 100), pg.Color('dodgerblue2')) 
    enemy = Player((300, 100), pg.Color('sienna2')) 
    enemy2 = Player((200, 300), pg.Color('sienna2')) 
    all_sprites = pg.sprite.Group(player, enemy, enemy2) 
    enemies = pg.sprite.Group(enemy, enemy2) 

    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 
      if event.type == pg.MOUSEMOTION: 
       player.rect.center = event.pos 

     all_sprites.update() 

     collided_enemies = pg.sprite.spritecollide(player, enemies, False) 
     for collided_enemy in collided_enemies: 
      print(collided_enemy.rect) 

     screen.fill((50, 50, 50)) 
     all_sprites.draw(screen) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    pg.init() 
    main() 
    pg.quit() 
    sys.exit() 
+1

非常感謝你!我不能相信那只是它,只是提升我的反應姿勢!感謝您的幫助! –

+0

不客氣。請注意並接受有用的答案。 – skrx

+0

還有一件事:'clock.tick()'應該每幀只調用一次,而不是每個對象一次。最好在main while循環中調用'time_passed = clock.tick()',然後將'time_passed'傳遞給sprite的'update'方法。並熟悉[sprite groups](http://programarcadegames.com/index.php?chapter=introduction_to_sprites&lang=de#section_13)。 – skrx