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()