Python学习之路

可回放的点彩画板 教程

这次作业的知识要点:

  • list及其函数熟练运用
  • for in 循环的运用
  • timer 时间函数的掌握
  • 按顺序回顾点彩画板信息

ps: 按顺序回顾点彩画板信息 最难,难度在于按顺序,且呈现不同的画笔形状。方法1,
按顺序: 将3个不同的list,按照点击的顺序汇总成一个列表。
呈现不同的画笔 :汇总的同时,加入n值区分不同画笔的位置信息。方式如(n, (50, 80));

完成必要的课程学习

  • list 相关课程的学习
  • timer 相关课程的学习
  • 其他等,如有需要

作业解析

  • 开始阶段:拿到作业准备做的时候,一般都是一头雾水,不知道如何下笔。这个时候需要尝试着用大脑已有的概念动手操作起来,如果不动手敲代码,老是认为还未准备好,可能永远都处在开始阶段;
  • 进阶阶段1:开始敲代码后,就会有打游戏通关的感觉了。设置3种不同的画笔.增加button按钮,通过按钮驱动完成选择;注意这里只是选择,不同的画笔,需要在主函数draw里来完成

      def select1():
          global n
          n = 1
          print " red circle "
          print " interval is ", interval
      def select2():
          global n
          n = 2
          print " green triangle "
          print " interval is ", interval
    
      def select3():
          global n
          n = 0
          print " blue rectangle "
          print " interval is ", interval
    

    ...

      frame.add_button("Circle Brush", select1, 150) 
      frame.add_button("Triangle Brush", select2, 150) 
      frame.add_button("Rectangle Brush", select3, 150)          
    
  • 进阶阶段2:设定颜色. 在了解了draw函数后,我们知道,其中都有参数color的设定。所以,我们只需要增加input_color输入按钮来完成颜色的设定

      def change_color(input_color):
          global color
          color = input_color   
          print "color is", color
    

    ...

      frame.add_input("print color", change_color, 150)
    
  • 进阶阶段3:点击画布,绘制当前画笔形状.通过list1/list2/list3来区分不同的画笔。另外,为了保留先前的画笔,需要运用 for in的循环概念,就是把list里面的所有位置都画一遍。

      def click(pos):
          if n == 1:
            list1.append(pos) 
            list.append([n, pos])  
          elif n == 2:
            list2.append(pos)
            list.append([n, pos]) 
          else:
            list3.append(pos) 
            list.append([n, pos])    
    

    注:上面函数在扩展list1/list2/list3的同时,也把这3个list汇总到了list中;

      def draw_handler(canvas):
          if project == False:
              for ball_pos in list1:
                  canvas.draw_circle(ball_pos, 15, 1, "Black", color) 
    
              for tri_pos in list2:
                   canvas.draw_polygon([tri_pos, (tri_pos[0]+10, tri_pos[1]),
                                       (tri_pos[0], tri_pos[1]+10)], 20, color) 
    
              for rec_pos in list3:
                   canvas.draw_polygon([rec_pos, (rec_pos[0]+10, rec_pos[1]), 
                                        (rec_pos[0]+20, rec_pos[1])], 20, color) 
    

注:project是用来区分点画,还是回放的。这里有参考Frank Hu同学的代码。

  • 进阶阶段4:回放,且按顺序,对应画笔。用list合并所有的位置信息=》合并的同时,加入n值,通过n来区分不同的画笔。 下面是draw函数的另一部分,用于playback。

          else :
    
              if list[t][0] == 1:
                  ball_pos = list[t][1]
                  canvas.draw_circle(ball_pos, 15, 1, "Black", color) 
    
              elif list[t][0] == 2:
                  tri_pos = list[t][1]
                  canvas.draw_polygon([tri_pos, (tri_pos[0]+10, tri_pos[1]), 
                                      (tri_pos[0], tri_pos[1]+10)], 20, color) 
    
              else:
                  rec_pos = list[t][1]
                  canvas.draw_polygon([rec_pos, (rec_pos[0]+10, rec_pos[1]), 
                                      (rec_pos[0]+20, rec_pos[1])], 20, color) 
    
  • 最终阶段:完成细节。如timer的设定、文本输出等。

          def playback():
              global project
              global timer
              project = True
              timer = simplegui.create_timer(interval, tick)
              timer.start() 
              print " playback start "
    
          def change_interval(input_interval):
              global interval
              interval = int(input_interval)
              print "interval is ", interval 
    
          def tick():
              global t
              global list1
              global list2
              global list3
              global project
              global list
    
              if t < len(list)-1:
                  t += 1
                  print t
              else:
                  list1 = []
                  list2 = []
                  list3 = []
                  list = []
                  timer.stop() 
                  t = 0
                  project = False
                  print " playback finished "
    

不足处:回放的时候,不能同时呈现所有的画笔,只能逐个呈现。想用for in 来遍历总list中(n,(pos)) 单独 pos的信息,试了好几次,貌似不行。待进一步研究。主函数draw写的过于复杂,可能是目前这种靠靠汇总list来完成回放的方法导致的。待研究

bug list:

  1. 绘制矩形的时候,3个坐标点如何定义个一个二位的矩形的。3个坐标点必须在一条直线上,矩形另一条边取其垂直线。
  2. timer计时器的设定,需要主要global timer的设定,另外就是,如果不在驱动事件playback中设定timer时钟,则会产生,输入interval的值时,实际没有改变的问题。
  3. list的设定很灵活,可以在扩展的时候,增加维度。如原有的扩展为(1, 2), 可设定为(1, (1, 2))