Pygame程序运行黑屏,仅关闭窗口可见预期画面求助
Pygame程序黑屏问题排查
我已自行排查Pygame程序的黑屏问题但未获进展,确认未过度调用.display命令,程序运行无报错但窗口始终呈黑屏状态,仅在关闭窗口时能短暂看到预期显示内容。以下是程序代码,恳请帮忙分析问题原因:
import math import random import pygame from pygame import mixer # Initialize the pygame pygame.init() # create the screen screen = pygame.display.set_mode((800, 600)) # Background background = pygame.image.load('space background.png') # Background Sound # come back to this from bg music 'mixer.music.load('insert file name')' # mixer.music.play(-1) # Title and Icon pygame.display.set_caption("Space Invaders") icon = pygame.image.load('ufo.png') pygame.display.set_icon(icon) # Player playerImg = pygame.image.load('ship.png') playerX = 370 playerY = 480 playerX_change = 0 # Enemy enemyImg = [] enemyX = [] enemyY = [] enemyX_change = [] enemyY_change = [] num_of_enemies = 6 for i in range(num_of_enemies): enemyImg.append(pygame.image.load('enemy.png')) enemyX.append(random.randint(0, 735)) enemyY.append(random.randint(50, 150)) enemyX_change.append(0.3) enemyY_change.append(40) # Bullet # Ready - you cat see the bullet on the screen # Fire - The bullet is currently moving bulletImg = pygame.image.load('bullet.png') bulletX = 0 bulletY = 480 bulletX_change = 0 bulletY_change = 1 # Bullet speed bullet_state = "ready" # Score score_value = 0 font = pygame.font.Font('Minecraft.ttf', 24) textX = 10 testY = 10 # might have to change back to 'text' # Game Over text over_font = pygame.font.Font('Minecraft.ttf', 64) def show_score(x, y): score = font.render("Score : " + str(score_value), True, (225, 225, 255)) screen.blit(score, (x, y)) def game_over_text(x, y): over_text = over_font.render("GAME OVER", True, (225, 225, 255)) screen.blit(over_text, (200, 250)) def player(x, y): screen.blit(playerImg, (x, y)) def enemy(x, y, i): screen.blit(enemyImg[i], (x, y)) def fire_bullet(x, y): global bullet_state bullet_state = "fire" screen.blit(bulletImg, (x + 16, y + 10)) def iscollision(enemyX, enemyY, bulletX, bulletY): distance = math.sqrt(math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)) if distance < 27: return True else: return False # Game Loop running = True while running: # RGB screen.fill((0, 0, 0)) # background image screen.blit(background, (0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # if keystroke is pressed check whether its right or left if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: playerX_change = -0.7 # player speed if event.key == pygame.K_RIGHT: playerX_change = 0.7 if event.key == pygame.K_SPACE: if bullet_state == "ready": bullet_Sound = mixer.Sound('laser.wav') bullet_Sound.play() # Get the current X corrdinate of te spaceship bulletX = playerX fire_bullet(playerX, bulletY) if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: playerX_change = 0 # 5 = 5 + -0.1 -> 5 = 5 - 0.1 # 5 = 5 + 0.1 # Checking for boundries of spaceship playerX += playerX_change if playerX <= 0: playerX = 0 elif playerX >= 736: playerX = 736 # Enemy Movement for i in range(num_of_enemies): # Game over if enemyY[i] > 440: for j in range(num_of_enemies): enemyY[j] = 2000 game_over_text() break enemyX[i] += enemyX_change[i] if enemyX[i] <= 0: enemyX_change[i] = 0.3 # enemy speed enemyY[i] += enemyY_change[i] elif enemyX[i] >= 736: enemyX_change[i] = -0.3 enemyY[i] += enemyY_change[i] # Collision collision = iscollision(enemyX[i], enemyY[i], bulletX, bulletY) if collision: explosion_Sound = mixer.Sound('explosion.wav') explosion_Sound.play() bulletY = 480 bullet_state = "ready" score_value += 100 enemyX[i] = random.randint(0, 736) enemyY[i] = random.randint(50, 150) enemy(enemyX[i], enemyY[i], i) # Bullet Movement if bulletY <= 0: bulletY = 480 bullet_state = "ready" if bullet_state == "fire": fire_bullet(bulletX, bulletY) bulletY -= bulletY_change player(playerX, playerY) show_score(textX, testY) pygame.display.update()
问题原因及修复方案
核心问题
所有绘制、子弹逻辑和显示更新的代码都写在了游戏主循环while running的外面,这些代码只会在循环终止(窗口关闭)时执行一次,这就是窗口全程黑屏、关闭时才短暂看到内容的根本原因。
其他次要问题
- 函数调用参数错误:
game_over_text定义时需要接收x,y参数,但调用时未传参,会触发报错 - 碰撞检测公式错误:
iscollision里的距离计算把加号放在了math.sqrt()外面,正确公式应为math.sqrt(math.pow(enemyX - bulletX, 2) + math.pow(enemyY - bulletY, 2)) - 变量名笔误:分数显示的Y坐标变量
testY应为textY,否则会用错坐标位置
修复后的完整代码
import math import random import pygame from pygame import mixer # Initialize the pygame pygame.init() # create the screen screen = pygame.display.set_mode((800, 600)) # Background background = pygame.image.load('space background.png') # Background Sound # come back to this from bg music 'mixer.music.load('insert file name')' # mixer.music.play(-1) # Title and Icon pygame.display.set_caption("Space Invaders") icon = pygame.image.load('ufo.png') pygame.display.set_icon(icon) # Player playerImg = pygame.image.load('ship.png') playerX = 370 playerY = 480 playerX_change = 0 # Enemy enemyImg = [] enemyX = [] enemyY = [] enemyX_change = [] enemyY_change = [] num_of_enemies = 6 for i in range(num_of_enemies): enemyImg.append(pygame.image.load('enemy.png')) enemyX.append(random.randint(0, 735)) enemyY.append(random.randint(50, 150)) enemyX_change.append(0.3) enemyY_change.append(40) # Bullet # Ready - you can't see the bullet on the screen # Fire - The bullet is currently moving bulletImg = pygame.image.load('bullet.png') bulletX = 0 bulletY = 480 bulletX_change = 0 bulletY_change = 1 # Bullet speed bullet_state = "ready" # Score score_value = 0 font = pygame.font.Font('Minecraft.ttf', 24) textX = 10 textY = 10 # Game Over text over_font = pygame.font.Font('Minecraft.ttf', 64) def show_score(x, y): score = font.render("Score : " + str(score_value), True, (225, 225, 255)) screen.blit(score, (x, y)) def game_over_text(): over_text = over_font.render("GAME OVER", True, (225, 225, 255)) screen.blit(over_text, (200, 250)) def player(x, y): screen.blit(playerImg, (x, y)) def enemy(x, y, i): screen.blit(enemyImg[i], (x, y)) def fire_bullet(x, y): global bullet_state bullet_state = "fire" screen.blit(bulletImg, (x + 16, y + 10)) def iscollision(enemyX, enemyY, bulletX, bulletY): distance = math.sqrt(math.pow(enemyX - bulletX, 2) + math.pow(enemyY - bulletY, 2)) if distance < 27: return True else: return False # Game Loop running = True while running: # RGB screen.fill((0, 0, 0)) # background image screen.blit(background, (0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # if keystroke is pressed check whether its right or left if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: playerX_change = -0.7 # player speed if event.key == pygame.K_RIGHT: playerX_change = 0.7 if event.key == pygame.K_SPACE: if bullet_state == "ready": bullet_Sound = mixer.Sound('laser.wav') bullet_Sound.play() # Get the current X corrdinate of te spaceship bulletX = playerX fire_bullet(playerX, bulletY) if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: playerX_change = 0 # Checking for boundries of spaceship playerX += playerX_change if playerX <= 0: playerX = 0 elif playerX >= 736: playerX = 736 # Enemy Movement game_over = False for i in range(num_of_enemies): # Game over if enemyY[i] > 440: game_over = True break enemyX[i] += enemyX_change[i] if enemyX[i] <= 0: enemyX_change[i] = 0.3 # enemy speed enemyY[i] += enemyY_change[i] elif enemyX[i] >= 736: enemyX_change[i] = -0.3 enemyY[i] += enemyY_change[i] # Collision collision = iscollision(enemyX[i], enemyY[i], bulletX, bulletY) if collision: explosion_Sound = mixer.Sound('explosion.wav') explosion_Sound.play() bulletY = 480 bullet_state = "ready" score_value += 100 enemyX[i] = random.randint(0, 736) enemyY[i] = random.randint(50, 150) enemy(enemyX[i], enemyY[i], i) if game_over: for j in range(num_of_enemies): enemyY[j] = 2000 game_over_text() # Bullet Movement if bulletY <= 0: bulletY = 480 bullet_state = "ready" if bullet_state == "fire": fire_bullet(bulletX, bulletY) bulletY -= bulletY_change player(playerX, playerY) show_score(textX, textY) pygame.display.update()
内容的提问来源于stack exchange,提问作者GOOD kid m.A.A.d city
相关产品推荐
相关产品推荐

