-1

I've been trying to code the snake game with pyglet and I have everything worked out except for one problem, and that problem is that I can't figure out how to have the snake actually turn instead of just rotate 90 degrees. My current code makes the snake always move the direction the head is facing, however, when you turn the snake, it makes a full 90 degree turn instead of doing what the snake normally does in for example the google doodle snake game, and I can't figure out why. Does anyone have any ideas? (FYI I am pretty new to python, so my code may be very ugly.)

# Modules
import pyglet as pyg
import random
import math
from pyglet.window import key
from time import sleep
# Creating the window, sprites, and labels
window = pyg.window.Window(800,600)
snake_head_image = pyg.image.load('snake_head.png')
snake_head_image.anchor_x = 12
snake_head_image.anchor_y = 12
snake_body_image = pyg.image.load('snake_body.png')
snake_body_image.anchor_x = 12
snake_body_image.anchor_y = 12
snake_head = pyg.sprite.Sprite(snake_head_image,x=400,y=300)
snake_bodies = [pyg.sprite.Sprite(snake_body_image,x=snake_head.x,y=snake_head.y-25),pyg.sprite.Sprite(snake_body_image,x=snake_head.x,y=snake_head.y)]
apple = pyg.shapes.Circle(x=random.randint(10,790),y=random.randint(10,590),radius=10,color=(255,0,0))
keys = key.KeyStateHandler()
window.push_handlers(keys)
score = pyg.text.Label(f"Score: {len(snake_bodies)}",font_size=12,x=760,y=590,anchor_x='center',anchor_y='center')
end = pyg.text.Label("",font_size=36,x=400,y=300,anchor_x='center',anchor_y='center')
@window.event
def on_draw():
    window.clear()
    apple.draw()
    snake_head.draw()
    snake_bodies[0].draw()
    for z in range(len(snake_bodies)):
        snake_bodies[z].draw()
    score.draw()
    end.draw()
# Rotating the snake on key press
@window.event
def on_key_press(symbol,modifiers):
    if (symbol == pyg.window.key.LEFT) and snake_head.rotation != 90:
        snake_head.rotation = 270
        snake_bodies[0].rotation = 270
        snake_bodies[0].y = snake_head.y
        snake_bodies[0].x = snake_head.x + 25
    elif (symbol == pyg.window.key.RIGHT) and snake_head.rotation != 270:
        snake_head.rotation = 90
        snake_bodies[0].rotation = 90
        snake_bodies[0].y = snake_head.y
        snake_bodies[0].x = snake_head.x - 25
    elif (symbol == pyg.window.key.UP) and snake_head.rotation != 180:
        snake_head.rotation = 0
        snake_bodies[0].rotation = 0
        snake_bodies[0].y = snake_head.y - 25
        snake_bodies[0].x = snake_head.x
    elif (symbol == pyg.window.key.DOWN) and snake_head.rotation != 0:
        snake_head.rotation = 180
        snake_bodies[0].rotation = 180
        snake_bodies[0].y = snake_head.y + 25
        snake_bodies[0].x = snake_head.x 
