Looking for fluid movements in snake

Trying to make the movement in snake fluid…

import pygame


class Snake(pygame.sprite.Sprite):
    def __init__(self):
        super(Snake, self).__init__()
        self.starting_pos()
        self.head = pygame.Surface((20, 20))
        self.head.fill((255, 255, 0))
        self.body = pygame.Surface((20, 20))
        self.body.fill((0, 255, 0))
        self.image = self.head

    def starting_pos(self):
        self.x = 200
        self.y = 200
        head_pos = self.x, self.y
        self.bodycoord = [[self.x - c * 20, self.y] for c in range(3)]
        self.counter = 0


    def draw(self):
        start = 1
        for coord in self.bodycoord:
            if start == 1:
                screen.blit(self.head, (coord[0], coord[1]))
                start = 0
            else:
                screen.blit(self.body, (coord[0], coord[1]))

    def update(self):
        pygame.time.delay(1)
  
        if self.counter == 0:
            self.memx, self.memy = self.bodycoord[0]

 
        if movedown:
            self.y += 1
            self.distancedown = +20

        if moveup:
            self.y -= 1
            self.distanceup = -20

        if moveright:
            self.x += 1
            self.distanceright = 20

        if moveleft:
            self.x -= 1
            self.distanleft = -20

        self.bodycoord[0] = self.x, self.y
        self.counter += 1
        if self.counter == 20:
            self.move(self.memx, self.memy)
            self.counter = 0
            
        
    def move(self, x, y):
        start = 1
        for n, coord in enumerate(self.bodycoord[1:]):
            if start == 1:
                x1, y1 = self.bodycoord[1]
                self.bodycoord[1] = x, y
                start = 0
            else:
                x2, y2 = self.bodycoord[n+1]
                self.bodycoord[n+1] = x1, y1


screen = pygame.display.set_mode((400, 400))
tempwin = pygame.Surface((400, 400))
snake = Snake()

