更改pygame中的级别

时间:2016-06-19 17:49:02

标签: python pygame

我试图切换级别,但是我收到了这个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()  

1 个答案:

答案 0 :(得分:0)

问题是,如错误消息所示,与levels列表一起使用的索引超出范围。它只能是01。问题似乎是因为在主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始终在范围内 - 就像我在调试过程中必须做的那样你的计划。