-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfruitNinja.py
241 lines (166 loc) · 7.54 KB
/
fruitNinja.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# -*- coding: utf-8 -*-
"""
EECS 332 Fruit Ninja Final Project
written by Alvin Tan
This file will eventually include declarations for objects and a live-stream
with the ability to overlay randomly generated objects over it.
"""
import cv2
import alvinFingerDetection as aFD
import gameObjects as gO
''' First we set up the webcam feed and grab a histogram for skin detection '''
STALL = 5
LEVEL_START_PAUSE = 10
# We open a new window and open access to the video camera
cv2.namedWindow("Squares are Bombs!")
vidFeed = cv2.VideoCapture(0)
# If we have successfully connected to the webcam, we grab a frame
if vidFeed.isOpened():
gotFrame, frame = vidFeed.read()
# Otherwise, we cry
else:
gotFrame = False
x0 = int(vidFeed.get(3)) # Gets the width of the video feed
y0 = int(vidFeed.get(4)) # Gets the length of the video feed
# We generate our skin-tone histogram here
gotHisto = False
histBits = None
# This is the setup time, when we have not yet gotten a histogram yet
while gotFrame and not gotHisto:
frame = cv2.flip(frame, 1)
aFD.drawRect(frame, x0, y0)
# Once all the fruits have been drawn on the frame, we display the frame
cv2.imshow("Squares are Bombs!", frame)
# Then, pause for 10 ms to see if we entered an interrupt key or not
key = cv2.waitKey(STALL)
if key == ord('q'): # Exit on 'q'
break
elif key == ord('h'): # Create skin histogram on 'h'
histBits = aFD.makeHisto(frame, x0, y0)
gotHisto = True
# After displaying the frame, we grab a new frame from the video feed
gotFrame, frame = vidFeed.read()
''' Now we are ready to begin our gameplay '''
# Here we instantiate our levels:
levels = []
levels.append(gO.Level(1, 2, 0, 100))
levels.append(gO.Level(3, 5, 0, 100))
levels.append(gO.Level(3, 5, 1, 100))
levels.append(gO.Level(5, 7, 3, 200))
# We instantiate our score and our lives
score = 0
lives = 3
gameOver = False
# For each of the levels, we do game stuff
for curLevel in range(len(levels)):
# We instantiate our game objects
texts = []
fruits = []
bombs = []
explodedBits = []
# We generate the text for this level
texts.append(gO.Text((10, 50), (0, 255, 0), "Lives: "))
texts.append(gO.Text((int(x0/2)-100, 50), (0, 255, 0), "Level: " + str(curLevel)))
texts.append(gO.Text((x0 - 300, 50), (0, 255, 0), "Score: "+str(score)))
# We generate all of the fruits in this level
for count in range(levels[curLevel].numFruits):
fruits.append(gO.randomFruit(x0, y0))
# We generate all of the bombs in this level
for count in range(levels[curLevel].numBombs):
bombs.append(gO.randomBomb(x0, y0))
startPause = 0
while (startPause < LEVEL_START_PAUSE) and gotFrame:
# Flips the frame horizontally so it's a mirror image. Makes sense while
# facing the screen.
frame = cv2.flip(frame, 1)
gO.Text((int(x0/2)-100, int(y0/2)-25), (0, 0, 0), "LEVEL "+str(curLevel)).write(frame)
gO.Text((int(x0/2)-200, int(y0/2)-75), (0, 0, 0), "Squares are bombs!").write(frame)
cv2.imshow("Squares are Bombs!", frame)
startPause += 1
# After displaying the frame, we grab a new frame from the video feed
gotFrame, frame = vidFeed.read()
# Then, pause for 10 ms to see if we entered an interrupt key or not
if cv2.waitKey(STALL) == ord('q'): # Exit on q
gotFrame = False
break
levelFrames = 0
while gotFrame and not gameOver and levelFrames < levels[curLevel].numFrames:
# Flips the frame horizontally so it's a mirror image. Makes sense while
# facing the screen.
frame = cv2.flip(frame, 1)
# Grab the coordinate of the player's fingertip
fingerTip = aFD.getFingerTip(frame, x0, y0, histBits)
# For each fruit we have,
for count in range(len(fruits)):
# we draw it on screen
fruits[count].draw(frame)
# If our fintertip intersects with the fruit, we explode the fruit
if fruits[count].intersects(fingerTip):
fruits[count].explode(explodedBits)
# Update the score and display the new score
score += levels[curLevel].pointsPerFruit
texts[2] = gO.Text((x0 - 300, 50), (0, 255, 0), "Score: "+str(score))
# Generate a new fruit to replace it
fruits[count] = gO.randomFruit(x0, y0)
# and increment the physics. If the fruit goes offscreen, we remove it
# and implement another randomly generated fruit in its place
if not fruits[count].doPhysics(x0, y0):
fruits[count] = gO.randomFruit(x0, y0)
# For each bomb we have,
for count in range(len(bombs)):
# we draw it on screen
bombs[count].draw(frame)
# If our fingertip intersects with the bomb, we explode the bomb
if bombs[count].intersects(fingerTip):
bombs[count].explode(explodedBits)
# Update the number of lives and checks if you are dead
lives -= 1
if lives <= 0:
gameOver = True
# Generates a new bomb to replace it
bombs[count] = gO.randomBomb(x0, y0)
# and increment the physics
if not bombs[count].doPhysics(x0, y0):
bombs[count] = gO.randomBomb(x0, y0)
# Write all of our text on the screen
for text in texts:
text.write(frame)
# Display the lives we have
for count in range(lives):
cv2.circle(frame, (175 + count*50, 35), 20, (0, 0, 255), -1)
# Let exploded bits continue falling down
for exBit in explodedBits:
exBit.draw(frame)
if not exBit.doPhysics(x0, y0):
explodedBits.remove(exBit)
# Draw in the detected fingertip for troubleshooting purposes
cv2.circle(frame,(fingerTip[1], fingerTip[0]), 10, (0,255,0), -1)
# Once all the fruits have been drawn on the frame, we display the frame
cv2.imshow("Squares are Bombs!", frame)
# Increment the frame counter
levelFrames += 1
# After displaying the frame, we grab a new frame from the video feed
gotFrame, frame = vidFeed.read()
# Then, pause to see if we entered an interrupt key or not
if cv2.waitKey(STALL) == ord('q'): # Exit on q
break
# If the player loses
while gameOver:
# Flips the frame horizontally so it's a mirror image. Makes sense while
# facing the screen.
frame = cv2.flip(frame, 1)
# Write all of our text on the screen
for text in texts:
text.write(frame)
# Writes the game over message
gO.Text((int(x0/2)+10, int(y0/2)-25), (0, 0, 0), "GAME OVER").write(frame)
cv2.imshow("Squares are Bombs!", frame)
if cv2.waitKey(STALL) == ord('q'): # Exit on q
gotFrame = False
break
# Once an interrupt key is entered, or we fail to get another screen,
# we print some statements, release the video feed, and close the window.
print("exited the loop")
vidFeed.release()
print("released video feed")
cv2.destroyAllWindows() # For some reason python always crashes here