IIPP迷你项目(三)“Stopwatch: The Game”
0 本周项目说明
这一次博客是Coursera的IIPP课程第三周迷你项目的实现,基础要求是做一个秒表,能start能stop能reset,更高的要求是在此秒表的基础上完成两个小游戏,但是鉴于第二个小游戏牵扯到“按下键盘的某一个键则frame会立即反应”,而这一步怎么实现课程还没讲,所以本次博客暂且先不实现这个小游戏,单纯实现靠button控制的秒表,以及第一个小游戏。
1 canvas简介
为了方便后续过程中我自己的查阅,我将canvas整理如下。本文内容除过参考Coursera的视频之外,还有simpleguics2pygame — canvas,但是个人感觉这个说明文档写得不够好,不如CodeSculptor中带的那个清晰,但是Google不是被墙了么无法方便地登入CodeSculptor,所以只能结合视频和这个文档来写程序了。
Joe老师在视频中打开的CodeSculptor的canvas说明书界面如下,我感觉真是一目了然……
简单来说就是canvas这个类所提供的成员函数能够完成以下功能:
(1)写字(canvas.draw_text);
(2)画直线(canvas.draw_line);
(3)画折线(canvas.draw_polyline);
(4)画闭合多边形(canvas.draw_polygon);
(5)画圆(canvas.draw_circle);
(6)载入外部图像(canvas.draw_image)。
而具体每个成员函数里面填写什么样的参数,就得查阅 simpleguics2pygame — canvas 了,虽然这个文档怎么用这些函数说的不清不楚,但是查个参数还是可以的。
这里我给出一段用于实验的代码,里面包含了上述canvas类中所有成员函数(除了canvas.draw_image),为了方便显示各成员函数的效果,我用不同颜色对这些形状予以绘制。
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui ### event handler ###
def draw(canvas):
canvas.draw_text("Hello!",[100,100],24,"Red") # 文本
canvas.draw_line([3,3],[20,40],3,"White") # 直线
canvas.draw_polyline([(50,80),(60,10),(40,44)],3,"Green") # 折线
canvas.draw_polygon([(80,80),(110,120),(120,160)],3,"Blue") # 闭合图形
canvas.draw_circle([60,60],40,3,"Yellow") # 画圆 ### create a frame ###
frame = simplegui.create_frame("Stopwatch: the game",200,200) # 200*200为画布大小 ### register event handlers ###
frame.set_draw_handler(draw) ### start frame ###
frame.start()
其基本过程大致描述如下:在启动frame的一刻,画布也随之启动,于是与画布相挂钩的回调函数draw()将被调用。在draw()函数中设定画什么,在画布上也就相应显示什么。最终画布上的显示如下:
至于canvas.draw_image,目测是后面的迷你项目会讲到的,这里我还暂时不知道怎么使用它载入图像,先放着不管。
2 timers简介
timer是本次小项目中关键环节之二,时间的变化正是由它产生的。
具体的用法还是看Scott老师打开的CodeSculptor说明书吧:
可以发现创建timer的时候需要给出两个参数,一个是时间间隔——也就是每隔多长时间调用一次回调函数timer_handler;另一个则是等待被调用的回调函数。
同时,如果要使用timer,除过创建它之外还需要开启它,方法是在启动frame之前先启动timer,即timer.start()。这里有点像单片机里的定时计数器,需要开启定时器才能运作,否则定时器是不工作的,就像开关被关掉了一样。
下面我给出在canva上不断更新当前秒数的代码:
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui ### global variable ###
message = ""
interval = 1000 ### event handler ###
def draw(canvas): # canva的回调函数
canvas.draw_text( message,[100,100],24,"Red") def tick(): # timer的回调函数
global message
num = int(message)
num += 1
message = str(num) ### create a frame ###
frame = simplegui.create_frame("Stopwatch: the game",200,200) # 200*200为画布大小 ### register event handlers ###
frame.set_draw_handler(draw)
timer = simplegui.create_timer(interval,tick) ### start frame ###
timer.start()
frame.start()
大概意思就是说每隔interval(1秒钟)时长,就会调用一次timer的回调函数tick。回调函数tick负责改变message的值,然后画布就可以利用其超快自我刷新机制自动更新了。
到此为止一个秒表的雏形就打得差不多了,下面要做的工作就是进一步细化,以及加上“开始”“停止”以及“复位”按钮。
3 普通秒表
这一次的秒表只能实现“按start开启”“按stop暂停”以及“按reset复位”的功能,不添加游戏。
其基本思想就是把A:BC.D中的A、B、C、D当成四个int变量来处理,然后再转成字符串进行拼接,拼接结果就是message。这点似乎和Joe老师提示的不同,不过我觉得这样比较省事。
然后那三个按钮所对应的回调函数start、stop、reset各司其职,往里面填写功能就行了。
代码如下:
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui ### global variable ###
message = "0:00.0"
interval = 100
A = 0
B = 0
C = 0
D = 0 ### helper function ###
def format():
global A,B,C,D
global message
message = str(A) + ":" + str(B) + str(C)+ "." + str(D) ### event handler ###
def draw(canvas): # canva 的回调函数
canvas.draw_text( message,[60,100],30,"White") def tick(): # timer 的回调函数
global A,B,C,D
if D < 9:
D += 1
else:
D = 0
if C < 9:
C += 1
else:
C = 0
if B < 5:
B += 1
else:
B = 0
if A < 9:
A += 1
else:
A = 0
format() def start():
timer.start() def stop():
timer.stop() def reset():
global message
timer.stop()
message = "0:00.0" ### create a frame ###
frame = simplegui.create_frame("Stopwatch: the game",200,200) # 200*200为画布大小 ### register event handlers ###
frame.set_draw_handler(draw)
timer = simplegui.create_timer(interval,tick)
frame.add_button("start", start, width=100)
frame.add_button("stop", stop, width=100)
frame.add_button("reset", reset, width=100) ### start frame ###
frame.start()
4 能玩stop游戏的秒表
首先对于这个游戏进行一些必要说明:
(1)这里的秒表是精确到秒的小数点后一位的,也就是D。D每个100毫秒增加1,游戏的规则就是如果说我们刚好在D=0的时候点下了stop键,则分数+1。鉴于此,在画图板右上角设定了红色的“stop/chance”,其中stop记录“成功在D=0时按下stop的次数”,而chance记录“不论成功失败,我总共点了多少次stop”。
(2)同时还规定,在秒表停止(暂停或复位)的时候,再点stop是不进入累计的,因此根据这一点需要设定一个全局变量timer_on,如果定时器是开着的则为True,是关着的则为False,规定在timer_on变量为False的时候不论是stop还是chance都不进行累计。
(3)每一次timer.start()之后,立刻把timer_on置为True,每一次timer.stop()之后,立刻把timer_on置为False。这就是为什么在stop按钮的回调函数中要先写“判断stop/chance”的代码,然后再timer.stop(),因为判断的时候务必得保证定时器是跑着的。
该程序的代码如下所示:
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui ### global variable ###
message = "0:00.0"
game_chance = 0
game_stop = 0
timer_on = False
interval = 100
A = 0
B = 0
C = 0
D = 0 ### helper function ###
def format():
global A,B,C,D
global message
message = str(A) + ":" + str(B) + str(C)+ "." + str(D) ### event handler ###
def draw(canvas): # canva 的回调函数
global game_stop,game_chance
game = str(game_stop) + "/" + str(game_chance)
canvas.draw_text( message, [60,100], 30, "White")
canvas.draw_text( game, [150,30], 30, "Red") def tick(): # timer 的回调函数
global A,B,C,D
if D < 9:
D += 1
else:
D = 0
if C < 9:
C += 1
else:
C = 0
if B < 5:
B += 1
else:
B = 0
if A < 9:
A += 1
else:
A = 0
format() def start():
global timer_on
timer.start()
timer_on = True def stop():
global timer_on
global game_chance,game_stop
global D
if (timer_on == True):
game_chance += 1
if (D == 0):
game_stop += 1
timer.stop()
timer_on = False def reset():
global timer_on
global game_chance,game_stop
global message
timer.stop()
timer_on = False
message = "0:00.0"
game_chance = 0
game_stop = 0 ### create a frame ###
frame = simplegui.create_frame("Stopwatch: the game",200,200) # 200*200为画布大小 ### register event handlers ###
frame.set_draw_handler(draw)
timer = simplegui.create_timer(interval,tick)
frame.add_button("start", start, width=100)
frame.add_button("stop", stop, width=100)
frame.add_button("reset", reset, width=100) ### start frame ###
frame.start()
最终的界面如下:
这是五次里有两次成功点中整秒数(即D=0)时所得的结果。
2016.6.9
by 悠望南山
IIPP迷你项目(三)“Stopwatch: The Game”的更多相关文章
- IIPP迷你项目(一)“Rock-paper-scissor-lizard-Spock”
0 前言——关于IIPP 本系列博客的内容均来自<An Introduction to Interactive Programming in Python (Part 1)>(在此我简称为 ...
- IIPP迷你项目(四)"Pong"
1 小球在墙面的反弹 1-1 让小球在画布上匀速运动 在这一步中,首先应该明确小球是如何匀速运动的.它的方法是规定一个列表v,Scott老师说这代表着“速度(Velocity)”,但是我觉得也可以拿“ ...
- IIPP迷你项目(二)"Guess the Number!"
本来这个程序是早就编完了的,一直没时间发布博客.时至今日已时隔多天,也算是复习一下事件驱动型编程的过程吧. 1 事件驱动型编程 本质上这次的作业是披着猜数字皮的图形化界面编程,好在 simplegui ...
- 在Tomcat下部属项目三种方式:
在Tomcat下部属项目三种方式: 1直接复制: 2. 通过配置虚拟路径的方式 直接修改配置文件 写到tomcat/conf/server.xml 找到<H ...
- android 实践项目三
android 实践项目三 本周我主要完成的任务是将代码进行整合,然后实现百度地图的定位与搜索功能.在这次实现的 图形界面如下: 在本周的工作中主要的实现出来定位与收索的功能,在地图中能实现了定位,显 ...
- crm 系统项目(三) 自动分页
crm 系统项目(三) 自动分页 需求: 1. 做一个自动分页, 每15条数据1页 2. 让当前页数在中间显示 3. 上一页, 下一页 注意情况: 1.总页数 小于 规定显示的页数 2. 左右两边极值 ...
- Java实验项目三——职工类对象数组按照职工生日排序
Program: 修改项目三(1)中的第3题,实现比较方法,将对象数组的数据按照生日的大小给职工排序. Description:令日期类MyDate和员工类Worker类实现接口Comparable, ...
- 摸鱼人常备5个Python迷你项目,玩一整天不是问题(附源码)
大家好鸭,我是小熊猫 在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍5个通过Python构建的项目,以此来学习Python编程. 一.石头剪 ...
- Weblogic部署项目三种方式
在weblogic中部署项目通常有三种方式:第一,在控制台中安装部署:第二,将部署包放在domain域中autodeploy目录下部署:第三,使用域中配置文件config.xml 进行项目的部署. 控 ...
随机推荐
- ssh只读事务的管理
概念:从这一点设置的时间点开始(时间点a)到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在时间点a之后提交的数据) 应用场合: 如果你一次执行单条查询语句,则没有必 ...
- LoadRunner测试Google Suggest
Google的搜索框是典型的AJAX应用,用户在输入关键字的同时,前端页面通过xmlhttp与后台服务器动态交互,根据用户输入的关键字查找匹配的内容,向用户提示建议的搜索项,也就是所谓的“google ...
- 语言那点事,crt
C语言标准(不管是ANSI 还是ISO)包含2部分,一部分是语言本身的标准,另一部分是C标准函数库.C标准函数库规定了函数的原型和功能,但是并没限定这些函数要怎么实现.所谓满足标准C规定的C编译器,不 ...
- 04-1下载Win系统(装机助理)
下载Win系统(装机助理): http://www.zhuangjizhuli.com/upan.html http://www.krlxx.com/64win7.html 选择你需要安装的系统: 以 ...
- spring学习笔记(五)
1.后置通知 需求:调用相应业务方法后,完成资源的关闭. a. 在beans.xml中配置 .... <beans> <!--配置被代理对象--> <bean id=&q ...
- MongoDB之索引
索引是用来加快查询的,这里不解说索引的原理和数据结构.事实上大部分数据库的索引就是B+Tree,想要了解的同学能够看索引原理,要掌握怎样为查询配置最佳索引会有些难度. MongoDB索引差点儿和关系型 ...
- es redis logstash 日志收集系统排错
用logstash收集日志并发送到redis,然后通过logstash取redis数据写入到es集群,最近kibana显示日志总是中断,日志收集不过来,客户端重启发现报错: Failed to sen ...
- Pmon (LS1B)start.s
loongson ls1b FPGA验证 只有DDR flash UART pmon移植 和原版本相比,DDR controller和ls1b不一致. /* $Id: start.S,v 1.1.1. ...
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...
- spring定时任务(@Scheduled注解)cron表达式详解
cron表达式详解: 一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素. 按顺序依次为 秒(~) 分钟(~) 小时(~) 天(~) 月(~) 星期(~ =SUN 或 SUN,MON,TU ...