import pygame
import random
pygame.init()
#game is 64 cells x 32 cells
width = 64
height = 32
WIDTH = width * 20
HEIGHT = height * 20
FPS = 60
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Snake")
clock = pygame.time.Clock()
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BEIGE = (232, 220, 202)
ORANGE = (255, 165, 0)
blockHeight = HEIGHT / height
blockWidth = WIDTH / width
class Fruit:
def __init__(self):
self.xpos = random.randint(1, width) * blockWidth
self.ypos = random.randint(0, height - 1) * blockHeight
self.FruitRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Fruit = pygame.draw.rect(screen, ORANGE, self.FruitRect)
def __str__(self):
return f"fruit: x: {self.xpos}, y: {self.ypos}"
def draw(self):
self.FruitRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Fruit = pygame.draw.rect(screen, ORANGE, self.FruitRect)
def eat(self, snakePos):
self.xpos = random.randint(1, width) * blockWidth
self.ypos = random.randint(0, height - 1) * blockHeight
if (self.xpos, self.ypos) in snakePos:
while (self.xpos, self.ypos) in snakePos:
self.xpos = random.randint(1, width) * blockWidth
self.ypos = random.randint(0, height - 1) * blockHeight
def returnPos(self):
return self.xpos, self.ypos
class Head:
def __init__(self):
self.xpos = width // 2 * blockWidth
self.ypos = height // 2 * blockHeight
self.HeadRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Head = pygame.draw.rect(screen, RED, self.HeadRect)
def __str__(self):
return f"head: x: {self.xpos}, y: {self.ypos}"
def draw(self):
self.HeadRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Head = pygame.draw.rect(screen, RED, self.HeadRect)
def update(self, xFac, yFac):
self.xpos += blockWidth * xFac
self.ypos += blockHeight * yFac
def returnPos(self):
return self.xpos, self.ypos
class Body:
def __init__(self, xpos, ypos):
self.xpos = xpos
self.ypos = ypos
self.BodyRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Body = pygame.draw.rect(screen, GREEN, self.BodyRect)
def __str__(self):
return f"body: x: {self.xpos}, y: {self.ypos}"
def draw(self):
self.BodyRect = pygame.Rect(self.xpos, self.ypos, blockWidth, blockHeight)
self.Body = pygame.draw.rect(screen, GREEN, self.BodyRect)
def update(self, xFac, yFac):
self.xpos += blockWidth * xFac
self.ypos += blockHeight * yFac
def returnPos(self):
return self.xpos, self.ypos
def main():
run = True
screen.fill(BEIGE)
snake = Head()
yVel = 0
xVel = 0
time = 0
fruits = [Fruit(), Fruit(), Fruit(), Fruit(), Fruit()]
snakeParts = [snake]
snakeVels = [(xVel, yVel)]
while run:
clock.tick(FPS)
time += 1
if time == FPS:
time = 0
for fruit in fruits:
if snake.returnPos() == fruit.returnPos():
snakePos = []
for snakePart in snakeParts:
snakePos.append(snakePart.returnPos())
fruit.eat(snakePos)
snakeParts.append(Body(snakeParts[-1].returnPos()[0], snakeParts[-1].returnPos()[1])) #add a body part
snakeVels.append((0, 0)) #the velocity of the new body part is 0
fruit.draw()
for snakePart in snakeParts:
if snakePart.returnPos() == snake.returnPos() and snakePart != snakeParts[0] and len(snakeParts) != 2:
run = False #if the snake hits itself, the game ends
snakePart.draw()
if snake.returnPos()[0] < 0 or snake.returnPos()[0] + blockWidth > WIDTH or snake.returnPos()[1] < 0 or snake.returnPos()[1] + blockHeight > HEIGHT:
run = False #if the snake goes off the edge of the screen, the game ends
pygame.display.update()
if time == 0 or time == FPS // 2: #twice a second...
screen.fill(BEIGE)
#update the velocoties (add one new velcoity at the front and remove the last one)
snakeVels.insert(0, (xVel, yVel))
if snakeVels[-1] == (0, 0) and len(snakeParts) != 1:
#if the last velocity is 0, make the second to last velocity 0 in order to be able to remove the last velocity
#this is a list instead of a tuple so next iteration it is removed and the velocity does not stay at 0
snakeVels[-2] = [0, 0]
snakeVels.remove(snakeVels[-1])
for i in range(len(snakeParts)):
snakeParts.update(snakeVels[0], snakeVels[1]) #update the position of each body part based on its corresponding velocity
#my attempted debugging
print(snakeVels)
snakePartsString = []
for snakePart in snakeParts:
snakePartsString.append(str(snakePart))
print(snakePartsString)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
xVel = -1
yVel = 0
if event.key == pygame.K_RIGHT:
xVel = 1
yVel = 0
if event.key == pygame.K_UP:
xVel = 0
yVel = -1
if event.key == pygame.K_DOWN:
xVel = 0
yVel = 1
main()
pygame.quit()
< /code>
Das Problem ist, wenn Sie in schneller Folge mehrere Eingänge (Drücken Sie Pfeile) ein, wird die Schlange manchmal aufgeteilt. Auch wenn Sie keine Eingänge eingeben, kann es sich teilen. Wenn Sie Eingaben eingeben, wird nur die Wahrscheinlichkeit erhöht, dass es sich spaltet. Ich denke, dass das Problem mit der Event -Handhabung oder der Art und Weise, wie Geschwindigkeiten hinzugefügt, entfernt und in der Snakevels -Liste verwendet werden. Wenn Sie die Snakevels -Liste drucken, können Sie feststellen, dass die Geschwindigkeiten nach den Kurven nicht immer richtig geändert werden.>
Pygame Snake Spliting Bug [geschlossen] ⇐ Python
-
- Similar Topics
- Replies
- Views
- Last post