You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame Zero游戏运行窗口黑屏无响应问题求助

Pygame Zero坦克游戏运行黑屏问题修复

我使用Python的Pygame Zero开发一款坦克游戏,此前的问题已解决,但现在运行游戏时窗口仅显示黑屏,以下是完整代码:

import pgzrun
from pgzero.builtins import Actor, animate, keyboard
import random as r

# settings
TITLE = "Tonk Game"
WIDTH = 800
HEIGHT = 600

enemyAmount = 5
wallpercent= 50

# actors
tank = Actor('tank_green.png')
tank.angle = 90

# variables
bulletH = 0

# bullets
bullets = []

# game  variables
gameWin = False
gameLose = False
gameStart = False

# walls + enemy tank
walls = []
enemies = []
for i in range(enemyAmount):
    enemy = Actor('tank_red.png')
    enemy.x = i*200-10
    enemy.y = 25
    enemy.angle = 270
    enemy.move_count = 0
    enemies.append(enemy)

# explosion particle
explosion = Actor('explosion.png')
explosion.pos = 900, 700

for x in range(16):
    for y in range(10):
        if r.randint(0, 100) < wallpercent:
            wall = Actor('wall.jpeg')
            wall.x = x*50+25
            wall.y = y*50+25+50
            walls.append(wall)

# actors pos
tank.pos = 400, 575

# enemy bullets
enBullets = []

# buttons for main menu (settings)
# enemy amount adjustment buttons
diff1= Actor('tank_red.png')
diff2= Actor('tank_red.png')
diff3= Actor('tank_red.png')

diff1.pos=200,400
diff2.pos=400,400
diff3.pos=600,400

diff1.angle=270
diff2.angle=270
diff3.angle=270

# wall amount buttons
wol1= Actor('wall.jpeg')
wol2= Actor('wall.jpeg')
wol3= Actor('wall.jpeg')

wol1.pos=200,200
wol2.pos=400,200
wol3.pos=600,200

# start button
start= Actor('bowl.png')
start.pos= 400,560
start.angle=180

# draw def
def draw():
    screen.clear()

    # these only happen when the game has started
    if gameStart:
        screen.blit('grass.png', (0, 0))

        for wall in walls:
            wall.draw()

        tank.draw()
        explosion.draw()

        for enemy in enemies:
            enemy.draw()

        for bullet in bullets:
            bullet.draw()

        for enBullet in enBullets:
            enBullet.draw()

        screen.draw.text("Enemies remaining: " +str(len(enemies)), topleft=(10, 10))
        if gameWin:
            screen.fill('black')
            screen.draw.text("You Win!", fontsize=80, topleft=(280, 250))
        elif gameLose:
            screen.fill('black')
            screen.draw.text("You Lose!", fontsize=80, topleft=(280, 250))
    else:
        screen.fill('black')
        # settings title
        screen.draw.text("Settings",topleft=(370, 50))

        # enemy amount
        diff1.draw()
        diff2.draw()
        diff3.draw()

        screen.draw.text("3 Enemies",topleft=(160, 360))
        screen.draw.text("5 Enemies",topleft=(360, 360))
        screen.draw.text("8 Enemies",topleft=(560, 360))

        # wall amount
        wol1.draw()
        wol2.draw()
        wol3.draw()

        screen.draw.text("25%",topleft=(185, 190))
        screen.draw.text("50%",topleft=(385, 190))
        screen.draw.text("75%",topleft=(585, 190))
        
        # start button
        start.draw()
        screen.draw.text("Start",topleft=(382, 555))

def on_mouse_down(pos):
    global enemyAmount, wallpercent, gameStart

    # enemy amount setting
    if diff1.collidepoint(pos):
        enemyAmount= 3
        print(enemyAmount)
    elif diff2.collidepoint(pos):
        enemyAmount= 5
        print(enemyAmount)
    elif diff3.collidepoint(pos):
        enemyAmount= 8
        print(enemyAmount)

    # wall amount setting
    if wol1.collidepoint(pos):
        wallpercent= 75
        print(wallpercent)
    elif wol2.collidepoint(pos):
        wallpercent= 50
        print(wallpercent)
    elif wol3.collidepoint(pos):
        wallpercent=25
        print(wallpercent)

    # start button
    if start.collidepoint(pos):
        gameStart= True

