Mini_project开发过程
1.通过添加代码画出一个在乒乓球台移动的球。我们提醒你给乒乓台添加位置信息给draw handler像在”Motion"那节课第二部分介绍的那样
2.添加代码到spwn_ball里面,该函数可以在桌子中间产生一个球,并给球分配一个固定的速度(for now).此时此刻先忽略“direction”这个参数
3.在new_game这个函数里面调用spwn_ball,new_game函数是用来开始乒乓球游戏的。注意模板程序包含一个initial call to new_game在你程序的主体目是让游戏运行的比较快。
4.如果球撞到上下墙壁的话,球要反弹。用不同的初始速度测试你的代码,看能不能实现这一的功能
5.在spawn_ball(direction)这个代码里面给速度添加随机变量。如果direction == RIGHT,球的速度应该向右上方;如果direction == LEFT,速度应该向左上。速度的水平和垂直分量应该用random.randrage()产生。对于水平分量,我们建议速度大概范围是random.randrange(120,240)像素/秒。对于垂直分量,我们建议速度范围是random.randrange(60, 180)像素/秒。(你需要清楚的表达这两个速度)
6.添加代码到draw handler测试球是否接触/碰撞到左右gutter.(记得gutter是画布的左边缘和右边缘的offset到拍子的厚度,就像视频里面讲的那样。)当球接触到gutter,用spawn_ball(LEFT)或者spawn_ball(RIGHT)将球复位到桌子中心,走向对面的gutter
7.然后添加代码画出在gutters里面画出左右两边的球拍。两个球拍垂直位置应该由两个全局变量决定(在模板中,变量是paddle1_pos和paddle2_pos)
8.添加代码修饰垂直位置通过draw handler更新。更新值应该参考两个全局变量,这两个全局变量包含拍子的垂直速度。(在模板中,变量是paddle1_vel和paddle2_vel)
9.用key handler更新两个垂直速度值."W"和“S”应该控制左边拍子的垂直速度,上下箭头键应该控制右边拍子的速度。在我们的版本中,如果按“W”,左边拍子以一个固定速度向上移动,如果按"S"而且静止不动的,如果啥也没按(如果两个都按,会如何移动由我们自己决定)为了实现这样的效果,你会使用keydown和keyup handler来增加或者减小垂直速度在一个适当的方式。
10.限制你的球拍完全在画布里面通过添加一个检查在你更新拍子的垂直位置在draw handler。特别要说明的是:试一试是否实时更新拍子的位置可以让拍子的一部分超出屏幕。如果是的话,不要更新拍子的位置。
11.修改你第六步的撞击代码检查球是否真的撞到拍子当它跟gutter接触的时候。如果是这样,把球弹回去继续运行。这种撞击模式排除了可能性,啥可能性呢,球撞到paddle边缘,而且极大的简化了你的撞击/反弹代码。
12.为了适当的增加你的游戏难度,每次撞击拍子速度增加10%
13.想视频里面展示的那样增加游戏计分。每次球撞到左边或者右边的gutter(不是拍子),相反的玩家得1分,然后生成一个新的球
14.最后,添加代码到new_game里面,new_game可以重置得分在调用spawn_ball之前。添加一个“Reset"按钮来重置得分,并重新发射球
······你最终版本的Pang应该跟原始的Pang类似。我们完整的Pang包括评论大概要稍微多于100行代码。
评分规则:
1.球从画布中间发射出去的速度或者左上或者右上,不要水平向左或者向右,那样会很无聊。
2.球撞到上下墙可以正确的反弹
2.球会归位到屏幕中央,当球撞到了左边或者右边的gutter,如果球撞到了画布的边缘,而不是gutter边缘反弹就不好了
1.左边和右边gutter(不是画布中央)恰当的用作桌子的边缘
1.球重新向最后胜利的一方发射
2.”W"和“S”按键正确的控制左边拍子的速度,请分别测试每个按键(如果拍子移动,但是ws按键回应方式不正确)
2.每个拍子的边缘flush with the gutter
2.拍子一直呆在画布里面
2.球撞到左右球拍后可以正确的反弹
1.记分牌的位置正确,而且可以更新。位置跟视频中的类似
1.游戏包含一个“Restart"按钮,重新积分,重新发射球
code clinic tips for Pang
Tip#1
关于控制拍子,请记住,在draw handler里面更新拍子的位置。所以它可以连续变化。当键盘被按下或松开的时候拍子的速度在key handlers更新,用keyup和keydown两个按键来控制拍子的速度。
tip#2
paddle1_pos,paddle2_pos,paddle1_vel和paddle2_vel应该是数字,不是列表,如果是列表会导致他们不必要的复杂,非常不推荐。只要用paddle2_pos和paddle2_pos数字表达来建立拍子。
如果你对pang的视觉效果有疑问,请review Pang视频,用纸和笔描画Pang框架和变量
Tip#3
仔细读描述,不然会很困难
Tip#4
板子是Pang这个游戏这个游戏的难点,保证板子在屏幕里面,最好像下面这样更新板子信息:
paddle1_pos += paddle1_vel
下面的这种不好:
if paddle1_pos >= Half_pad_height:
    paddle1_pos += paddle1_vel
