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

这篇具有很好参考价值的文章主要介绍了python-游戏篇-初级-超级画板。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开发环境要求

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

  • 操作系统: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所示。
python-游戏篇-初级-超级画板,# python产品篇,python

程序运行效果如图2所示(说明:单击左侧的铅笔或者橡皮,然后单击加减号可以增加或者缩小宽度,选择一个颜色,即可在右侧绘制图形,或者擦除绘制的图形)。
python-游戏篇-初级-超级画板,# python产品篇,python

图2 项目主界面

VScode

python-游戏篇-初级-超级画板,# python产品篇,python

代码

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 = 1
        self.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 = True
        self.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.5
            size = 0.5 # 设置画笔最小尺寸为0.5
        elif size > 32: # 判断画笔尺寸大于32
            size = 32 # 设置画笔最大尺寸为32
        self.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 / length
        step_y = len_y / length
        for 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 = None
        self.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 = brush

    def 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 + 32
        y = 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 down
                    self.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 True
        return False

class 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:  # 退出事件
                    return
                elif 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)):  # 未点击画板按钮
                        pass
                    else:
                        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()  # 更新画板

效果

python-游戏篇-初级-超级画板,# python产品篇,python

PS:全部文档放下载处
python-游戏篇-初级-超级画板,# python产品篇,python文章来源地址https://www.toymoban.com/news/detail-835491.html

到了这里,关于python-游戏篇-初级-超级画板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 带你用Python制作超级经典的2048游戏(文末赠书)

    名字:阿玥的小东东 学习:Python、C/C++ 主页链接:阿玥的小东东的博客_CSDN博客-pythonc++高级知识,过年必备,C/C++知识讲解领域博主 目录 2048游戏Python实现 本期赠书 2048游戏是一款非常流行的益智游戏,玩家需要通过合并数字方块来获得更高的分数。本文将介绍如何使用Python语

    2024年02月11日
    浏览(48)
  • python-产品篇-游戏-成语填填乐

    无需其他文件,复制即用

    2024年02月19日
    浏览(31)
  • 【Python游戏开发】超级玛丽v1.0——《跟老吕学Python编程》附录资料

    在一个背景上,超级玛丽通过 空格键 跳跃,越过水管和飞弹 本次系统的软件开发及运行环境具体如下: 操作系统: Windows 10(WindowsXP以上系统均可运行) Python版本:Python 3.12.2(凡是3.0及以上版本均可运行) 开发工具:PyCharm(老吕比较习惯PyCharm和VS开发环境) 第三方模块

    2024年04月11日
    浏览(45)
  • 保姆级教你用Python制作超级玛丽游戏(文末赠书)

    名字:阿玥的小东东 学习:Python、C/C++ 主页链接:阿玥的小东东的博客_CSDN博客-pythonc++高级知识,过年必备,C/C++知识讲解领域博主 目录 贪吃蛇游戏 弹珠游戏 超级玛丽(爷青回~)

    2024年02月09日
    浏览(44)
  • 用Python编写的超级马里奥小游戏(基于Pygame)

    在本文中,我将向您展示如何使用Python编写一个简单的超级马里奥小游戏,使用Pygame库来处理游戏的图形和输入。 首先,我们需要确保已安装Pygame库。您可以使用以下命令在终端或命令提示符中安装Pygame: 一旦安装完成,我们就可以开始编写代码了。下面是完整的Python代码

    2024年01月16日
    浏览(50)
  • Unity游戏开发客户端面经——算法(初级)

    前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是 算法 常问问题总结,有帮助的可以收藏。           时间复杂度:O(n²)        :冒泡排序、选择排序、插入排序                 

    2024年03月22日
    浏览(48)
  • Unity游戏开发客户端面经——网络(初级)

    前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是 网络 常问问题总结,有帮助的可以收藏。 区别 UDP TCP 是否连接 不连接 面向连接 是否可靠 不可靠 可靠传输(传输过程中会丢失,但会重发)使用

    2024年02月01日
    浏览(45)
  • Unity游戏开发客户端面经——Unity(初级)

    前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是 Unity 常问问题总结,有帮助的可以收藏。          Awake — OnEnable — Start — FixedUpdate —Update  — LateUpdate— OnGUl — OnDisable — OnDestr

    2024年02月02日
    浏览(54)
  • Unity游戏开发客户端面经——热更新(初级)

    前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是 热更新 常问问题总结,有帮助的可以收藏。 1.1 为什么使用Lua作为热更新语言,不用C#         热更新本身对于资源热更新是非常容易的,Unit

    2023年04月20日
    浏览(45)
  • Unity游戏开发客户端面经——性能优化(初级)

    前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是 性能优化 常问问题总结,有帮助的可以收藏。 性能优化,主要聚焦在 内存、 CPU、GPU 三大方向上。 1.1 详细介绍    Unity内存占用组成 Unity(基本

    2024年03月22日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包