如何解决蛇墙传送的bug

问题描述 投票:0回答:1

我正在做一个蛇游戏,我遇到了一个我不知道如何解决的错误,我想让我的蛇传送槽墙壁,当蛇与墙壁碰撞时,它会以相反的速度和位置传送到另一个墙壁,就像经典游戏一样,但是用我的代码,当蛇靠近墙壁时,它会复制到对面的墙壁,但它甚至应该还没有检测到碰撞

重要的事情:在网格中,蛇位于墙的一侧,就像这样

SSSS
WWWW

而不是这样:

SSSS
NNNN
WWWW

当S代表蛇时,W代表墙,N代表什么都没有。

编辑:整个代码

import pygame, random, os, sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((1020, 585))
pygame.display.set_caption('2snakes!')

#files location
current_path = os.path.dirname(__file__)
data_path = os.path.join(current_path, 'data')
icon = pygame.image.load(os.path.join(data_path, 'icon.png'))
press_any = pygame.image.load(os.path.join(data_path, 'press_any.png'))
pygame.display.set_icon(icon)


#collission
def collision(c1,c2):
    return (c1[0] == c2[0]) and (c1[1] == c2[1])

#game over
def gameOverBlue():
    print("blue")
    main()
def gameOverRed():
    print("red")
    main()
fps = 15
def main():
#variables
    direction = 'RIGHT'
    direction2 = 'RIGHT'
    change_to = direction
    change2_to = direction2
    

    #snake
    size = 15
    s_posx = 60
    s_posy = 60
    snake = [(s_posx + size * 2, s_posy),(s_posx + size, s_posy),(s_posx, s_posy)]
    s_skin = pygame.Surface((size, size))
    s_skin.fill((82,128,208))

    #snake2
    size2 = 15
    s2_posx = 390
    s2_posy = 390
    snake2 = [(s2_posx + size2 * 2, s2_posy),(s2_posx + size2, s2_posy),(s2_posx, s2_posy)]
    s2_skin = pygame.Surface((size2, size2))
    s2_skin.fill((208,128,82))

    #apple
    apple = pygame.Surface((size, size))
    apple_pos = ((random.randint(0, 67)) * 15, (random.randint(0, 38)) * 15)
