コード例 #1
0
ファイル: driver.py プロジェクト: rautamiekka/duckhunt
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())
コード例 #2
0
class Tower:
    def __init__(self, i, x, y, s, t=0):
        self.identity = i
        self.x = x
        self.y = y
        self.size = s
        self.t_num = t
        self.box = pygame.Rect((self.x, self.y), (self.size, self.size))
        self.level = 1
        self.__c_mod = 1.0  # gets smaller
        self.coolness = 0  # 0 means ready to shoot
        self.__r_mod = 1.0  # gets bigger
        self.__p_mod = 1.0  # gets bigger
        self.__s_mod = 1.0  # gets bigger
        self.gun = Gun((self.x, self.y), s, t, tower_colors[self.t_num],
                       self.level)
        self.upgrade_cost = 10
        self.follow_mouse = False
        self.show_r = False
        self.font = pygame.font.SysFont('Century Gothic', 12)

    def color(self):
        return tower_colors[self.t_num]

    def cooldown(self):
        return enums.tower_cooldown[self.t_num] * self.__c_mod

    def range(self):
        return (enums.tower_range[self.t_num] * self.__r_mod *
                self.size) + self.size / 2

    def power(self):
        return enums.tower_power[self.t_num] * self.__p_mod

    def speed(self):
        return enums.tower_speed[self.t_num] * self.__s_mod

    def t_type(self):
        return enums.TowerType(self.t_num)

    def pos(self):
        return self.x, self.y

    def render(self, surf):
        if self.t_num == 0 or self.t_num == 7:  # PATH = 7, ZEROTOWER = 0
            pass
        else:
            pygame.draw.circle(surf, self.color(), self.box.center,
                               self.size // 2, 4)
            self.gun.render(surf)
            text = self.font.render(str(self.level), False, self.color())
            surf.blit(text, (self.pos()[0] + 15, self.pos()[1] + 10))
            if self.show_r:
                pygame.draw.circle(surf, red, self.box.center,
                                   int(self.range()), 1)

    def update(self, enemies, on_screen_shots, register):
        if self.t_num != 0 and self.t_num != 7:
            aim_spot = (0, 0)
            for e in enemies:
                if is_in_circle(e.center(), self.box.center, self.range()):
                    aim_spot = e.pos()
                    if self.coolness <= 0:
                        on_screen_shots.append(
                            Shot(self.box.center, e.id, self.color(),
                                 self.speed(), self.power()))
                        register(on_screen_shots[
                            len(on_screen_shots) -
                            1])  # register this bullet to be drawn
                        if self.t_num == 1:
                            on_screen_shots[len(on_screen_shots) -
                                            1].poison = True
                        if self.t_num == 2:
                            on_screen_shots[len(on_screen_shots) -
                                            1].ice = True
                        self.coolness = self.cooldown()
                        break
            if self.coolness > 0:
                self.coolness -= 1
            # point at the first enemy in range
            self.gun.update(aim_spot)

    def move(self, pos):
        self.x = pos[0]
        self.y = pos[1]
        self.gun.x = pos[0]
        self.gun.y = pos[1]
        self.box = pygame.Rect((self.x, self.y), (self.size, self.size))

    def is_in(self, pos):
        if self.x < pos[0] < self.x + self.size:
            if self.y < pos[1] < self.y + self.size:
                return True
        return False

    def upgrade(self):
        self.__c_mod -= 0.05  # gets smaller
        self.__r_mod += 0.07  # gets bigger
        self.__p_mod += 1.0  # gets bigger
        # self.__s_mod += 0.5  # gets bigger
        self.upgrade_cost += (self.upgrade_cost / 2)
        self.upgrade_cost = int(self.upgrade_cost * 1.5)
        self.level += 1

    def show_range(self, mouse):
        if self.is_in(mouse):
            self.show_r = True
        else:
            self.show_r = False