0
\$\begingroup\$

I'm making a game where the main character is a cat and has to avoid dogs and eat food. The collision detection works for the dogs and will subtract a bar of health from the cat, but when the cat collides with the food, it does not recognize that a collision has occurred.

Here is the code for the dog collision:

for i in range(len(dogObjs)-1, -1, -1):
                dgObj = dogObjs[i]
                if 'rect' in dgObj and playerObj['rect'].colliderect(dgObj['rect']):
                    # a player/dog collision has occurred

                        if not invulnerableMode:
                            # player is smaller and takes damage
                            invulnerableMode = True
                            invulnerableStartTime = time.time()
                            playerObj['health'] -= 1
                            if playerObj['health'] == 0:
                                gameOverMode = True # turn on "game over mode"
                                gameOverStartTime = time.time()

The above code is the code that works. Now here is the code for the food

for i in range(len(foodObjs)-1, -1, -1):
                fdObj = foodObjs[i]
                if 'rect' in fdObj and playerObj['rect'].colliderect(fdObj['rect']):

                    if fdObj['width'] * fdObj['height'] <= playerObj['size']**2:
                        playerObj['size'] += int( (playerObj['width'] * playerObj['height'])**0.2 ) + 1
                        del foodObjs[i]

                    if playerObj['facing'] == LEFT:
                        playerObj['surface'] = pygame.transform.scale(L_CAT_IMG, (playerObj['size'], playerObj['size']))
                    if playerObj['facing'] == RIGHT:
                        playerObj['surface'] = pygame.transform.scale(R_CAT_IMG, (playerObj['size'], playerObj['size']))

                    if playerObj['size'] > WINSIZE:
                        winMode = True # turn on "win mode"

I would like to make it where the size of the food does not matter, but I am more focused on just making the collision detection work between the cat and the food.

Both of these for loops are inside an if statement. I will show the whole thing below.

if not gameOverMode:
            # actually move the player
            if moveLeft:
                playerObj['x'] -= MOVERATE
            if moveRight:
                playerObj['x'] += MOVERATE
            if moveUp:
                playerObj['y'] -= MOVERATE
            if moveDown:
                playerObj['y'] += MOVERATE

            # check if the player has collided with any dogs
            for i in range(len(dogObjs)-1, -1, -1):
                dgObj = dogObjs[i]
                if 'rect' in dgObj and playerObj['rect'].colliderect(dgObj['rect']):
                    # a player/dog collision has occurred

                        if not invulnerableMode:
                            # player is smaller and takes damage
                            invulnerableMode = True
                            invulnerableStartTime = time.time()
                            playerObj['health'] -= 1
                            if playerObj['health'] == 0:
                                gameOverMode = True # turn on "game over mode"
                                gameOverStartTime = time.time()

            # check if player has collided with food
            for i in range(len(foodObjs)-1, -1, -1):
                fdObj = foodObjs[i]
                if 'rect' in fdObj and playerObj['rect'].colliderect(fdObj['rect']):

                    if fdObj['width'] * fdObj['height'] <= playerObj['size']**2:
                        playerObj['size'] += int( (playerObj['width'] * playerObj['height'])**0.2 ) + 1
                        del foodObjs[i]

                    if playerObj['facing'] == LEFT:
                        playerObj['surface'] = pygame.transform.scale(L_CAT_IMG, (playerObj['size'], playerObj['size']))
                    if playerObj['facing'] == RIGHT:
                        playerObj['surface'] = pygame.transform.scale(R_CAT_IMG, (playerObj['size'], playerObj['size']))

                    if playerObj['size'] > WINSIZE:
                        winMode = True # turn on "win mode"
        else:
            # game is over, show "game over" text
            DISPLAYSURF.blit(gameOverScreen, (0,0))
            if time.time() - gameOverStartTime > GAMEOVERTIME:
                return # end the current game
\$\endgroup\$
  • \$\begingroup\$ So I figured out that it is not even entering the food for loop. Could this be due to the scope that it is in? \$\endgroup\$ – Taylor Apr 19 '17 at 18:25
  • \$\begingroup\$ As an unrelated side-question: Why are you using dictionaries as object data storage instead of a nicer specific class? \$\endgroup\$ – Tyyppi_77 Apr 19 '17 at 18:58
  • \$\begingroup\$ I just wanted to get the code down and working before I compartmentalized into classes. \$\endgroup\$ – Taylor Apr 19 '17 at 19:48
0
\$\begingroup\$

I figured it out. It was not a problem with the code I posted but with some code earlier in the file. My food objects did not have a 'rect' aspect to them, so when I tried to compare the two 'rect's of both the character and the food, nothing happened.

Here is the before code of the food Objects:

for fObj in foodObjs:
            gRect = pygame.Rect( (fObj['x'] - camerax,
                                  fObj['y'] - cameray,
                                  fObj['width'],
                                  fObj['height']) )
            DISPLAYSURF.blit(FOODIMAGES[fObj['foodImage']], gRect)

Here is the fixed and working code:

for fObj in foodObjs:
            fObj['rect'] = pygame.Rect( (fObj['x'] - camerax,
                                  fObj['y'] - cameray,
                                  fObj['width'],
                                  fObj['height']) )
            DISPLAYSURF.blit(FOODIMAGES[fObj['foodImage']], fObj['rect'])
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.