I know there are near 5 or 6 questions similar to this one I'm making, but none of the answers helped me (they probably would if I weren't a complete noob), so I'll try to show my specific case.
I'm trying to make a sprite collision test in PyGame (Python lib) but I can't get it to work, all I get is "False" when colliding, it simply won't work and I can't figure out why, been searching for 2 days straight.
In my game I have the object Player (which I called "dude") and the object Enemy (which I called... "enemy"). The __init__ on both is very similar, and both have rects generated.
This is the __init__ for the player:
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()
For the enemy, I have this:
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
When testing collision, these are two methods that return something (wich is already awesome for me, cause there were other tries that only returned errors) but they always return 0's even when I collide then ingame. The collision should occur when player (controlled by key input) touches the enemy sprite ou image (moved randomly though the stage).
These are the testing methods I have:
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) I've been oriented to show more code so the problem can be found, so there it is (I'm also going to load the sprites globally, passing them as parameters to the objects, tanks for the tip).
Player Object:
# -*- 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
Enemy Object:
# -*- 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
Main script:
# -*- 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()
Thats it, thanks for the feedback on my post!