这种解法的问题在于板子会sticks当条件是真的时候,板子不能再移动了!问题在于代替paddle1_pos在if条件通过paddle1_pos + paddle1_vel.现在,检查条件来看看是否板子的下一个运动碰到了边缘。要是这样的话,是不允许移动的,现在你可以把板子向下移动

球是纯白的,板子也是纯白的。球已经画出来了,但是加了几个全局变量(球的位置,球的初速度)

v1 = random.randrange(2,4)  v2 = random.randrange(1,3)
球撞到左右沟槽没有重新开始游戏,可能是spawn_ball函数有问题?
解决了!!spawn_ball可以正常工作了,之前不工作因为我:第二行写了个return ball_pos,这样的话它肯定不行啊,我删掉以后球就来回弹跳,但是速度都没规律,因为执行了randrange这个函数,但是没有从中间发射,所以我就添加ball_pos = [300, 200],就可以啦!!
def spawn_ball(direction):
    global ball_pos, vel # these are vectors stored as lists
    #产生球的函数,功能是给一个初始位置和初始速度
    if direction == RIGHT:#True和FALSE是啥?
        vel[0] = random.randrange(2, 4)#速度有问题?太快了?
        vel[1] = - random.randrange(1, 3)
        ball_pos = [300, 200]
       
    if direction == LEFT:
        vel[0] = -random.randrange(2, 4)
        vel[1] = - random.randrange(1, 3)
        ball_pos = [300, 200]
=====================================================
       现在写paddle的代码
paddle颜色不是全白的,让线宽一点就行啦!!
如何用键盘更新拍子的位置?之前的视频里面有么?按一下动一下,不能一直动,视频里面有
现在我的拍子一直往下跑,停不住,我通过keydown函数里面将速度变成0解决了这个问题
现在要解决板子跑出屏幕的问题。已经解决
 
球跟拍子接触要反弹,现在要解决这个。现在反弹了,但是接不住没有重新开始游戏,接不住可以重新开始游戏了,可能有点bug,碰到paddle边缘会卡住?
现在要设计计分板
撞到gutter,对面玩家得分;撞到板子分数不变
计分板可以工作了,现在完善new_game代码,重置得分,添加Reset按钮,重置得分,重新发射球
Reset button的功能是new_game,
我完成了这个功能但是Reset后一直向右发射--没关系
现在要让球速度加快
2.每个拍子的边缘flush with the gutter
按键有点不灵
以静止开始的么,运动的球开始
将keyup按照下面的格式写,就没问题了
def keyup(key):
    global paddle1_vel, paddle2_vel
    if key == simplegui.KEY_MAP["w"]:
        paddle1_vel = 0
    elif key == simplegui.KEY_MAP["s"]:
        paddle1_vel = 0
    elif key == simplegui.KEY_MAP["up"]:
        paddle2_vel = 0
    elif key == simplegui.KEY_MAP["down"]:
        paddle2_vel = 0
我原来的代码:控制两个板子同时运动,松开一个按键,两个板子的速度都变成0了,单独左边或者右边激活了keyup, paddle1_vel和paddle2_vel都归零了,所以就卡顿了。上面的代码详细的讨论了按键松开的情况,所以左边keyup只能让左边的paddle1_vel归零右边的不归零。
def keyup(key):
    gllobal paddle1_vel, paddle2_vel
    paddle1_vel = 0
    paddle2_vel = 0
