""" dog.py """

import math
import pygame
import random
import sys
from pygame.locals import *

pygame.init()
pygame.key.set_repeat(5,5)
SURFACE = pygame.display.set_mode((400,300))
FPSCLOCK = pygame.time.Clock()
pygame.display.set_caption("DOG & BURGERS")
sysfont = pygame.font.SysFont(None, 24)

class Burger:
    """バーガーオブジェクト"""
    def __init__(self):
        self.x = 0
        self.y = 0
        self.direction = 0
        self.point = 0
        self.status = 0
        self.speed = 0
        self.type = 0
        self.image_burger = pygame.image.load("burger.gif")
        self.image_golden_burger = pygame.image.load("golden_burger.gif")
        
    #表示オン
    def on(self, counter):
        self.direction = random.randint(1,2)
        self.status = 1
        if self.direction == 1:
            self.x = -50
        elif self.direction == 2:
            self.x = 400
        self.y = random.randint(0,200) #初期Y座標(ランダム)
        if counter > 4000 and random.randint(0,149) == 0: #ゴールデンバーガー出現条件
            self.point = 30000
            self.speed = 10
            self.type = 1
            self.image = self.image_golden_burger
        else:
            self.point = 100
            self.speed = random.randint(3,8)
            self.type = 0
            self.image = self.image_burger
        
    #動作
    def move(self, dogx, dogy):
        if self.status == 1:
            if self.direction == 1:
                self.x += self.speed
                if self.x > 400:
                    self.status = 0
            elif self.direction == 2:
                self.x -= self.speed
                if self.x < -50:
                    self.status = 0
            if (self.x - dogx)**2 + (self.y - dogy)**2 * 0.7 < 1000: #衝突判定
                self.status = 0
                return(self.point, self.x, self.y) #戻り値: 得点と座標 
            SURFACE.blit(self.image,(self.x, self.y))
        return(0, self.x, self.y) #戻り値: 得点(0)と座標    

class Snake:
    """蛇オブジェクト"""
    def __init__(self):
        self.x = 0
        self.y = 0
        self.direction = 0
        self.status = 0
        self.speed = 0
        self.image = pygame.image.load("snake.gif")
        
    #表示オン
    def on(self):
        self.direction = random.randint(1,2)
        self.status = 1
        self.speed = random.randint(2,4)
        if self.direction == 1:
            self.x = -50
        elif self.direction == 2:
            self.x = 400
        self.y = 250

    #動作
    def move(self, dogx, dogy):
        if self.status == 1:
            if self.direction == 1:
                self.x += self.speed
                if self.x > 400:
                    self.status = 0
            elif self.direction == 2:
                self.x -= self.speed
                if self.x < -50:
                    self.status = 0
            if ((self.x - dogx)**2 * 1.3) + (self.y - dogy)**2 * 0.7 < 1000: #衝突判定
                self.status = 0
                SURFACE.blit(self.image,(self.x, self.y))
                return(1) #戻り値: ゲームオーバーフラグ
            SURFACE.blit(self.image,(self.x, self.y))
        return(0) #戻り値: ゲームオーバーフラグ(0)

class Bird(Snake):
    """鳥オブジェクト(蛇クラスから継承)"""
    def __init__(self):
        super().__init__()
        self.image_bird_right = pygame.image.load("bird1.gif")
        self.image_bird_left = pygame.image.load("bird2.gif")
    
    #表示オン
    def on(self):
        self.direction = random.randint(1,2)
        self.status = 1
        self.speed = random.randint(4,6)
        self.dy = random.randint(0,1)*2-1
        if self.direction == 1:
            self.x = -50
            self.image = self.image_bird_right
        elif self.direction == 2:
            self.x = 400
            self.image = self.image_bird_left
        self.y = random.randint(0,200)
      
    #動作
    def move(self, dogx, dogy):
        if self.status == 1:
            if self.direction == 1:
                self.x += self.speed
                if self.x > 400:
                    self.status = 0
            elif self.direction == 2:
                self.x -= self.speed
                if self.x < -50:
                    self.status = 0
            self.y += self.dy
            if self.y > 200:
                self.y = 200
                self.dy = -self.dy
            if self.y < 0:
                self.y = 0
                self.dy = -self.dy
            if ((self.x - dogx)**2 * 1.3) + (self.y - dogy)**2 * 0.7 < 1000: #衝突判定
                self.status = 0
                SURFACE.blit(self.image,(self.x, self.y))
                return(1) #戻り値: ゲームオーバーフラグ
            SURFACE.blit(self.image,(self.x, self.y))
        return(0) #戻り値: ゲームオーバーフラグ(0)

