python-游戏篇-初级-超级画板

文章目录

  • 开发环境要求
  • 运行方法
    • PyCharm
    • VScode
  • 代码
    • main.py
    • tools.py
  • 效果

开发环境要求

本系统的软件开发及运行环境具体如下。

  • 操作系统:Windows 7、Windows 10。
  • Python版本:Python 3.7.1。
  • 开发工具:PyCharm 2018。
  • Python内置模块:os、sys、time、math。
  • 第三方模块:pygame。
    注意:在使用第三方模块时,首先需要使用pip install命令安装该模块,例如,安装pygame模块,可以在Python命令窗口中执行以下命令:
pip install pygame

运行方法

PyCharm

打开PyCharm开发环境,然后打开源码文件夹,找到drawBoard文件夹,按下<Ctrl+C>进行复制,切换到PyCharm开发环境,在左侧列表中按下<Ctrl+V>进行粘贴,展开drawBoard文件夹,双击main.py打开该文件,然后在右侧窗口中单击右键,选择“Run’main”即可运行程序,如图1所示。
图1  选择“Run’main”即可运行程序

程序运行效果如图2所示(说明:单击左侧的铅笔或者橡皮,然后单击加减号可以增加或者缩小宽度,选择一个颜色,即可在右侧绘制图形,或者擦除绘制的图形)。
在这里插入图片描述

图2 项目主界面

VScode

在这里插入图片描述

代码

main.py

# -*- coding: utf-8 -*-
import os
import sys
import time# 导入Pygame
try:import pygame
except ModuleNotFoundError:print('正在安装pygame,请稍等...')os.system('pip install pygame') # 安装pygame模块
import tools # 导入tools模块# 检测Python版本号
__MAJOR, __MINOR, __MICRO = sys.version_info[0], sys.version_info[1], sys.version_info[2]
if __MAJOR < 3:print('Python版本号过低,当前版本为 %d.%d.%d, 请重装Python解释器' % (__MAJOR, __MINOR, __MICRO))time.sleep(2)exit()if __name__ == '__main__':# 创建Paint类的对象paint = tools.Paint()try:paint.run()  # 启动主窗口except Exception as e:print(e)

tools.py

