python tkinter实现彩球碰撞屏保


Posted in Python onJuly 30, 2019

利用Tkinter实现彩球碰撞屏保,供大家参考,具体内容如下

一、架构与思路

(1)主函数:

main():通过类启动程序;

(2)类:

ScreenSaver():用于定义屏保和主画布,调用球创建、运动等函数;
RandomBall():定义球的基本属性、球创建与运动函数;

(3)对象:单个球,需要创建、运动(包括碰撞反弹),通过循环调用实现多个球并存的效果

create_ball():单个球创建函数;
move_ball():单个球运动函数;

(4)20181215更新:此处对原有屏保程序的退出环节进行了扩展,使用messabox工具建立消息框,询问是否退出,点击“确定”会直接退出,点击“取消”仍留在程序中。

程序架构和思路如下:

python tkinter实现彩球碰撞屏保

二、代码实现

根据上述思路,利用python实现屏保程序,代码如下:

import random
import tkinter
import tkinter.messagebox


class RandomBall():
 '''
 单个球定义、运动的类
 '''
 def __init__(self, root_canvas, width, height):
  '''
  参数说明:
  canvas:从ScreenSaver类中传入的画布
  width,height:从SS类中传入的宽高,即屏幕宽高
  '''

  # 将传入变量赋为RB类的属性
  self.canvas = root_canvas
  self.width = width
  self.height = height

  # 随机生成球的中心坐标
  self.xcenter = random.randint(100, width-100)
  self.ycenter = random.randint(100, height-100)
  # 随机生成球的运动速度
  self.xvelocity = random.randint(8,16)
  self.yvelocity = random.randint(8,16)
  # 计算球的半径
  self.radius = random.randint(60, 100)
  # 利用十六进制随机数与lambda表达式生成球的颜色
  # RGB表示法:三个数字,每个数字的值是0-255之间,表示红绿蓝三个颜色的大小
  # 在某些系统中,直接用英文单词表示也可以,比如red,green
  color = lambda : random.randint(0,255)
  self.color = '#%02x%02x%02x' % (color(),color(),color())

 # 创建球的函数
 def create_ball(self):
  '''
  用构造函数定义的变量值,在canvas上画一个球
  '''
  # tkinter没有画圆形函数
  # 只有一个画椭圆函数,画椭圆需要定义两个坐标,
  # 在一个长方形内画椭圆,我们只需要定义长方形左上角和右下角就好
  # 求两个坐标的方法是,已知圆心的坐标,则圆心坐标减去半径能求出
  # 左上角坐标,加上半径能求出右下角坐标(向右x为正,向下y为正)
  xleftup = self.xcenter - self.radius
  yleftup = self.ycenter - self.radius
  xrightdown = self.xcenter + self.radius
  yrightdown = self.ycenter + self.radius
  # 创建球
  self.item = self.canvas.create_oval(xleftup,yleftup,
           xrightdown,yrightdown,
           fill=self.color,
           outline=self.color)

 # 球运动的函数
 def move_ball(self):
  # 计算球移动后的中心点坐标
  self.xcenter += self.xvelocity
  self.ycenter += self.yvelocity
  # 当球与边框发生碰撞时,需要进行回弹操作,即对应方向的速度取负
  if self.xcenter + self.radius >= self.width:
   self.xvelocity = - self.xvelocity
  if self.xcenter - self.radius <= 0:
   self.xvelocity = - self.xvelocity
  if self.ycenter + self.radius >= self.height:
   self.yvelocity = - self.yvelocity
  if self.ycenter - self.radius <= 0:
   self.yvelocity = - self.yvelocity
  # 在canvas上移动球,前提是create_ball已经调用
  self.canvas.move(self.item, self.xvelocity, self.yvelocity)



