蛇游戏:蛇与自己碰撞 [英] snake game: snake colliding with itself

查看:64
本文介绍了蛇游戏:蛇与自己碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在编写一个蛇游戏代码,我快完成了,但是我很难编写一个代码,如果蛇的头部与其身体相撞,这将导致游戏结束,我想我可以创建一个碰撞函数类似于蛇和苹果的碰撞函数:

Hi I am currently writing a snake game code and I am nearly finished however I am having difficulty writing a code which will cause the game to end if the head of the snake collides with its body, I thought I could create a collide function similar to the collide function for the snake and the apple:

pygame.sprite.collide_rect(h, a)

然而,蛇的所有独立部分都以相同的方式运作,因此蛇将始终与自身发生碰撞.有什么办法可以解决这个问题.

however all the separate parts of the snake act in the same way so the snake will always be constantly colliding with itself. Are there any ways around this.

这是我的完整蛇代码:

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

推荐答案

在您的代码中,看起来好像您正在检查蛇的头部是否与自身发生碰撞,这将始终返回 True.您需要单独检查蛇的头部是否与它的任何尾随部分碰撞:

In your code it looks as though you are checking if the head of the snake collide with itself, which will always return True. You need to individually check that the head of snake does not collide with any of it's trailing segments:

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

蛇的头部预计会与其直接后面的段发生碰撞,这就是为什么我们需要从列表中的第三个元素开始.

The head of the snake is expected to collide with the segment directly behind it, which is why we need to start with the 3rd element in the list.

这篇关于蛇游戏:蛇与自己碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