игра змея: змея сталкивается сама с собой - PullRequest
0 голосов
/ 31 декабря 2018

Привет, я сейчас пишу код игры со змеей, и я почти закончил, но у меня возникают трудности с написанием кода, который приведет к завершению игры, если голова змеи столкнется с ее телом, я подумал, что могу создать столкновениефункция, аналогичная функции столкновения для змеи и яблока:

pygame.sprite.collide_rect(h, a)

, однако все отдельные части змеи действуют одинаково, поэтому змея всегда будет постоянно сталкиваться с собой.Есть ли способы обойти это?

вот мой полный код змеи:

import pygame
import random


BLACK = (0, 0, 0)
GREEN = (0, 250, 0)
RED = (250, 0, 0)
Width = 15
Space = 3
Xspeed = 18
Yspeed = 0
Factor = 18
clock = pygame.time.Clock()
segments = 2
HitLoop = 0
ScreenWidth = 800
AppleCount = 1

#creating initial snake
class HEAD(pygame.sprite.Sprite):
    def __init__(self, x, y, colour = GREEN):
        super().__init__()
        self.image = pygame.Surface([Width, Width])
        self.image.fill(colour)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class APPLE(pygame.sprite.Sprite):
    def __init__(self, z, q):
        super().__init__()
        self.image = pygame.Surface([Width, Width])
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = z
        self.rect.y = q

pygame.init()
screen = pygame.display.set_mode([ScreenWidth, ScreenWidth])
pygame.display.set_caption('Snake')
allspriteslist = pygame.sprite.Group()


SnakeSegments = []
for i in range(segments):
    x = 250 - (Width + Space) * i
    y = 30
    h = HEAD(x, y)
    SnakeSegments.append(h)
    allspriteslist.add(h)

AppleList = []
for i in range(0,AppleCount):
    z = random.randint(10,ScreenWidth-25)
    q = random.randint(10,ScreenWidth-25)
    a = APPLE(z, q)
    AppleList.append(a)
    allspriteslist.add(a)

#main loop
done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                if Xspeed == -Factor:
                    Xspeed = 0
                if Xspeed == Factor:
                    Xspeed = Factor
                else:
                    Xspeed = Xspeed - Factor
                    Yspeed = 0
            elif event.key == pygame.K_RIGHT:
                if Xspeed == Factor:
                    Xspeed = 0
                if Xspeed == -Factor:
                    Xspeed = -Factor
                else:
                    Xspeed = Xspeed + Factor
                    Yspeed = 0
            elif event.key == pygame.K_UP:
                if Yspeed == -Factor:
                    Yspeed = 0
                if Yspeed == Factor:
                    Yspeed = Factor
                else:
                    Yspeed = Yspeed - Factor
                    Xspeed = 0
            elif event.key == pygame.K_DOWN:
                if Yspeed == Factor:
                    Yspeed = 0
                if Yspeed == -Factor:
                    Yspeed = -Factor
                else:
                    Yspeed = Yspeed + Factor
                    Xspeed = 0
    clock.tick(10)
    #snake builder
    OldSegment = SnakeSegments.pop(-1)
    allspriteslist.remove(OldSegment)

    x = SnakeSegments[0].rect.x + Xspeed
    y = SnakeSegments[0].rect.y + Yspeed

    h = HEAD(x, y)
    SnakeSegments.insert(0, h)
    allspriteslist.add(h,a)
    allspriteslist.update()

    # collision had to create apples own list for respawn
    if pygame.sprite.collide_rect(h, a) == True and HitLoop == 0:
        SnakeSegments.append(h)
        AppleList.append(a)
        HitLoop = HitLoop + 1
        z = random.randint(10, ScreenWidth - 25)
        q = random.randint(10, ScreenWidth - 25)
        OldApple = AppleList.pop()
        allspriteslist.remove(OldApple)
        a = APPLE(z, q)
        allspriteslist.update()

# collision had to create a new class
    if pygame.sprite.collide_rect(h, h) == True:
        pass


    # hit timer
    if HitLoop > 0:
        HitLoop += 1
    if HitLoop > 4:
        HitLoop = 0

    screen.fill(BLACK)

    #game walls
    pygame.draw.rect(screen, GREEN, [0, 0, ScreenWidth, 10])
    pygame.draw.rect(screen, GREEN, [0, 0, 10, ScreenWidth])
    pygame.draw.rect(screen, GREEN, [0, ScreenWidth - 10, ScreenWidth, 10])
    pygame.draw.rect(screen, GREEN, [ScreenWidth - 10, 0, 10, ScreenWidth])
    if x <= 10:
        done = True
    if x >= ScreenWidth - Width:
        done = True
    if y <= 10:
        done = True
    if y >= ScreenWidth - Width:
        done = True


    allspriteslist.draw(screen)
    pygame.display.flip()

1 Ответ

0 голосов
/ 31 декабря 2018

В вашем коде выглядит так, как будто вы проверяете, сталкивается ли голова змеи с собой, что всегда возвращает True.Вы должны индивидуально проверить, не сталкивается ли голова змеи ни с одним из ее конечных сегментов:

for segment in SnakeSegments[2:]:
    if pygame.sprite.collide_rect(h, segment):
        pass # collision detected, game-over

Ожидается, что голова змеи столкнется с сегментом непосредственно позади нее, поэтому нам необходимоначать с 3-го элемента в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...