class ScreenSaver():
 '''
 屏保定义类
 程序启动
 '''
 def __init__(self):
  # 创建球存储列表
  self.balls = []
  # 随机生成球的数量
  self.num = random.randint(10,20)

  # 利用tkinter生成root窗口
  self.root = tkinter.Tk()
  # 获取屏幕宽、高尺寸
  root_w, root_h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
  # 取消边框
  self.root.overrideredirect(1)
  # 绑定退出函数与相应动作
  self.root.bind('<Motion>', self.myquit)
  self.root.bind('<Key>', self.myquit)
  self.root.bind('<Any-Button>', self.myquit)

  # 创建画布,配置尺寸与颜色属性
  self.canvas = tkinter.Canvas(self.root, width=root_w, height=root_h)
  self.canvas.pack()

  # 利用循环与RandomBall类在画布上画球,并append到列表中
  for i in range(self.num):
   ball = RandomBall(self.canvas, width=root_w, height=root_h)
   ball.create_ball()
   self.balls.append(ball)

  # 调用球运动函数
  self.run_screen_saver()
  # 启用tkinter时间消息循环mainloop
  self.root.mainloop()

 # 球运动函数
 def run_screen_saver(self):
  # 循环实例化的ball调用move_ball函数
  for ball in self.balls:
   ball.move_ball()
  # 使用after实现递归,通过不断调用各球的move_ball函数,实现位置刷新
  self.root.after(50, self.run_screen_saver)

 # 停止运行
 # 此处e只是利用了事件处理机制,际上并不关心事件的类型
 def myquit(self, e):
  # 扩展:
  # 此屏保程序扩展成,一旦捕获事件,则判断屏保不退出
  # 显示一个Button,Button上显示事件类型,点击Button后屏保才退出
  if tkinter.messagebox.askokcancel("彩球碰撞", '确定退出?'):
   self.root.destroy()
  else:
   pass


if __name__ == '__main__':
 # 启动屏保
 ScreenSaver()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用Python给文本创立向量空间模型的教程
Apr 23 Python
python 通过 socket 发送文件的实例代码
Aug 14 Python
python对日志进行处理的实例代码
Oct 06 Python
pandas数据筛选和csv操作的实现方法
Jul 02 Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
Aug 13 Python
Python django搭建layui提交表单,表格,图标的实例
Nov 18 Python
python获取array中指定元素的示例
Nov 26 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
Jun 09 Python
解决TensorFlow调用Keras库函数存在的问题
Jul 06 Python
python温度转换华氏温度实现代码
Dec 06 Python
Python first-order-model实现让照片动起来
Jun 25 Python
详解python pandas 分组统计的方法
Jul 30 #Python
python文档字符串(函数使用说明)使用详解
Jul 30 #Python
python3.6 tkinter实现屏保小程序
Jul 30 #Python
简单了解python变量的作用域
Jul 30 #Python
学习和使用python的13个理由
Jul 30 #Python
Win10系统下安装labelme及json文件批量转化方法
Jul 30 #Python
python利用tkinter实现屏保
Jul 30 #Python
You might like
php+AJAX传送中文会导致乱码的问题的解决方法
2008/09/08 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
2014/11/29 PHP
one.php 多项目、函数库、类库 统一为一个版本的方法
2020/08/24 PHP
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
Javascript基础教程之数据类型 (数值 Number)
2015/01/18 Javascript
使用js复制链接中的部分文字的方法
2015/07/30 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
2016/08/10 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
2017/01/21 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
2017/02/08 Javascript
Bootstrap table 定制提示语的加载过程
2017/02/20 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
2017/04/06 Javascript
Node.js学习之查询字符串解析querystring详解
2017/09/28 Javascript
vue.js分页中单击页码更换页面内容的方法(配合spring springmvc)
2018/02/10 Javascript
python中MySQLdb模块用法实例
2014/11/10 Python
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
web.py在SAE中的Session问题解决方法(使用mysql存储)
2015/06/24 Python
python3安装speech语音模块的方法
2018/12/24 Python
对python3 Serial 串口助手的接收读取数据方法详解
2019/06/12 Python
Django文件上传与下载(FileFlid)
2019/10/06 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
Java Servlet的主要功能和作用是什么
2014/02/14 面试题
中国文明网签名寄语
2014/01/18 职场文书
详细的大学生创业计划书模板
2014/01/27 职场文书
网络技术专业推荐信
2014/02/20 职场文书
食品安全演讲稿
2014/09/01 职场文书
离婚协议书范文2015
2015/01/26 职场文书
会计工作态度自我评价
2015/03/06 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书
2015年店长个人工作总结
2015/10/23 职场文书
使用canvas实现雪花飘动效果的示例代码
2021/03/30 HTML / CSS
Python实现滑雪小游戏
2021/09/25 Python
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers
Python使用Web框架Flask开发项目
2022/06/01 Python