I have two different sprites in the same group, variables 'player' and 'ground'. They both are separate classes, with a mask of their surface. This line is in both of their classes.
self.mask = pygame.mask.from_surface(self.surface)
The images used in their surfaces have 'convert_alpha()' used on them so part of them is transparent, and the mask should work on them. The ground is a few platforms, and I want to check for collision so I can keep the player on the ground, and have them fall when they are not on the non-transparent parts.
if pygame.sprite.collide_mask(player,ground):
print("collision")
else:
print("nope")
This prints "nope", even as the player sprite is falling over where the colored ground sprite pixels are. So the documentation for 'collide_mask()' says that it returns "NoneType" when there is no collision. So I tried this.
if pygame.sprite.collide_mask(player,ground)!= NoneType:
print("collision")
This prints "collision" no matter where the player is(I have jumping, left, and right movements setup for the player). I asked a question about collision yesterday with no answer that helped. And I was told to condense my code submitted in the question so hopefully I explained this well enough without posting all 90 lines. I've checked a lot of other questions on here, and they all seem to do it a little different so I'm very confused (and fairly new). Emphasis on both sprites being in the same group, I couldn't get spritecollide() to work because of this.
The sprites do not only need the mask
attribute, they also need the rect
attribute. the mask
defines the bitmask and rect
specifies the posiotion of the sprite on the screen. See pygame.sprite.collide_mask
:
Tests for collision between two sprites, by testing if their bitmasks overla. If the sprites have a mask attribute, it is used as the mask, otherwise a mask is created from the sprite's image. Sprites must have a rect attribute; the mask attribute is optional.
If sprites are used in pygame.sprite.Group
s then each sprite should have image
and rect
attributes. pygame.sprite.Group.draw()
and pygame.sprite.Group.update()
are methods which are provided by pygame.sprite.Group
.
The latter delegates to the update
method of the contained pygame.sprite.Sprite
s — you have to implement the method. See pygame.sprite.Group.update()
:
Calls the
update()
method on all Sprites in the Group. [...]
The former uses the image
and rect
attributes of the contained pygame.sprite.Sprite
s to draw the objects — you have to ensure that the pygame.sprite.Sprite
s have the required attributes. See pygame.sprite.Group.draw()
:
Draws the contained Sprites to the Surface argument. This uses the
Sprite.image
attribute for the source surface, andSprite.rect
. [...]
Minimal example
import os, pygame
os.chdir(os.path.dirname(os.path.abspath(__file__)))
class SpriteObject(pygame.sprite.Sprite):
def __init__(self, x, y, image):
super().__init__()
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.mask = pygame.mask.from_surface(self.image)
pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((400, 400))
size = window.get_size()
object_surf = pygame.image.load('AirPlane.png').convert_alpha()
obstacle_surf = pygame.image.load('Rocket').convert_alpha()
moving_object = SpriteObject(0, 0, object_surf)
obstacle = SpriteObject(size[0] // 2, size[1] // 2, obstacle_surf)
all_sprites = pygame.sprite.Group([moving_object, obstacle])
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
moving_object.rect.center = pygame.mouse.get_pos()
collide = pygame.sprite.collide_mask(moving_object, obstacle)
window.fill((255, 0, 0) if collide else (0, 0, 64))
all_sprites.draw(window)
pygame.display.update()
pygame.quit()
exit()