# -*- coding: utf-8 -*-
import math
import pygame
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE, MOUSEBUTTONDOWN, MOUSEMOTION, MOUSEBUTTONUP  # 导入事件class Brush:"""画笔类"""def __init__(self, screen):self.screen = screen  # 屏幕对象self.color = (0, 0, 0)  # 颜色self.size = 1  # 大小self.drawing = False  # 是否绘画self.last_pos = None  # 鼠标滑过最后的位置self.space = 1self.brush = pygame.image.load("img/pen.png").convert_alpha()  # 画笔图片self.brush_now = self.brush.subsurface((0, 0), (1, 1))  # 初始化画笔对象# 开始绘画def start_draw(self, pos):self.drawing = Trueself.last_pos = pos # 记录鼠标最后位置# 结束绘画def end_draw(self):self.drawing = False# 获取当前使用画笔def get_current_brush(self):return self.brush_now # 获取当前使用的画笔对象def set_size(self, size):  # 设置画笔大小if size < 0.5: # 判断画笔尺寸小于0.5size = 0.5 # 设置画笔最小尺寸为0.5elif size > 32: # 判断画笔尺寸大于32size = 32 # 设置画笔最大尺寸为32self.size = size # 设置画笔尺寸# 生成画笔对象self.brush_now = self.brush.subsurface((0, 0), (size * 2, size * 2))# 获取画笔大小def get_size(self):return self.size# 设置画笔颜色def set_color(self, color):self.color = color # 记录选择的颜色for i in range(self.brush.get_width()): # 获取画笔的宽度for j in range(self.brush.get_height()): #获取画笔的高度# 以指定颜色显示画笔self.brush.set_at((i, j), color + (self.brush.get_at((i, j)).a,))# 获取画笔颜色def get_color(self):return self.color# 绘制动作def draw(self, pos):if self.drawing: # 判断是否开始绘画for p in self._get_points(pos):# 在两点之间的每个点上都画上实心点pygame.draw.circle(self.screen, self.color, p, int(self.size))self.last_pos = pos # 记录画笔最后位置# 获取两点之间所有的点位,该函数通过对鼠标坐标前一次记录点与当前记录点之间进行线性插值# 从而获得一系列点的坐标,从而使得绘制出来的画笔痕迹更加平滑自然def _get_points(self, pos):points = [(self.last_pos[0], self.last_pos[1])]len_x = pos[0] - self.last_pos[0]len_y = pos[1] - self.last_pos[1]length = math.sqrt(len_x ** 2 + len_y ** 2)step_x = len_x / lengthstep_y = len_y / lengthfor i in range(int(length)):points.append((points[-1][0] + step_x, points[-1][1] + step_y))# 对 points 中的点坐标进行四舍五入取整points = map(lambda x: (int(0.5 + x[0]), int(0.5 + x[1])), points)return list(set(points)) # 去除坐标相同的点class Menu:"""菜单类"""def __init__(self, screen):self.screen = screen  # 初始化窗口self.brush = Noneself.colors = [  # 颜色表(0xff, 0x00, 0xff), (0x80, 0x00, 0x80),(0x00, 0x00, 0xff), (0x00, 0x00, 0x80),(0x00, 0xff, 0xff), (0x00, 0x80, 0x80),(0x00, 0xff, 0x00), (0x00, 0x80, 0x00),(0xff, 0xff, 0x00), (0x80, 0x80, 0x00),(0xff, 0x00, 0x00), (0x80, 0x00, 0x00),(0xc0, 0xc0, 0xc0), (0x00, 0x00, 0x00),(0x80, 0x80, 0x80), (0x00, 0xc0, 0x80),]self.eraser_color = (0xff, 0xff, 0xff) # 初始颜色# 计算每个色块在画板中的坐标值,便于绘制self.colors_rect = []for (i, rgb) in enumerate(self.colors):  # 方块颜色表rect = pygame.Rect(10 + i % 2 * 32, 254 + i / 2 * 32, 32, 32)self.colors_rect.append(rect)self.pens = [  # 画笔图片pygame.image.load("img/pen.png").convert_alpha(),]self.erasers = [  # 橡皮图片pygame.image.load("img/eraser.png").convert_alpha(),]self.erasers_rect = []for (i, img) in enumerate(self.erasers):  # 橡皮列表rect = pygame.Rect(10, 10 + (i + 1) * 64, 64, 64)self.erasers_rect.append(rect)self.pens_rect = []for (i, img) in enumerate(self.pens):  # 画笔列表rect = pygame.Rect(10, 10 + i * 64, 64, 64)self.pens_rect.append(rect)self.sizes = [  # 加减号图片pygame.image.load("img/plus.png").convert_alpha(),pygame.image.load("img/minus.png").convert_alpha()]# 计算坐标,便于绘制self.sizes_rect = []for (i, img) in enumerate(self.sizes):rect = pygame.Rect(10 + i * 32, 138, 32, 32)self.sizes_rect.append(rect)def set_brush(self, brush):  # 设置画笔对象self.brush = brushdef draw(self):  # 绘制菜单栏for (i, img) in enumerate(self.pens): # 绘制画笔样式按钮self.screen.blit(img, self.pens_rect[i].topleft)for (i, img) in enumerate(self.erasers): # 绘制橡皮按钮self.screen.blit(img, self.erasers_rect[i].topleft)for (i, img) in enumerate(self.sizes): # 绘制 + - 按钮self.screen.blit(img, self.sizes_rect[i].topleft)# 绘制用于实时展示画笔的小窗口self.screen.fill((255, 255, 255), (10, 180, 64, 64))pygame.draw.rect(self.screen, (0, 0, 0), (10, 180, 64, 64), 1)size = self.brush.get_size()x = 10 + 32y = 180 + 32# 在窗口中展示画笔pygame.draw.circle(self.screen, self.brush.get_color(), (x, y), int(size))for (i, rgb) in enumerate(self.colors): # 绘制色块pygame.draw.rect(self.screen, rgb, self.colors_rect[i])def click_button(self, pos):# 点击加减号事件for (i, rect) in enumerate(self.sizes_rect):if rect.collidepoint(pos):if i:  # i == 1, size downself.brush.set_size(self.brush.get_size() - 0.5)else:self.brush.set_size(self.brush.get_size() + 0.5)return True# 点击颜色按钮事件for (i, rect) in enumerate(self.colors_rect):if rect.collidepoint(pos):self.brush.set_color(self.colors[i])return True# 点击橡皮按钮事件for (i, rect) in enumerate(self.erasers_rect):if rect.collidepoint(pos):self.brush.set_color(self.eraser_color)return Truereturn Falseclass Paint:"""窗口绘制类"""def __init__(self):self.screen = pygame.display.set_mode((800, 600)) # 显示窗口pygame.display.set_caption("超级画板") # 设置窗口标题self.clock = pygame.time.Clock() # 控制速率self.brush = Brush(self.screen) # 创建画刷对象self.menu = Menu(self.screen) # 创建窗口菜单self.menu.set_brush(self.brush) # 设置默认画刷def clear_screen(self):self.screen.fill((255, 255, 255))  # 填充空白def run(self):self.clear_screen() # 清除屏幕while True:# 设置fps,表示每秒执行30次(注意:30不是毫秒数)self.clock.tick(30)for event in pygame.event.get(): # 遍历所有事件if event.type == QUIT:  # 退出事件returnelif event.type == KEYDOWN:  # 按键事件# 按ESC键清空画板if event.key == K_ESCAPE:  # ESC按键事件self.clear_screen()elif event.type == MOUSEBUTTONDOWN:  # ;鼠标左键按下事件if ((event.pos)[0] <= 74 and self.menu.click_button(event.pos)):  # 未点击画板按钮passelse:self.brush.start_draw(event.pos)  # 开始绘画elif event.type == MOUSEMOTION:  # 鼠标移动事件self.brush.draw(event.pos)  # 绘画动作elif event.type == MOUSEBUTTONUP:  # 鼠标左键松开事件self.brush.end_draw()  # 停止绘画self.menu.draw()pygame.display.update()  # 更新画板

