0

I am using Pygame, I have a Windows 10 computer, working in Anaconda- Spyder.

I made a game where a car moves around the screen dodging objects. Currently the background is white but I would like to put a background image. However when I do the FPS drops dramatically. I understand this is because I am updating the display at 60 fps. I heard about dirty rect animation and I am trying to understand it but at the moment I am stuck on how to achieve my goal of having a background without the game suffering because of it.

If anyone could also answer a separate question that would be great. How do I make the car speed higher without having to increase the fps rate

Here is my code. The comments are my attempts at dirty rec animation.

   """
Racing Game
Created on Mon Nov 11 13:36:45 2017
Author: Oscar
"""
import pygame
import random

#from gameHub import userName
#add powerups
#add borders
#add stickman Oscar that throws bombs
#add help menu

pygame.init()

displayWidth = 800
displayHeight = 644

crashWidth = 800
crashHeight = 600

introWidth = 800
introHeight = 555

black = (0,0,0)
white = (255,255,255)

red = (200,0,0)
green = (0,200,0)

brightRed = (255,0,0)
brightGreen = (0,255,0)

carWidth = 73
carHeight = 82

rocketHeight = 261
rocketWidth = 95

gameDisplay = pygame.display.set_mode((displayWidth,displayHeight))
pygame.display.set_caption('Rocky Racing')
clock = pygame.time.Clock()

carImg = pygame.image.load('racecar.jpg').convert_alpha()
rocketImg = pygame.image.load('rocket.png').convert_alpha()
stickImg = pygame.image.load('stickman.png').convert_alpha()
speedPowerImg= pygame.image.load('speedPower.png').convert_alpha()
slowTimePowerImg= pygame.image.load('slowTimePower.png').convert_alpha()
pause = False

#----------------------------------Tools--------------------------------------------
def rocketDodged(count):
    font = pygame.font.SysFont("comicsansms", 25)
    text = font.render("Missles Dodged: "+str(count), True, black)
    gameDisplay.blit(text,(0,0))

def gameObjects(objectImg,posX,posY):
    gameDisplay.blit(objectImg,(posX,posY))

def gamePowerUp(objectImg):
    posX = random.randrange(0, displayWidth)
    posY = random.randrange(70, displayHeight - 50)
    gameDisplay.blit(objectImg,(posX,posY))

def textObjects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def crash():
    gameDisplay = pygame.display.set_mode((crashWidth,crashHeight))
    gameDisplay.blit((pygame.image.load('citynuke.jpg')),(0,0))
    largeText = pygame.font.SysFont("comicsansms",115)
    TextSurf, TextRect = textObjects("You Crashed!", largeText)
    TextRect.center = ((displayWidth/2),(displayHeight/2))
    gameDisplay.blit(TextSurf, TextRect)


    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        button("Play Again",150,450,100,50,20,green,brightGreen,gameLoop)
        button("Quit",550,450,100,50,20,red,brightRed,quitgame)

        pygame.display.update()
        clock.tick(15)