class Hedgehog(Snake):
    """ハリネズミオブジェクト(蛇クラスから継承)"""
    def __init__(self):
        super().__init__()
        self.image_hedgehog = pygame.image.load("hedgehog.gif")
        self.image_hedgehog_jump1 = pygame.image.load("hedgehog_jump1.gif")
        self.image_hedgehog_jump2 = pygame.image.load("hedgehog_jump2.gif")

    #表示オン
    def on(self):
        self.direction = random.randint(1,2)
        self.status = 1
        self.speed = random.randint(4,5)
        self.jump_up = 0
        if self.direction == 1:
            self.x = -50
        elif self.direction == 2:
            self.x = 400
        self.y = 250
        self.image = self.image_hedgehog
       
    #動作
    def move(self, dogx, dogy):
        if self.status > 0:
            if self.status < 20:
                self.status += 1
            if self.status == 20:
                self.jump_up += 2
                self.image = self.image_hedgehog_jump1
                if (self.jump_up >= 8 and random.randint(0,4) == 0) or self.jump_up >= 24:
                    self.status = 21
            if self.status == 21:
                if self.direction == 1:
                    self.x += self.speed
                    if self.x > 400:
                        self.status = 0
                elif self.direction == 2:
                    self.x -= self.speed
                    if self.x < -50:
                        self.status = 0       
                self.y -= self.jump_up
                self.jump_up -= 1
                self.image = self.image_hedgehog_jump2
                if self.y > 250:
                    self.y = 250
                    self.status = 1
                    self.image = self.image_hedgehog
            if ((self.x - dogx)**2 * 1.3) + (self.y - dogy)**2 * 0.7 < 1000: #衝突判定
                self.status = 0
                SURFACE.blit(self.image,(self.x, self.y))
                return(1) #戻り値: ゲームオーバーフラグ
            SURFACE.blit(self.image,(self.x, self.y))
        return(0) #戻り値: ゲームオーバーフラグ(0)

class Point:
    """得点表示オブジェクト"""
    def __init__(self):
        self.x = 0
        self.y = 0
        self.status = 0
        self.point = 0
        self.combo = 0

    #表示オン
    def on(self, x, y, point, combo):
        self.x = x
        self.y = y + 15
        self.status = 20
        self.point = point
        self.combo = combo
 
    #得点表示
    def indication(self):
        self.status -= 1
        if self.status > 0:
            if self.point < 10000:
                count_image = sysfont.render(
                    "{} x {}".format(self.point, self.combo), True, (0,0,255))
                SURFACE.blit(count_image, (self.x, self.y))
            else:
                count_image = sysfont.render(
                    " {} ".format(self.point), True, (255, 0, 0))
                SURFACE.blit(count_image, (self.x, self.y + 20))  

#イメージ設定
image_background = pygame.image.load("coast.jpg")
image_title = pygame.image.load("title_small.gif")
image_gameover = pygame.image.load("gameover_small.gif")
image_dog = pygame.image.load("dog.gif")
image_dog_jump1 = pygame.image.load("dog_jump1.gif")
image_dog_jump2 = pygame.image.load("dog_jump2.gif")

def score_indication(score, best_score):
    """ スコア表示 """
    count_image = sysfont.render(
        "Best Score: {}".format(best_score), True, (0,0,0))
    SURFACE.blit(count_image, (10,2))
    count_image = sysfont.render(
        "Your Score: {}".format(score), True, (0,0,0))
    SURFACE.blit(count_image, (200,2))

