4
\$\begingroup\$

I am working on a small game that deals the main character, which is a cat, and dogs that chase it. The dogs are able to wander around like they are supposed to do, but the cat will only move a small space left and right; the cat will move down once but it will not move up. Would the size of the cat cause the camera not to follow or allow the cat to move more? Size is a thing inside the playerObj.

Also, when a dog collides with the cat, the cat is supposed to lose one bar of health. When the cat collides with the dog, it does not detect that that the dog "hit" the cat and the cat does not lose one bar of health, as it should. This is a problem with the collision detection in my code. The cat doesn't lose health at all. Not sure if there is a function in my code that isn't executing or what. I'm going to post the whole main code, which deals with both movement and the health.

Main Game File

import pygame, sys, math, random
import time
# from pygame import *
from globals import *
from Start import *
from instructions import *

def main():
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    startScreen()
    displayInst()
    instructions()


def instructions():
        while True:
            for event in pygame.event.get():
                keyE = pygame.event.get(KEYUP)
                if event.type == pygame.QUIT:
                    terminate()
                if event.type == pygame.KEYDOWN:
                    DISPLAYSURF.fill(WHITE)
                    runGame()
                    if event.key == pygame.K_ESCAPE:
                        terminate()

def runGame():

    invulnerable = False   # if the player is invulnerable
    invulnerableStart = 0
    gameOverMode = False   # if the player has lost
    gameOverStartTime = 0  # time the player lost
    winMode = False        # if the player won
    INVULTIME = 2

    dogObjs = []  #stores all dog objects in the game
    # cameraX and cameraY are the top left of where the camera view is
    cameraX = 0
    cameraY = 0

    dogObjs = [] # stores all the non-player objects
    foodObjs = [] # stores all the food objects

    playerObj = {'surface': pygame.transform.scale(HungryCat, (STARTSIZE, STARTSIZE)),
                 'facing': RIGHT,
                  'size' : STARTSIZE,
                  'x': HALF_WINWIDTH,
                  'y': HALF_WINHEIGHT,
                  'health': MAXHEALTH}

    moveLeft = False
    moveRight = False
    moveUp = False
    moveDown = False

    while True:  # main game loop
        DISPLAYSURF.fill(WHITE)
        if invulnerable and time.time() - invulnerableStart > INVULTIME:
            invulnerable = False

        for dObj in dogObjs:
            # move all the dogs
            dObj['x'] += dObj['moveX']
            dObj['y'] += dObj['moveY']

            if random.randint(0,99) < DIRECTIONCHANGE:
                dObj['moveX'] = getRandomVelocity()
                dObj['moveY'] = getRandomVelocity()
                if dObj['moveX'] > 0:  # faces right
                    dObj['surface'] = pygame.transform.scale(TScaryDog, (dObj['width'], dObj['height']))
                else:  # faces left
                    dObj['surface'] = pygame.transform.scale(ScaryDog, (dObj['width'], dObj['height']))

        # go through all objects and see if any need to be deleted
        for i in range(len(dogObjs) -1, -1, -1):
            if isOutsideActiveArea(cameraX, cameraY, dogObjs[i]):
                del dogObjs[i]

        # if there are not enough dogs, make more
        while len(dogObjs) < NUMDOGS:
            dogObjs.append(makeNewDog(cameraX, cameraY))

        # adjusts the cameras X and Y if they are beyond the allowed camera slack value
        playerCenterX = playerObj['x'] + int(playerObj['size'] / 2)
        playerCenterY = playerObj['y'] + int(playerObj['size'] / 2)
        if (cameraX + HALF_WINWIDTH) - playerCenterX > CAMERASLACK:
            cameraX = playerCenterX + CAMERASLACK - HALF_WINWIDTH
        elif playerCenterX - (cameraX + HALF_WINWIDTH) > CAMERASLACK:
            cameraX = playerCenterX - CAMERASLACK - HALF_WINWIDTH
        if (cameraY + HALF_WINHEIGHT) - playerCenterY > CAMERASLACK:
            cameraY = playerCenterY + CAMERASLACK - HALF_WINHEIGHT
        elif playerCenterY - (cameraY + HALF_WINHEIGHT) > CAMERASLACK:
            cameraY = playerCenterY - CAMERASLACK - HALF_WINHEIGHT

        # draw all dogs
        for dObj in dogObjs:
            dObj['rect'] = pygame.Rect(dObj['x'] - cameraX,
                                          dObj['y'] - cameraY,
                                          dObj['width'],
                                          dObj['height'])
            DISPLAYSURF.blit(dObj['surface'], dObj['rect'])

        # draw the player
        flashIsOn = round(time.time(), 1) * 10 % 2 == 1
        if not gameOverMode and not (invulnerable and flashIsOn):
        # and not flashIsOn:
            playerObj['rect'] = pygame.Rect( (playerObj['x'] - cameraX,
                                                playerObj['y'] - cameraY,
                                                playerObj['size'],
                                                playerObj['size']) )
            DISPLAYSURF.blit(playerObj['surface'], playerObj['rect'])

        # draws the health meter
        healthMeter(playerObj['health'])


        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()

            elif event.type == KEYDOWN:
                if event.key in (K_UP, K_w):
                    moveDown = False
                    moveUP = True
                elif event.key in (K_DOWN, K_s):
                    moveUp = False
                    moveDown = True
                elif event.key in (K_LEFT, K_a):
                    moveRight = False
                    moveLeft = True
                    if playerObj['facing'] != LEFT:
                        playerObj['surface'] = pygame.transform.scale(THungryCat, (playerObj['size'], playerObj['size']))
                    playerObj['facing'] = LEFT
                elif event.key in (K_RIGHT, K_d):
                    moveLeft = False
                    moveRight = True
                    if playerObj['facing'] != RIGHT:
                        playerObj['surface'] = pygame.transform.scale(HungryCat, (playerObj['size'], playerObj['size']))
                    playerObj['facing'] = RIGHT
                elif winMode and event.key == K_RETURN:
                    return

            elif event.type == KEYUP:
                # stop moving the players
                if event.key in (K_LEFT, K_a):
                    moveLeft = False
                elif event.key in (K_RIGHT, K_d):
                    moveRight = False
                elif event.key in (K_UP, K_w):
                    moveUp = False
                elif event.key in (K_DOWN, K_s):
                    moveDown = False

                elif event.key == K_ESCAPE:
                    terminate()


        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 for collision with dogs
            for i in range(len(dogObjs)- 1, -1, -1):
                dgObjs = dogObjs[i]
                if rect in dgObjs and playerObj['rect'].colliderect(dgObjs['rect']):
                    # this means a collision has occured

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

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

                        if playerObj['size'] > HOWBIG:
                            winMode = True

                    elif not invulnerable:

                        invulnerable = True
                        invulnerableStart = time.time()
                        playerObj['health'] -= 1
                        if playerObj['health'] == 0:
                            gameOverMode = True
                            gameOverStartTime = time.time()


        else:
            # game is over, show "game over" screen
            gameOverScreen = pygame.image.load('gameOver.png')
            DISPLAYSURF.blit(gameOverScreen, (0,0))
            if time.time() - gameOverStartTime > GAMEOVERTIME:
                return # end the current game

        # check if player has won
        if winMode:
            WinScreen = pygame.image.load('Win.png')
            DISPLAYSURF.blit(WinScreen, (0,0))

        pygame.display.update()
        FPSCLOCK.tick(FPS)


