I have a snake game, that for generating parts of the snakes I need to keep add and remove rectangles to shape the snake's body. But if you run the game, the squares look like this instead of being green and big:
Although I'm all positive that it's not a problem with the code, but here are the codes for you:
Snake-Game.py:
from customtkinter import *
from httpx import head
from Mods.Snake import Snake
from Mods.Apple import Apple
WIDTH = 1080
HEIGHT = 720
SPEED = 70
SPACE_SIZE = 50
BODY_PARTS = 3
SNAKE_COLOR = "#00FF00"
APPLE_COLOR = "#FF0000"
BG_COLOR = "#000000"
SPEED_INCREASE_LEVEL = 5
MAP_INCREASE_LEVEL = 30
current_size = BODY_PARTS
ate = False
upgrade = False
snake_position = [0,0]
score = 0
dir = 'down'
w = 0
def main():
global w
w = CTk()
w.title("Snake Game")
w.resizable(False, False)
l = CTkLabel(w, text="Score: {}".format(score), font=("consolas", 40))
l.pack()
board = CTkCanvas(w, bg=BG_COLOR, width=WIDTH, height=HEIGHT)
board.pack()
centerize_window(w)
Listen_for(w, 'left', 'right', 'down', 'up')
restart(board, l)
w.mainloop()
def restart(board: CTkCanvas, l: CTkLabel):
snake = Snake(board, current_size, SPACE_SIZE, SNAKE_COLOR, snake_position[0])
apple = Apple(board, WIDTH, HEIGHT, SPACE_SIZE, APPLE_COLOR, snake_position)
start(w, board, l, snake, apple)
def start(window: CTk, canvas: CTkCanvas, label: CTkLabel, snake: Snake, apple: Apple):
global ate
global upgrade
global score
global current_size
global SPEED
global SPACE_SIZE
global snake_position
x, y = snake.coo[Head := 0]
if dir == 'up': y -= SPACE_SIZE
elif dir == 'down': y += SPACE_SIZE
elif dir == 'right': x += SPACE_SIZE
elif dir == 'left': x -= SPACE_SIZE
snake.coo.insert(Head, (x, y))
snake.squares.insert(Head, canvas.create_rectangle(x, y, x+BODY_PARTS, y+BODY_PARTS, fill=SNAKE_COLOR))
if x == apple.coo[0] and y == apple.coo[1]:
ate = True
upgrade = True
current_size+=1
print(current_size)
score+=1 # Make different apples that if you eat them
# they either give you additional score or decrease your score
# plus slowing you down for some seconds or forever
label.configure(text="Score: {}".format(score))
canvas.delete('apple')
apple = Apple(canvas, WIDTH, HEIGHT, SPACE_SIZE, APPLE_COLOR, snake.coo)
else:
del snake.coo[-1]
canvas.delete(snake.squares[-1])
del snake.squares[-1]
if hasCrashed(snake): Game_Over(canvas)
else:
if not current_size%SPEED_INCREASE_LEVEL and ate:
SPEED-=5
print("Speed: ", SPEED)
ate = False
if not current_size%MAP_INCREASE_LEVEL and upgrade:
snake_position = snake.coo.copy()
# SPACE_SIZE-=20
print("Leveled up!")
upgrade = False
window.after(SPEED, start, window, canvas, label, snake, apple)
def change_dir(new_dir: str):
global dir
if new_dir == 'left' and dir != 'right': dir = new_dir
elif new_dir == 'right' and dir != 'left': dir = new_dir
elif new_dir == 'up' and dir != 'down': dir = new_dir
elif new_dir == 'down' and dir != 'up': dir = new_dir
def hasCrashed(snake: Snake):
x, y = snake.coo[Head:=0]
if (x < 0 or x >= WIDTH) or (y < 0 or y >= HEIGHT): return None
for part in snake.coo[Head+1:]:
if x == part[0] and y == part[1]: return True
return False
def Game_Over(canvas: CTkCanvas):
canvas.delete(ALL)
canvas.create_text(canvas.winfo_width()/2, canvas.winfo_height()/2, font=('consolas', 70), text="GAME OVER", fill='red', tag='gameover')
def centerize_window(window: CTk):
window.update()
window_width = window.winfo_width()
window_height = window.winfo_height()
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
X = int((screen_width/2) - (window_width/2))
Y = int((screen_height/2) - (window_height/2))
window.geometry(f"{window_width}x{window_height}+{X}+{Y}")
def Listen_for(window: CTk, go_left: str, go_right: str, go_down: str, go_up: str):
window.bind(f'<{go_left.capitalize()}>', lambda event: change_dir(go_left))
window.bind(f'<{go_right.capitalize()}>', lambda event: change_dir(go_right))
window.bind(f'<{go_up.capitalize()}>', lambda event: change_dir(go_up))
window.bind(f'<{go_down.capitalize()}>', lambda event: change_dir(go_down))
if __name__ == "__main__": main()
Snake.py
:
class Snake:
def __init__(self,
canvas,
BODY_SIZE: int,
BOARD_SIZE: int,
SNAKE_COLOR: str,
location: list[int]) -> None:
self.body_size = BODY_SIZE
self.coo = []
self.squares = []
if location == 0: location = [0,0]
for i in range(0, BODY_SIZE): self.coo.append(location)
for x, y in self.coo: self.squares.append(canvas.create_rectangle(x, y, x+BOARD_SIZE, y+BOARD_SIZE, fill=SNAKE_COLOR, tag="snake"))
Apple.py
:
import random
class Apple:
def __init__(self,
canvas,
BOARD_WIDTH: int,
BOARD_HEIGHT: int,
SPACE_SIZE: int,
APPLE_COLOR: str,
SNAKE_POSITION: list[int]) -> None:
SPACE_SIZE = int(SPACE_SIZE)
while True:
X = random.randint(0, int((BOARD_WIDTH/SPACE_SIZE)-1))*SPACE_SIZE
Y = random.randint(0, int((BOARD_HEIGHT/SPACE_SIZE)-1))*SPACE_SIZE
self.coo = [X,Y]
if not self.coo in SNAKE_POSITION: break # Force the apple to not appear on snake's body
canvas.create_oval(X, Y, X+SPACE_SIZE, Y+SPACE_SIZE, fill=APPLE_COLOR, tag="apple")
I also have some other problems which I guess I'll post them in different questions, but for now, how can I fix this???
It is because you have use the wrong size (BODY_PARTS
) on the following line:
def start(window: CTk, canvas: CTkCanvas, label: CTkLabel, snake: Snake, apple: Apple):
...
# BODY_PARTS = 3, SPACE_SIZE (50) should be used instead
snake.squares.insert(Head, canvas.create_rectangle(x, y, x+BODY_PARTS, y+BODY_PARTS, fill=SNAKE_COLOR))
...
I think SPACE_SIZE
should be used instead of BODY_PARTS
:
snake.squares.insert(Head, canvas.create_rectangle(x, y, x+SPACE_SIZE, y+SPACE_SIZE, fill=SNAKE_COLOR))