Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. import random
  2. import tkinter
  3.  
  4.  
  5. class RandomBall(object):
  6. '''
  7. 定义运动的球的类
  8. '''
  9.  
  10. def __init__(self, canvas, scrnwidth, scrnheight):
  11. '''
  12. canvas: 画布,所有的内容都应该在画布上呈现出来,此处通过此变量传入
  13. scrnwidth/scrnheigh:屏幕宽高
  14. '''
  15.  
  16. self.canvas = canvas
  17. # 球出现的初始位置要随机,此处位置表示的球的圆心
  18. # xpos表示位置的x坐标
  19. self.xpos = random.randint(10, int(scrnwidth) - 20)
  20. # ypos表示位置的y坐标
  21. self.ypos = random.randint(10, int(scrnheight) - 20)
  22.  
  23. # 定义球运动的速度
  24. # 模拟运动:不断的擦掉原来画,然后在一个新的地方再从新绘制
  25. # 此处xvelocity模拟x轴方向运动
  26. self.xvelocity = random.randint(4, 20)
  27.  
  28. # 同理,yvelocity模拟的是y轴方向运动
  29. self.yvelocity = random.randint(4, 20)
  30.  
  31. # 定义屏幕的大小
  32. self.scrnwidth = scrnwidth
  33. # 定义屏幕的高度
  34. self.scrnheight = scrnheight
  35.  
  36. # 球的大小随机
  37. # 此处球的大小用半径表示
  38. self.radius = random.randint(20, 120)
  39.  
  40. # 定义颜色
  41. # RGB表示法:三个数字,每个数字的值是0-255之间,表示红绿蓝三个颜色的大小
  42. # 在某些系统中,之间用英文单词表示也可以,比如red, green
  43. # 此处用lambda表达式
  44. c = lambda: random.randint(0, 255)
  45. self.color = '#%02x%02x%02x' % (c(), c(), c())
  46.  
  47. # 以上函数代码忘了缩进了,自行处理
  48.  
  49.  
  50. def create_ball(self):
  51. '''
  52. 用构造函数定义的变量值,在canvas上画一个球
  53. '''
  54. # tkinter没有画圆形函数
  55. # 只有一个画椭圆函数,画椭圆需要定义两个坐标,
  56. # 在一个长方形内画椭圆,我们只需要定义长方形左上角和右下角就好
  57. # 求两个坐标的方法是,已知圆心的坐标,则圆心坐标减去半径能求出
  58. # 左上角坐标,加上半径能求出右下角坐标
  59. x1 = self.xpos - self.radius
  60. # 继续球y1, x2, y2
  61. y1 = self.ypos - self.radius
  62. x2 = self.xpos + self.radius
  63. y2 = self.ypos + self.radius
  64. # 再有两个对角坐标的前提下,可以进行画圆
  65. # fill表示填充颜色
  66. # outline是外围边框颜色
  67. self.item = self.canvas.create_oval(x1, y1, x2, y2, fill=self.color, outline=self.color)
  68.  
  69.  
  70. def move_ball(self):
  71. # 移动球的时候,需要控制球的方向
  72. # 每次移动后,球都有一个新的坐标
  73. self.xpos += self.xvelocity
  74. # 同理计算ypos
  75. self.ypos += self.yvelocity
  76. # 以下判断是会否撞墙
  77. # 撞了南墙就要回头
  78. # 注意撞墙的算法判断
  79. if self.xpos + self.radius >= self.scrnwidth:
  80. # 装到了右边墙
  81. self.xvelocity *= -1
  82. # 或者以下代码
  83. # self.xvelocity *= -1
  84. # 同理可以判断撞别的墙的算法
  85. if self.ypos + self.radius >= self.scrnwidth:
  86. self.yvelocity *= -1
  87. if self.xpos - self.radius <= 0:
  88. self.xvelocity *= -1
  89. if self.ypos + self.radius <= 0:
  90. self.yvelocity *= -1
  91.  
  92. # 在画布上挪动图画
  93. self.canvas.move(self.item, self.xvelocity, self.yvelocity)
  94.  
  95.  
  96. class ScreenSaver():
  97. '''
  98. 定义屏保的类
  99. 可以被启动
  100. '''
  101. # 如何装随机产生的球?
  102. balls = list()
  103.  
  104. def __init__(self):
  105. # 每次启动球的数量随机
  106. self.num_balls = random.randint(6, 20)
  107.  
  108. self.root = tkinter.Tk()
  109. # 取消边框
  110. self.root.overrideredirect(1)
  111. self.root.attributes('-alpha', 0.3)
  112. # 任何鼠标移动都需要取消
  113. self.root.bind('<Motion>', self.myquit)
  114. # 同理,按动任何键盘都需要退出屏保
  115. self.root.bind('<Key>', self.myquit)
  116. # 得到屏幕大小规格
  117. w, h = self.root.winfo_screenwidth(), self.winfo_screenheight()
  118.  
  119. # 创建画布,包括画布的归属,规格
  120. self.canvas = tkinter.Canvas(self.root, width=2, height=h)
  121. self.canvas.pack()
  122.  
  123. # 在画布上画球
  124. for i in range(self.num_balls):
  125. ball = RandomBall(self.cavas, scrnwidth=w, scrnheight=h)
  126. ball.create_ball()
  127. self.balls.append(ball)
  128.  
  129. self.run_screen_saver()
  130. self.root.mainloop()
  131.  
  132. def run_screen_saver():
  133. for ball in self.balls:
  134. ball.move_ball()
  135.  
  136. # after是200毫秒后启动一个函数,需要启动的函数是第二个参数
  137. self.cavas.after(200, self.run_screen_saver)
  138.  
  139. def myquit(self, e):
  140. # 此处只是利用了事件处理机制
  141. # 实际上并不关心事件的类型
  142. # 作业:
  143. # 此屏保程序扩展成,一旦捕获事件,则判断屏保不退出
  144. # 显示一个Button,Button上显示事件类型,点击Button后屏保
  145. # 才退出
  146. self.root.destroy()
  147.  
  148.  
  149. if __name__ == "__main__":
  150. # 启动屏保
  151. ScreenSaver()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement