-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsnake.py
More file actions
164 lines (128 loc) · 5.14 KB
/
Copy pathsnake.py
File metadata and controls
164 lines (128 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# this program is written for Python2
# imports
import Tkinter
import time
import random
import sys
import math
# create game window
window = Tkinter.Tk()
# create window size and set no-resize option
window_dimensions = [625, 625]
window.geometry(str(window_dimensions[0]) + "x" + str(window_dimensions[1]))
window.resizable(0, 0)
# set window title
window.title("Snake Game")
# close window when OS close button is clicked
window.protocol("WM_DELETE_WINDOW", sys.exit)
# choose fps for game
frames_per_second = 12
# create game canvas
game_canvas = Tkinter.Canvas(window, width=window_dimensions[0], height=window_dimensions[1], bd=0, highlightthickness=0)
game_canvas.pack()
# create game variables
game_scale = 25
game_dimensions = [ window_dimensions[0] / game_scale, window_dimensions[1] / game_scale ]
# center player coordinates (position of snake head), and create player tail array
player_coords = [math.floor(game_dimensions[0] / 2.0), math.floor(game_dimensions[1] / 2.0)]
player_tail = []
# player velocity variable (decides which direction to move every frame)
player_velocity = [1, 0]
# generate new random apple coordinates
def generateAppleCoords():
# declare global variable(s)
global player_tail
# variable for generated random apple coordinates
generated_apple_coords = [random.randint(0, (game_dimensions[0] - 1)), random.randint(0, (game_dimensions[1] - 1))]
# loop through tail and check if generated apple coords overlap the tail; if they do, generate again (recursion!)
for item in player_tail:
if(item[0] == generated_apple_coords[0] and item[1] == generated_apple_coords[1]):
return generateAppleCoords()
# apple coords do not overlap, so return them
return generated_apple_coords
# apple coordinates
apple_coords = generateAppleCoords()
# create velocity changed variable (used to fix bug in arrow key binds)
velocity_changed_this_frame = False
# function to create grid item of specific game coordinates and bg color
def createGridItem(coords, hexcolor):
game_canvas.create_rectangle((coords[0]) * game_scale, (coords[1]) * game_scale, (coords[0] + 1) * game_scale, (coords[1] + 1) * game_scale, fill=hexcolor, outline="#222222", width=3)
# gameloop
def gameloop():
# declare use of global variables
global frames_per_second
global velocity_changed_this_frame
global game_canvas
global game_dimensions
global window_dimensions
global player_tail
global player_coords
global player_velocity
global apple_coords
# call gameloop again in 100 milleseconds (gameloops is called every 100 MS)
window.after(1000 / frames_per_second, gameloop)
# change velocity changed variable back to false
velocity_changed_this_frame = False
# clear canvas
game_canvas.delete("all")
# create dark gray background
game_canvas.create_rectangle(0, 0, window_dimensions[0], window_dimensions[1], fill="#222222", outline="#222222")
# add head to tail
player_tail.append([player_coords[0], player_coords[1]])
# move player in direction specified in player velocity variable
player_coords[0] += player_velocity[0]
player_coords[1] += player_velocity[1]
# add ability to move through walls
if(player_coords[0] == game_dimensions[0]):
player_coords[0] = 0
elif(player_coords[0] == -1):
player_coords[0] = game_dimensions[0] - 1
elif(player_coords[1] == game_dimensions[1]):
player_coords[1] = 0
elif(player_coords[1] == -1):
player_coords[1] = game_dimensions[1] - 1
# loop through tail, display each item in tail, and check if it's colliding w/head: if so, gameover and restart
for item in player_tail:
# check for collision
if(item[0] == player_coords[0] and item[1] == player_coords[1]):
# restart game and variables
player_coords = [math.floor(game_dimensions[0] / 2.0), math.floor(game_dimensions[1] / 2.0)]
player_tail = []
player_velocity = [1, 0]
apple_coords = generateAppleCoords()
# display item
createGridItem(item, "#00ff00")
# display apple
createGridItem(apple_coords, "#ff0000")
# check if player has eaten apple; if yes, add 1 to tail; if not, move as normal
if(apple_coords[0] == player_coords[0] and apple_coords[1] == player_coords[1]):
apple_coords = generateAppleCoords()
else:
player_tail.pop(0)
# handle arrow keys keydown events
def onKeyDown(e):
# declare use of global variable(s)
global player_velocity
global velocity_changed_this_frame
# only handle event if velocity has not been changed in current frame
if(velocity_changed_this_frame == False):
# set velocity changed variable to true
velocity_changed_this_frame = True
# bind arrow keys to specific player velocity directions
if(e.keysym == "Left" and player_velocity[0] != 1):
player_velocity = [-1, 0]
elif(e.keysym == "Right" and player_velocity[0] != -1):
player_velocity = [1, 0]
elif(e.keysym == "Up" and player_velocity[1] != 1):
player_velocity = [0, -1]
elif(e.keysym == "Down" and player_velocity[1] != -1):
player_velocity = [0, 1]
else:
# if player velocity indeed was not changed, then revert variable back to false
velocity_changed_this_frame = False
# connect keydown event to function
window.bind("<KeyPress>", onKeyDown)
# call gameloop
gameloop()
# display window and mainloop
window.mainloop()