snake game: snake colliding with itself

2024/11/24 3:05:50

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.

here is my full snake code:

import pygame
import randomBLACK = (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 = xself.rect.y = yclass 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 = zself.rect.y = qpygame.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) * iy = 30h = 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 = Trueif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:if Xspeed == -Factor:Xspeed = 0if Xspeed == Factor:Xspeed = Factorelse:Xspeed = Xspeed - FactorYspeed = 0elif event.key == pygame.K_RIGHT:if Xspeed == Factor:Xspeed = 0if Xspeed == -Factor:Xspeed = -Factorelse:Xspeed = Xspeed + FactorYspeed = 0elif event.key == pygame.K_UP:if Yspeed == -Factor:Yspeed = 0if Yspeed == Factor:Yspeed = Factorelse:Yspeed = Yspeed - FactorXspeed = 0elif event.key == pygame.K_DOWN:if Yspeed == Factor:Yspeed = 0if Yspeed == -Factor:Yspeed = -Factorelse:Yspeed = Yspeed + FactorXspeed = 0clock.tick(10)#snake builderOldSegment = SnakeSegments.pop(-1)allspriteslist.remove(OldSegment)x = SnakeSegments[0].rect.x + Xspeedy = SnakeSegments[0].rect.y + Yspeedh = HEAD(x, y)SnakeSegments.insert(0, h)allspriteslist.add(h,a)allspriteslist.update()# collision had to create apples own list for respawnif pygame.sprite.collide_rect(h, a) == True and HitLoop == 0:SnakeSegments.append(h)AppleList.append(a)HitLoop = HitLoop + 1z = 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 classif pygame.sprite.collide_rect(h, h) == True:pass# hit timerif HitLoop > 0:HitLoop += 1if HitLoop > 4:HitLoop = 0screen.fill(BLACK)#game wallspygame.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 = Trueif x >= ScreenWidth - Width:done = Trueif y <= 10:done = Trueif y >= ScreenWidth - Width:done = Trueallspriteslist.draw(screen)pygame.display.flip()
Answer

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.

https://en.xdnf.cn/q/120586.html

Related Q&A

python3 function not defined even though it is

when I try to call the changeProfile function, I keep getting the error "getAuthCode is not defined" even though it is clearly defined. Why do I keep getting this error? What am I doing wron…

Python maximum and minimum

Im supposed to write a function max_and_min that accepts a tuple containing integer elements as an argument and returns the largest and smallest integer within the tuple. The return value should be a t…

Get differences between two excel files

Problem SummaryGiven 2 excel files, each with 200 columns approx, and have a common index column - ie each row in both files would have a name property say, what would be the best to generate an output…

Most pythonic way to call a list of functions [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 4…

Unable to get wanted output using for and range functions

For my homework assignment, I am using the for loop and the range function. I have to create a loop that printsHello 0 Hello 1 Hello 3 Hello 6 Hello 10The question says that the number corresponds to t…

i want to add a new field to an existing module odoo11 but i dont know why it didnt work

product_template.xmlthe view to add the customizing field to the product module<?xml version="1.0" encoding="utf-8"?><odoo><data><record id="product_temp…

How to check with more RegEx for one address in python using re.findall()

How to check with more RegEx for one address in python using re.findall()Ex: I want to apply the below regex rules # need to get addresstxt = "hello user 44 West 22nd Street, New York, NY 12345 fr…

Finding all roots of an equation in Python

I have a function that I want to find its roots. I could write a program to figure out its roots but the point is, each time that I want to find the other root I should give it an initial value manuall…

defining matrix class in python

Define a class that abstracts the matrix that satisfies the following examples of practice

Why do round() and math.ceil() give different values for negative numbers in Python 3? [duplicate]

This question already has an answer here:What is the algorithmic difference between math.ceil() and round() when trailing decimal points are >= 0.5 in Python 3?(1 answer)Closed 6 years ago.Why do r…