movedown = 1
moveup = 0
moveright = 0
moveleft = 0
clock = pygame.time.Clock()
loop = 1
while loop:
    screen.fill((0, 0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = 0
    if snake.y > 350:
        movedown = 0
        moveright = 1
    if snake.x > 250:
        moveup = 1
        moveright = 0
    if snake.y < 10:
        moveup = 0
        moveleft = 1
    if snake.x < 30:
        movedown = 1
        moveleft = 0
    snake.draw()
    snake.update()
    # pygame.time.delay(1000)
    pygame.display.update()
    clock.tick(144)

pygame.quit()

Still… not good.

Fluid but… not good still

import pygame


class Snake(pygame.sprite.Sprite):
    def __init__(self):
        super(Snake, self).__init__()
        self.starting_pos()
        self.head = pygame.Surface((20, 20))
        self.head.fill((255, 255, 0))
        self.body = pygame.Surface((20, 20))
        self.body.fill((0, 255, 0))
        self.image = self.head
        self.distancedown = +20
        self.distanceup = -20
        self.distanceright = 20
        self.distanceleft = -20

    def starting_pos(self):
        self.x = 200
        self.y = 200
        head_pos = self.x, self.y
        self.bodycoord = [[self.x - c * 20, self.y] for c in range(3)]
        self.counter = 0


    def draw(self):
        start = 1
        for coord in self.bodycoord:
            if start == 1:
                screen.blit(self.head, (coord[0], coord[1]))
                start = 0
            else:
                screen.blit(self.body, (coord[0], coord[1]))

    def update(self):
        pygame.time.delay(1)
  
        # if self.counter == 0:
        self.memx, self.memy = self.bodycoord[0]

 
        if movedown:
            self.y += 1
            

        if moveup:
            self.y -= 1
            

        if moveright:
            self.x += 1
            

        if moveleft:
            self.x -= 1
            

        self.bodycoord[0] = self.x, self.y
        self.counter += 1
        # if self.counter == 20:
        self.move(self.memx, self.memy)
        #     self.counter = 0
            
        
    def move(self, x, y):
        start = 1
        xx = 0
        yy = 0
        for n, coord in enumerate(self.bodycoord[1:]):
            if moveright:
                xx = -20
            if moveleft:
                xx = 20
            if moveup:
                yy = 20
            if movedown:
                yy = -20
            if start == 1:
                self.bodycoord[1] = x + xx, y + yy
                x1, y1 = self.bodycoord[1][0], self.bodycoord[1][1] 
                start = 0
            else:
                self.bodycoord[n+1] = x1 + xx * (n) , y1 + yy * n
                x2, y2 = self.bodycoord[n+1][0] + xx, self.bodycoord[n+1][1] + yy


screen = pygame.display.set_mode((300, 300))

snake = Snake()

movedown = 1
moveup = 0
moveright = 0
moveleft = 0
clock = pygame.time.Clock()
loop = 1
while loop:
    screen.fill((0, 0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = 0
    if snake.y > 200:
        movedown = 0
        moveright = 1
    if snake.x > 200:
        moveup = 1
        moveright = 0
    if snake.y < 10:
        moveup = 0
        moveleft = 1
    if snake.x < 30:
        movedown = 1
        moveleft = 0
    snake.draw()
    snake.update()
    # pygame.time.delay(1000)
    pygame.display.update()
    clock.tick(144)

pygame.quit()

 

Looking in stakoverflow

I found this interesting code… but there is still something that I want to change…

import pygame
import random
import math

pygame.init()
COLUMNS, ROWS, SIZE = 10, 10, 20
WIDTH, HEIGHT = COLUMNS*SIZE, ROWS*SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock  = pygame.time.Clock()

background = pygame.Surface((WIDTH, HEIGHT))
background.fill((255, 255, 255))
for i in range(1, COLUMNS):
    pygame.draw.line(background, (128, 128, 128), (i*SIZE-1, 0), (i*SIZE-1, ROWS*SIZE), 2)
for i in range(1, ROWS):
    pygame.draw.line(background, (128, 128, 128), (0, i*SIZE-1), (COLUMNS*SIZE, i*SIZE-1), 2)

def hit(pos_a, pos_b, distance):
    dx, dy = pos_a[0]-pos_b[0], pos_a[1]-pos_b[1]
    return math.sqrt(dx*dx + dy*dy) < distance

def random_pos(body):
    pos = None
    while True:
        pos = random.randint(SIZE//2, WIDTH-SIZE//2), random.randint(SIZE//2, HEIGHT-SIZE//2)
        if not any([hit(pos, bpos, 20) for bpos in body]):
            break    
    return pos

def create_body(track, no_pearls, distance):
    body = [(track[0])]
    track_i = 1
    for i in range(1, no_pearls):
        while track_i < len(track):
            pos = track[track_i]
            track_i += 1
            dx, dy = body[-1][0]-pos[0], body[-1][1]-pos[1]
            if math.sqrt(dx*dx + dy*dy) >= distance:
                body.append(pos)
                break
    while len(body) < no_pearls:
        body.append(track[-1])
    del track[track_i:]
    return body

length = 1
track = [(WIDTH//2, HEIGHT//2)]
dir = (1, 0)
food = random_pos(track)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT: dir = (-1, 0)
            elif event.key == pygame.K_RIGHT: dir = (1, 0)
            elif event.key == pygame.K_UP: dir = (0, -1)
            elif event.key == pygame.K_DOWN: dir = (0, 1)

    track.insert(0, track[0][:])    
    track[0] = (track[0][0] + dir[0]) % WIDTH, (track[0][1] + dir[1]) % HEIGHT

    body = create_body(track, length, 20)

    if hit(body[0], food, 20):
        food = random_pos(body)
        length += 1 

    screen.blit(background, (0, 0))
    pygame.draw.circle(screen, (255, 0, 255), food, SIZE//2)
    for i, pos in enumerate(body):
        color = (255, 0, 0) if i==0 else (0, 192, 0) if (i%2)==0 else (255, 128, 0)
        pygame.draw.circle(screen, color, pos, SIZE//2)
    pygame.display.flip()


Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.