0
\$\begingroup\$

This is the first game I've ever tried to make using Pygame and I am running into some issues displaying the player character and the enemy characters. I have a "main" game file and other files that are imported into it.

Here is a picture of what I mean enter image description here

So yeah. They images seem to leave behind their former selves and just keep going. Never mind that yes the dog is the one from Undertale and the cat is Pusheen lol. I will post my main code and the supporting imported files.

Here is the main game file::

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()
    while True:
        #displays instructions.png on game
        for event in pygame.event.get():
            keyE = pygame.event.get(KEYUP)
            if event.type == pygame.QUIT:
                terminate()
            if event.type == pygame.KEYDOWN:
                # while True:
                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

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

Thanks for taking the time to look at this and let me know if I need to upload anything else. Thanks!!

\$\endgroup\$
1
\$\begingroup\$

You need to clear the screen at the start of each frame. So, put DISPLAYSURF.fill((0, 0, 0)) at the start of your game mainloop (which you oddly seem to have two).

Currently you clear the screen before calling runGame, but then runGame takes over the mainloop, so the screen won't be cleared in main again.

You really want to just have one main loop, where you start with polling for events, the update all your objects, after which you clear the screen, then render all your objects, and finally flip the window buffer.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks so much! That worked. If you don't mind answering another question... I can't seem to get my cat to move up at all. It only moves down and side to side \$\endgroup\$ – Taylor Apr 13 '17 at 17:55
  • \$\begingroup\$ I think it'd be the best if you posted a new question with the relevant bits of your code in it. \$\endgroup\$ – Tyyppi_77 Apr 13 '17 at 19:39

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.