forked from aosyborg/duckhunt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdriver.py
174 lines (152 loc) · 5.77 KB
/
driver.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
import os, sys, time, pygame, gun, duck
from gun import Gun
from duck import Duck
HIT_POSITION = 245, 440
HIT_RECT = 0, 0, 287, 43
HIT_DUCK_POSITION = 329, 445
HIT_DUCK_WHITE_RECT = 217, 43, 19, 16
HIT_DUCK_RED_RECT = 199, 43, 19, 16
SCORE_POSITION = 620, 440
SCORE_RECT = 69, 43, 130, 43
FONT = os.path.join('media', 'arcadeclassic.ttf')
FONT_STARTING_POSITION = 730, 442
ROUND_POSITION = 60, 410
NOTICE_POSITION = 370, 120
NOTICE_RECT = 0, 86, 128, 63
NOTICE_WIDTH = 128
NOTICE_LINE_1_HEIGHT = 128
NOTICE_LINE_2_HEIGHT = 150
class Driver(object):
def __init__(self, surface):
self.surface = surface
self.gun = Gun(surface)
self.ducks = [Duck(surface), Duck(surface)]
self.round = 1
self.phase = 'start'
self.score = 0
self.timer = int(time.time())
self.roundTime = 10 # Seconds in a round
self.controlImgs = pygame.image.load(os.path.join('media', 'screenobjects.png'))
self.hitDucks = [False for i in range(10)]
self.hitDuckIndex = 0
self.nextRoundSound = os.path.join('media', 'next-round.mp3')
self.flyawaySound = os.path.join('media', 'flyaway.mp3')
self.notices = ()
def handleEvent(self, event):
# If we are in the shooting phase, pass event off to the gun
if event.type == pygame.MOUSEMOTION:
self.gun.moveCrossHairs(event.pos)
elif event.type == pygame.MOUSEBUTTONDOWN:
gunFired = self.gun.shoot()
for duck in self.ducks:
if gunFired:
if duck.isShot(event.pos):
self.score += 10
self.hitDucks[self.hitDuckIndex] = True
self.hitDuckIndex += 1
else:
duck.flyOff = True
def update(self):
allDone = False
# Update game based on phase
if self.phase == 'start':
self.startRound()
elif self.phase == 'shoot':
# Update all ducks
for duck in self.ducks:
duck.update(self.round)
self.manageRound()
elif self.phase == 'end':
self.endRound()
def render(self):
# If there is a notice, display and return
if len(self.notices) > 0:
font = pygame.font.Font(FONT, 20)
text = font.render(str(self.notices[0]), True, (255, 255, 255));
x, y = NOTICE_POSITION
x = x + (NOTICE_WIDTH - text.get_width()) / 2
y = NOTICE_LINE_1_HEIGHT
self.surface.blit(self.controlImgs, NOTICE_POSITION, NOTICE_RECT)
self.surface.blit(text, (x, y));
if len(self.notices) > 1:
text = font.render(str(self.notices[1]), True, (255, 255, 255));
x, y = NOTICE_POSITION
x = x + (NOTICE_WIDTH - text.get_width()) / 2
y = NOTICE_LINE_2_HEIGHT
self.surface.blit(text, (x, y));
return
# Show the ducks
for duck in self.ducks:
duck.render()
# Show round number
font = pygame.font.Font(FONT, 20)
text = font.render(("R= %d" % self.round), True, (154, 233, 0), (0, 0, 0));
self.surface.blit(text, ROUND_POSITION);
# Show the hit counter
self.surface.blit(self.controlImgs, HIT_POSITION, HIT_RECT)
startingX, startingY = HIT_DUCK_POSITION
for i in range(10):
x = startingX + (19 * i)
y = startingY
if self.hitDucks[i]:
self.surface.blit(self.controlImgs, (x, y), HIT_DUCK_RED_RECT)
else:
self.surface.blit(self.controlImgs, (x, y), HIT_DUCK_WHITE_RECT)
# Show the score
self.surface.blit(self.controlImgs, SCORE_POSITION, SCORE_RECT)
font = pygame.font.Font(FONT, 20)
text = font.render(str(self.score), True, (255, 255, 255));
x, y = FONT_STARTING_POSITION
x -= text.get_width();
self.surface.blit(text, (x,y));
# Show the cross hairs
self.gun.render()
def manageRound(self):
timer = int(time.time())
# Check round end
timesUp = (timer - self.timer) > self.roundTime
if not (timesUp or (self.ducks[0].isFinished and self.ducks[1].isFinished)):
return
# Let any remaining ducks fly off
for duck in self.ducks:
if not duck.isFinished:
duck.flyOff = True
return
# Check for fly offs and increment the index
for duck in self.ducks:
if not duck.isDead:
self.hitDuckIndex += 1
# Start new around if duck index is at the end
if self.hitDuckIndex >= 9:
pygame.mixer.music.load(self.nextRoundSound)
pygame.mixer.music.play()
self.phase = 'end'
return
# Populate screen with new ducks
self.ducks = [Duck(self.surface), Duck(self.surface)]
self.timer = int(time.time())
self.gun.reloadIt()
def startRound(self):
timer = int(time.time())
self.notices = ("ROUND", self.round)
if (timer - self.timer) > 2:
self.phase = 'shoot'
self.notices = ()
def endRound(self):
# Pause game for new round music to play
while pygame.mixer.music.get_busy():
return
# Count missed ducks - more than 4 and you're done
missedCount = 0
for i in self.hitDucks:
if i == False:
missedCount += 1
if missedCount > 4:
self.notices = ("GAME OVER", "")
return
# Prep for new round
self.round += 1
self.hitDucks = [False for i in range(10)]
self.hitDuckIndex = 0
self.phase = 'start'
self.timer = int(time.time())