# Always making the snake move forward
@window.event
def moveSnake(dt):
    if snake_head.rotation == 270:
        snake_head.x -= 3
        snake_bodies[0].x -= 3
        for z in range(len(snake_bodies)):
            if z != 0:
                snake_bodies[z].x = snake_bodies[z-1].x + 25
                snake_bodies[z].y = snake_bodies[z-1].y
                snake_bodies[z].rotation = snake_bodies[0].rotation
            else:
                pass
    elif snake_head.rotation == 90:
        snake_head.x += 3
        snake_bodies[0].x += 3
        for z in range(len(snake_bodies)):
            if z != 0:
                snake_bodies[z].x = snake_bodies[z-1].x - 25
                snake_bodies[z].y = snake_bodies[z-1].y
                snake_bodies[z].rotation = snake_bodies[0].rotation
            else:
                pass
    elif snake_head.rotation == 0:
        snake_head.y += 3 
        snake_bodies[0].y += 3
        for z in range(len(snake_bodies)):
            if z != 0:
                snake_bodies[z].x = snake_bodies[z-1].x
                snake_bodies[z].y = snake_bodies[z-1].y - 25
                snake_bodies[z].rotation = snake_bodies[0].rotation
            else:
                pass
    elif snake_head.rotation == 180:
        snake_head.y -= 3
        snake_bodies[0].y -= 3
        for z in range(len(snake_bodies)):
            if z != 0:
                snake_bodies[z].x = snake_bodies[z-1].x
                snake_bodies[z].y = snake_bodies[z-1].y + 25
                snake_bodies[z].rotation = snake_bodies[0].rotation
            else:
                pass
    # Collisions with the apple and the borders
    distance_x_apple = snake_head.x - apple.x
    distance_y_apple = snake_head.y - apple.y
    distance_x_upper_border = snake_head.x - window.width
    distance_y_upper_border = snake_head.y - window.height
    distance_x_lower_border = snake_head.x - 0
    distance_y_lower_border = snake_head.y - 0
    if 10 >= abs(distance_x_apple) and 10 >= abs(distance_y_apple):
        apple.x = random.randint(10,790)
        apple.y = random.randint(10,590)
        if snake_head.rotation == 270:
            snake_bodies.append(pyg.sprite.Sprite(snake_body_image,x=snake_bodies[len(snake_bodies)-1].x-25,y=snake_bodies[len(snake_bodies)-1].y))
            snake_bodies[-1].rotation = 270
        elif snake_head.rotation == 90:
            snake_bodies.append(pyg.sprite.Sprite(snake_body_image,x=snake_bodies[len(snake_bodies)-1].x+25,y=snake_bodies[len(snake_bodies)-1].y))
            snake_bodies[-1].rotation = 90
        elif snake_head.rotation == 180:
            snake_bodies.append(pyg.sprite.Sprite(snake_body_image,x=snake_bodies[len(snake_bodies)-1].x,y=snake_bodies[len(snake_bodies)-1].y-25))
            snake_bodies[-1].rotation = 180
        elif snake_head.rotation == 0:
            snake_bodies.append(pyg.sprite.Sprite(snake_body_image,x=snake_bodies[len(snake_bodies)-1].x,y=snake_bodies[len(snake_bodies)-1].y+25))
            snake_bodies[-1].rotation = 0
        score.text = f"Score: {len(snake_bodies)}"
    if 5 >= abs(distance_x_upper_border) or 5 >= abs(distance_y_upper_border) or 5 >= abs(distance_x_lower_border) or 5>= abs(distance_y_lower_border):
        snake_head.visible = False
        for z in range(len(snake_bodies)):
            snake_bodies[z].visible = False
        sleep(0.3)
        end.text = f"Game Over!\nScore: {len(snake_bodies)}"
pyg.clock.schedule_interval(moveSnake, 1 / 60)
pyg.app.run()

1 Answers1

0

You have probably already done it, except because everything doesn't move in cells, and there is no time between snake's head and snake's body updating and moving, it is turning itself so fast that you cannot see it. You can either keep it without cells and make time intervals in between turning, or create cells and it makes everything much easier.

Either that your you have your turning done wrong. I am not sure if your code is doing this already, but if you keep it without cells you need to 1. save position of head on turning and 2. iterate through the body pieces and make the the last one follow the next piece.

I will probably try to fix the code and post it here later. (I cannot comment because I have less than 50 reputation, even though this should have been a comment. Hope this helped in some way)

Notebooked
  • 75
  • 7
  • you could use threading to use time.sleep without freezing everything. this is explained here: https://stackoverflow.com/questions/5136266/python-sleep-without-interfering-with-script – Notebooked Jun 29 '21 at 00:49
  • I saw that, it's just that since the constant movement of the snake is in the function in which I would need that I still can't use threading because it appears to only work for functions and not specific loops. – demon__hunter Jun 29 '21 at 00:59