#endregion
    while True:
        pygame.time.Clock().tick(fps)
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()

        

        #input
            elif event.type == pygame.KEYDOWN:
                #snake
                if event.key == ord('w'):
                    change_to = 'UP'
                if event.key == ord('s'):
                    change_to = 'DOWN'
                if event.key == ord('a'):
                    change_to = 'LEFT'
                if event.key == ord('d'):
                    change_to = 'RIGHT'   
                        
                #snake2
                if event.key == pygame.K_UP:
                    change2_to = 'UP'
                if event.key == pygame.K_DOWN:
                    change2_to = 'DOWN'
                if event.key == pygame.K_LEFT:
                    change2_to = 'LEFT'
                if event.key == pygame.K_RIGHT:
                    change2_to = 'RIGHT'

                #quit game
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.quit()
                    
    #smooth snake movement
            #snake
        if change_to == 'UP' and direction != 'DOWN':
            direction = 'UP'
        if change_to == 'DOWN' and direction != 'UP':
            direction = 'DOWN'
        if change_to == 'LEFT' and direction != 'RIGHT':
            direction = 'LEFT'
        if change_to == 'RIGHT' and direction != 'LEFT':
            direction = 'RIGHT'
            
            #snake2
        if change2_to == 'UP' and direction2 != 'DOWN':
            direction2 = 'UP'
        if change2_to == 'DOWN' and direction2 != 'UP':
            direction2 = 'DOWN'
        if change2_to == 'LEFT' and direction2 != 'RIGHT':
            direction2 = 'LEFT'
        if change2_to == 'RIGHT' and direction2 != 'LEFT':
            direction2 = 'RIGHT'

    #movement
        #snake
        new_pos = None
        if direction == 'DOWN':
            new_pos = (snake[0][0], snake[0][1] + size)
        if direction == 'UP':
            new_pos = (snake[0][0], snake[0][1] - size)
        if direction == 'LEFT':
            new_pos = (snake[0][0] - size, snake[0][1])
        if direction == 'RIGHT':
            new_pos = (snake[0][0] + size, snake[0][1])
        if new_pos:
            snake = [new_pos] + snake
            del snake[-1]
        
        #snake2
        new_pos2 = None
        if direction2 == 'DOWN':
            new_pos2 = (snake2[0][0], snake2[0][1] + size2)
        if direction2 == 'UP':
            new_pos2 = (snake2[0][0], snake2[0][1] - size2)
        if direction2 == 'LEFT':
            new_pos2 = (snake2[0][0] - size2, snake2[0][1])
        if direction2 == 'RIGHT':
            new_pos2 = (snake2[0][0] + size2, snake2[0][1])
        if new_pos2:
            snake2 = [new_pos2] + snake2
            del snake2[-1]

    #apple collision
        #snake
        if collision(snake[0], apple_pos):
            snake.append((-20,-20))
            size = 15
            s_skin = pygame.Surface((size, size))
            s_skin.fill((82,128,208))
            apple_pos = ((random.randint(0, 32)) * 15, (random.randint(0, 19)) * 15)
        #snake2
        if collision(snake2[0], apple_pos):
            snake2.append((-20,-20))
            
            apple_pos = ((random.randint(0, 67)) * 15, (random.randint(0, 38)) * 15)

    #wall collisison
        #snake
        _pos = None
        if snake[0][0] == 15:
            _pos = (990, snake[0][1])
        elif snake[0][1] == 15:
            _pos = (snake[0][0], 555)
        elif snake[0][0] == 990:
            _pos = (15, snake[0][1])
        elif snake[0][1] == 555:
            _pos = (snake[0][0], 15)
        if _pos:
            snake = [_pos] + snake
            del snake[-1]
        #snake2
        _pos2 = None
        if snake2[0][0] == 15:
            _pos2 = (1005, snake2[0][1])
        elif snake2[0][1] == 0:
            _pos2 = (snake2[0][0], 570)
        elif snake2[0][0] == 1005:
            _pos2 = (0, snake2[0][1])
        elif snake2[0][1] == 570:
            _pos2 = (snake2[0][0], 0)
        if _pos2:
            snake2 = [_pos2] + snake2
            del snake2[-1]

    #self collisison
        #snake
        if snake[0] in snake[1:]:
            print("self collision")
            gameOverBlue()
        #snake2
        if snake2[0] in snake2[1:]:
            print("self collision")
            gameOverRed()
        #snakes colliding with each other
        if snake2[0] == snake[0]:
            print("head to head collisions")
        if snake[0] in snake2:
            gameOverRed()
        if snake2[0] in snake:
            gameOverBlue()

    #rendering
        apple.fill((255,0,0))
        screen.fill((10,10,10))
        screen.blit(apple,apple_pos)
        for pos in snake:
            screen.blit(s_skin,pos)
        for pos2 in snake2:
            screen.blit(s2_skin,pos2)
        pygame.display.update()

while True:
        pygame.time.Clock().tick(fps)
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()

        #input
            elif event.type == pygame.KEYDOWN:
                main()
        screen.blit(press_any, (0,0))
        pygame.display.update()

编辑:红点是食物/苹果

python pygame collision-detection
1个回答
4
投票

您想要实现一个传送器。因此,一旦蛇越过窗户边缘,你就必须传送到另一边。您的窗口大小为 1020x585。如果 x == -15y == -15x == 1020y == 585,蛇就在窗外,因此你必须执行以下传送:

  • 如果 x = 1020 传送到 x = 0
  • 如果 x = -15 传送到 x = 1005
  • 如果 y = 585 传送到 y = 0
  • 如果 y = -15 传送到 y = 570
_pos = None
if snake[0][0] == -15:
    _pos = (1005, snake[0][1])
elif snake[0][1] == -15:
    _pos = (snake[0][0], 570)
elif snake[0][0] == 1020:
    _pos = (0, snake[0][1])
elif snake[0][1] == 585:
    _pos = (snake[0][0], 0)
if _pos:
    snake = [_pos] + snake
    del snake[-1]

另一个最简单的解决方案是使用

%
(模)运算符:

x1 = (x1 + x1_change) % dis_width
y1 = (y1 + y1_change) % dis_height
>>> width = 100
>>> 101 % width
1
>>> -1 % width
99
>>>

最小示例: repl.it/@Rabbid76/PyGame-ContinouslyMovement

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))

    keys = pygame.key.get_pressed()
    
    dx = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
    dy = (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
        
    rect.centerx = (rect.centerx + dx) % window.get_width()
    rect.centery = (rect.centery + dy) % window.get_height()

    window.fill(0)
    pygame.draw.rect(window, (255, 0, 0), rect)
    pygame.display.flip()

pygame.quit()
exit()

注:

>>> width = 100
>>> 101 % width
1
>>> -1 % width
99
>>>
© www.soinside.com 2019 - 2024. All rights reserved.