def button(msg,xPos,yPos,width,height,fontSize,ic,ac,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if xPos+width > mouse[0] > xPos and yPos+height > mouse[1] > yPos:
        pygame.draw.rect(gameDisplay, ac,(xPos,yPos,width,height))
        if click[0] == 1 and action != None:
            action()
    else:
        pygame.draw.rect(gameDisplay, ic,(xPos,yPos,width,height))

    smallText = pygame.font.SysFont("comicsansms",fontSize)
    textSurf, textRect = textObjects(msg, smallText)
    textRect.center = ( (xPos+(width/2)), (yPos+(height/2)) )
    gameDisplay.blit(textSurf, textRect)


def quitgame():
    pygame.quit()
    quit()

#--------------------------------Screens---------------------------------------------
def unpause():
    global pause
    pause = False


def paused():
    gameDisplay.fill(white)
    largeText = pygame.font.SysFont("comicsansms",115)
    TextSurf, TextRect = textObjects("Paused", largeText)
    TextRect.center = ((displayWidth/2),(displayHeight/2))
    gameDisplay.blit(TextSurf, TextRect)

    while pause:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        button("Continue",150,450,100,50,20,green,brightGreen,unpause)
        button("Quit",550,450,100,50,20,red,brightRed,quitgame)

        pygame.display.update()
        clock.tick(15)

#------------------------------------Game--------------------------------------------
def gameIntro():
    intro = True
    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        gameDisplay.fill(white)
        gameDisplay.blit((pygame.image.load('introscreen.jpg')),(0,0))

        button("GO!",150,450,100,50,20,green,brightGreen,gameLoop)
        button("Quit",550,450,100,50,20,red,brightRed,quitgame)

        pygame.display.update()
        clock.tick(25)


def gameLoop():
    global pause
    dirtyRec = []

    carX = (displayWidth * 0.45)
    carY = (displayHeight * 0.8)

    xChange = 0
    yChange = 0

    rocketX = random.randrange(0, displayWidth - rocketWidth)
    rocketY = -600
    rocketSpeed = 4

    stickY = 28


    dodged = 0

    #display = pygame.Rect(0,0,displayWidth,displayHeight)
    #gameDisplay.fill(white)
    #pygame.display.update(display)

    gameExit = False

    while not gameExit:

        stickX = rocketX


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

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                  xChange = -5
                if event.key == pygame.K_RIGHT:
                    xChange = 5
                if event.key == pygame.K_DOWN:
                    yChange = 5
                if event.key == pygame.K_UP:
                    yChange = -5
                if event.key == pygame.K_p:
                    pause = True
                    paused()


            if event.type == pygame.KEYUP:
                keys = pygame.key.get_pressed()
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    xChange = 0
                    if keys[pygame.K_LEFT]:
                      xChange = -5
                    if keys[pygame.K_RIGHT]:
                      xChange = 5
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    yChange = 0
                    if keys[pygame.K_DOWN]:
                      yChange = 5
                    if keys[pygame.K_UP]:
                      yChange = -5

        carX += xChange
        carY += yChange

        #carPos = pygame.Rect(carX,carY,carWidth+5,carHeight+5)
        #dirtyRec.append(carPos)
        #rocketPos = pygame.Rect(rocketX,rocketY,rocketWidth+5,rocketHeight+5)
        #dirtyRec.append(rocketPos)
        gameDisplay.fill(white)
        #speedUpPower = gamePowerUp(speedPowerImg)
        #slowTimePower = gamePowerUp(slowTimePowerImg)
        rockets= gameObjects(rocketImg,rocketX, rocketY)
        stickFigure = gameObjects(stickImg,stickX,stickY)

        rocketY += rocketSpeed
        car = gameObjects(carImg,carX,carY)
        rocketDodged(dodged)

        if carX > displayWidth - carWidth or carX < 0 or carY > displayHeight - carHeight or carY < 0:
            crash()

        if rocketY > displayHeight:
            rocketY = 0 - rocketHeight
            rocketX = random.randrange(0,displayWidth)
            dodged += 1
            rocketSpeed += .5

        if carY < rocketY+rocketHeight and carY > rocketY:
            if carX > rocketX and carX < rocketX + rocketWidth or carX+carWidth > rocketX and carX + carWidth < rocketX + rocketWidth:
                crash()

        #pygame.display.update(dirtyRec)
        pygame.display.update()
        clock.tick(40)

def rrMain():
  gameIntro()
  gameLoop()
  pygame.quit()
  quit()

rrMain()
Oscar
  • 1
  • I wonder if there's a way to reproduce the issue with a bit less code? As it currently stands, your code sample isn't quite a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Jeff B Dec 01 '17 at 20:07
  • ie. car moves slowly when it moves 1pixel in frame, car moves faster when it moves more than 1 pixel in frame (ie. 10 pixels). Or it move fast if you move then in every frame, and it moves slower if you move it every 2-3 frames. (BTW: instead counting frame you can use get_ticks to use timer and it will work the same in slow and fast computer). – furas Dec 01 '17 at 20:08
  • BTW: putting image as background shouldn't slowdown program - maybe you should show how you draw background. – furas Dec 01 '17 at 20:14
  • BTW: you could load all images and create all fonts only once - at start. – furas Dec 01 '17 at 20:18
  • 1
    Yes, don't load images (`pygame.image.load`) from your hard disk in your while loops, because that's slow. You should also call the `convert` (or `convert_alpha`) method after loading an image, e.g. `pygame.image.load('introscreen.jpg').convert()`. I've tried to run your game with replacement images (pygame.Surfaces) and I get the full 40 fps in the `gameLoop` scene. – skrx Dec 01 '17 at 20:31
  • I understand you get the full 40 fps, but that's without a background image. I want to put a background image. – Oscar Dec 02 '17 at 21:08

0 Answers0