1

I've been looking for days to find a solution but any of the other threads could help me.

I've been trying to make the sprite move over the background image. The background have transparent streets that should be the possible paths for the sprite.

I need to detect when the sprite collide with the other part of the background image that is not transparent. i tried perfect collision method but i don't think it's the right solution for my case because the background.rect doesn't make any sense. I also tried the overlap method but it always return true.

The pictures are 32 bit depth and i'm calling convert_alpha()

class sprites(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.x = 200   
        self.y = 300
        self.img= player_sprite
        self.rect = player_sprite.get_rect()
        self.mask = pygame.mask.from_surface(player_sprite)


    def position(self):

        dx = mouse_x-self.x
        dy = self.y-mouse_y
        d = float((dx**2+dy**2)**0.5)

        displ_x = dx/d
        displ_y = dy/d
        self.x += displ_x
        self.y += displ_y

        if  type(self.mask.overlap(object_background.mask,(0,0))):  
            self.x -= displ_x
            self.y -= displ_y


class object_background_class(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.img = object_background_img
        self.rect = object_background_img.get_rect()
        self.mask = pygame.mask.from_surface(object_background_img.convert_alpha())

object_background = object_background_class()
player = sprites()


player.position() changes each time the coordinates of the sprite accordind to the mouse(x,y) and check if with the new x,y of the player make it collides with the background

game_state = False

while not game_state:

    for e in pygame.event.get():
        if e == pygame.QUIT:
            game_state = True
        if e.type == pygame.KEYDOWN and e.type == pygame.K_ESCAPE:
            game_state = True
        if e.type == pygame.KEYDOWN:
            if e.key == 27:
                game_state = True

    mouse_x, mouse_y = pygame.mouse.get_pos()

    player.position()

    DISPLAYSURFACE.blit(color_background, (0, 0))
    DISPLAYSURFACE.blit(player.img, (player.x, player.y))
    DISPLAYSURFACE.blit(object_background.img, (0, 0))


    pygame.display.flip()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
lm18
  • 11
  • 1
  • You have to draw (paintshop) a mask with the streets – Rabbid76 Apr 11 '20 at 05:13
  • I had already tried with the pixel colour of the steets to check the sprite,but i was looking for an alternative method that could detect if any of the sprite edges were colliding with the street's borders and not just his cords x, y. – lm18 Apr 11 '20 at 15:02
  • is it possible to the detect the collsion beetween a sprite and elements of a background image that has trasparent parts (street) and opaque parts(obstacles), without fragmenting the elements of the background? – lm18 Apr 11 '20 at 15:06
  • i need to detect the collision just with the opaque elements but i can't spilt them. – lm18 Apr 11 '20 at 15:07

2 Answers2

0

The game screen is one big coordinate plane, just say if x, y coords of player go over or under whatever x,y coord threshold than do something

Pmac1687
  • 9
  • 1
  • I can't map all the x,y cords of the elements of background since the obstacles are irregular. – lm18 Apr 10 '20 at 21:17
  • Have you thought about using sprites to make a threshold spot on the screen, if you blit it to screen before the background is blitted the threshold sprite will be invisible – Pmac1687 Apr 11 '20 at 01:28
0

I also tried the overlap method but it always return true.

Of course. pygame.sprite.collide_mask() use the .rect and .mask attribute of the sprite object for the collision detection.
You have to update self.rect after moving the player and changing the self.x and self.y attribute of the player:

class sprites(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.x = 200   
        self.y = 300
        self.img= player_sprite
        self.rect = player_sprite.get_rect()
        self.mask = pygame.mask.from_surface(player_sprite)

    def position(self):

        dx = mouse_x-self.x
        dy = self.y-mouse_y
        d = float((dx**2+dy**2)**0.5)

        displ_x = dx/d
        displ_y = dy/d
        self.x += displ_x
        self.y += displ_y

        if  type(self.mask.overlap(object_background.mask,(0,0))):  
            self.x -= displ_x
            self.y -= displ_y

        self.rect.topleft = (round(self.x), round(self.y)) # <--- THIS IS MISSING

Now you can use collide_mask:

if pygame.sprite.collide_mask(player, object_background):
    # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174