-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOOPy flappy bird.py
180 lines (146 loc) · 5.45 KB
/
OOPy flappy bird.py
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#Spring 2016: OOP and Animation - FlappyBird
import random
from tkinter import *
class Bird(object):
def __init__(self, x, y, size, canvasWidth, canvasHeight):
self.x = x
self.y = y
self.size = size
self.velocity = 0
self.gravity = 1
self.canvasHeight = canvasHeight
self.canvasWidth = canvasWidth
def draw(self, canvas):
canvas.create_oval(self.x - self.size, self.y - self.size,
self.x + self.size, self.y + self.size, fill = "red")
def onThrust(self):
self.velocity = -10.0
def move(self):
self.velocity += self.gravity
self.y = self.y + self.velocity
if (self.y + self.size > self.canvasHeight):
self.y = self.canvasHeight - self.size
elif (self.y - self.size < 0):
self.y = self.size
def getLocation(self):
return self.x, self.y
def getSize(self):
return self.size
class Obstacle(object):
def __init__(self, gapSize, width, canvasWidth, canvasHeight):
self.gapSize = gapSize
self.width = width
self.canvasWidth = canvasWidth
self.canvasHeight = canvasHeight
self.y = random.randrange(gapSize, canvasHeight - gapSize)
self.x = canvasWidth + gapSize // 2
self.speed = 10
def draw(self, canvas):
canvas.create_rectangle(self.x - self.width // 2, 0,
self.x + self.width // 2, self.y - self.gapSize // 2, fill="green")
canvas.create_rectangle(self.x - self.width // 2,
self.y + self.gapSize // 2, self.x + self.width // 2,
self.canvasHeight, fill="green")
def move(self):
self.x -= self.speed
def isColliding(self, birdX, birdY, birdSize):
birdCorners = [(birdX - birdSize, birdY - birdSize),
(birdX + birdSize, birdY - birdSize),
(birdX - birdSize, birdY + birdSize),
(birdX + birdSize, birdY + birdSize)]
obstacleX1, obstacleY1 = (self.x - self.width // 2,
self.y - self.gapSize // 2)
obstacleX2, obstacleY2 = (self.x + self.width // 2,
self.y + self.gapSize // 2)
for (cornerX, cornerY) in birdCorners:
if ((obstacleX1 <= cornerX <= obstacleX2) and
not (obstacleY1 <= cornerY <= obstacleY2)):
return True
return False
def isOffScreen(self):
if self.x <= self.gapSize // 2:
return True
return False
###########################################################
def keyPressed(event, data):
if (event.keysym == "space"):
data.bird.onThrust()
def mousePressed(event, data):
pass
def checkCollision(data):
birdX, birdY = data.bird.getLocation()
birdSize = data.bird.getSize()
for obstacle in data.obstacles:
if (obstacle.isColliding(birdX, birdY, birdSize)):
data.gameOver = True
return
def moveObstacles(data):
for obstacle in data.obstacles:
if obstacle.isOffScreen():
data.obstacles.remove(obstacle)
for obstacle in data.obstacles:
obstacle.move()
def makeNewObstacle(data):
if (data.totalTime % data.obstacleFreq == 0):
data.obstacles.append(Obstacle(data.gapSize, data.obstacleWidth,
data.width, data.height))
def timerFired(data):
data.totalTime += data.timerDelay
if (not data.gameOver):
makeNewObstacle(data)
data.bird.move()
moveObstacles(data)
checkCollision(data)
def redrawAll(canvas, data):
if (not data.gameOver):
data.bird.draw(canvas)
for obstacle in data.obstacles:
obstacle.draw(canvas)
else:
canvas.create_rectangle(0, 0, data.width, data.height, fill="yellow")
def init(data):
birdX, birdY = data.width // 3, data.height // 2
birdSize = data.height // 20
data.bird = Bird(birdX, birdY, birdSize, data.width, data.height)
data.obstacles = []
data.obstacleFreq = 4000
data.obstacleWidth = data.width // 6
data.gapSize = data.height // 4
data.totalTime = 0
data.gameOver = False
def run(width=300, height=300):
def redrawAllWrapper(canvas, data):
canvas.delete(ALL)
redrawAll(canvas, data)
canvas.update()
def mousePressedWrapper(event, canvas, data):
mousePressed(event, data)
redrawAllWrapper(canvas, data)
def keyPressedWrapper(event, canvas, data):
keyPressed(event, data)
redrawAllWrapper(canvas, data)
def timerFiredWrapper(canvas, data):
timerFired(data)
redrawAllWrapper(canvas, data)
canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
# Set up data and call init
class Struct(object): pass
data = Struct()
data.width = width
data.height = height
data.timerDelay = 100 # milliseconds
init(data)
# create the root and the canvas
root = Tk()
canvas = Canvas(root, width=data.width, height=data.height)
canvas.pack()
# set up events
root.bind("<Button-1>", lambda event:
mousePressedWrapper(event, canvas, data))
root.bind("<Key>", lambda event:
keyPressedWrapper(event, canvas, data))
timerFiredWrapper(canvas, data)
# and launch the app
root.mainloop() # blocks until window is closed
print("bye!")
run(800, 800)