简体   繁体   English

改变pygame的水平

[英]change levels in pygame

I'm trying to switch levels, but I get this Traceback error. 我正在尝试切换级别,但是出现此回溯错误。

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

I am really stuck here, and this is the last component of my game so any help is appreciated. 我真的很困在这里,这是我游戏的最后一个组成部分,感谢您的帮助。 I'm also fairly new to pygame and python so my experience is very limited. 我对pygame和python还是很陌生,所以我的经验非常有限。 Thanks in advance! 提前致谢!

The code: 编码:

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()  

The problem is, as the error message indicates, that the index used with the levels list is out of range. 如错误消息所示,问题是与levels列表一起使用的索引超出范围。 It can only be 0 or 1 . 它只能是01 The problem appears to be because in the main while game loop you increment currentLevel by one without checking its value before or after. 问题似乎是因为在主while game循环中,您将currentLevel递增了一个,而没有检查其之前或之后的值。 Initially it was set to 0 but later it gets set to 1 when user presses the 1 key to play game. 最初将其设置为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)

I'm not sure, but setting its value to 1 when the user starts playing may be wrong. 我不确定,但是当用户开始播放时将其值设置为1可能是错误的。 Regardless, you either need to add some checks to prevent it from ever getting out-of-range or always check it's value before use. 无论如何,您要么需要添加一些检查以防止其超出范围,要么总是在使用前检查其值。 One obvious way would be simply making incrementing it conditional: 一种显而易见的方法是简单地使它有条件地递增:

            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)

Even better, you could make the program more flexible by avoiding hardcoding constants that might change in your code. 更好的是,通过避免对代码中可能更改的常量进行硬编码,可以使程序更灵活。 Here that could be done by defining a global constant near the beginning: 这可以通过在开始处定义一个全局常量来完成:

HIGHEST_LEVEL = len(levels)-1  # index of topmost level

...and then using it any and every where necessary to ensure currentLevel is or stays valid: ...然后在任何必要的地方使用它,以确保currentLevel保持有效:

                    ...
                if PlayerRect.colliderect(endRect)
                    if currentLevel < HIGHEST_LEVEL:
                        currentLevel += 1
                    ...

Using this approach here would allow you can add levels to the game and not need to search far and wide though the code making sure currentLevel was always in range — much as I had to do in the process of debugging your program. 在这里使用这种方法可以使您可以向游戏中添加关卡,尽管需要确保currentLevel始终在范围内的代码,而无需进行广泛搜索-就像我在调试程序的过程中要做的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM