How do I chain the movement of a snake's body?
In general you have to distinguish between 2 different types of snake. In the first case, the snake moves in a grid and every time when the snake moves, it strides ahead one field in the grid. In the other type, the snakes position is not in a raster and not snapped on the fields of the grid, the position is free and the snake slides smoothly through the fields.
In former each element of the body is snapped to the fields of the grid, as the head is. The other is more trick, because the position of a body element depends on the size of the element and the dynamic, previous positions of the snakes head.
First the snake, which is snapped to a grid.
The elements of the snake can be stored in a list of tuples. Each tuple contains the column and row of the snakes element in the grid. The changes to the items in the list directly follow the movement of the snake. If the snake moves, a the new position is add to the head of the list and the tail of the list is removed.
For instance we have a snake with the following elements:
body = [(3, 3), (3, 4), (4, 4), (5, 4), (6, 4)]
When the snakes head moves form (3, 3)
to (3, 2
), then the new head position is add to the head of the list (body.insert(0, (3, 2)
):
body = [(3, 2), (3, 3), (3, 4), (4, 4), (5, 4), (6, 4)]
Finally the tail of the ist is removed (del body[-1]
):
body = [(3, 2), (3, 3), (3, 4), (4, 4), (5, 4)]
Minimal example: repl.it/@Rabbid76/PyGame-SnakeMoveInGrid
import pygame
import random
pygame.init()
COLUMNS, ROWS, SIZE = 10, 10, 20
screen = pygame.display.set_mode((COLUMNS*SIZE, ROWS*SIZE))
clock = pygame.time.Clock()
background = pygame.Surface((COLUMNS*SIZE, ROWS*SIZE))
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 random_pos(body):
while True:
pos = random.randrange(COLUMNS), random.randrange(ROWS)
if pos not in body:
break
return pos
length = 1
body = [(COLUMNS//2, ROWS//2)]
dir = (1, 0)
food = random_pos(body)
run = True
while run:
clock.tick(5)
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)
body.insert(0, body[0][:])
body[0] = (body[0][0] + dir[0]) % COLUMNS, (body[0][1] + dir[1]) % ROWS
if body[0] == food:
food = random_pos(body)
length += 1
while len(body) > length:
del body[-1]
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (255, 0, 255), (food[0]*SIZE, food[1]*SIZE, SIZE, SIZE))
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.rect(screen, color, (pos[0]*SIZE, pos[1]*SIZE, SIZE, SIZE))
pygame.display.flip()
Now the snake with completely free positioning.
We have to track all the positions which the snake's head has visited in a list. We have to place the elements of the snakes body on the positions in the list like the pearls of a chain.
The key is, to compute the Euclidean distance between the last element of the body in the chain and the following positions on the track.
When an new point with a distance that is large enough is found, then an new pearl (element) is add to the chain (body).
dx, dy = body[-1][0]-pos[0], body[-1][1]-pos[1]
if math.sqrt(dx*dx + dy*dy) >= distance:
body.append(pos)
The following function has 3 arguments. track
is the list of the head positions. no_pearls
is then number of elements of the shakes body and distance
is the Euclidean distance between the elements. The function creates and returns a list of the snakes body positions.
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
Minimal example: repl.it/@Rabbid76/PyGame-SnakeMoveFree
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()
How do I chain the movement of a snake's body?
In general you have to distinguish between 2 different types of snake. In the first case, the snake moves in a grid and every time when the snake moves, it strides ahead one field in the grid. In the other type, the snakes position is not in a raster and not snapped on the fields of the grid, the position is free and the snake slides smoothly through the fields.
In former each element of the body is snapped to the fields of the grid, as the head is. The other is more trick, because the position of a body element depends on the size of the element and the dynamic, previous positions of the snakes head.
First the snake, which is snapped to a grid.
The elements of the snake can be stored in a list of tuples. Each tuple contains the column and row of the snakes element in the grid. The changes to the items in the list directly follow the movement of the snake. If the snake moves, a the new position is add to the head of the list and the tail of the list is removed.
For instance we have a snake with the following elements:
body = [(3, 3), (3, 4), (4, 4), (5, 4), (6, 4)]
When the snakes head moves form (3, 3)
to (3, 2
), then the new head position is add to the head of the list (body.insert(0, (3, 2)
):
body = [(3, 2), (3, 3), (3, 4), (4, 4), (5, 4), (6, 4)]
Finally the tail of the ist is removed (del body[-1]
):
body = [(3, 2), (3, 3), (3, 4), (4, 4), (5, 4)]
Minimal example: repl.it/@Rabbid76/PyGame-SnakeMoveInGrid
import pygame
import random
pygame.init()
COLUMNS, ROWS, SIZE = 10, 10, 20
screen = pygame.display.set_mode((COLUMNS*SIZE, ROWS*SIZE))
clock = pygame.time.Clock()
background = pygame.Surface((COLUMNS*SIZE, ROWS*SIZE))
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 random_pos(body):
while True:
pos = random.randrange(COLUMNS), random.randrange(ROWS)
if pos not in body:
break
return pos
length = 1
body = [(COLUMNS//2, ROWS//2)]
dir = (1, 0)
food = random_pos(body)
run = True
while run:
clock.tick(5)
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)
body.insert(0, body[0][:])
body[0] = (body[0][0] + dir[0]) % COLUMNS, (body[0][1] + dir[1]) % ROWS
if body[0] == food:
food = random_pos(body)
length += 1
while len(body) > length:
del body[-1]
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (255, 0, 255), (food[0]*SIZE, food[1]*SIZE, SIZE, SIZE))
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.rect(screen, color, (pos[0]*SIZE, pos[1]*SIZE, SIZE, SIZE))
pygame.display.flip()
Now the snake with completely free positioning.
We have to track all the positions which the snake's head has visited in a list. We have to place the elements of the snakes body on the positions in the list like the pearls of a chain.
The key is, to compute the Euclidean distance between the last element of the body in the chain and the following positions on the track.
When an new point with a distance that is large enough is found, then an new pearl (element) is add to the chain (body).
dx, dy = body[-1][0]-pos[0], body[-1][1]-pos[1]
if math.sqrt(dx*dx + dy*dy) >= distance:
body.append(pos)
The following function has 3 arguments. track
is the list of the head positions. no_pearls
is then number of elements of the shakes body and distance
is the Euclidean distance between the elements. The function creates and returns a list of the snakes body positions.
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
Minimal example: repl.it/@Rabbid76/PyGame-SnakeMoveFree
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()
Python Snake Game snake does not follow
See the answer referenced in your question How do I chain the movement of a snake's body?.
You need to use the 2nd solution and adjust the function that creates the snake body. The new function needs to update the positions of the Snakes body Sprites:
def update_body(track, distance):
body = snakegroup.sprites()
no_parts = len(body)
body[0].update(*track[0])
track_i = 1
next_i = 1
for i in range(1, no_parts):
while track_i < len(track):
pos = track[track_i]
track_i += 1
dx, dy = body[i-1].x_pos-pos[0], body[i-1].y_pos-pos[1]
if math.sqrt(dx*dx + dy*dy) >= distance:
body[i].update(*pos)
next_i = i+1
break
while next_i < no_parts:
body[next_i].update(*track[-1])
next_i += 1
del track[track_i:]
return body
Example based on your (revised) code:
import pygame
import math
from random import randint
from sys import exit
pygame.init()
clock = pygame.time.Clock()
disp_surface = pygame.display.set_mode(size = (610, 700))
class Snake(pygame.sprite.Sprite):
def __init__(self, x_pos = 300, y_pos = 300):
#Access the super class of Sprite
super().__init__()
#self.image = pygame.image.load("square1.png").convert_alpha()
self.image = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(self.image, (0, 255, 0), (10, 10), 10)
self.x_pos = x_pos
self.y_pos = y_pos
self.rect = self.image.get_rect(x = x_pos, y = y_pos)
def update(self, x_pos, y_pos):
self.x_pos = x_pos
self.y_pos = y_pos
self.rect = self.image.get_rect(center = (x_pos, y_pos))
class Food(pygame.sprite.Sprite):
"""class to control food action"""
def __init__(self):
super().__init__() #access the Sprite super class methods
#self.image = pygame.image.load("food1.png").convert_alpha()
self.image = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(self.image, (255, 0, 0), (10, 10), 10)
x_pos = randint(50,600)
y_pos = randint(50,650)
self.rect = self.image.get_rect(x = x_pos,y = y_pos)
def update(self, pos):
x_pos = randint(50,600)
y_pos = randint(50,650)
self.rect = self.image.get_rect(x = x_pos,y = y_pos)
def update_body(track, distance):
body = snakegroup.sprites()
no_parts = len(body)
body[0].update(*track[0])
track_i = 1
next_i = 1
for i in range(1, no_parts):
while track_i < len(track):
pos = track[track_i]
track_i += 1
dx, dy = body[i-1].x_pos-pos[0], body[i-1].y_pos-pos[1]
if math.sqrt(dx*dx + dy*dy) >= distance:
body[i].update(*pos)
next_i = i+1
break
while next_i < no_parts:
body[next_i].update(*track[-1])
next_i += 1
del track[track_i:]
return body
snakegroup = pygame.sprite.Group()
original_snake = Snake()
snakegroup.add(original_snake)
track = [(original_snake.x_pos, original_snake.y_pos)]
foods = pygame.sprite.GroupSingle()
foods.add(Food())
direction = (0, 0)
speed = 1
run = True
while run:
for eachevent in pygame.event.get():
if eachevent.type == pygame.QUIT:
run = False
if eachevent.type == pygame.KEYDOWN:
if eachevent.key == pygame.K_LEFT and direction[0] != 1:
direction = (-1, 0)
if eachevent.key == pygame.K_RIGHT and direction[0] != -1:
direction = (1, 0)
if eachevent.key == pygame.K_UP and direction[1] != 1:
direction = (0, -1)
if eachevent.key == pygame.K_DOWN and direction[1] != -1:
direction = (0, 1)
track.insert(0, track[0][:])
track[0] = (track[0][0] + direction[0] * speed) % disp_surface.get_width(), (track[0][1] + direction[1] * speed) % disp_surface.get_height()
update_body(track, 20)
if pygame.sprite.spritecollideany(foods.sprite, snakegroup):
foods.empty()
foods.add(Food())
last_part = snakegroup.sprites()[-1]
snakegroup.add(Snake(last_part.x_pos, last_part.y_pos))
speed = min(10, speed + 1)
disp_surface.fill((64,64,64))
snakegroup.draw(disp_surface)
foods.draw(disp_surface)
pygame.display.update()
clock.tick(120)
Snake bodies not appending to snake correctly
You have to track the positions which have been met by the snake. Add a list attribute self.position
to the class Snake
:
class Snake:
def __init__(self, x, y):
# [...]
self.positions = [(self.x, self.y)]
# [...]
Add the new position to the list when the snake moves:
class Snake:
# [...]
def update(self):
# move
if self.direction == 1:
self.y -= self.speed
if self.direction == 2:
self.x += self.speed
if self.direction == 3:
self.y += self.speed
if self.direction == 4:
self.x -= self.speed
# add ne position
if self.x != self.positions[0][0] or self.y != self.positions[0][1]:
self.positions.insert(0, (self.x, self.y))
Update the x
and y
coordinate of the body along the stored positions in events
. Define a distance between the parts of the body (e.g. 35). And use a method getPos
to get the position of a part, by its index:
class Snake:
# [...]
def events(self):
# change direction on key press
self.keys = pygame.key.get_pressed()
if self.keys[pygame.K_UP] and self.direction != 3:
self.direction = 1
if self.keys[pygame.K_DOWN] and self.direction != 1:
self.direction = 3
if self.keys[pygame.K_LEFT] and self.direction != 2:
self.direction = 4
if self.keys[pygame.K_RIGHT] and self.direction != 4:
self.direction = 2
if self.rect.colliderect(food.rect):
self.speed += 0.5
food.x = random.randint(100, WIN_WIDTH - 125)
food.y = random.randint(150, WIN_HEIGHT - 175)
self.score += 5
self.colliide = False
self.bodies.append(Body(0, 0))
# Move the end bodies first in reverse order
for i in range(len(self.bodies)):
pos = self.getPos(i+1, 35, i == len(self.bodies)-1)
snake.bodies[i].x = pos[0]
snake.bodies[i].y = pos[1]
snake.bodies[i].draw()
The arguments to method getPos
are the index of the body part, the distance between the parts and delToEnd
. delToEnd
becomes true, when the last part of the body is get and indicates, that the positions at the end of the list, which are "behind" the last part of the snake can be deleted:
class Snake:
# [...]
def getPos(self, i, dist, delToEnd):
lenToI = i * dist
lenAct = 0
px, py = self.positions[-1]
for j in range(len(self.positions)-1):
px, py = self.positions[j]
pnx, pny = self.positions[j+1]
delta = math.sqrt((px-pnx)*(px-pnx) + (py-pny)*(py-pny))
lenAct += delta
if lenAct >= lenToI:
w = (lenAct - lenToI) / delta
px = pnx - (pnx-px) * w
py = pny - (pny-py) * w
if delToEnd:
del self.positions[j:]
break
return (round(px), round(py))
How to add snake body in pygame
The comments below might sound harsh, and I've tried to write them in a neutral way simply pointing out facts and state them as they are. If you are truly a new programmer, this is a pretty good project to learn from and you've done quite good to come this far. So keep an mind that these comments are not meant to be mean, but objective and always comes with a proposed solution to make you an even better programmer, not to bash you.
I also won't go into detail in the whole list
as a body thing, others have covered it but I'll use it also in this code.
Here's the result, and blow is the code and a bunch of pointers and tips.
Never mix logic in one function
You've also bundled the food into the player object, which is a big no-no. As well as render logic in the movement logic. So I propose a re-work in the shape of even more OOP where food and player are two separate entities and a function for each logical operation (render, move, eat, etc..).
So I restructured it into this logic:
While I'm at it, I also re-worked the movement mechanics a bit, to use less lines and logic to produce the same thing. I also removed all this logic:
self.r = random.randint(0,500)
while True:
if self.r % 25 == 0:
break
else:
self.r = random.randint(0,500)
continue
And replaced it with this, which does the exact same thing, but uses built-ins to produce it. And hopefully the functions/variables are more descriptive than a rogue while
loop.
self.r = random.choice(range(0, 500, 25))
And the final result would look something like this:
import random
import pygame
from pygame import *
import sys
import os
import time
# Constants (Used for bitwise operations - https://www.tutorialspoint.com/python/bitwise_operators_example.htm)
UP = 0b0001
DOWN = 0b0010
LEFT = 0b0100
RIGHT = 0b1000
###objects
class Food:
def __init__(self, window, x=None, y=None):
self.window = window
self.width = 25
self.height = 25
self.x, self.y = x, y
if not x or not y: self.new_position()
def draw(self):
pygame.draw.rect(self.window, (255,0,0), (self.x, self.y, 25, 25))
def new_position(self):
self.x, self.y = random.choice(range(0, 500, 25)), random.choice(range(0, 500, 25))
class Snake:
def __init__(self, window):
self.width = 25
self.width = 25
self.height = 25
self.window = window
self.vel = 25
self.update = pygame.display.update()
start_position = random.choice(range(0, 500, 25)), random.choice(range(0, 500, 25))
self.body = [start_position]
self.direction = RIGHT
def move(self, window):
self.keys = pygame.key.get_pressed()
# since key-presses are always 1 or 0, we can multiply each key with their respective value from the
# static map above, LEFT = 4 in binary, so if we multiply 4*1|0 we'll get binary 0100 if it's pressed.
# We can always safely combine 1, 2, 4 and 8 as they will never collide and thus always create a truth map of
# which direction in bitwise friendly representation.
if any((self.keys[pygame.K_UP], self.keys[pygame.K_DOWN], self.keys[pygame.K_LEFT], self.keys[pygame.K_RIGHT])):
self.direction = self.keys[pygame.K_UP]*1 + self.keys[pygame.K_DOWN]*2 + self.keys[pygame.K_LEFT]*4 + self.keys[pygame.K_RIGHT]*8
x, y = self.body[0] # Get the head position, which is always the first in the "history" aka body.
self.body.pop() # Remove the last object from history
# Use modolus to "loop around" when you hit 500 (or the max width/height desired)
# as it will wrap around to 0, try for instance 502 % 500 and it should return "2".
if self.direction & UP:
y = (y - self.vel)%500
elif self.direction & DOWN:
y = (y + self.vel)%500
elif self.direction & LEFT:
x = (x - self.vel)%500
elif self.direction & RIGHT:
x = (x + self.vel)%500 # window.width
self.body.insert(0, (x, y))
defeat(self, food):
x, y = self.body[0] # The head
if x >= food.x and x+self.width <= food.x+food.width:
if y >= food.y and y+self.height <= food.y+food.height:
self.body.append(self.body[-1])
return True
return False
def draw(self):
for x, y in self.body:
pygame.draw.rect(self.window, (0,255,0), (x, y, self.width, self.width))
##variables
clock = pygame.time.Clock()
##game
pygame.init()
window = pygam
Related Topics
Python Dictionary Comprehension
How to Improve Performance of This Code
How to Explicitly Free Memory in Python
What Is the Eafp Principle in Python
How to Pad a String With Zeroes
How to Pass a Variable Between Flask Pages
How to Expand the Output Display to See More Columns of a Pandas Dataframe
How to Modify List Entries During For Loop
Loop "Forgets" to Remove Some Items
Read Subprocess Stdout Line by Line
Explanation of How Nested List Comprehension Works
How to Play Wav File in Python
Is There Any Pythonic Way to Combine Two Dicts (Adding Values For Keys That Appear in Both)
How to Concatenate Text Files in Python