效果

在这里插入图片描述

PS:全部文档放下载处
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/255229.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13. Threejs案例-绘制3D文字

13. Threejs案例-绘制3D文字 实现效果 知识点 FontLoader 一个用于加载 JSON 格式的字体的类。 返回 font&#xff0c;返回值是表示字体的 Shape 类型的数组。 其内部使用 FileLoader 来加载文件。 构造器 FontLoader( manager : LoadingManager ) 参数类型描述managerLo…

微信小程序(三十四)搜索框-带历史记录

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.搜索框基本模板 2.历史记录基本模板 3.细节处理 源码&#xff1a; index.wxml <!-- 1.点击搜索按钮a.非空判断b.历史记录&#xff08;去重&#xff09;c.清空搜索框d.去除前后多余空格2.删除搜索 3.无搜索…

问题:老年人心理健康维护与促进的原则为________、________、发展原则。 #媒体#知识分享

问题&#xff1a;老年人心理健康维护与促进的原则为________、________、发展原则。 参考答案如图所示

深度学习驱动下的自然语言处理进展及其应用前景

文章目录 每日一句正能量前言技术进步应用场景挑战与前景自然语言处理技术当前面临的挑战未来的发展趋势和前景 伦理和社会影响实践经验后记 每日一句正能量 一个人若想拥有聪明才智&#xff0c;便需要不断地学习积累。 前言 自然语言处理&#xff08;NLP&#xff09;是一项正…

【C++第二阶段】空指针访问成员函数常成员函数常成员属性

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 空指针访问成员函数常成员函数&常成员属性 空指针访问成员函数 类对象类型的空指针可以访问成员函数&#xff0c;但是不能够访问带有成员属性的成员函数。…