def healthMeter(currentHealth):  # draws the players health bar
    for i in range(currentHealth):
        pygame.draw.rect(DISPLAYSURF, RED, (15, 5 + (10 * MAXHEALTH) - i * 10, 20, 10))
    for i in range(MAXHEALTH):
        pygame.draw.rect(DISPLAYSURF, WHITE, (15, 5 + (10 * MAXHEALTH) - i * 10, 20, 10), 1)

def getRandomVelocity():
    speed = random.randint(DOGMINSPEED, DOGMAXSPEED)
    if random.randint(0, 1) == 0:
        return speed
    else:
        return -speed

def makeNewDog(cameraX, cameraY):
    dog = {}
    generalSize = random.randint(5, 25)
    multiplier = random.randint(1,3)
    dog['width'] = (generalSize + random.randint(0,10)) * multiplier
    dog['height'] = (generalSize + random.randint(0,10)) * multiplier
    dog['x'], dog['y'] = getRandomOffCameraPos(cameraX, cameraY, dog['width'], dog['height'])
    dog['moveX'] = getRandomVelocity()
    dog['moveY'] = getRandomVelocity()
    if dog['moveX'] < 0:  # faces right
        dog['surface'] = pygame.transform.scale(ScaryDog, (dog['width'], dog['height']))
    else:  #dog is facing left
        dog['surface'] = pygame.transform.scale(TScaryDog, (dog['width'], dog['height']))
    return dog

def getRandomOffCameraPos(cameraX, cameraY, objWidth, objHeight):

    cameraRect = pygame.Rect(cameraX, cameraY, WINWIDTH, WINHEIGHT)
    while True:
        x = random.randint(cameraX - WINWIDTH, cameraX + (2 * WINWIDTH))
        y = random.randint(cameraY - WINHEIGHT, cameraY + (2 * WINHEIGHT))

        objRect = pygame.Rect(x,y, objWidth, objHeight)
        if not objRect.colliderect(cameraRect):
            return x, y

def isOutsideActiveArea(cameraX, cameraY, obj):
    # Return False if camerax and cameray are more than
    # a half-window length beyond the edge of the window.
    boundsLeftEdge = cameraX - WINWIDTH
    boundsTopEdge = cameraY - WINHEIGHT
    boundsRect = pygame.Rect(boundsLeftEdge, boundsTopEdge, WINWIDTH * 5, WINHEIGHT * 5)
    objRect = pygame.Rect(obj['x'], obj['y'], obj['width'], obj['height'])
    return not boundsRect.colliderect(objRect)

if __name__ == '__main__':
    main()
\$\endgroup\$
  • 1
    \$\begingroup\$ Possible duplicate of Character Won't Move very far on X or Y axis \$\endgroup\$ – Tyyppi_77 Apr 18 '17 at 13:19
  • \$\begingroup\$ Is there a way I can delete earlier questions? \$\endgroup\$ – Taylor Apr 18 '17 at 16:50
  • \$\begingroup\$ Sorry I am new to this site but I figured out how to delete questions and have gone and deleted my first question that is very similar to this one. I apologize \$\endgroup\$ – Taylor Apr 18 '17 at 16:58
  • \$\begingroup\$ Please tag responsibly. These tags are not appropriate to your question, which is about a bug it the code, not about how a game should be played. \$\endgroup\$ – Vaillancourt Apr 18 '17 at 17:05
  • \$\begingroup\$ Sorry. I didn't know exactly what tags to put it under. I'm new here \$\endgroup\$ – Taylor Apr 18 '17 at 17:16
1
\$\begingroup\$

So I believe the problem stemmed from:

1). Having multiple "main game" loops and

2). issues with importing pygame.

I believe I had multiple "bad" imports with the different files I had along with "built-in" modules. I believe they were conflicting, because as soon as I commented out the rest of my files and made it one big main file, it was running how I intended.

Thanks to everyone who helped me with the basics of Stack Exchange!

| 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.