蛇游戏:蛇与自己碰撞 [英] snake game: snake colliding with itself
问题描述
我目前正在编写一个蛇游戏代码,我快完成了,但是我很难编写一个代码,如果蛇的头部与其身体相撞,这将导致游戏结束,我想我可以创建一个碰撞函数类似于蛇和苹果的碰撞函数:
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屋!