# update
def update():
    global bulletH, gameWin, gameLose, enemyAmount

    if gameStart:
        # save original tank pos
        orix = tank.x
        oriy = tank.y

        # arrow keys/wasd movement
        if keyboard.right or keyboard.d:
            tank.x += 7
            tank.angle = 0
        elif keyboard.left or keyboard.a:
            tank.x -= 7
            tank.angle = 180
        elif keyboard.up or keyboard.w:
            tank.y -= 7
            tank.angle = 90
        elif keyboard.down or keyboard.s:
            tank.y += 7
            tank.angle = 270

        # tank collision with walls
        if tank.collidelist(walls) != -1:
            tank.pos = orix, oriy

        # stop tanks from going outside
        if tank.x > 800 or tank.x < 0 or tank.y > 600 or tank.y < 0:
            tank.x = orix
            tank.y = oriy

        # bullet fire cooldown
        if bulletH == 0:
            if keyboard.space:
                bullet = Actor('bulletblue.png')
                bullet.angle = tank.angle
                bullet.x = tank.x
                bullet.y = tank.y
                bullets.append(bullet)
                bulletH = 100
        else:
            bulletH -= 1

        # move bullets
        for bullet in bullets.copy():
            if bullet.angle == 0:
                bullet.x += 9
            elif bullet.angle == 180:
                bullet.x -= 9
            elif bullet.angle == 90:
                bullet.y -= 9
            elif bullet.angle == 270:
                bullet.y += 9

            # bullet collision with walls
            wallInd = bullet.collidelist(walls)
            if wallInd != -1:
                del walls[wallInd]
                bullets.remove(bullet)
                continue

            # bullet collision with enemies
            enInd = bullet.collidelist(enemies)
            if enInd != -1:
                explosion.pos = enemies[enInd].x, enemies[enInd].y
                del enemies[enInd]
                bullets.remove(bullet)
                enemyAmount -= 1
                print(f"1 Enemy has died. Enemy remaining: {enemyAmount}")

        # enemy bullet collision with walls
        for enBullet in enBullets.copy():
            wallInd = enBullet.collidelist(walls)
            if wallInd != -1:
                del walls[wallInd]
                enBullets.remove(enBullet)
                continue

            # move enemy bullets
            if enBullet.angle == 0:
                enBullet.x += 12
            elif enBullet.angle == 180:
                enBullet.x -= 12
            elif enBullet.angle == 90:
                enBullet.y -= 12
            elif enBullet.angle == 270:
                enBullet.y += 12

            # player hit by enemy bullet
            if enBullet.colliderect(tank):
                gameLose = True

        # enemy movement and AI
        for enemy in enemies:
            orinemx = enemy.x
            orinemy = enemy.y

            if enemy.move_count > 0:
                enemy.move_count -= 1
                if enemy.angle == 0:
                    enemy.x += 9
                elif enemy.angle == 180:
                    enemy.x -= 9
                elif enemy.angle == 90:
                    enemy.y -= 9
                elif enemy.angle == 270:
                    enemy.y += 9

                # enemy boundary check
                if enemy.x > 800 or enemy.x < 0 or enemy.y > 600 or enemy.y < 0:
                    enemy.x = orinemx
                    enemy.y = orinemy
                # enemy wall collision
                elif enemy.collidelist(walls) != -1:
                    enemy.pos = orinemx, orinemy
            else:
                choice = r.randint(0, 2)
                if choice == 0:
                    enemy.move_count = 20
                elif choice == 1:
                    enemy.angle = r.randint(0, 3)*90
                else:
                    enBullet = Actor('bulletred.png')
                    enBullet.angle = enemy.angle
                    enBullet.x = enemy.x
                    enBullet.y = enemy.y
                    enBullets.append(enBullet)

        # check win condition
        if enemyAmount == 0:
            gameWin = True
    
pgzrun.go()

关键修复说明

  1. 替换draw()中的死循环:把while gameStart!= True改成else分支,避免渲染线程卡死,确保每帧都能正常绘制界面。
  2. 修正开始按钮的变量赋值:在on_mouse_down中添加global gameStart,并将startGame= True改为gameStart= True,确保点击开始后能正确进入游戏状态。
  3. 替换update()中的死循环:把while gameStart改成if gameStart,避免更新线程无限循环,保证游戏帧更新正常。
  4. 修复未定义变量错误:删除了update()中提前访问未定义enemy变量的代码,将敌人生成的位置保存逻辑移到for enemy in enemies循环内部。
  5. 优化子弹遍历逻辑:遍历子弹列表时使用.copy(),避免在遍历过程中修改列表导致的索引错误。

内容的提问来源于stack exchange,提问作者Azbojrn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:25:59