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.hqwc.cn/news/473197.html

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

相关文章

书生·浦语-模型评测opencompass

大预言模型评测 模型评测包括主管评测与客观评测 测试模型对提示词的敏感性&#xff0c;或通过提示词获得更准确地答案 主流评测框架 opencompass评测平台 作业

基于边缘计算的智能家居能源管理系统

一、项目背景 随着智能家居设备的普及&#xff0c;能源消耗问题日益凸显。为了更有效地管理家庭能源使用&#xff0c;减少浪费&#xff0c;并可能实现能源自给自足&#xff0c;我们提出了基于边缘计算的智能家居能源管理系统 该系统能够实时监控和分析家庭能源消耗数据&#xf…

精品springboot基于大数据技术的电商数据挖掘平台设计与实现购物商城

《[含文档PPT源码等]精品基于springboot基于大数据技术的电商数据挖掘平台设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端…

人工智能学习与实训笔记(七):神经网络之模型压缩与知识蒸馏

人工智能专栏文章汇总&#xff1a;人工智能学习专栏文章汇总-CSDN博客 本篇目录 七、模型压缩与知识蒸馏 7.1 模型压缩 7.2 知识蒸馏 7.2.1 知识蒸馏的原理 7.2.2 知识蒸馏的种类 7.2.3 知识蒸馏的作用 七、模型压缩与知识蒸馏 出于对响应速度&#xff0c;存储大小和能…

Capacity Maximization for Movable Antenna Enabled MIMO Communication

文章目录 II. SYSTEM MODEL AND PROBLEM FORMULATIONC. Problem Formulation III. PROPOSED ALGORITHMA. Alternating OptimizationB. Solution for Problem (P2-m) APPENDIX II. SYSTEM MODEL AND PROBLEM FORMULATION C. Problem Formulation 为了揭示支持 MA 的MIMO通信的…

【JS逆向+Python模拟API请求】逆向某一个略微中等的混淆网站,并模拟调用api请求 仅供学习。注:不是源代码混淆,而是一个做代码混淆业务的网站,

逆向日期&#xff1a;2024.02.16 使用工具&#xff1a;Node.js 加密方法&#xff1a;RSA标准库 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 AES解密处理&#xff08;直接解密即可&#xff09;&#xff08;crypto-js.js 标准算法&#xf…

JavaWeb-JDBC-API详解

一、JDBC介绍 二、JDBC 快速入门 package com.itheima.jdbc;import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;public class JDCBDemo {public static void main(String[] args) throws Exception {//1、注册驱动Class.forName("co…

LeetCode LCR 085. 括号生成

题目链接https://leetcode.cn/problems/IDBivT/description/ 正整数 n 代表生成括号的对数&#xff0c;请设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 class Solution {public List<String> generateParenthesis(int n) {List<String>…

【C++11】:unordered系列关联式容器

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关unordered系列关联式容器的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;…

重塑高校评价体系,缓解内卷,培养有远见的研究者

重塑高校评价体系&#xff0c;缓解内卷&#xff0c;培养有远见的研究者 摘要&#xff1a;当前高等教育和科研环境中普遍存在的“非升即走”制度&#xff0c;尽管表面上看似激励科研人员努力工作&#xff0c;但实际上反映了学术界的内卷状况。这一制度的设置在人才供过于求的背景…

ClickHouse--10--临时表、视图、向表中导入导出数据

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.临时表1.1 特征1.2 创建一个临时表 2.视图2.1 普通视图2.2 物化视图 3.向表中导入导出数据3.1 案例 1.临时表 1.1 特征 ClickHouse 支持临时表&#xff0c;临时表…

自然语言编程系列(四):GPT-4对编程开发的支持

在编程开发领域&#xff0c;GPT-4凭借其强大的自然语言理解和代码生成能力&#xff0c;能够深刻理解开发者的意图&#xff0c;并基于这些需求提供精准的编程指导和解决方案。对于开发者来说&#xff0c;GPT-4能够在代码片段生成、算法思路设计、模块构建和原型实现等方面给予开…