• Mini projects #3 ---- Stopwatch: The Game


    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University

    授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong

    工具:http://www.codeskulptor.org/, simplegui 模块

    这是第三次作业,前面两次主要是熟悉Python动手做起来都很简单,就不记录了。

    作业需要完成一个关于手表的游戏,估计很多人也都玩过。初中和高中考试做完卷子,但离收卷还有很久,就折腾手上的电子表用来掐秒,锻炼反应力。这里要实现的游戏是一个道理,就是酱紫。

    这个Mini project开始采用事件驱动(event-driven)的交互方式,所以先明确一些问题。

    1. 界面canvas的drawing速率大概是 60 frams/sec

    2. 每一个应用程序需要注册一个特殊的事件句柄叫做 draw handler

    3. 在simplegui 模块中,创建和注册draw handler最后的绘制是在canvas中

    4. 绘制的操作有很多种,例如线、圆、多边形等,这些都在simplegui模块里面定义,具体查看doc

    canvas的布局如下,原点在左上角,第一个坐标是宽度,第二个坐标是高度

    image

    Stopwatch完成的结果如下:

    image

    Start开始游戏,Stop暂停,Reset重置。右上角记录 成功停在整数秒次数/尝试次数

    需要的元素:

    frame:主界面

    start button, stop button, reset button.

    timer: 计时

    逻辑设计:

    start button事件: 开始计时

    def start_handler():
        global is_running
        if is_running is False:
            timer.start()
            is_running = True

    stop button事件:停止计时,更新右上角记录

    def stop_handler():
        global num_stop, num_succ_stop, is_running
        if is_running is True:
            timer.stop()
            num_stop += 1
            if tick % 10 == 0 and tick != 0:
                num_succ_stop += 1
            is_running = False

    reset button事件:停止计时,重置相关参数

    def reset_handler():
        global tick, num_stop, num_succ_stop, is_running
        timer.stop()
        num_succ_stop, num_stop, tick = 0, 0, 0
        is_running = False

    timer 事件:负责计时不断增加,每次0.1s

    def timer_handler():
        global tick
        tick += 1

    draw事件:界面元素绘制

    def draw_handler(canvas):
        canvas.draw_text(format(tick), [100, 100], 30, "Green")
        canvas.draw_text(str(num_succ_stop) + "/" + str(num_stop), [250, 20], 20, "Green")

    定义了一个辅助的方法format用来转换当前时间t为00:00.0格式

    def format(t):
        D = str(t % 10)
        BC = t / 10 % 60
        if BC < 10:
            BC = '0'+str(BC)
        else:
            BC = str(BC)
        A = str(t / 10 / 60)
        return A + ":" + BC + "." + D

    整体完整代码如下:

    # template for "Stopwatch: The Game"
    
    import simplegui
    
    # define global variables
    tick = 0
    num_stop = 0
    num_succ_stop = 0
    is_running = False
    
    # define helper function format that converts time
    # in tenths of seconds into formatted string A:BC.D
    def format(t):
        D = str(t % 10)
        BC = t / 10 % 60
        if BC < 10:
            BC = '0'+str(BC)
        else:
            BC = str(BC)
        A = str(t / 10 / 60)
        return A + ":" + BC + "." + D
        
    # define event handlers for buttons; "Start", "Stop", "Reset"
    def start_handler():
        global is_running
        if is_running is False:
            timer.start()
            is_running = True
    
    def stop_handler():
        global num_stop, num_succ_stop, is_running
        if is_running is True:
            timer.stop()
            num_stop += 1
            if tick % 10 == 0 and tick != 0:
                num_succ_stop += 1
            is_running = False
    
    def reset_handler():
        global tick, num_stop, num_succ_stop, is_running
        timer.stop()
        num_succ_stop, num_stop, tick = 0, 0, 0
        is_running = False
        
    
    # define event handler for timer with 0.1 sec interval
    def timer_handler():
        global tick
        tick += 1
    
    # define draw handler
    def draw_handler(canvas):
        canvas.draw_text(format(tick), [100, 100], 30, "Green")
        canvas.draw_text(str(num_succ_stop) + "/" + str(num_stop), [250, 20], 20, "Green")
        
    # create frame
    frame = simplegui.create_frame('Stopwatch: The Game', 300, 200)
    
    # register event handlers
    start_btn = frame.add_button('Start', start_handler, 200)
    stop_btn = frame.add_button('Stop', stop_handler, 200)
    reset_btn = frame.add_button('Reset', reset_handler, 200)
    frame.set_draw_handler(draw_handler)
    timer = simplegui.create_timer(100, timer_handler)
    
    # start frame
    frame.start()
    
    # Please remember to review the grading rubric

    其中is_running用来记录当前timer是否在运行,防止重复点击stop出现计数错误的问题。

    整体逻辑也比较简单,课程挺有意思,声音听着超棒,锻炼听力挺不错。每个老师相当的负责和认真。感叹自己本科那时初学C的时候,授课的差距是那么大,也感慨现在有这么多好的资源可以利用。学无止境。

  • 相关阅读:
    (转)-为什么分布式一定要有Redis?
    (九)redis使用lua脚本
    (八)redis实现分布式锁
    (七)面试题-Redis比较常见的面试题-转载
    (六)redis缓存穿透,击穿,雪崩以及解决方案
    (五)redis的主从复制
    (四)redis的数据持久化-RDB,AOF
    (三)redis的其他功能-Bitmap,HyperLogLog,GEO
    JsTracker
    Web开发者助手 FeHelper
  • 原文地址:https://www.cnblogs.com/tiny656/p/4029340.html
Copyright © 2020-2023  润新知