python - 贪吃蛇游戏错误代码(IndexError : list index out of range)

标签 python pygame

我正在创建一个带有菜单的蛇 Pygame,并且当我遇到错误时正在微调错误等

索引错误:列表索引超出范围

在我打开选项卡本身并将光标移到其上后,实际上会出现错误

我对它的实际含义有一个模糊的概念,但我对 python 和一般编码很陌生,所以如果有人可以解释并展示解决方案,我将不胜感激,

非常感谢,这是代码

import pygame
import sys
import random
import time

pygame.init()

WHITE = (255, 255, 255)
YELLOW = (255, 255, 102)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
DARKRED = (125, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

screenWidth = 800
screenHeight = 800

screen = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()

snakeBlock = 10
snakeSpeed = 15

fontTitle = pygame.font.SysFont("arial",100)
fontStyle = pygame.font.SysFont("ariel", 50)
scoreFont = pygame.font.SysFont("ariel", 35)


def score(score):
    value = scoreFont.render(" Score: " + str(score), True, BLACK)
    screen.blit(value, [50, 50])



def snake(snakeBlock, snake_list):
    for x in snake_list:
        pygame.draw.rect(screen, GREEN, [x[0], x[1], snakeBlock, snakeBlock])


def message(msg, colour):
    msg = fontStyle.render(msg, True, BLACK)
    screen.blit(msg, [screenWidth / 20, screenHeight / 2])


def gameLoop():

    gameOver = False
    gameEnd = False
    instructions = False
    game = True
    intro = True
    main = True



    x1 = screenWidth / 2
    y1 = screenHeight / 2

    dx = 0
    dy = 0

    snakeList = []
    snakeLength = 2

    foodx = round(random.randrange(0, screenWidth - snakeBlock) / 10.0) * 10.0
    foody = round(random.randrange(0, screenHeight - snakeBlock) / 10.0) * 10.0

    def menu(titles):
        buttonTitleFont = pygame.font.SysFont("arial", 52)
        selection = []
        rectWidth = 400
        rectHeight = 60
        x = int(screen.get_width()/2 - rectWidth/2)
        y = 450
        length = len(titles)
        num = 0
        hover = False
        # creates the Rects (containers) for the buttons

        for i in range (0,length,1):
            choiceRect = pygame.Rect(x,y,rectWidth,rectHeight)
            selection.append(choiceRect)
            y += 100

            #main loop in menu    
            menu = True
            while menu:    
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        menu = False
                        pygame.quit()
                        sys.exit()
                    if event.type ==pygame.MOUSEMOTION:     # if mouse moved
                        hover = False
                        mx, my = pygame.mouse.get_pos()     # get the mouse position
                        for i in range (length):            
                            if selection[i].collidepoint((mx,my)):  # check if x,y of mouse is in a button
                                num = i
                                hover = True
                    if event.type == pygame.MOUSEBUTTONDOWN and hover == True:  #if mouse is in button
                        menu = False                                              # and has been clicked

                # draw all buttons                                                                
                for choice in selection:
                    pygame.draw.rect(screen,WHITE,choice,0)

                # redraw selected button in another colour
                pygame.draw.rect(screen,GREEN,selection[num],0)

                # draw all the titles on the buttons
                x = int(screen.get_width()/2 - 150)
                y = 450
                for i in range(0,length,1):
                    buttonTitle = buttonTitleFont.render(titles[i],True,BLACK)
                    screen.blit(buttonTitle,(x,y))
                    y += 100

                pygame.display.update()
            return num

    while main:
        for event in pygame.event.get(): # check for any events (i.e key press, mouse click etc.)
            if event.type ==pygame.QUIT: # check to see if it was "x" at top right of screen
                main = False         # set the "main" variable to False to exit while loop

        while intro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    main = False
                    intro = False

            screen.fill(BLACK)

            menuMain = ["Launch", "Instructions","QUIT"]

            mainMenu = True
            mainInt = True
            while mainInt:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        main = False
                        intro = False
                        mainInt = False

                screen.fill(BLACK)

                #Centers the rendered tiles
                textTitle = fontTitle.render("Snake", True, GREEN )
                textW = textTitle.get_width()
                textH = textTitle.get_height()
                xTitle = int(screenWidth/2 - textW/2)
                yTitle = int(screenHeight/4 - textH/2)
                screen.blit(textTitle, (xTitle,yTitle))
                pygame.display.update()

                # in the intro, this asks the user where they would like to go
                if mainMenu ==True:
                    choose = menu(menuMain)
                    if choose == 0:
                        menu = False
                        intro = False
                        mainInt = False
                        mainMenu = False
                        game = True
                        screen.fill(BLACK)
                    elif choose ==1:
                        menu = False
                        instructions = True
                        mainMenu = False
                        screen.fill(BLACK)
                        pygame.display.update()
                    else:
                        menu = False
                        main = False
                        intro = False
                        mainInt = False
                        mainMenu = False

        while game: 

            if gameOver == True:
                game = False

            while gameEnd == True:
                screen.fill(DARKRED)
                message("You Lost! Press C to Play Again or Q to Quit", RED)
                score(snakeLength - 1)
                pygame.display.update()

                for event in pygame.event.get():
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_q:
                            gameOver = True
                            gameEnd = False
                        if event.key == pygame.K_c:
                            gameLoop()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameOver = True
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        dx = -snakeBlock
                        dy = 0
                    elif event.key == pygame.K_RIGHT:
                        dx = snakeBlock
                        dy = 0
                    elif event.key == pygame.K_UP:
                        dx = 0
                        dy = -snakeBlock
                    elif event.key == pygame.K_DOWN:
                        dx = 0
                        dy = snakeBlock

            if x1 >= screenWidth or x1 < 0 or y1 >= screenHeight or y1 < 0:
                gameEnd = True

            x1 += dx
            y1 += dy

            screen.fill(WHITE)

            pygame.draw.rect(screen, RED, [foodx, foody, snakeBlock, snakeBlock])
            snakeHead = []
            snakeHead.append(x1)
            snakeHead.append(y1)
            snakeList.append(snakeHead)

            if len(snakeList) > snakeLength:
                del snakeList[0]

            for x in snakeList[:-1]:
                if x == snakeHead:
                    gameEnd = True

            snake(snakeBlock, snakeList)
            score(snakeLength - 1)

            pygame.display.update()

            if x1 == foodx and y1 == foody:
                foodx = round(random.randrange(0, screenWidth - snakeBlock) / 10.0) * 10.0
                foody = round(random.randrange(0, screenHeight - snakeBlock) / 10.0) * 10.0
                snakeLength += 1

            clock.tick(snakeSpeed)

        pygame.quit()
        quit()


gameLoop()


最佳答案

我发现在您的代码中,您引用了 selection[some_index]多次。如果你研究一下选择实际上是什么,你会发现它是一个数组,里面有一个矩形对象:

[<rect(200, 450, 400, 60)>]

这个矩形永远不会改变,所以我建议通过调用直接引用它

selection[0]

例如,这里是给您带来错误的代码片段。

for i in range (length):   
    if selection[i].collidepoint((mx,my)):  # check if x,y of mouse is in a button
        num = i
        hover = True

由于选择是一个包含一个永不更改的元素的数组,因此在 for 循环的第一次迭代后,您会收到“索引超出范围”错误。也许这看起来很熟悉:

IndexError: list index out of range

要解决此问题,您可以做的是摆脱循环(因为这是不必要的 - 如果选择列表中只有一个矩形,则不应循环遍历索引!)并提取第 0 个索引处的矩形.


if selection[0].collidepoint((mx,my)):  # check if x,y of mouse is in a button
    num = i
    hover = True

这不是我在您的代码中遇到的唯一错误,但我相信这会对您有所帮助!

关于python - 贪吃蛇游戏错误代码(IndexError : list index out of range),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59852655/

相关文章:

python - Pygame在while true循环中显示图像内存问题

python - 在Python中解码消息头和消息体

python - sys.stdout.flush() 无法与 python 和 electronjs 一起正常工作

python - 解释 yield 在这个生命游戏实现中的使用

python - pygame双显示器和全屏

audio - 如何播放会持续变化的声音-Pygame

Python根据网页上的序列号用数据填充sql

Python PIL Crop 不裁剪图像

python - 找到要使用的图像?

python - pygame.camera 不工作?