python - 我的蛇在水平和垂直时向后退

标签 python pygame

我正在制作一个游戏,但是当我同时按下水平键和垂直键或按得足够快时,我的蛇会向后移动,如果它的长度超过 2 个方 block ,就会导致游戏超出屏幕。

我尝试制作一个很长的 if 语句。并清理了代码。

import pygame
import os
import sys
pygame.mixer.pre_init()
pygame.mixer.init(44100, 16, 2, 262144)
pygame.init()
from pygame.locals import*
import cv2
import time
import random
import pickle
import shutil

dw = 1280
dh = 720 
at = 40
bs = 20
screen = pygame.display.set_mode((dw, dh))
clock = pygame.time.Clock()
def pause():

    paused = True

    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    paused = False
                elif event.key == pygame.K_SPACE:
                    menu(1)
        screen.fill(white)
        mts("Paused", black, -100, 100)
        mts("Press esc to go back to the game or press space to go back to the menu", black, 25, 45)
        pygame.display.update()
        clock.tick(60)

#define the apple to spawn in a random place
def randAppleGen():
    randAppleX = random.randrange(0, dw-at, bs)
    randAppleY = random.randrange(0, dh-at, bs)

    return randAppleX,randAppleY

def snake(bs, sl):
    for XnY in sl:
        pygame.draw.rect(screen, Dgreen, [XnY[0],XnY[1],bs,bs])

def gameLoop():
    global at
    global bs
    hs = pickle.load( open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "rb" ) )
    gameExit = False
    gameOver = False
    gameHack = False
    Speed = 20
    lead_x = dw/2
    lead_y = dh/2

    lead_x_change = 0
    lead_y_change = 0
    pygame.mixer.music.load(os.path.join(os.getcwd(), 'Sounds', 'music1.ogg'))
    pygame.mixer.music.play(-1) 

    slist = []
    sl = 0
    if sl > 2304:
        gameHack = True

    randAppleX,randAppleY = randAppleGen()

    while not gameExit:

        while gameOver == True:
            screen.fill(white)
            mts("Game over", red, -50,100)
            mts("Press enter to play again or press space to go back to the menu", black, 50,50)
            pygame.display.update()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameOver = False
                    gameExit = True
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_KP_ENTER or event.key==pygame.K_RETURN:
                        gameLoop()
                    if event.key == pygame.K_SPACE:
                        gameExit = False
                        gameOver = False
                        menu(1)
        while gameHack == True:
            pygame.mixer.music.stop()
            screen.fill(white)
            mts("Hacked", red, -50,100)
            mts("You hacked or exploit the game, press enter to quit the game", black, 50,50)
            pygame.display.update()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameOver = False
                    gameExit = True
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_KP_ENTER or event.key==pygame.K_RETURN:
                        pygame.quit()
                        sys.exit()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT and lead_x_change != bs:
                    lead_x_change = -bs
                    lead_y_change = 0
                elif event.key == pygame.K_RIGHT and lead_x_change != -bs:
                    lead_x_change = bs
                    lead_y_change = 0
                elif event.key == pygame.K_UP and lead_y_change != bs:
                    lead_y_change = -bs
                    lead_x_change = 0
                elif event.key == pygame.K_DOWN and lead_y_change != -bs:
                    lead_y_change = bs
                    lead_x_change = 0
                elif event.key == pygame.K_ESCAPE:
                    pause()
                elif event.key == pygame.K_s and Speed >= 10 and Speed < 60:
                    Speed += 10
                    clock.tick(Speed)
                elif event.key == pygame.K_d and Speed <= 60 and Speed > 10:
                    Speed -= 10
                    clock.tick(Speed)

        if not pygame.Rect(0, 0, dw, dh).contains(lead_x, lead_y, bs, bs):
            gameOver = True

        lead_x += lead_x_change
        lead_y += lead_y_change

        screen.fill(white)

        #draw the apple
        apple = pygame.draw.rect(screen, red, [randAppleX,randAppleY,at,at])

        sh = []
        sh.append(lead_x)
        sh.append(lead_y)
        slist.append(sh)
        snake(bs, slist)

        if len(slist) > sl:
            del slist[0]

        for eachSegment in slist[:-1]:
            if eachSegment == sh:
                gameOver = True

        score(sl)
        highscore(hs)

        if sl > hs:
            hs += 1
            os.remove( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN') )
            pickle.dump( sl, open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "wb" ) )
            hs = pickle.load( open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "rb" ) )


        pygame.display.update()

        #make the apple spawn
        if lead_x > randAppleX and lead_x < randAppleX + at or lead_x + bs > randAppleX and lead_x + bs < randAppleX + at:
            if lead_y > randAppleY and lead_y < randAppleY + at:
                randAppleX,randAppleY = randAppleGen()
                sl += 1
            elif lead_y + bs > randAppleY and lead_y + bs < randAppleY + at:
                randAppleX,randAppleY = randAppleGen()
                sl += 1


        clock.tick(Speed)

    pygame.quit()
    quit()

我希望它不会倒退,即使有一个代码。我还是往后走。怎么解决呢?

最佳答案

出现此问题是因为事件是在循环中处理的:

for event in pygame.event.get():

   if event.type == pygame.KEYDOWN:

       # [...]

假设蛇向左移动,并且 lead_x_change == -bs 分别为 lead_y_change == 0。如果(例如)按下pygame.K_UP并且满足以下条件:

elif event.key == pygame.K_UP and lead_y_change != bs:

这会导致移动状态更改为 lead_x_change = 0lead_y_change = -bs

如果 pygame.K_RIGHT 按下的时间稍晚一些,但速度足够快,可以在主循环的同一帧中处理,那么它会在事件循环中处理,稍后一次。这也会导致满足以下条件:

elif event.key == pygame.K_RIGHT and lead_x_change != -bs:

现在,移动状态更改为 lead_x_change = bslead_y_change = 0。看来,蛇已经转了180度了。事实上,它在一帧内改变了从左到上和从上到右的方向(在主循环的一次传递中,但在事件循环的两次传递中)。

幸运的是,这个问题可以轻松解决。只需在事件循环之前复制 lead_x_changelead_y_change 的值,并使用这些副本来评估事件循环中的移动条件。 请注意,条件必须检查 lead_x_changelead_y_change 的状态,它们在帧开始时具有:

prev_x, prev_y = lead_x_change, lead_y_change 
for event in pygame.event.get():

    # [...]

    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_LEFT and prev_x != bs:
            lead_x_change, lead_y_change = -bs, 0
        elif event.key == pygame.K_RIGHT and prev_x != -bs:
            lead_x_change, lead_y_change = bs, 0
        elif event.key == pygame.K_UP and prev_y != bs:
            lead_x_change, lead_y_change = 0, -bs
        elif event.key == pygame.K_DOWN and prev_y != -bs:
            lead_x_change, lead_y_change = 0, bs

        # [...]

关于python - 我的蛇在水平和垂直时向后退,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55677506/

相关文章:

python - seaborn:默认情况下绝望图

Python,通过创建复制文件

python - PyCharm numpy - 对数组进行排序不起作用?

python - 在 HTML 中使用 BeautifulSoup 查找元素

python - 我试图在 Pygame 中绘制一个矩形,但颜色在闪烁……为什么?

python - 尝试在 macOS Sierra 上显示文本时 Pygame 没有响应

python - 不使用嵌套循环读取文件和文件夹

python - 事件未定义?

python - pygame中的不断运动

python - 无法通过 pip 在 Python 上安装 pygame (Windows 10)