PyGame中的雪碧碰撞测试(尝试:rect和组)
我知道有近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()
完蛋了,感谢在我的岗位反馈!
如果碰撞检测有问题,通常会帮助打印精灵的rect
,例如, print(player.rect)
。它会告诉你rects永远不会更新,并且它们保持在同一个位置,并且因为它们用于碰撞检测,所以你的sprite不会碰撞。
要解决你的问题,你必须精灵的设定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()
非常感谢你!我不能相信那只是它,只是提升我的反应姿势!感谢您的帮助! –
不客气。请注意并接受有用的答案。 – skrx
还有一件事:'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
你的代码示例是不完整的,足以发现其中的错误。所提到的碰撞检测功能应能正常工作。请编辑您的帖子并提供一个[最小,完整且可验证的示例](http://*.com/help/mcve),我们可以复制并执行。 ---旁注:不要在你的类中加载图像,因为每次创建新实例时都必须重新加载它们。在主循环开始之前全局加载它们,然后重新使用它们。 – skrx
修正了它,谢谢! –