【问题标题】:Function is Repeating Ten Times Instead of Once - Pygame Zero函数重复十次而不是一次 - Pygame 零
【发布时间】:2020-06-02 20:23:23
【问题描述】:

我用 Pygame Zero 编写了一个简单的赛车游戏。这来自 MagPi “使用 Raspberry Pi 进行复古游戏” 一书。我是一个初学者程序员,所以我可能会问一个明显的问题。我想做关卡。每 100 个scorelevel + 1。赢得 10 个级别。

感兴趣的领域可能是我的draw() 函数:

    global gameStatus, level
    screen.fill((128, 128, 128))
    if gameStatus == 0:
        car.draw()
        b = 0
        while b < len(trackLeft):
            trackLeft[b].draw()
            trackRight[b].draw()
            b += 1
        screen.draw.text("Score: " + str(score), (50, 30), color="black")
        if score % 100 == 0:
            check_levels()
        screen.draw.text("Level: " + str(level), (50, 50), color="black")
    if gameStatus == 1:
        screen.blit('rflag', (318, 268))
    if gameStatus == 2:
        screen.blit('cflag', (318, 268))

还有我的level_up() 函数:

    global level
    if level <= 10:
        level += 1
    if level == 10:
        gameStatus == 2

每完成一首曲目,就会计算出一个更高的分数。

我的问题:当我达到 100 score 时,等级增加了 10,而不是增加了 1。我不知道似乎发生了什么。会不会是每个分数都有几个 FPS/tick,并且随着每一刻更新关卡,似乎当分数在 100 上挂起大约 10 个刻时,关卡每刻更新一次?

由于我的程序很短,我将继续发布所有代码:

import time
from random import randint
import pygame
import pgzrun


WIDTH = 700
HEIGHT = 800


car = Actor("racecar")
car.pos = 250, 700
SPEED = 4
trackLeft = []
trackRight = []
trackCount = 0
trackPosition = 250
trackWidth = 120
trackDirection = False
gameStatus = 0
score = 0
level = 1


def draw():
    global gameStatus, level
    screen.fill((128, 128, 128))
    if gameStatus == 0:
        car.draw()
        b = 0
        while b < len(trackLeft):
            trackLeft[b].draw()
            trackRight[b].draw()
            b += 1
        screen.draw.text("Score: " + str(score), (50, 30), color="black")
        if score % 100 == 0:
            check_levels()
        screen.draw.text("Level: " + str(level), (50, 50), color="black")
    if gameStatus == 1:
        screen.blit('rflag', (318, 268))
    if gameStatus == 2:
        screen.blit('cflag', (318, 268))


def update():
    global gameStatus, trackCount
    if gameStatus == 0:
        if keyboard.left: car.x -= 2
        if keyboard.right: car.x += 2
        update_track()


def make_track():
    global trackCount, trackLeft, trackRight, trackPosition, trackWidth, score
    trackLeft.append(Actor("barrier", pos=(trackPosition - trackWidth, 0)))
    trackRight.append(Actor("barrier", pos=(trackPosition + trackWidth, 0)))
    trackCount += 1
    score += 1


def update_track():
    global trackCount, trackPosition, trackDirection, trackWidth, gameStatus
    b = 0
    while b < len(trackLeft):
        if car.colliderect(trackLeft[b]) or car.colliderect(trackRight[b]):
            gameStatus = 1
        trackLeft[b].y += SPEED
        trackRight[b].y += SPEED
        b += 1
    if trackLeft[len(trackLeft) - 1].y > 32:
        if trackDirection == False: trackPosition += 16
        if trackDirection == True: trackPosition -= 16
        if randint(0, 4) == 1: trackDirection = not trackDirection
        if trackPosition > 700 - trackWidth: trackDirection = True
        if trackPosition < trackWidth: trackDirection = False
        make_track()


def check_levels():
    global level
    if level <= 10:
        level += 1
    if level == 10:
        gameStatus = 2


make_track()


pgzrun.go()

【问题讨论】:

  • gameStatus == 2 - 应该是gameStatus = 2
  • 是的,对不起!我会编辑的!

标签: python python-3.x pygame pgzero


【解决方案1】:

您必须在分数更新时进行级别检查。请注意,draw 执行的频率更高,然后分数会更新,因此if score % 100 == 0: 会被多次执行,并且级别会多次增加:

def draw():
    global gameStatus, level
    screen.fill((128, 128, 128))
    if gameStatus == 0:
        # [...]

        screen.draw.text("Score: " + str(score), (50, 30), color="black")

        # DELETE <--------------------------
        #if score % 100 == 0:
        #    check_levels()

        screen.draw.text("Level: " + str(level), (50, 50), color="black")
def make_track():
    #[...]
    trackCount += 1
    score += 1

    # ADD <-----------------------------
    if score % 100 == 0:
        check_levels()

此外,您的游戏会在一段时间后滞后,因为列表 trackLefttrackRight 正在不断增长。从列表中移除底部窗口之外的障碍:

def make_track():
    global trackCount, trackLeft, trackRight, trackPosition, trackWidth, score
    trackLeft.append(Actor("barrier", pos=(trackPosition - trackWidth, 0)))
    trackRight.append(Actor("barrier", pos=(trackPosition + trackWidth, 0)))

    # remove barriers which are out of screen
    if trackLeft[0].y >= HEIGHT:
        del trackLeft[0]
    if trackRight[0].y >= HEIGHT:
        del trackRight[0]

    trackCount += 1
    score += 1
    if score % 100 == 0:
        check_levels()

【讨论】:

  • 感谢您的回复,它有效。而且几乎没有延迟!但现在我很感兴趣——在程序结束时,make_track() 运行了。 draw() 也运行。这是否意味着 draw() 在帧之间运行?
  • @PolarBear123 No. draw()update 每帧调用一次。但是make_track 被称为if trackLeft[len(trackLeft) - 1].y &gt; 32:。所以它不会在每一帧中调用,并且分数不会在每一帧中递增。代码末尾对make_track的调用在启动时执行,并将第一个元素添加到trackLefttrackRight
猜你喜欢
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多