coursera—Mini-project #4—Pong

这是来自 The Rice的课程 An Introduction to Interactive Programming in Python (Part 1)最后一周的项目,一个乒乓球小游戏,可以分别用上下方向键和 “w” “S”键控制两方对手打乒乓球,最后一个项目相对之前的来说稍微复杂一些,主要完成的思路是先做好拍子,再让拍子按照规则上下移动不超过球台;再做好可以直线运动的球,接触到球桌边缘会直角反弹;最后再根据球是否触拍计分或者重新开始,具体步骤的解析,写在代码的注释里啦

源代码

# Implementation of classic arcade game Pong

import simplegui
import random

# initialize globals - pos and vel encode vertical info for paddles
WIDTH = 600 
HEIGHT = 400   # table size    
BALL_RADIUS = 20 # ball size
PAD_WIDTH = 8
PAD_HEIGHT = 80  # pad size
HALF_PAD_WIDTH = PAD_WIDTH / 2
HALF_PAD_HEIGHT = PAD_HEIGHT / 2
LEFT = False
RIGHT = True
t = 0
ball_pos = [WIDTH / 2, HEIGHT / 2]  # initial position of the ball

# 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():  # spown new ball
    global ball_pos, ball_vel  # these are vectors stored as lists
    ball_pos = [WIDTH / 2, HEIGHT / 2] 
    ball_vel = [0, 0]  # the velocity of ball
    ball_vel[1] = - random.randrange(60, 180) / 60  # y axis of the velocity
    if LEFT:   
        ball_vel[0] = random.randrange(120, 240) / 60    # x axis of the velocity
    else:
        ball_vel[0] = - random.randrange(120, 240) / 60

# define event handlers
def new_game():  # start a new game
    global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel  # these are numbers
    global score1, score2  # these are ints
    paddle1_vel = 0
    paddle2_vel = 0
    paddle1_pos = (HEIGHT + PAD_HEIGHT) / 2
    paddle2_pos = (HEIGHT + PAD_HEIGHT) / 2
    score1 = 0
    score2 = 0  
    spawn_ball()
    
def draw(canvas):  # draw the canvas
    global score1, score2, paddle1_pos, paddle2_pos, ball_pos, ball_vel, LEFT, RIGHT        
    # 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 position
    ball_pos[0] += ball_vel[0]
    ball_pos[1] += ball_vel[1]
    # the ball bounce or game restart when touch the wall---right
    if ball_pos[0] + ball_vel[0] >= WIDTH - PAD_WIDTH - BALL_RADIUS:
        ball_pos[0] = WIDTH - PAD_WIDTH - BALL_RADIUS
        ball_vel[0] = - ball_vel[0]
        if paddle2_pos >= ball_pos[1] >= paddle2_pos - PAD_HEIGHT:
            score2 += 1   # you win and get 1 score when your pad touch the ball
        else:
            new_game()
    # the ball bounce or game restart when touch the wall---left      
    if ball_pos[0] + ball_vel[0] <= PAD_WIDTH + BALL_RADIUS:
        ball_pos[0] = PAD_WIDTH + BALL_RADIUS
        ball_vel[0] = - ball_vel[0]
        if paddle1_pos >= ball_pos[1] >= paddle1_pos - PAD_HEIGHT:
            score1 += 1  # you win and get 1 score when your pad touch the ball
        else:
            new_game()
    # the ball bounce when touch the wall---up
    if ball_pos[1] + ball_vel[1] <= BALL_RADIUS:
        ball_pos[1] = BALL_RADIUS
        ball_vel[1] = - ball_vel[1]
    # the ball bounce when touch the wall---down
    if ball_pos[1] + ball_vel[1] >= HEIGHT - BALL_RADIUS:
        ball_pos[1] = HEIGHT - BALL_RADIUS
        ball_vel[1] = - ball_vel[1]
    
    # draw ball
    canvas.draw_circle(ball_pos, BALL_RADIUS, 1, "White")
    
    # update paddle's vertical position by the velocity, keep paddle on the screen
    if (paddle1_pos > PAD_HEIGHT and paddle1_vel < 0) or (paddle1_pos < HEIGHT and paddle1_vel > 0):
        paddle1_pos += paddle1_vel
    if (paddle2_pos > PAD_HEIGHT and paddle2_vel < 0) or (paddle2_pos < HEIGHT and paddle2_vel > 0):
        paddle2_pos += paddle2_vel
        
    # draw paddles
    canvas.draw_line([PAD_WIDTH / 2, paddle1_pos], [PAD_WIDTH / 2, paddle1_pos - PAD_HEIGHT], PAD_WIDTH, "White")
    canvas.draw_line([WIDTH - PAD_WIDTH / 2, paddle2_pos],[WIDTH - PAD_WIDTH / 2, paddle2_pos - PAD_HEIGHT], PAD_WIDTH, "White")
        
    # determine whether paddle and ball collide    
    if ball_vel[0] > 0:
        LEFT = False
    elif ball_vel[0] < 0:
        LEFT = True
    RIGHT = (not LEFT)   
            
    # draw scores
    canvas.draw_text(str(score1), [30, 20], 20, "White")
    canvas.draw_text(str(score2), [550, 20], 20, "White")
    
def keydown(key):
    global paddle1_vel, paddle2_vel
    if LEFT:  # if the ball move left, you just can move the left pad
        if key == simplegui.KEY_MAP['W']:
            paddle1_vel = -10
        elif key == simplegui.KEY_MAP['S']:
            paddle1_vel = 10
    if RIGHT: # if the ball move right, you just can move the right pad
        if key == simplegui.KEY_MAP['up']:
            paddle2_vel = -10       
        elif key == simplegui.KEY_MAP['down']:
            paddle2_vel = 10        
            
def keyup(key):  # the pad just move when keydown
    global paddle1_vel, paddle2_vel
    paddle1_vel = 0
    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)
frame.add_button('Restart', new_game, 100)
# start frame
new_game()
frame.start()

运行结果示例
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值