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

