I'm trying to change collision for my game and I saw pygame has mask collision so I tried to use it, but collision is registered all the time and I dont know how to fix it
Here's my code
Class Enemy for fishes spawning in from both sides of the screen and Respawning after hit
class Enemy(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.x = 0
self.y = 0
self.x_change = 0
def enemySpawn(self, i, x, x_change, y, img, screen):
if i < 6:
if x[i] <= -64 or x[i] >= 900:
if i % 2 == 1:
x[i] = random.randint(-64, 0)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(834, 900)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
elif 5 < i < 10:
if x[i] <= -128 or x[i] >= 964:
if i % 2 == 1:
x[i] = random.randint(-128, -64)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(900, 964)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
elif i > 9:
if x[i] <= -256 or x[i] >= 1028:
if i % 2 == 1:
x[i] = random.randint(-256, -128)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(964, 1028)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
screen.blit(img[i], (x[i], y[i]))
self.rect = img[i].get_rect()
self.mask = pygame.mask.from_surface(img[i])
def enemyRespawn(self, i, x, x_change, y, img, screen):
if i < 6:
if i % 2 == 1:
x[i] = random.randint(-64, 0)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(834, 900)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
elif 5 < i < 10:
if i % 2 == 1:
x[i] = random.randint(-128, -64)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(900, 964)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
elif i > 9:
if i % 2 == 1:
x[i] = random.randint(-256, -128)
x_change[i] = abs(x_change[i])
else:
x[i] = random.randint(964, 1028)
x_change[i] = -x_change[i]
y[i] = random.randint(0, 500)
screen.blit(img[i], (x[i], y[i]))
self.rect = img[i].get_rect()
self.mask = pygame.mask.from_surface(img[i])
Class Player, that's a shark that moves by key input and get's bigger by eating
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.x = 420
self.y = 270
self.x_change = 0
self.y_change = 0
self.direction = 0
self.lastKey = 'l'
self.score = 0
self.height = 128
self.width = 128
self.keyInput = True
def drawImg(self, x, y, img, screen):
screen.blit(img, (x, y))
def setDimenzije(self, img):
self.height = img.get_height()
self.width = img.get_width()
def playerMovement(self, img, screen):
# Provera u koju stranu ide
pressed = pygame.key.get_pressed()
if self.keyInput:
if pressed[pygame.K_LEFT]:
self.x_change = -1.5
self.direction = -1
if pressed[pygame.K_RIGHT]:
self.x_change = +1.5
self.direction = 1
if pressed[pygame.K_LEFT] and pressed[pygame.K_RIGHT]:
self.x_change = 0
if not (pressed[pygame.K_LEFT] or pressed[pygame.K_RIGHT]):
self.x_change = 0
if pressed[pygame.K_UP]:
self.y_change = -1.5
if pressed[pygame.K_DOWN]:
self.y_change = +1.5
if pressed[pygame.K_UP] and pressed[pygame.K_DOWN]:
self.y_change = 0
if not (pressed[pygame.K_UP] or pressed[pygame.K_DOWN]):
self.y_change = 0
self.x += self.x_change
self.y += self.y_change
if self.direction == 1 or self.lastKey == 'r':
img_flip = pygame.transform.flip(img, True, False)
if 5 < self.score < 50:
self.setDimenzije(img_flip)
self.drawImg(self.x, self.y, img_flip, screen)
else:
img = pygame.transform.scale(img_flip, (64, 64))
self.setDimenzije(img)
self.drawImg(self.x, self.y, img, screen)
elif self.lastKey == 'l':
if 5 < self.score < 50:
self.setDimenzije(img)
self.drawImg(self.x, self.y, img, screen)
else:
img = pygame.transform.scale(img, (64, 64))
self.setDimenzije(img)
self.drawImg(self.x, self.y, img, screen)
if self.x <= -60:
self.x = 900
elif self.x >= 900:
self.x = -60
if self.y >= 534:
self.y = 534
if self.y <= 0:
self.y = 0
self.rect = img.get_rect()
self.mask = pygame.mask.from_surface(img)
Main Class that has my Collision
enemyImg = []
player = Player()
enemy = Enemy()
enemySprite = pygame.sprite.Group()
def main():
# Inicijalizacija
pygame.init()
clock = pygame.time.Clock()
num_of_enemies = 12
font = pygame.font.Font('freesansbold.ttf', 32)
over_font = pygame.font.Font('freesansbold.ttf', 48)
# kreiram ekran
screen = pygame.display.set_mode((900, 600))
# Pozadina
pozadina = pygame.image.load("pozadina.png")
# Naslov i ikona
pygame.display.set_caption("Gladna ajkula")
icon = pygame.image.load("sharkIcon.png")
pygame.display.set_icon(icon)
enemyImg0 = pygame.image.load("fish1smol-left.png").convert_alpha()
enemyImg1 = pygame.image.load("fish1smol-right.png").convert_alpha()
enemyImg2 = pygame.image.load("fish2smol-left.png").convert_alpha()
enemyImg3 = pygame.image.load("fish2smol-right.png").convert_alpha()
enemyImg4 = pygame.image.load("fish3smol-left.png").convert_alpha()
enemyImg5 = pygame.image.load("fish3smol-right.png").convert_alpha()
enemyImg6 = pygame.image.load("fish1med-left.png").convert_alpha()
enemyImg7 = pygame.image.load("fish1med-right.png").convert_alpha()
enemyImg8 = pygame.image.load("fish3med-left.png").convert_alpha()
enemyImg9 = pygame.image.load("fish3med-right.png").convert_alpha()
enemyImg10 = pygame.image.load("orca-left.png").convert_alpha()
enemyImg11 = pygame.image.load("orca-right.png").convert_alpha()
enemyImg = [enemyImg0, enemyImg1, enemyImg2, enemyImg3, enemyImg4, enemyImg5, enemyImg6, enemyImg7, enemyImg8,
enemyImg9, enemyImg10, enemyImg11]
# Igrac
playerImgLevo1 = pygame.image.load("SharkScaleLeft.png").convert_alpha()
playerImgDesno1 = pygame.image.load("SharkScaleRight.png").convert_alpha()
player.keyInput = True
enemyList = []
enemyX = []
enemyY = []
enemyX_change = []
for i in range(num_of_enemies):
if i % 2 == 1:
enemyX.append(random.randint(-64, 0))
enemyX_change.append(1)
else:
enemyX.append(random.randint(850, 900))
enemyX_change.append(-1)
enemyY.append(random.randint(0, 500))
enemyList.append(enemy)
running = True
while running:
clock.tick(120)
# Pozadina
screen.blit(pozadina, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.playerMovement(playerImgLevo1, screen)
# Enemy
for i in range(12):
enemyX[i] += enemyX_change[i]
enemy.enemySpawn(i, enemyX, enemyX_change, enemyY, enemyImg, screen)
enemySprite.add(enemy)
mob_hits = pygame.sprite.spritecollide(player, enemySprite, False, pygame.sprite.collide_mask)
#mob_hits = pygame.sprite.collide_mask(player, enemyList[i])
if mob_hits:
if player.width > enemyImg[i].get_width():
enemy.enemyRespawn(i, enemyX, enemyX_change, enemyY, enemyImg, screen)
player.score += 1
print('hit')
I know it's kinda messy at this point, but i tried to get hit with just collide mask, and spritecollide but i don't know where did I go wrong. Enemies just keep respawning countless times and pump my score to 1000 in a sec
For the collision detection functions like pygame.sprite.spritecollide
the rect
attribute of the pygame.sprtie.Sprite
objects is used. Therefore you need to make sure that the position of the sprite is set in the rect
attribute of the Enemy
self.rect = img[i].get_rect()
self.rect = img[i].get_rect(topleft = (x[i], y[i]))
and the Player
self.rect = img.get_rect()
self.rect = img.get_rect(topleft = (self.x, self.y))
Note, pygame.Surface.get_rect.get_rect()
returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit
at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the top left of the rectangle can be specified with the keyword argument topleft
. These keyword argument are applied to the attributes of the pygame.Rect
before it is returned (see pygame.Rect
for a full list of the keyword arguments).