1
votes

So I'm trying to make a game where there are 2 objects and am trying to make it so that my program knows when the 2 objects collide.

if players[0].mask.overlap(players[1].mask, offset):
    print("collided")`

My objects both rotate clockwise and counterclockwise and have masks both for the head and the body. (I have 2 images which are both the same size but one contains only the head and another contains only the body, in order to use mask.from_surface().)

def turn(self, event):
    self.surface = self.ojSurface
    if event == 0:
        self.deg -= self.turnSpd
    elif event == 1:
        self.deg += self.turnSpd
    self.surface = pygame.transform.rotate(self.surface, self.deg)
    self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
    self.mask = pygame.mask.from_surface(self.surface)

However, what I find is when I try to check for collision when they are rotated the mask isn't in the same place as the image. It should update the mask every frame through the move function which is called every loop

def move(self):
    self.pos[0] = pygame.mouse.get_pos()[0]
    self.pos[1] = pygame.mouse.get_pos()[1]
    self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
    self.mask = pygame.mask.from_surface(self.surface)

Faulty Hit Detection

If you want to peruse what I have so far here it is:

import pygame

class Player:

    def __init__(self, pos,surface,screen):
        self.pos = [pos[0],pos[1]]
        self.newPos = (pos[0] - surface.get_width()/2, pos[1] - surface.get_height()/2)
        self.deg = 0
        self.surface = surface
        self.ojSurface = surface
        self.screen = screen
        self.mask = pygame.mask.from_surface(self.surface)

    def turn(self, event):
        self.surface = self.ojSurface

        #clockwise
        if event == 0:
            self.deg -= 0.1

        #counter clockwise
        elif event == 1:
            self.deg += 0.1
        self.surface = pygame.transform.rotate(self.surface, self.deg)

        #resetting pos and mask
        self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
        self.mask = pygame.mask.from_surface(self.surface)

    def move(self):
        self.pos[0] = pygame.mouse.get_pos()[0]
        self.pos[1] = pygame.mouse.get_pos()[1]
        self.newPos = (self.pos[0] - self.surface.get_width() / 2, self.pos[1] - self.surface.get_height() / 2)
        self.mask = pygame.mask.from_surface(self.surface)

    def draw(self):
        self.screen.blit(self.surface, self.newPos)

screenRes = (640,480)
screen = pygame.display.set_mode(screenRes)
closed = False
players = [Player((320,240),pygame.image.load("body.png"), screen),Player((480,240),pygame.image.load("body.png"), screen)]

controls = [[pygame.K_a,pygame.K_s],[pygame.K_k,pygame.K_l]]
while not closed:
    screen.fill((0, 0, 0))
    keys = pygame.key.get_pressed()
    offset = (int(players[0].newPos[0] - players[1].newPos[0]), int(players[0].newPos[1] - players[1].newPos[1]))

    #collision
    if players[0].mask.overlap(players[1].mask, offset):
        print("collided")

    #controls
    for i in range(len(players)):
        if keys[controls[i][0]]:
            players[i].turn(0)
        if keys[controls[i][1]]:
            players[i].turn(1)
        players[i].draw()

    players[0].move()
    pygame.display.update()
    for event in pygame.event.get():
        # standard quit
        if event.type == pygame.QUIT:
            pygame.display.quit()
            closed = True
            pygame.quit()
2
Please read the minimal, complete and verifiable example page. We don't like to read and debug hundreds of lines of unknown code. - skrx
Thanks, the shortened example is a lot easier to read. I forgot to mention that external links to projects are also frowned upon here, since the code could change or the link could get lost. Better add the content of your Test.py file to your question. - skrx

2 Answers

0
votes

So I've reviewed your GitHub code, and while I'm not completely sure (I skimmed your code, looking for certain methods being called), I believe that you're not updating your masks every frame. Somewhere in your code, you'll have to update the masks every frame/loop, allowing for the collision to work properly. Try to update all the masks, the head, body and the one in the Player class. Hope this helps!

0
votes

You're calculating the offset in the wrong order. Subtract players[0]'s position from players[1]'s position:

offset = (
    int(players[1].newPos[0] - players[0].newPos[0]),
    int(players[1].newPos[1] - players[0].newPos[1]),
)