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.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.ytop: paddle2.y -= paddle_speed if keyboard.down and paddle2.y= HEIGHT: ball_speed_y *= -1 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()