1

How can I make a mask that's alpha pixels don't collide?

I've tried everything, following tutorials, viewing other stackoverthrow questions/answers, nothing works. PLEASE SPECIFY THE PROBLEM AND THE SOLUTION.

Here's my code:

level = pygame.image.load(r'data\test lvl.png').convert_alpha()
rect = level.get_rect(center = (400,400))
levelmask = pygame.mask.from_surface(image)

This mask is just a solid box, drawing it yields a solid box. Here's the collision between the level and the player.

        offset = (X2, Y2)
        collide = levelmask.overlap(self.rect_mask, offset)
        print(offset)
        print(collide)
        if collide == None:
            collide = -1
        else:
            collide = 0
        return collide

And here's the code for the initialization of self.rect_mask.

        self.rect_mask = pygame.mask.Mask((75, 160))
        self.rect_mask.fill()

1 Answers1

2

There seems to be nothing wrong with your code. I have incorporated elements of it into an example below.

So where could the issue be:

  • The "level" image has weird transparency (probably not, see comment above)
  • The levelmask used in the overlap() test is somehow different to the one created in the OP's example.
  • The offset is wrong somehow.
  • The 75 x 160 filled comparison mask is always too big to be "inside" the levelmask.

The example below uses the exact operations presented in the OP's example code. It works. A mask is created for the maze, where the non-wall parts are transparent. Another mask is created for the moving object (alien_*), also based on transparency.

Demo:

demo video

Code:

import pygame

# Window size
WINDOW_WIDTH  = 612
WINDOW_HEIGHT = 612
FPS           = 60

# background colours
INKY_BLACK = (   0,  0,  0 )
FIREY_RED  = ( 203, 49,  7 )


class Coordinate:
    def __init__( self, x, y=None ):
        if ( type(x) is tuple ):
            self.x = x[0]
            self.y = x[1]   # Pygame.Rect corner
        else:
            self.x = x
            self.y = y


### MAIN
pygame.init()
pygame.font.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF
window  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Mask Example")

# Make some bitmaps with masks for collision
maze_image = pygame.image.load( "square_maze_10x10.png" ).convert_alpha()
maze_rect  = maze_image.get_rect()
maze_mask  = pygame.mask.from_surface( maze_image )

alien_image = pygame.image.load( "green_guy.png" ).convert_alpha()
alien_rect  = alien_image.get_rect()
alien_rect.topleft = ( 20, 20 )
alien_mask  = pygame.mask.from_surface( alien_image )


clock = pygame.time.Clock()
done  = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True

    # Handle continuous-keypresses
    keys = pygame.key.get_pressed()
    delta = Coordinate( 0,0 )
    if ( keys[pygame.K_UP] ):
        delta.y = -1
    elif ( keys[pygame.K_DOWN] ):
        delta.y = 1
    elif ( keys[pygame.K_LEFT] ):
        delta.x = -1
    elif ( keys[pygame.K_RIGHT] ):
        delta.x = 1
    # move according to keys
    alien_rect.x += delta.x 
    alien_rect.y += delta.y 

    # has the alien hit the walls use a Mask Check?
    background = INKY_BLACK
    if ( None != maze_mask.overlap( alien_mask, alien_rect.topleft ) ):   # <<-- Mask check here
        background = FIREY_RED

    # Repaint the screen
    window.fill( background )
    window.blit( maze_image, maze_rect )
    window.blit( alien_image, alien_rect )

    pygame.display.flip()
    clock.tick_busy_loop( FPS )

pygame.quit()

Resources:

green_guy.png square_maze_10x10.png

Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • See [Creating collisions between a Sprite and a list (that aren't sprites) in a Maze](https://stackoverflow.com/questions/68665022/creating-collisions-between-a-sprite-and-a-list-that-arent-sprites-in-a-maze) – Rabbid76 Jun 30 '22 at 04:55
  • 1
    I found the issue. I used "image" instead of "level" when creating the levelmask. – ThreeGordons Jul 04 '22 at 18:20