完了!!!!
完整代码如下:这次只用了一天就做完了,加油
# 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_pos = [WIDTH / 2, HEIGHT / 2]#需要么?
vel = [-3, -1]#需要么?
paddle1_pos = 200#建议是数字不是list
paddle2_pos = 200
paddle1_vel = 0#建议是数字不是list
paddle2_vel = 0
soccera = 0
soccerb = 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, vel # these are vectors stored as lists
#产生球的函数,功能是给一个初始位置和初始速度
if direction == RIGHT:#True和FALSE是啥?
vel[0] = random.randrange(2, 4)#速度有问题?太快了?
vel[1] = - random.randrange(1, 3)
ball_pos = [300, 200] if direction == LEFT:
vel[0] = - random.randrange(2, 4)
vel[1] = - random.randrange(1, 3)
ball_pos = [300, 200] # define event handlers
def new_game():
global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel # these are numbers
global soccera, soccerb # these are ints
soccera = 0
soccerb = 0
paddle1_pos = 200
paddle2_pos = 200
paddle1_vel = 0
paddle2_vel = 0
spawn_ball(RIGHT) def draw(canvas):
global score1, score2, paddle1_pos, paddle2_pos, ball_pos, vel, soccera, soccerb
# 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
ball_pos[0] += vel[0]
ball_pos[1] += vel[1]
#撞击上下墙壁反弹
if ball_pos[1] <= BALL_RADIUS:
vel[1] = - vel[1]
elif ball_pos[1] >= HEIGHT - 1 - BALL_RADIUS:
vel[1] = - vel[1]
#球撞击gutter后要复位游戏,调用spawn_ball
elif ball_pos[0] <= BALL_RADIUS + PAD_WIDTH and paddle1_pos - 40 <= ball_pos[1] <= paddle1_pos + 40:
vel[0] = - vel[0] * 1.1
vel[1] = vel[1] * 1.1
elif ball_pos[0] >= WIDTH - 1 - BALL_RADIUS - PAD_WIDTH and paddle2_pos - 40 <= ball_pos[1] <= paddle2_pos + 40:
vel[0] = - vel[0] * 1.1
vel[1] = vel[1] * 1.1
elif ball_pos[0] <= BALL_RADIUS + PAD_WIDTH and ball_pos[1] < paddle1_pos - 40:
spawn_ball(RIGHT)
soccerb += 1
elif ball_pos[0] <= BALL_RADIUS + PAD_WIDTH and ball_pos[1] > paddle1_pos + 40:
spawn_ball(RIGHT)
soccerb += 1
elif ball_pos[0] >= WIDTH - 1 - BALL_RADIUS - PAD_WIDTH and ball_pos[1] < paddle2_pos - 40:
spawn_ball(LEFT)
soccera += 1
elif ball_pos[0] >= WIDTH - 1 - BALL_RADIUS - PAD_WIDTH and ball_pos[1] > paddle2_pos + 40:
spawn_ball(LEFT)
soccera += 1
# draw ball
canvas.draw_circle(ball_pos, BALL_RADIUS, 2, "White", "White")
# update paddle's vertical position, keep paddle on the screen
paddle1_pos += paddle1_vel
if paddle1_pos <= 40:
paddle1_pos = 40
elif paddle1_pos >= 360:
paddle1_pos = 360 paddle2_pos += paddle2_vel
if paddle2_pos <= 40:
paddle2_pos = 40
elif paddle2_pos >= 360:
paddle2_pos = 360
# draw paddles
canvas.draw_line([0, paddle1_pos], [8, paddle1_pos], 80, "White")
canvas.draw_line([592,paddle2_pos], [600, paddle2_pos], 80, "White")
# draw scores
canvas.draw_text(str(soccera), [140, 100], 50, "White")
canvas.draw_text(str(soccerb), [450, 100], 50, "White")
def keydown(key):
global paddle1_vel, paddle2_vel
if key == simplegui.KEY_MAP["w"]:
paddle1_vel -= 4
elif key == simplegui.KEY_MAP["s"]:
paddle1_vel += 4
elif key == simplegui.KEY_MAP["up"]:
paddle2_vel -= 4
elif key == simplegui.KEY_MAP["down"]:
paddle2_vel += 4 def keyup(key):
global paddle1_vel, paddle2_vel
if key == simplegui.KEY_MAP["w"]:
paddle1_vel = 0
elif key == simplegui.KEY_MAP["s"]:
paddle1_vel = 0
elif key == simplegui.KEY_MAP["up"]:
paddle2_vel = 0
elif 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)
frame.add_button("Restart", new_game,100) # start frame
new_game()
frame.start()

  多年以后,我会看到我的挣扎

