用Simplegui模块写了个弹球游戏

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# python 弹球游戏
# Jackie Luo

# 引入simplegui以及random模块
import simplegui
import random

# 初始化全局变量
WIDTH = 600     #画布宽度
HEIGHT = 400    #画布高度   
BALL_RADIUS = 20  #小球半径
PAD_WIDTH = 8     #挡板宽度
PAD_HEIGHT = 80   #挡板高度
HALF_PAD_WIDTH = PAD_WIDTH / 2   
HALF_PAD_HEIGHT = PAD_HEIGHT / 2
LEFT = False      #发球方向-左
RIGHT = True      #发球方向-右


#主题函数部分

#发球
def spawn_ball(direction):
    global ball_pos, ball_vel  # 全局变量,小球位置与速度
    ball_pos = [WIDTH/2, HEIGHT/2]  #初始化小球位置,画布中心
    if direction :    #若方向为右,则随机生成水平垂直速度
        ball_vel = [random.randrange(2,4), random.randrange(1,3)]
    else:             #方向为左,随机生成水平垂直速度
        ball_vel = [random.randrange(-4,-2), random.randrange(1,3)]
    
# 新游戏
def new_game():
    global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel  # 声明全局变量
    global score1, score2  
    score1, score2 = [0, 0]   #初始化分数
    paddle1_pos = [HALF_PAD_WIDTH, HEIGHT/2]  #初始化挡板一位置
    paddle2_pos = [WIDTH - HALF_PAD_WIDTH, HEIGHT/2]   #初始化挡板二位置
    paddle1_vel = [0, 0]  #初始化挡板一速度
    paddle2_vel = [0, 0]  #初始化挡板二速度
    spawn_ball(random.choice([LEFT,RIGHT])) #随机开球
    
    
