import pgzrun
import random
import time

# 窗口参数
WIDTH = 1920
HEIGHT = 1080
TITLE = "Ping_Pang"

# 计时变量
start_time = time.perf_counter()
elapsed_time = 0
TIME_LIMIT = 60  # 分数模式限时60秒

# 游戏状态：menu / playing / gameover
game_state = "menu"
# mode 1=Score Mode(1分钟限时)  2=Game Over Mode
game_mode = 1

#分数
scorep1 = 0
scorep2 = 0
# 防重复加分标记
hit_paddle1 = False
hit_paddle2 = False

#随机方块坐标
random_intX = random.randint(235, 1685)
random_intY = random.randint(235, 845)

# 背景音乐
music.set_volume(0.8)
music.play('bgm')

# 左右球拍
paddle1 = Actor("1")
paddle1.x = 10
paddle1.y = HEIGHT / 2
paddle_speed = 8

paddle2 = Actor("2")
paddle2.x = WIDTH - 10
paddle2.y = HEIGHT / 2

# 障碍方块
tbox = Actor("t_box")
tbox.x = random_intX
tbox.y = HEIGHT / 2

# 乒乓球
ball = Actor("ball")
ball.pos = (WIDTH//2, HEIGHT//2)
ball_speed_x = 7
ball_speed_y = 7

lose_text = ""

# 球拍上下限位
half_h = paddle1.height / 2
top = half_h
bottom = HEIGHT - half_h

bg = Actor("bg")

def draw():
    global elapsed_time
    screen.clear()
    bg.draw()

    # 开局选择菜单界面
    if game_state == "menu":
        screen.draw.text("PING PONG GAME", center=(WIDTH//2, 200), fontsize=90, color="white")
        screen.draw.text("Please select game mode", center=(WIDTH//2, 320), fontsize=45, color="yellow")
        screen.draw.text("Press D - Score Mode (1 minute time limit)", center=(WIDTH//2, 420), fontsize=40, color="white")
        screen.draw.text("Ball out of bounds → add score, ball reset to center", center=(WIDTH//2, 470), fontsize=28, color="#cccccc")
        screen.draw.text("Press F - Game Over Mode", center=(WIDTH//2, 570), fontsize=40, color="white")
        screen.draw.text("Ball out of bounds → opponent wins, game end", center=(WIDTH//2, 620), fontsize=28, color="#cccccc")
        return

    # 游戏进行画面
    paddle1.draw()
    paddle2.draw()
    ball.draw()
    tbox.draw()

    # 左右分数
    screen.draw.text(f'Player 1 Score: {scorep1}', (15,10), color=(255,255,255), fontsize=30)
    screen.draw.text(f'Player 2 Score: {scorep2}', (1700,10), color=(255,255,255), fontsize=30)

    # 顶部居中计时，区分限时模式显示剩余时间
    if game_mode == 1:
        remain = TIME_LIMIT - elapsed_time
        if remain < 0:
            remain = 0
        screen.draw.text(f"Time Left: {remain:.1f} s", center=(WIDTH//2, 12), color=(255,255,255), fontsize=32)
    else:
        screen.draw.text(f"Time: {elapsed_time:.2f} s", center=(WIDTH//2, 12), color=(255,255,255), fontsize=32)

    # 游戏结束提示
    if game_state == "gameover":
        screen.draw.text(lose_text, center=(WIDTH//2, HEIGHT//2), fontsize=80, color="red")
        screen.draw.text("Press SPACE to restart", center=(WIDTH//2, HEIGHT//2+80), fontsize=40, color="white")

def update():
    global ball_speed_x, ball_speed_y, game_state, lose_text
    global scorep1, scorep2, hit_paddle1, hit_paddle2
    global random_intX, random_intY, elapsed_time, start_time

    # 菜单界面不运行游戏逻辑
    if game_state == "menu":
        return

    # 游戏进行中刷新计时
    if game_state == "playing":
        elapsed_time = time.perf_counter() - start_time
        # 分数模式计时到60秒结束游戏
        if game_mode == 1 and elapsed_time >= TIME_LIMIT:
            game_state = "gameover"
            if scorep1 > scorep2:
                lose_text = "Player 1 Win!"
            elif scorep2 > scorep1:
                lose_text = "Player 2 Win!"
            else:
                lose_text = "Draw!"
            sounds.zhanbai.play()

    hit_paddle1 = False
    hit_paddle2 = False

    if game_state != "playing":
        return

    # 左拍 W S
    if keyboard.w and paddle1.y>top:
        paddle1.y -= paddle_speed
    if keyboard.s and paddle1.y<bottom:
        paddle1.y += paddle_speed
    # 右拍 ↑ ↓
    if keyboard.up and paddle2.y>top:
        paddle2.y -= paddle_speed
    if keyboard.down and paddle2.y<bottom:
        paddle2.y += paddle_speed

    # 小球移动
    ball.x += ball_speed_x
    ball.y += ball_speed_y

    # 上下墙壁反弹
    if ball.top <= 0 or ball.bottom >= HEIGHT:
        ball_speed_y *= -1
        sounds.bump.set_volume(1.6)
        sounds.bump.play()

    # 左球拍碰撞加分
    if ball.colliderect(paddle1) and not hit_paddle1:
        ball_speed_x *= -1
        sounds.bump.play()
        scorep1 += 1
        hit_paddle1 = True

    # 右球拍碰撞加分
    if ball.colliderect(paddle2) and not hit_paddle2:
        ball_speed_x *= -1
        sounds.bump.play()
        scorep2 += 1
        hit_paddle2 = True

    # 撞击方块逻辑
    if ball.colliderect(tbox):
        sounds.box_co.play()
        if ball.centerx < tbox.x:
            ball_speed_x = -abs(ball_speed_x) - 1
        else:
            ball_speed_x = abs(ball_speed_x) + 1
        if ball.centery < tbox.y:
            ball_speed_y = -abs(ball_speed_y)
        else:
            ball_speed_y = abs(ball_speed_y)
        random_intX = random.randint(235, 1685)
        random_intY = random.randint(235, 845)
        tbox.x = random_intX
        tbox.y = random_intY

    # 球出界逻辑，区分两种模式
    if ball.left <= 0:
        if game_mode == 1:
            # 计分模式：仅加分，球回中心继续
            scorep2 += 1
            ball.pos = (WIDTH//2, HEIGHT//2)
            ball_speed_x = 7
            ball_speed_y = 7
        else:
            # 出局即结束模式
            game_state = "gameover"
            lose_text = "Player 2 Win!"
            sounds.zhanbai.play()

    if ball.right >= WIDTH:
        if game_mode == 1:
            scorep1 += 1
            ball.pos = (WIDTH//2, HEIGHT//2)
            ball_speed_x = 7
            ball_speed_y = 7
        else:
            game_state = "gameover"
            lose_text = "Player 1 Win!"
            sounds.zhanbai.play()

def on_key_down(key):
    global game_state, ball_speed_x, ball_speed_y, scorep1, scorep2
    global start_time, elapsed_time, game_mode

    # 菜单界面按 D / F 选择模式
    if game_state == "menu":
        if key == keys.D:
            game_mode = 1
            game_state = "playing"
            start_time = time.perf_counter()
            elapsed_time = 0
        elif key == keys.F:
            game_mode = 2
            game_state = "playing"
            start_time = time.perf_counter()
            elapsed_time = 0
        return

    # 游戏结束按空格重启
    if key == keys.SPACE and game_state == "gameover":
        game_state = "playing"
        ball.pos = (WIDTH//2, HEIGHT//2)
        ball_speed_x = 7
        ball_speed_y = 7
        scorep1 = 0
        scorep2 = 0
        start_time = time.perf_counter()
        elapsed_time = 0

pgzrun.go()



