Compare commits

..

6 Commits

Author SHA1 Message Date
Frank
af719d3720 声音 2026-06-22 09:34:10 +08:00
Frank
638aaf36b5 声音 2026-06-22 09:30:22 +08:00
Frank
ca2d07272a add the menu of two mode and the timer 2026-06-18 10:57:08 +08:00
Frank
ed26cee5c5 111 2026-06-17 15:32:42 +08:00
Frank
30d1934359 这里写本次修改说明 2026-06-17 14:56:33 +08:00
b43e424640 Update README.md 2026-06-17 06:48:40 +00:00
3 changed files with 143 additions and 44 deletions

View File

@@ -1,11 +1,7 @@
# Ping Pong Game # Ping Pong Game
This ping_pong game made by frank This ping_pong game made by frank
<<<<<<< HEAD
![Game Cover](https://api.yppp.net/pc.php)
=======
![Game Cover](https://cocktailhourentertainment.com/wp-content/uploads/2022/07/atari-pong-arcade-1920x1080-3.jpg) ![Game Cover](https://cocktailhourentertainment.com/wp-content/uploads/2022/07/atari-pong-arcade-1920x1080-3.jpg)
>>>>>>> 2d13872febf768c59aec106182ed404dbbf57614
## Setup & Run ## Setup & Run
Install the required dependency and start the game with the following commands: Install the required dependency and start the game with the following commands:

183
main.py
View File

@@ -1,45 +1,58 @@
import pgzrun import pgzrun
<<<<<<< HEAD
import random import random
import time
#随机数生成
random_intX = random.randint(235, 1685)
random_intY = random.randint(235, 845)
=======
>>>>>>> 2d13872febf768c59aec106182ed404dbbf57614
music.play('bgm')
# 窗口参数 # 窗口参数
WIDTH = 1920 WIDTH = 1920
HEIGHT = 1080 HEIGHT = 1080
TITLE = "Ping_Pang" 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 = Actor("1")
paddle1.x = 80 paddle1.x = 10
paddle1.y = HEIGHT / 2 paddle1.y = HEIGHT / 2
paddle_speed = 8 paddle_speed = 8
paddle2 = Actor("2") paddle2 = Actor("2")
paddle2.x = WIDTH - 80 paddle2.x = WIDTH - 10
paddle2.y = HEIGHT / 2 paddle2.y = HEIGHT / 2
<<<<<<< HEAD # 障碍方块
#box生成
tbox = Actor("t_box") tbox = Actor("t_box")
tbox.x = random_intX tbox.x = random_intX
tbox.y = HEIGHT / 2 tbox.y = HEIGHT / 2
=======
>>>>>>> 2d13872febf768c59aec106182ed404dbbf57614
# 乒乓球 # 乒乓球
ball = Actor("ball") ball = Actor("ball")
ball.pos = (WIDTH//2, HEIGHT//2) ball.pos = (WIDTH//2, HEIGHT//2)
ball_speed_x = 7 ball_speed_x = 7
ball_speed_y = 7 ball_speed_y = 7
# 游戏状态: playing / gameover
game_state = "playing"
lose_text = "" lose_text = ""
# 球拍上下限位 # 球拍上下限位
@@ -50,23 +63,70 @@ bottom = HEIGHT - half_h
bg = Actor("bg") bg = Actor("bg")
def draw(): def draw():
global elapsed_time
screen.clear() screen.clear()
bg.draw() 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() paddle1.draw()
paddle2.draw() paddle2.draw()
ball.draw() ball.draw()
<<<<<<< HEAD
tbox.draw() tbox.draw()
=======
>>>>>>> 2d13872febf768c59aec106182ed404dbbf57614 # 左右分数
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": if game_state == "gameover":
screen.draw.text(lose_text, center=(WIDTH//2, HEIGHT//2), fontsize=80, color="red") screen.draw.text(lose_text, center=(WIDTH//2, HEIGHT//2), fontsize=80, color="red")
screen.draw.text("click space to restar", center=(WIDTH//2, HEIGHT//2+80), fontsize=40, color="white") screen.draw.text("Press SPACE to restart", center=(WIDTH//2, HEIGHT//2+80), fontsize=40, color="white")
def update(): def update():
global ball_speed_x, ball_speed_y, game_state, lose_text 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": if game_state != "playing":
return return
@@ -88,51 +148,94 @@ def update():
# 上下墙壁反弹 # 上下墙壁反弹
if ball.top <= 0 or ball.bottom >= HEIGHT: if ball.top <= 0 or ball.bottom >= HEIGHT:
ball_speed_y *= -1 ball_speed_y *= -1
sounds.bump.set_volume(1.6)
sounds.bump.play() sounds.bump.play()
# 球拍碰撞反弹 # 球拍碰撞加分
if ball.colliderect(paddle1) or ball.colliderect(paddle2): if ball.colliderect(paddle1) and not hit_paddle1:
ball_speed_x *= -1 ball_speed_x *= -1
sounds.bump.play() sounds.bump.play()
<<<<<<< HEAD scorep1 += 1
#方块实现 hit_paddle1 = True
if ball.colliderect(tbox):
# 右球拍碰撞加分
if ball.colliderect(paddle2) and not hit_paddle2:
ball_speed_x *= -1
sounds.bump.play() sounds.bump.play()
# 判断撞方块左侧/右侧翻转X速度 scorep2 += 1
hit_paddle2 = True
# 撞击方块逻辑
if ball.colliderect(tbox):
sounds.box_co.play()
if ball.centerx < tbox.x: if ball.centerx < tbox.x:
ball_speed_x = -abs(ball_speed_x) - 1 ball_speed_x = -abs(ball_speed_x) - 1
else: else:
ball_speed_x = abs(ball_speed_x) + 1 ball_speed_x = abs(ball_speed_x) + 1
# 判断撞方块上侧/下侧翻转Y速度
if ball.centery < tbox.y: if ball.centery < tbox.y:
ball_speed_y = -abs(ball_speed_y) ball_speed_y = -abs(ball_speed_y)
else: else:
ball_speed_y = abs(ball_speed_y) ball_speed_y = abs(ball_speed_y)
# 重新生成方块坐标(现在能修改全局变量)
random_intX = random.randint(235, 1685) random_intX = random.randint(235, 1685)
random_intY = random.randint(235, 845) random_intY = random.randint(235, 845)
tbox.x = random_intX tbox.x = random_intX
tbox.y = random_intY tbox.y = random_intY
=======
>>>>>>> 2d13872febf768c59aec106182ed404dbbf57614
# 出左右边界直接失败 # 球出界逻辑,区分两种模式
if ball.left <= 0: if ball.left <= 0:
game_state = "gameover" if game_mode == 1:
lose_text = "player 1 win!" # 计分模式:仅加分,球回中心继续
sounds.zhanbai.play() scorep2 += 1
if ball.right >= WIDTH: ball.pos = (WIDTH//2, HEIGHT//2)
game_state = "gameover" ball_speed_x = 7
lose_text = "player 2 win!" ball_speed_y = 7
sounds.zhanbai.play() 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): def on_key_down(key):
global game_state, ball_speed_x, ball_speed_y 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": if key == keys.SPACE and game_state == "gameover":
game_state = "playing" game_state = "playing"
ball.pos = (WIDTH//2, HEIGHT//2) ball.pos = (WIDTH//2, HEIGHT//2)
ball_speed_x = 7 ball_speed_x = 7
ball_speed_y = 7 ball_speed_y = 7
scorep1 = 0
scorep2 = 0
start_time = time.perf_counter()
elapsed_time = 0
pgzrun.go() pgzrun.go()

BIN
sounds/box_co.wav Normal file

Binary file not shown.