snake game in python
TRANSCRIPT
from tkinter import *
import random
class SnakeGUI():
def __init__(self): #initiate the window, the canvas and the start button
self.window = Tk()
self.window.geometry('800x800')
self.window.title('Snake Game')
self.w = 600
self.h = 600
self.canvas = Canvas(self.window, bg = 'yellow', width = self.w, height = self.h)
self.canvas.pack()
self.frame = Frame(self.window)
self.frame.pack()
self.frame.focus_set()
self.button = Button(self.frame,text = 'Start',command = self.start)
self.button.pack(side = LEFT)
self.newgame()
self.window.mainloop()
def newgame(self):
self.side =20
self.a = range(0,601)
self.c = [x for x in self.a if x%10 ==0]
self.b = [x for x in self.c if (x//10)%2 != 0] #setting the group of coordinates that the food and each snake segment will be in
self.button.config(text = 'Start', command = self.start) #initiate the start button again when renew the game
self.score = 0
self.n = 0 #size of each 'step' when the snake moves
self.m = 0
self.x = 310 #initial coordinates of the first snake segment
self.y = 310
self.segment = [] #a list of snake segments
self.coor = [[self.x,self.y]] #a list of the coordinates of each snake segment to make the food not falling in this list
self.w = 600
self.h = 600
self.time = 200
self.button.bind('<Button-1>', self.gori)
self.window.bind('<Up>', self.goup) #bind the moving buttons
self.window.bind('<w>', self.goup)
self.window.bind('<Down>', self.godown)
self.window.bind('<s>', self.godown)
self.window.bind('<Right>', self.gori)
self.window.bind('<d>', self.gori)
self.window.bind('<Left>', self.gole)
self.window.bind('<a>', self.gole)
self.food()
self.segment.append(self.canvas.create_rectangle(self.x - self.side/2,self.y - self.side/2, self.x + self.side/2,\
self.y + self.side/2, fill = 'purple', tags = 'segment')) #initiate the first snake segment
self.window.after(self.time,self.animate)
self.isPaused = True
def food(self): #drawing food on the canvas
self.xfood = random.randint(0,len(self.b)-1) #coordinate of the food
self.yfood = random.randint(0,len(self.b)-1)
if [self.b[self.xfood],self.b[self.yfood]] not in self.coor: #check if the food is in the snake or not
self.canvas.create_oval(self.b[self.xfood] - 10, self.b[self.yfood] -10, self.b[self.xfood] + 10, self.b[self.yfood] +10, \
fill = 'red', tags = 'food')
else:
self.food()
def pause(self):
self.button.config(text = 'Resume',command = self.start)
self.isPaused = True
def start(self):
self.button.unbind('<Button-1>')
self.isPaused = False
self.button.config(text = 'Pause',command = self.pause)
self.animate()
def recall(self): #renew the game
self.canvas.delete('all')
self.label.pack_forget()
self.newgame()
def animate(self):
if not self.isPaused:
self.time = 200 - 4*self.score
self.x+=self.m #change the coordinate of the snake's head to make it move
a = self.x
self.y+=self.n
b = self.y
self.coor.append([a,b])
if self.y > self.h-10 or self.y < 10 or self.x <10 or self.x > self.w-10 or (len(self.coor) > 2 and [self.x,self.y] in self.coor[:-1]): #conditions to make the game end
self.isPaused = True
self.label = Label(self.window, text = 'Game Over. Score: ' + str(self.score))
self.label.pack()
self.button.config(text = 'New Game',command = self.recall)
elif self.x == self.b[self.xfood] and self.y == self.b[self.yfood]: #when the snake eats food
self.score+=1
self.canvas.delete('food')
self.food()
self.segment.append(self.canvas.create_rectangle(self.x - self.side/2,self.y - self.side/2, self.x + self.side/2,\
self.y + self.side/2, fill = 'purple', tags = 'segment'))
else:
self.segment.append(self.canvas.create_rectangle(self.x - self.side/2,self.y - self.side/2, self.x + self.side/2,\
self.y + self.side/2, fill = 'purple', tags = 'segment'))
self.canvas.delete(self.segment[0])
del self.segment[0]
del self.coor[0]
self.window.after(self.time,self.animate)
def goup(self,event): #when the snake move, change the direction by changing m (as dx) and n (as dy)
self.n = -self.side
self.m = 0
def godown(self,event):
self.n = self.side
self.m = 0
def gori(self,event):
self.m = self.side
self.n = 0