Pregunta

Just out of curiosity, why does a game lag when I load an image as well as display pygame shapes for example rectangles, circles and ellipses. I have this code where you shoot the ghosts that fall down (I'm still working on the shooting part). I made the cannon out of pygame shapes. But when I run it the images of the ghosts are prefect but the images of the cannons lag and disappears and reappear and so on. Is there any way to stop this lag or disappear and reappear thing? I'm running python 2.6 with windows vista.

import pygame, sys, random, math
from pygame.locals import *

WINDOWHEIGHT = 600
WINDOWWIDTH = 600
FPS = 30
BACKGROUNDCOLOR = (255, 255, 255)
TEXTCOLOR = (0, 0, 0)
WHITE    = (255, 255, 255)
BLACK    = (  0,   0,   0)
BROWN    = (139,  69,  19)
DARKGRAY = (128, 128, 128)
BGCOLOR = WHITE

GHOSTSPEED = 10
GHOSTSIZE = 20
ADDNEWGHOSTRATE = 8

def keyToPlayAgain():
    while True:
        for event in event.type.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                return

def getAngle(x1, y1, x2, y2):
    # Return value is 0 for right, 90 for up, 180 for left, and 270 for down (and all values between 0 and 360)
    rise = y1 - y2
    run = x1 - x2
    angle = math.atan2(run, rise) # get the angle in radians
    angle = angle * (180 / math.pi) # convert to degrees
    angle = (angle + 90) % 360 # adjust for a right-facing sprite
    return angle

def Text(text, font, surface, x, y):
    textobj = font.render(text, 2, TEXTCOLOR)
    textrect = textobj.get_rect()
    textrect.topleft = (x, y)
    surface.blit(textobj, textrect)

pygame.init()
mainClock = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWHEIGHT, WINDOWWIDTH))
pygame.display.set_icon(pygame.image.load('s.icon'))
pygame.display.set_caption('Ghost Invasion Pacfighters')
pygame.mouse.set_visible(False)

font = pygame.font.SysFont(None, 48)

gameOverSound = pygame.mixer.Sound('gameover.wav')
pygame.mixer.music.load('background.mid')

ghostImage = pygame.image.load('ghosts.png')
dotImage = pygame.image.load('dot.png')
dotRect = dotImage.get_rect()
creditsPage = pygame.image.load('credits.png')
titlePage = pygame.image.load('title.png')

pygame.time.wait(10000)
DISPLAYSURF.blit(creditsPage, (0, 0))
pygame.time.wait(10000)
DISPLAYSURF.blit(titlePage, (0, 0))
pygame.display.update()

cannonSurf = pygame.Surface((100, 100))
cannonSurf.fill(BGCOLOR)
pygame.draw.circle(cannonSurf, DARKGRAY, (20, 50), 20) 
pygame.draw.circle(cannonSurf, DARKGRAY, (80, 50), 20) 
pygame.draw.rect(cannonSurf, DARKGRAY, (20, 30, 60, 40)) 
pygame.draw.circle(cannonSurf, BLACK, (80, 50), 15) 
pygame.draw.circle(cannonSurf, BLACK, (80, 50), 20, 1) 
pygame.draw.circle(cannonSurf, BROWN, (30, 70), 20) 
pygame.draw.circle(cannonSurf, BLACK, (30, 70), 20, 1) 

health = 100
score = 0
topScore = 0
while True:
    ghosts = []
    moveLeft = moveRight = moveUp = moveDown = False
    reverseCheat = slowCheat = False
    ghostAddCounter = 0
    pygame.mixer.music.play(-1, 0.0)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_x:
                    bombs()
                elif event.type == ESCAPE:
                    pygame.quit()
                    sys.exit()

        mousex, mousey = pygame.mouse.get_pos()
        for cannonx, cannony in ((100, 500), (500, 500)):

            degrees = getAngle(cannonx, cannony, mousex, mousey)

            rotatedSurf = pygame.transform.rotate(cannonSurf, degrees)
            rotatedRect = rotatedSurf.get_rect()
            rotatedRect.center = (cannonx, cannony)
            DISPLAYSURF.blit(rotatedSurf, rotatedRect)

            pygame.draw.line(DISPLAYSURF, BLACK, (mousex - 10, mousey), (mousex + 10, mousey))
            pygame.draw.line(DISPLAYSURF, BLACK, (mousex, mousey - 10), (mousex, mousey + 10))

            pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)

            pygame.display.update()

        if not reverseCheat and not slowCheat:
            ghostAddCounter += 1
        if ghostAddCounter == ADDNEWGHOSTRATE:
            ghostAddCounter = 0
            newGhost = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-GHOSTSIZE), 0 - GHOSTSIZE, GHOSTSIZE, GHOSTSIZE),
                        'speed': (GHOSTSIZE),
                        'surface':pygame.transform.scale(ghostImage, (GHOSTSIZE, GHOSTSIZE)),
                        }

            ghosts.append(newGhost)

        for s in ghosts:
            if not reverseCheat and not slowCheat:
                s['rect'].move_ip(0, s['speed'])
            elif reverseCheat:
                s['rect'].move_ip(0, -5)
            elif slowCheat:
                s['rect'].move_ip(0, -1)

        for s in ghosts[:]:
            if s['rect'].top > WINDOWHEIGHT:
                health -= 10

        DISPLAYSURF.fill(BACKGROUNDCOLOR)

        Text('Score: %s' % (score), font, DISPLAYSURF, 10, 0)
        Text('Top score: %s' % (topScore), font, DISPLAYSURF, 10, 40)
        Text('Health: %s' % (health), font, DISPLAYSURF, 10, 560)

        for s in ghosts:
            DISPLAYSURF.blit(s['surface'], s['rect'])

        pygame.display.update()

        mainClock.tick(FPS)

    pygame.mixer.music.stop()
    gameOverSound.play()

    Text('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
    pygame.display.update()
    keyToPlayAgain()
    pygame.display.update()

    gameOverSound.stop()
¿Fue útil?

Solución

The problem is that you draw your cannons, update the display, then clear the display, draw the other stuff, and update the display again. You basically never see the falling ghosts and the cannons at the same time. This results in the flickering you see.

So remove pygame.display.update() from this for loop

    for cannonx, cannony in ((100, 500), (500, 500)):
        ...
        pygame.display.update()

and put DISPLAYSURF.fill(BACKGROUNDCOLOR) at the top of your while loop (or at least before you draw anything):

while True:
    for event in pygame.event.get():
        ...

    mousex, mousey = pygame.mouse.get_pos()

    DISPLAYSURF.fill(BACKGROUNDCOLOR)

    for cannonx, cannony in ((100, 500), (500, 500)):
        ...

It's best to clear the background once at the start of your code that draws everything, and call pygame.display.update() once at the end of that drawing code.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top