我知道有近5或6个类似于我正在制作的问题,但没有一个答案对我有帮助(如果我不是一个完整的菜鸟,他们可能就会这样),所以我会尝试展示我的具体案例。
我正在尝试在PyGame(Python lib)中进行sprite碰撞测试,但是我无法让它工作,碰到时我得到的都是“False”,它根本不起作用我不能找出原因,一直在寻找2天。
在我的游戏中,我有对象Player(我称之为“dude”)和对象Enemy(我称之为“敌人”)。两者上的__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)
(编辑) 我一直致力于显示更多代码,以便找到问题,所以就是这样 (我也将全局加载精灵,将它们作为参数传递给对象,尖端的坦克)。
玩家对象:
# -*- 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()
多数民众赞成,感谢我对帖子的反馈!
答案 0 :(得分:0)
如果您遇到碰撞检测问题,打印精灵的rect
通常会有帮助,例如: print(player.rect)
。它会向您显示rects永远不会更新,并且它们保持在同一位置,并且因为它们被用于碰撞检测,所以您的精灵不会碰撞。
要解决您的问题,您必须将精灵的self.rect.center
(或self.rect.topleft
)设置为self.X
中的当前self.Y
和update
坐标方法
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()