[C#] 如何使用ScottPlot.WPF在WPF桌面程序中绘制图表

什么是ScottPlot.WPF&#xff1f; ScottPlot.WPF 是一个开源的数据可视化库&#xff0c;用于在 WPF 应用程序中创建高品质的绘图和图表。它是基于 ScottPlot 库的 WPF 版本&#xff0c;提供了简单易用的 API&#xff0c;使开发人员能够通过简单的代码创建各种类型的图表&#…

二十、K8S-1-权限管理RBAC详解

目录 k8s RBAC 权限管理详解 一、简介 二、用户分类 1、普通用户 2、ServiceAccount 三、k8s角色&角色绑定 1、授权介绍&#xff1a; 1.1 定义角色&#xff1a; 1.2 绑定角色&#xff1a; 1.3主体&#xff08;subject&#xff09; 2、角色&#xff08;Role和Cluster…

算法学习——LeetCode力扣栈与队列篇2

算法学习——LeetCode力扣栈与队列篇2 150. 逆波兰表达式求值 150. 逆波兰表达式求值 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。…

数据结构 - 线索树

一、 为什么要用到线索二叉树&#xff1f; 我们先来看看普通的二叉树有什么缺点。下面是一个普通二叉树&#xff08;链式存储方式&#xff09;&#xff1a; 乍一看&#xff0c;会不会有一种违和感&#xff1f;整个结构一共有 7 个结点&#xff0c;总共 14 个指针域&#xff0c…

IDEA中Git的使用小技巧-Toolbar(工具栏)的设置

目录 1 前言 2 步骤 2.1 打开设置 2.2 找到Menus and Toolbars 2.3 Menus and Toolbars界面的介绍 2.4 选择工具 2.5 查看 1 前言 工具栏的合理运用&#xff0c;能够极大程度上为我们省时省力 &#xff0c;接下来我将以Git工具的添加&#xff0c;介绍如何定制我们IDEA…

HarmonyOS 鸿蒙应用开发(十、第三方开源js库移植适配指南)

在前端和nodejs的世界里&#xff0c;有很多开源的js库&#xff0c;通过npm(NodeJS包管理和分发工具)可以安装使用众多的开源软件包。但是由于OpenHarmony开发框架中的API不完全兼容V8运行时的Build-In API&#xff0c;因此三方js库大都需要适配下才能用。 移植前准备 建议在适…

【开源】JAVA+Vue.js实现计算机机房作业管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课时管理模块2.4 学生作业模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程表3.2.2 课时表3.2.3 学生作业表 四、系统展示五、核心代码5.1 查询课程数据5.2 新增课时5.3 提交作…

React18原理: Fiber架构下的单线程CPU调度策略

概述 React 的 Fiber 架构, 它的整个设计思想就是去参考CPU的调度策略CPU现在都是多核多进程的&#xff0c;重点研究的是 CPU是单核单线程&#xff0c;它是如何调度的?为什么要去研究单线程的CPU&#xff1f; 浏览器中的JS它是单线程的JS 的执行线程和浏览器的渲染GUI 是互斥…

倒计时61天

M-智乃的36倍数(normal version)_2024牛客寒假算法基础集训营3 (nowcoder.com) //非ac代码,超时了,54.17/100#include<bits/stdc.h> using namespace std; const int N1e55; const int inf0x3f3f3f3f; #define int long long int n; string s1[N]; void solve() {cin>…

STM32的ADC电压采集

时间记录&#xff1a;2024/2/9 一、ADC相关知识点 &#xff08;1&#xff09;STM32的ADC时钟不要超过14MHz&#xff0c;不然结果的准确率将下降 &#xff08;2&#xff09;ADC分为规则组和注入组&#xff0c;规则组相当于正常运行的程序&#xff0c;注入组相当于中断可以打断…

随机MM引流源码PHP开源版

引流源码最新随机MM开源版PHP源码&#xff0c;非常简洁好看的单页全解代码没任何加密 直接上传即可用无需数据库支持主机空间

RabbitMQ-4.MQ的可靠性

MQ的可靠性 4.MQ的可靠性4.1.数据持久化4.1.1.交换机持久化4.1.2.队列持久化4.1.3.消息持久化 4.2.LazyQueue4.2.1.控制台配置Lazy模式4.2.2.代码配置Lazy模式4.2.3.更新已有队列为lazy模式 4.MQ的可靠性 消息到达MQ以后&#xff0c;如果MQ不能及时保存&#xff0c;也会导致消…

如何使用websocket

如何使用websocket 之前看到过一个面试题&#xff1a;吃饭点餐的小程序里&#xff0c;同一桌的用户点餐菜单如何做到的实时同步&#xff1f; 答案就是&#xff1a;使用websocket使数据变动时服务端实时推送消息给其他用户。 最近在我们自己的项目中我也遇到了类似问题&#xf…

全功能的屏幕截图工具 - PicPick

全功能的屏幕截图工具 - PicPick 1. PicPick1.1. PicPick 中文1.2. Hot keys References 1. PicPick https://picpick.app/zh/ https://picpick.app/en/ A full-featured screen capture and recording tool, Intuitive image editor, color picker, color palette, pixel-ru…

re:从0开始的CSS学习之路 9. 盒子水平布局

0. 写在前面 过年也不能停止学习&#xff0c;一停下就难以为继&#xff0c;实属不应 1. 盒子的水平宽度 当一个盒子出现在另一个盒子的内容区时&#xff0c;该盒子的水平宽度“必须”等于父元素内容区的宽度 盒子水平宽度&#xff1a; margin-left border-left padding-lef…