def draw(canvas):
    global score1, score2, paddle1_pos, paddle2_pos, ball_pos, ball_vel
        
    # 定义画布函数
    canvas.draw_line([WIDTH / 2, 0],[WIDTH / 2, HEIGHT], 1, "White")   #画布中画中线
    canvas.draw_line([PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1, "White")   #左边线
    canvas.draw_line([WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1, "White")  #右边线
        
    # 游戏功能函数
    if ball_pos[0] < PAD_WIDTH + BALL_RADIUS:  #若小球出左边界
        if ball_pos[1] in range(paddle1_pos[1] - PAD_HEIGHT, paddle1_pos[1] + PAD_HEIGHT):  #若小球被左挡板挡住
            ball_vel[0] = ball_vel[0] * -1.1   #水平速度加速10%,方向相反
        else:
            score2 +=1   #若未被挡板挡住,则玩家2记一分
            spawn_ball(RIGHT)  #重新发球
        
    if ball_pos[0] > WIDTH - PAD_WIDTH - BALL_RADIUS:  #若小球出左边界
        if ball_pos[1] in range(paddle2_pos[1] - PAD_HEIGHT, paddle2_pos[1] + PAD_HEIGHT): #若小球被右挡板挡住
            ball_vel[0] = ball_vel[0] * -1.1   #水平速度加速10%,方向相反
        else:
            score1 +=1   #若未被挡板挡住,则玩家1记一分
            spawn_ball(LEFT)  #重新发球
    if ball_pos[1] < BALL_RADIUS or ball_pos[1] > HEIGHT - BALL_RADIUS:  #若小球接近上下边界,垂直方向速度反向
        ball_vel[1] = ball_vel[1] * -1
    
    ball_pos[0] = ball_pos[0] + ball_vel[0]    #描绘小球水平位置
    ball_pos[1] = ball_pos[1] + ball_vel[1]    #描绘小球垂直位置
    # 在画布中画小球
    canvas.draw_circle(ball_pos, BALL_RADIUS, 5, "white", "white")  
    # 判定挡板1是否出界
    if paddle1_pos[1] < HALF_PAD_HEIGHT:  #若靠近上下边缘,则令其垂直速度为0,并停在顶部
        paddle1_vel[1] = 0
        paddle1_pos[1] = HALF_PAD_HEIGHT
    elif paddle1_pos[1] > HEIGHT - HALF_PAD_HEIGHT: #若靠近下边缘,垂直速度为0,停在底部
        paddle1_vel[1] = 0
        paddle1_pos[1] = HEIGHT - HALF_PAD_HEIGHT
        
    if paddle2_pos[1] < HALF_PAD_HEIGHT:  #挡板2,同1
        paddle2_vel[1] = 0
        paddle2_pos[1] = HALF_PAD_HEIGHT
    elif paddle2_pos[1] > HEIGHT - HALF_PAD_HEIGHT:
        paddle2_vel[1] = 0
        paddle2_pos[1] = HEIGHT - HALF_PAD_HEIGHT

    paddle1_pos[1] -= paddle1_vel[1]    #挡板垂直位置随垂直方向速度变化
    paddle2_pos[1] -= paddle2_vel[1]       
    
    # 画布中显示画板
    canvas.draw_polygon([(0,paddle1_pos[1]+HALF_PAD_HEIGHT),(PAD_WIDTH, paddle1_pos[1]+HALF_PAD_HEIGHT),(PAD_WIDTH, paddle1_pos[1]-HALF_PAD_HEIGHT),(0, paddle1_pos[1]-HALF_PAD_HEIGHT)], 1, "white", "white")
    canvas.draw_polygon([(WIDTH - PAD_WIDTH, paddle2_pos[1]+HALF_PAD_HEIGHT),(WIDTH, paddle2_pos[1]+HALF_PAD_HEIGHT),(WIDTH, paddle2_pos[1]-HALF_PAD_HEIGHT),(WIDTH - PAD_WIDTH, paddle2_pos[1]-HALF_PAD_HEIGHT)], 1, "white", "white")
 
    # 显示二者分数
    
    canvas.draw_text("Player1: " + str(score1), (WIDTH * 0.4, HEIGHT * 0.15), 40, 'white')
    canvas.draw_text("Player2: " + str(score2), (WIDTH * 0.57, HEIGHT * 0.15), 40, 'white')
    
def keydown(key):   #定义二块挡板按键-按下
    global paddle1_vel, paddle2_vel
    if key == simplegui.KEY_MAP['w']:
        paddle1_vel[1] = 10
    elif key == simplegui.KEY_MAP['s']:
        paddle1_vel[1] = -10
    elif key == simplegui.KEY_MAP['up']:
        paddle2_vel[1] = 10
    elif key == simplegui.KEY_MAP['down']:
        paddle2_vel[1] = -10
    
def keyup(key):    #定义挡板按键-弹起
    global paddle1_vel, paddle2_vel
    if key == simplegui.KEY_MAP['w']:
        paddle1_vel[1] = 0
    elif key == simplegui.KEY_MAP['s']:
        paddle1_vel[1] = 0
    elif key == simplegui.KEY_MAP['up']:
        paddle2_vel[1] = 0
    elif key == simplegui.KEY_MAP['down']:
        paddle2_vel[1] = 0

def start_handler():   #开始按钮函数
    new_game()
        
def reset_handler():   #重置按钮函数
    global score1, score2, ball_pos, ball_vel
    score1, score2 = [0, 0]
    ball_pos = [WIDTH/2, HEIGHT/2]
    ball_vel = [0, 0]

# 初始化画布
frame = simplegui.create_frame("Pong", WIDTH, HEIGHT)
frame.set_draw_handler(draw)    #定义画布函数
frame.set_keydown_handler(keydown)  #初始化按键函数-按下
frame.set_keyup_handler(keyup)      #初始化按键函数-弹起
start_button = frame.add_button("start", start_handler)  #初始化开始按钮
reset_button = frame.add_button("reset", reset_handler)  #初始化重置按钮


new_game()   #游戏开始
frame.start() #显示游戏画面

游戏画面