1

只是出于好奇,为什么当我加载图像以及显示 pygame 形状(例如矩形、圆形和椭圆形)时游戏会滞后。我有这段代码,你可以在其中拍摄掉下来的鬼魂(我仍在研究拍摄部分)。我用 pygame 形状制作了大炮。但是当我运行它时,鬼魂的图像是完美的,但大炮的图像滞后并消失并重新出现等等。有什么办法可以阻止这种滞后或消失并重新出现?我正在运行带有 windows vista 的 python 2.6。

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

1 回答 1

2

问题是您绘制大炮,更新显示,然后清除显示,绘制其他内容,然后再次更新显示。你基本上永远不会同时看到坠落的鬼魂和大炮。这会导致您看到的闪烁。

所以pygame.display.update()从这个for循环中删除

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

并放在循环DISPLAYSURF.fill(BACKGROUNDCOLOR)的顶部while(或至少在你绘制任何东西之前):

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

最好在绘制所有内容的代码开始时清除背景一次,并在该绘制代码pygame.display.update() 结束时调用一次。

于 2013-10-18T11:48:06.197 回答