def main():
    """ メインルーチン """
    #変数初期設定(ループ前)
    best_score = 0
    score = 0
    gameover_flag = 2

    #バーガーオブジェクト初期設定
    burger = []
    for i in range(40): 
        burger.append(0)
        burger[i] = Burger()

    #蛇オブジェクト初期設定
    snake = []
    for i in range(3): 
        snake.append(0)
        snake[i] = Snake()

    #鳥オブジェクト初期設定
    bird = []
    for i in range(3): 
        bird.append(0)
        bird[i] = Bird()

    #ハリネズミオブジェクト初期設定
    hedgehog = []
    for i in range(3): 
        hedgehog.append(0)
        hedgehog[i] = Hedgehog()

    #得点表示オブジェクト初期設定
    point_ind = []
    for i in range(20):
        point_ind.append(0)
        point_ind[i] = Point()

    #効果音
    sound_jump = pygame.mixer.Sound("jump.wav")
    sound_jump.set_volume(0.5)
    sound_eat = pygame.mixer.Sound("eat.wav")
    sound_eat.set_volume(1.0)
    sound_bonus = pygame.mixer.Sound("bonus.wav")
    sound_bonus.set_volume(1.0)
    sound_miss = pygame.mixer.Sound("miss.wav")
    sound_miss.set_volume(1.0)

    #BGM
    pygame.mixer.music.load("bgm.wav")

    while True:

        #変数設定(タイトル)
        a = 0
        counter = 0

        #画面塗りつぶし(背景描写)
        SURFACE.blit(image_background,(0,0))

        #タイトル表示
        SURFACE.blit(image_title,(50,80))

        #スコア表示
        score_indication(score, best_score)

        #説明書き&クレジット表示
        count_image = sysfont.render(
            "Press Space Key to Start", True, (0,0,0))
        SURFACE.blit(count_image, (105,160))
        count_image = sysfont.render(
            "© 2017 KUNISAN.JP", True, (0,0,0))
        SURFACE.blit(count_image, (125,250))

        #ループ1 (タイトル画面)
        while gameover_flag == 2:
                   
            #ウィンドウ閉じるボタン
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                    
            #キー入力判定   
            pressed = pygame.key.get_pressed()
            if pressed[K_SPACE]:
                a = 1
            elif pressed[K_SPACE] == 0 and a == 1:
                a = 0
                gameover_flag = 0

            #画面アップデート
            pygame.display.update()
            FPSCLOCK.tick(30)

        #変数設定(ゲーム)
        a = 0
        counter = 0
        score = 0
        burger_point = 0
        burger_combo = 0
        x = 175
        y = 250
        jump_up = 0
        jump_status = 0
        burger_counter = 0
        burger_interval = 50
        snake_counter = 0
        snake_interval = 500
        bird_counter = 0
        bird_interval = 1700
        hedgehog_counter = 0
        hedgehog_interval = 3500
        point_x = 0
        point_y = 0
        point_ind_counter = 0
        for i in range(len(burger)):
            burger[i].status = 0
        for i in range(len(snake)):
            snake[i].status = 0
        for i in range(len(bird)):
            bird[i].status = 0
        for i in range(len(hedgehog)):
            hedgehog[i].status = 0
        for i in range(len(point_ind)):
            point_ind[i].status = 0

        #BGM再生
        pygame.mixer.music.play()
        
        #ループ2 (メインループ)
        while gameover_flag == 0:

            counter += 1

            #ウィンドウ閉じるボタン
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                    
            #キー入力判定   
            pressed = pygame.key.get_pressed()
            if pressed[K_LEFT] and x > 0:
                        x -= 5
            if pressed[K_RIGHT] and x < 350:
                        x += 5
            if pressed[K_SPACE] and jump_status < 2: #ジャンプ準備
                        jump_status = 1
                        jump_up += 2
                        if jump_up < 8:
                            jump_up = 8
                        elif jump_up > 24:
                            jump_up = 24
                        
            if pressed[K_SPACE] == 0 and jump_status == 1: #ジャンプ開始
                sound_jump.play()
                jump_status = 2

            if jump_status == 2: #ジャンプ中
                y -= jump_up
                jump_up -= 1
                if y > 250: #ジャンプ終了
                    y = 250
                    jump_status = 0
                    burger_combo = 0

            #画面塗りつぶし(背景描写)
            SURFACE.blit(image_background,(0,0))
            
            #犬表示
            if jump_status == 0:
                SURFACE.blit(image_dog,(x,y))
            elif jump_status == 1:
                SURFACE.blit(image_dog_jump1,(x,y))
            elif jump_status == 2:
                SURFACE.blit(image_dog_jump2,(x,y))

            #バーガー処理
            if counter % burger_interval == 0:
                burger[burger_counter].on(counter)
                burger_counter += 1
                if burger_counter >= len(burger):
                    burger_counter = 0
            if counter % 75 == 0:
                burger_interval -= 1
                if burger_interval < 5:
                    burger_interval = 5

            #バーガー表示        
            for i in range(len(burger)):
                #バーガー得点&座標取得 
                (burger_point, point_x, point_y) = burger[i].move(x,y)
                if burger_point > 0:
                    sound_eat.play()
                    burger_combo += 1
                    if burger_point < 10000:
                        score += burger_point * burger_combo
                        point_ind[point_ind_counter].on(point_x, point_y, burger_point, burger_combo)
                    else:
                        sound_bonus.play()
                        score += burger_point
                        point_ind[point_ind_counter].on(point_x, point_y, burger_point, 1)
                    point_ind_counter += 1
                    if point_ind_counter >= len(point_ind):
                        point_ind_counter = 0
                    if burger_combo == 10: #コンボ10でボーナス10000点
                        sound_bonus.play()
                        score += 10000
                        point_ind[point_ind_counter].on(point_x, point_y, 10000, 1)
                        point_ind_counter += 1
                        if point_ind_counter >= len(point_ind):
                            point_ind_counter = 0

            #蛇処理
            if counter % snake_interval == 0 and snake[snake_counter].status == 0:
                snake[snake_counter].on()
                snake_counter += 1
                if snake_interval > 500:
                    snake_interval = 299
                if snake_counter >= len(snake):
                    snake_counter = 0
            if counter % 501 == 0:
                snake_interval -= random.randint(20, 100)
                if snake_interval < 10:
                    snake_interval += random.randint(100, 300)

            #蛇表示        
            for i in range(len(snake)):
                #ゲームオーバーフラグ取得 
                a = snake[i].move(x,y)
                if a == 1:
                    gameover_flag = 1

            #鳥処理
            if counter % bird_interval == 0 and bird[bird_counter].status == 0:
                bird[bird_counter].on()
                bird_counter += 1
                if bird_interval > 1000:
                    bird_interval = 299
                if bird_counter >= len(bird):
                    bird_counter = 0
            if counter % 501 == 0:
                bird_interval -= random.randint(20, 100)
                if bird_interval < 50:
                    bird_interval += random.randint(100, 300)

            #鳥表示        
            for i in range(len(bird)):
                #ゲームオーバーフラグ取得 
                a = bird[i].move(x,y)
                if a == 1:
                    gameover_flag = 1

            #ハリネズミ処理
            if counter % hedgehog_interval == 0 and hedgehog[hedgehog_counter].status == 0:
                hedgehog[hedgehog_counter].on()
                if counter > 4500:
                    hedgehog_counter += 1
                if hedgehog_interval > 900:
                    hedgehog_interval = 299
                if hedgehog_counter >= len(hedgehog):
                    hedgehog_counter = 0
            if counter % 501 == 0:
                hedgehog_interval -= random.randint(20, 100)
                if hedgehog_interval < 200:
                    hedgehog_interval += random.randint(100, 300)

            #ハリネズミ表示        
            for i in range(len(hedgehog)):
                #ゲームオーバーフラグ取得 
                a = hedgehog[i].move(x,y)
                if a == 1:
                    gameover_flag = 1

            #得点表示
            for i in range(len(point_ind)):
                point_ind[i].indication()
        
            #スコア表示
            if score > best_score:
                best_score = score
            score_indication(score, best_score)

            #画面アップデート
            pygame.display.update()
            FPSCLOCK.tick(30)

            #BGM再生確認&リピート
            if pygame.mixer.music.get_busy() == 0:
                pygame.mixer.music.play()

        #変数設定(ゲームオーバー)
        a = 0
        counter = 0

        #BGM停止
        pygame.mixer.music.stop()
        sound_miss.play()

        #ゲームオーバー表示
        SURFACE.blit(image_gameover,(75,130))

        #ループ3 (ゲームオーバー)
        while gameover_flag == 1:

            counter += 1
            if counter >= 150:
                gameover_flag = 2
                   
            #ウィンドウ閉じるボタン
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()

            #キー入力判定   
            pressed = pygame.key.get_pressed()
            if pressed[K_SPACE] == 0 and a == 0:
                a = 1
            elif pressed[K_SPACE] and a == 1:
                a = 2
            elif pressed[K_SPACE] == 0 and a == 2:
                a = 0
                gameover_flag = 2

            #画面アップデート
            pygame.display.update()
            FPSCLOCK.tick(30)

if __name__ == '__main__':
    main()