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
My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts