coursera课程上的第四个课程mini-project
设计经典的ponggame
游戏的介绍和说明参见http://www.ponggame.org/
在具体求解过程中的步骤如下
1,初始化各个变量(canvas尺寸,paddle尺寸,中间线,)
2,spawn_ball()函数的编写,此函数作用可以在初始game中进行调用,同时每次状态结束时怎样产生新的状态,初始变量的设置包括设定小球的起始位置和速度方向
3,new_game()函数的编写,此函数用于游戏处初始状态的说明,全局变两种score1和score2的初始化
4,定义event handler 具体包括以下
4.1 draw(canvas)函数,包括中间线各个paddle1,2,边缘线的画出,更新小球,此时首先分为上下、左右的更新,上下的更新较为简单,只需考虑球的竖直分量,不考虑paddle;左右的更新需要在判断球是否成功碰到paddle,需要在if中内嵌一个条件判断,如果成功碰到,球速增加1.1倍,如果没有碰撞上paddle,在对方的界面处产生新的小球并且对方得分。
draw ball, score显示的draw text()
设计keydown和keyup保证paddle的正常滑行
5,create frame
create frame
frame = simplegui.create_frame(“Pong”, WIDTH, HEIGHT)
frame.set_draw_handler(draw)
frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
6 开始
new_game()
frame.start()
最后的python 程序如下
# Implementation of classic arcade game Pong
import simplegui
import random
# initialize globals - pos and vel encode vertical info for paddles
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
ball_vel=[0,0]
score1=0
score2=0
# initialize ball_pos and ball_vel for new bal in middle of table
# if direction is RIGHT, the ball's velocity is upper right, else upper left
def spawn_ball(direction):
global ball_pos, ball_vel # these are vectors stored as lists
ball_pos=[WIDTH/2,HEIGHT/2]
ball_vel=[random.randrange(120,240),random.randrange(60,180)]
if (direction==LEFT):
ball_vel[0]=-ball_vel[0]
ball_vel[1]=-ball_vel[1]
elif(direction==RIGHT):
ball_vel[1]=-ball_vel[1]
# define event handlers
def new_game():
global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel # these are numbers
global score1, score2 # these are ints
paddle1_pos=HEIGHT/2
paddle2_pos=HEIGHT/2
paddle1_vel=0
paddle2_vel=0
spawn_ball(LEFT)
def draw(canvas):
global score1, score2, paddle1_pos, paddle2_pos, ball_pos, ball_vel
# draw mid line and gutters
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")
# update ball
if (ball_pos[1]<=BALL_RADIUS)or(ball_pos[1]>=HEIGHT-BALL_RADIUS):
ball_vel[1]=-ball_vel[1]
# ball_pos[1]+=ball_vel[1]
if (ball_pos[0]-BALL_RADIUS-PAD_WIDTH<=0):
if ((paddle1_pos-PAD_HEIGHT/2)<=ball_pos[1]<=(PAD_HEIGHT/2+paddle1_pos)):
ball_vel[0]=-ball_vel[0]
ball_vel[0]=1.1*ball_vel[0]
ball_vel[1]=1.1*ball_vel[1]
else:
spawn_ball(RIGHT)
score2+=1
if (WIDTH-BALL_RADIUS-PAD_WIDTH-ball_pos[0]<=0):
if ((paddle2_pos-PAD_HEIGHT/2)<=ball_pos[1]<=(PAD_HEIGHT/2+paddle2_pos)):
##judge the right side whether it correct
ball_vel[0]=-ball_vel[0]
ball_vel[0]=1.1*ball_vel[0]
ball_vel[1]=1.1*ball_vel[1]
else:
spawn_ball(LEFT)
score1+=1
ball_pos[0]+=ball_vel[0]/60
ball_pos[1]+=ball_vel[1]/60
# draw ball
canvas.draw_circle(ball_pos,BALL_RADIUS,2,"Red","White")
# update paddle's vertical position, keep paddle on the screen
if (PAD_HEIGHT/2<=paddle1_pos+paddle1_vel<=HEIGHT-PAD_HEIGHT/2):
paddle1_pos+=paddle1_vel
if (PAD_HEIGHT/2<=paddle2_pos+paddle2_vel<=HEIGHT-PAD_HEIGHT/2):
paddle2_pos+=paddle2_vel
# draw paddles
canvas.draw_line([PAD_WIDTH/2,paddle1_pos-PAD_HEIGHT/2],[PAD_WIDTH/2,paddle1_pos+PAD_HEIGHT/2],PAD_WIDTH,"White")
canvas.draw_line([WIDTH-PAD_WIDTH/2,paddle2_pos-PAD_HEIGHT/2],[WIDTH-PAD_WIDTH/2,paddle2_pos+PAD_HEIGHT/2],PAD_WIDTH,"White")
# determine whether paddle and ball collide
# draw scores
canvas.draw_text(str(score1),(230,80),50,"White")
canvas.draw_text(str(score2),(350,80),50,"White")
def keydown(key):
global paddle1_vel, paddle2_vel
acc=4
if key==simplegui.KEY_MAP["w"]:
paddle1_vel=-acc
elif key==simplegui.KEY_MAP["s"]:
paddle1_vel=acc
elif key==simplegui.KEY_MAP["up"]:
paddle2_vel=-acc
elif key==simplegui.KEY_MAP["down"]:
paddle2_vel=acc
def keyup(key):
global paddle1_vel, paddle2_vel
if (key == simplegui.KEY_MAP['w'] or key == simplegui.KEY_MAP['s']):
paddle1_vel = 0
if (key == simplegui.KEY_MAP['up'] or key == simplegui.KEY_MAP['down']):
paddle2_vel = 0
# create frame
frame = simplegui.create_frame("Pong", WIDTH, HEIGHT)
frame.set_draw_handler(draw)
frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
# start frame
new_game()
frame.start()