import pygame as pg
import random
import pickle
from tkinter import *
import sys
from PIL import Image, ImageTk
"""I used Tkinter just for practise, I know
that with only pygame game will be better
but I wanted to combine these two modules.
PIL was used to add image on tkinter window"""
HEIGHT, WIDTH = 640, 900
clock = pg.time.Clock()
best_result = 0
time = 10 # time = 60/time sec
lvl = 1
def start_window():
global lvl
"""Create main window, where you can choose difficult
:return None"""
root = Tk()
root.geometry(f'900x640+{310}+{80}')
root["bg"] = '#35b056'
root.title("The Snake")
root.iconbitmap("C:\Programming\Python\Games\Snake\project\icon.ico")
# https://наклейкибум.рф/wp-content/uploads/13150_0-250x250.png
img = ImageTk.PhotoImage(Image.open("C:\Programming\Python\Games\Snake\project\Snake3.png"))
img_lab = Label(image=img) # creating the snake on the main window, but I couldn't make it
img_lab.place(x=150, y=150) # without white bg
r_var = IntVar()
r_var.set(lvl)
start_but = Button(text="Start", width=32, height=3, background='#c5ff2e', font=("Arial 32", 12))
r1 = Radiobutton(text="Easy", variable=r_var, value=1, background='#35b056',
activebackground='#35b056', font=("Arial 32", 16))
r2 = Radiobutton(text="Normal", variable=r_var, value=2, background='#35b056',
activebackground='#35b056', font=("Arial 32", 16))
r3 = Radiobutton(text="Hard", variable=r_var, value=3, background='#35b056',
activebackground='#35b056', font=("Arial 32", 16))
start_but.place(y=150, x=460)
r1.place(y=450, x=220)
r2.place(y=450, x=450)
r3.place(y=450, x=680)
def change(event): # changing difficulties
global game_status, time, lvl
if r_var.get() == 1:
time = 10 # repeating of cycle = (60/time)
lvl = 1
elif r_var.get() == 2:
time = 17
lvl = 2
elif r_var.get() == 3:
time = 24
lvl = 3
root.destroy()
game_status = True
def but_animation_enter(event): # if mouse on the button change bg
start_but['bg'] = '#e6e200'
def but_animation_leave(event):
start_but['bg'] = '#c5ff2e'
def on_exit():
sys.exit()
root.protocol('WM_DELETE_WINDOW', on_exit) # if player clicked quit, close window
start_but.bind('<Button-1>', change)
start_but.bind('<Enter>', but_animation_enter)
start_but.bind('<Leave>', but_animation_leave)
root.mainloop()
try:
with open('pb.pickle', 'rb') as r: # checking best score
best_result = pickle.load(r)
except EOFError: # if no pb.pickle
with open('pb.pickle', 'wb') as w: # or pb.pickle clear, best_result = 1
pickle.dump('1', w)
except FileNotFoundError:
with open('pb.pickle', 'wb') as w:
pickle.dump('1', w)
start_window()
x, y = 440, 320
SIZE = 20 # size of all squares on the field
directions = {
'U': (0, -SIZE),
'D': (0, SIZE),
'R': (SIZE, 0),
'L': (-SIZE, 0)}
dir2 = {'U': False, 'D': False, 'R': False, 'L': False}
dx, dy = 0, 0
pg.font.init() # creating fonts for all text
score_font = pg.font.Font(None, 36)
lose_font = pg.font.Font(None, 80)
lose_text = lose_font.render("You lost :(", True, (1, 1, 1))
restart_img = pg.image.load('restart.png') # text of window
pg.display.set_caption('The Snake')
SNAKE = [(x, y)]
length = 1 # number of sections in Snake
ax, ay = random.randrange(0, 900, SIZE), random.randrange(0, 640, SIZE) # cords of apple
bg = pg.display.set_mode((WIDTH, HEIGHT)) # creating window
isQuit = False
game_status = True
while not isQuit:
bg.fill((53, 176, 86))
while game_status:
bg.fill((53, 176, 86))
score = score_font.render(str(length), True, (1, 1, 1))
bg.blit(score, (870, 612))
for i in SNAKE: # Snake moving
pg.draw.rect(bg, (181, 252, 2), (i[0], i[1], SIZE, SIZE))
pg.draw.rect(bg, (192, 85, 85), (ax, ay, SIZE, SIZE)) # the appearance of apple
x += dx
y += dy
SNAKE.append((x, y))
SNAKE = SNAKE[-length:]
for i in range(0, len(SNAKE) - 3): # if snake eat itself
if SNAKE[i][0] == SNAKE[-1][0] and SNAKE[i][1] == SNAKE[-1][1]:
game_status = False
if x >= 900 or y >= 640 or x <= -10 or y <= -10: # if touch boundaries
game_status = False
if x == ax and y == ay: # if eat apple, add new one, increase length and add score
pg.draw.rect(bg, (192, 85, 85), (ax, ay, 20, SIZE))
length += 1
ax, ay = random.randrange(0, 900, SIZE), random.randrange(0, 640, SIZE)
for i in SNAKE: # reduce probability of creating apple in snake
if i[0] == ax and i[1] == ay:
ax, ay = random.randrange(0, 900, SIZE), random.randrange(0, 640, SIZE)
pg.display.flip()
clock.tick(time)
time += 0.02 # every cycle speed increase
for i in pg.event.get(): # checking keyboard pressing
if i.type == pg.QUIT:
sys.exit()
elif i.type == pg.KEYDOWN:
if i.key == pg.K_a and dir2['R'] is False:
dx, dy = directions['L'][0], 0
dir2 = {'U': False, 'D': False, 'R': False, 'L': True}
elif i.key == pg.K_d and dir2['L'] is False:
dx, dy = directions['R'][0], 0
dir2 = {'U': False, 'D': False, 'R': True, 'L': False}
elif i.key == pg.K_w and dir2['D'] is False:
dy, dx = directions['U'][1], 0
dir2 = {'U': True, 'D': False, 'R': False, 'L': False}
elif i.key == pg.K_s and dir2['U'] is False:
dy, dx = directions['D'][1], 0
dir2 = {'U': False, 'D': True, 'R': False, 'L': False}
bg.blit(lose_text, (355, 120)) # if lose appears text "You lost"
if length > int(best_result): # if result > past best score, new best = result
best_result = length
with open('pb.pickle', 'wb') as w:
pickle.dump(str(best_result), w)
best_score = score_font.render(f"Best score: {best_result}", True, (1, 1, 1))
bg.blit(best_score, (410, 190)) # show best score
bg.blit(restart_img, (375, 340)) # restart icon
clock.tick(10)
pg.display.flip()
mouse_pos = pg.mouse.get_pos()
for i in pg.event.get(): # checking if we quit in main window
if i.type == pg.QUIT:
sys.exit()
if 380 <= mouse_pos[0] <= 570 and 348 <= mouse_pos[1] <= 524: # if player pressed on icon,
if i.type == pg.MOUSEBUTTONUP: # restart game
start_window()
x, y = 440, 320 # reinitialization of variables
SNAKE = [(x, y)]
dx, dy = 0, 0
length = 1
game_status = True
Я начинающий программист, решил немного попрактиковаться и сделать змейку. Использовал PyGame. Хочу узнать мнение опытных программистов. На моём этапе очень важна критика, чтоб мне помогли и подсказали мои ошибки. Если вам не сложно оцените мою работу и укажите мои ошибки пожалуйста. Как мне сделать код более читабельным и что вообще изменить в нём.