我试图切换级别,但是我收到了这个Traceback错误。
Traceback (most recent call last):
File "C:\Users\Recovery 1\Desktop\Comp sci performance task\compscipretask (1) (1).py", line 228, in <module>
walls,endRect,wallRect,wall = load_level(currentLevel)
File "C:\Users\Recovery 1\Desktop\Comp sci performance task\compscipretask (1) (1).py", line 87, in load_level
for row in levels[level]:
IndexError: list index out of range
我真的被困在这里,这是我游戏的最后一个组成部分,所以任何帮助都会受到赞赏。我对pygame和python也很新,所以我的经验非常有限。提前谢谢!
代码:
import pygame
import sys
import time
pygame.init()
screenSize = (800,600)
displayScreen = pygame.display.set_mode((screenSize),0)
pygame.display.set_caption("U1A2 Test")
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
displayScreen.fill(WHITE)
pygame.display.update()
clock = pygame.time.Clock()
fps= 60
game = False
menu = True
inst = False
jump= False
x = 53
y = 552
walls = []
dx = 0
dy = 0
currentLevel = 0
sprite= pygame.image.load('block sprite.png')
levels = [[
" ",
" ",
" D ",
" D ",
" ",
" ",
" WW ",
" ",
" ",
" WWWW ",
" ",
" ",
" WWW ",
" ",
" ",
" WWW ",
" WWW ",
" ",
"WWWWWWWWWWWWWWWWWWWWWWWWWW",
],
[
" ",
" ",
" D ",
" D ",
" ",
" WW ",
" ",
" WW ",
" ",
" WWWW ",
" ",
" ",
" WWW ",
" ",
" ",
" WWW ",
" WWW ",
" ",
"WWWWWWWWWWWWWWWWWWWWWWWWWW",
]]
def load_level(level):
m = n = 0
wall = (x, y)
walls = []
for row in levels[level]:
for col in row:
if col == "D":
endRect = pygame.Rect(m, n, 32, 32)
walls.append(endRect)
if col == " ":
jump = False
if col == "W":
wallRect = pygame.Rect(m,n,32,32)
walls.append(wallRect)
jump = True
m += 32
n += 32
m = 0
return walls,endRect,wallRect,wall
walls,endRect,wallRect,wall = load_level(currentLevel)
while menu:
fontTitle = pygame.font.SysFont("Ariel", 72)
textTitle = fontTitle.render("change this", True, (255,0,0))
displayScreen.blit(textTitle,(35, 50))
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("Press 1 to play", True, (255,0,0))
displayScreen.blit(textTitle,(35, 100))
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("Press 2 for instructions", True, (255,0,0))
displayScreen.blit(textTitle,(35, 150))
pygame.display.update()
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("Press 3 to quit", True, (255,0,0))
displayScreen.blit(textTitle,(35, 200))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
print "ds"
game = True
currentLevel = 1
elif event.key == pygame.K_2:
menu = False
inst = True
displayScreen.fill(WHITE)
elif event.key == pygame.K_3:
menu = False
while game:
#pygame.draw.rect(displayScreen,GREEN,PlayerRect,0)
#pygame.draw.rect(displayScreen, (255, 0, 0), PlayerRect, 1)
#walls, players = load_level(level1)
clock.tick(fps)
for event in pygame.event.get():
if event.type ==pygame.QUIT:
pygame.display.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
dx = -7
displayScreen.fill(WHITE)
elif event.key == pygame.K_d:
dx = 7
displayScreen.fill(WHITE)
elif event.key == pygame.K_w:
dy = -25
elif event.key == pygame.K_s:
dy = 25
displayScreen.fill(WHITE)
elif event.key == pygame.K_q:
stop = True
displayScreen.fill(WHITE)
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
dx = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
dy = 0
oldx = x
oldy = y
x = x + dx
y = y + dy
if game == True:
dy = dy + 2
if (x>=798 or x<=2):
x=oldx
if (y<=3 or y>=597):
y=oldy
displayScreen.fill(WHITE)
for wall in walls:
PlayerRect = pygame.Rect(x,y, sprite.get_width(), sprite.get_height())
if PlayerRect.colliderect(wall):
if dx > 0:
PlayerRect.left = wall.right
if dx < 0:
PlayerRect.right = wall.left
if dy > 0:
PlayerRect.bottom = wall.top
if dy < 0:
PlayerRect.top = wall.bottom
dy = 0
for wall in walls:
pygame.draw.rect(displayScreen,BLUE,wall,0)
pygame.draw.rect(displayScreen,RED, endRect, 0)
if PlayerRect.colliderect(endRect):
currentLevel += 1
walls,endRect,wallRect,wall = load_level(currentLevel)
displayScreen.blit(sprite,(x,y))
pygame.display.flip()
while inst:
fontTitle = pygame.font.SysFont("Ariel", 72)
textTitle = fontTitle.render("Instructions", True, (255,0,0))
displayScreen.blit(textTitle,(35, 50))
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("- Use W to jump,S to fall", True, (255,0,0))
displayScreen.blit(textTitle,(35, 100))
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("- Control your jump by using the A and D keys", True, (255,0,0))
displayScreen.blit(textTitle,(35,150))
pygame.display.update()
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("- Move left and right with the A and D keys", True, (255,0,0))
displayScreen.blit(textTitle,(35, 200))
pygame.display.update()
fontTitle = pygame.font.SysFont("Ariel", 52)
textTitle = fontTitle.render("Press 3 to exit", True, (255,0,0))
displayScreen.blit(textTitle,(35, 250))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_3:
inst = False
displayScreen.fill(WHITE)
menu = True
pygame.quit()
sys.exit()
答案 0 :(得分:0)
问题是,如错误消息所示,与levels
列表一起使用的索引超出范围。它只能是0
或1
。问题似乎是因为在主while game
循环中,您将currentLevel
递增1而不检查其值之前或之后。最初设置为0
,但稍后当用户按 1 键进行游戏时,它会设置为1
。
for wall in walls:
pygame.draw.rect(displayScreen,BLUE,wall,0)
pygame.draw.rect(displayScreen,RED, endRect, 0)
if PlayerRect.colliderect(endRect):
currentLevel += 1 # unconditionally increments the value
walls,endRect,wallRect,wall = load_level(currentLevel)
我不确定,但在用户开始播放时将其值设置为1
可能是错误的。无论如何,您需要添加一些检查以防止它超出范围或在使用前始终检查它的值。一个显而易见的方法是简单地将其递增为条件:
for wall in walls:
pygame.draw.rect(displayScreen,BLUE,wall,0)
pygame.draw.rect(displayScreen,RED, endRect, 0)
if PlayerRect.colliderect(endRect):
if currentLevel < 1: #### LIKE THIS ####
currentLevel += 1
walls,endRect,wallRect,wall = load_level(currentLevel)
更好的是,通过避免代码中可能发生变化的硬编码常量,可以使程序更加灵活。这可以通过在开头附近定义一个全局常量来完成:
HIGHEST_LEVEL = len(levels)-1 # index of topmost level
...然后在必要时使用它以确保currentLevel
有效或保持有效:
...
if PlayerRect.colliderect(endRect)
if currentLevel < HIGHEST_LEVEL:
currentLevel += 1
...
在这里使用这种方法可以让你可以为游戏添加关卡而不需要进行远距离搜索,尽管代码确保currentLevel
始终在范围内 - 就像我在调试过程中必须做的那样你的计划。