coursera-miniproject Pang任务总结的更多相关文章

  1. Coursera,Udacity,Edx 课程列表(更新ing)

    Coursera,Udacity,Edx 课程列表(更新ing) Coursera有很多特别好的课程,平时没有机会听到国外大牛的课程,通过Coursera算是可以弥补一下吧,国外的课程普遍比国内的老师 ...

  2. Coursera上一个不错的Java课

    地址:https://www.coursera.org/learn/java-chengxu-sheji/home/welcome 复习天昏地暗,看点视频调剂一下.发现这个讲的还是很不错的.北大毕竟比 ...

  3. Coursera系列-R Programming第二周

    博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html  --- 好久没发博客 且容我大吼一句 终于做完这周R Progra ...

  4. Coursera系列-R Programming第三周-词法作用域

    完成R Programming第三周 这周作业有点绕,更多地是通过一个缓存逆矩阵的案例,向我们示范[词法作用域 Lexical Scopping]的功效.但是作业里给出的函数有点绕口,花费了我们蛮多心 ...

  5. Coursera Robotics系列课心得

    Robotics Perception Professor Kostas and Jianbo Shi week 1: camera model 凸透镜成像原理:凸透镜焦点与焦距是固定的,这是物理性质 ...

  6. coursera机器学习-聚类,降维,主成分分析

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  7. coursera机器学习-支持向量机SVM

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  8. coursera机器学习笔记-建议,系统设计

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  9. coursera机器学习笔记-神经网络,学习篇

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  10. coursera机器学习笔记-神经网络,初识篇

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

随机推荐

  1. 程序员的恶性循环:加班->没空学习->老是写同等水平代码->无法提升代码质量->老是出BUG->老是需要修改->加班->...

    程序员的恶性循环:加班->没空学习->老是写同等水平代码->无法提升代码质量->老是出BUG->老是需要修改->加班->...

  2. aac格式解析

    AAC格式有以下两种: ADIF:Audio Data Interchange Format 音频数据交换格式.这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即 ...

  3. Spring的profile属性

    使用示例 //注解方式 public class DataSourceConfig { @Bean @Profile("prod") public DataSource dataS ...

  4. Remainder

    Remainder Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  5. BZOJ3673 : 可持久化并查集

    题目没有强制在线! 考虑离线做法. 把操作建立成一棵树的结构,然后按照欧拉序遍历,每次转移要么是一次合并操作,要么是一次撤销合并操作,可以看成是分离操作. 用LCT维护集合,合并就是加边,分离就是删边 ...

  6. 一个spring jdbc实例

    一.使用示例 (1)springJdbcContext.xml <?xml version="1.0" encoding="UTF-8"?> < ...

  7. 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  8. 【BZOJ】1041: [HAOI2008]圆上的整点(几何)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1041 所谓的神题,我不会,直接题解..看了半天看懂题解了.详见hzwer博客 这题呢,我只能 ...

  9. HDU 4614 Vases and Flowers(线段树+二分)

    题目链接 比赛的时候一直想用树状数组,但是树状数组区间更新之后,功能有局限性.线段树中的lz标记很强大,这个题的题意也挺纠结的. k = 1时,从a开始,插b个花,输出第一个插的位置,最后一个的位置, ...

  10. BZOJ4143 [AMPPZ2014]The Lawyer

    Description Byteasar要制订m天的会议计划,一共有n场会议,第i场会议开始于第d[i]天的第a[i]秒,结束于第d[i]天的第b[i]秒. 对于每一天,请找出这一天的两场会议i,j, ...