【像素画板】游戏地图编辑器-uniapp项目开发流程详解

嘿,用过像素画板没有哦,相信喜欢绘画的小朋友会对它感兴趣呢,用来绘制像素画非常好看,有没有发现,它是可以用来绘制游戏地图的,是不是很好奇,来一起看看吧。

像素画板,也叫像素画的绘图工具,可绘制游戏素材,也是游戏地图编辑器

文章目录

  • 游戏地图
  • 创建项目
  • 初始页面
  • 画板页面
    • 初始化数据
    • 初始化画布
    • 触摸操作
    • 绘制逻辑
  • 运行项目
    • 像素画
    • 迷宫地图

游戏地图

有个案例,绘制的游戏地图在以下两个游戏中都有用到,可以看一看这两篇文章

  • 地下迷宫游戏-微信小程序开发流程详解

创建项目

这里用HBuilderX开发工具来创建一个uniapp项目,

例如项目名填写uniapp_map_edit,依次选择如下图
在这里插入图片描述

  • 选择新建uni-app项目
  • 使用默认模板
  • Vue版本选择 3

初始页面

这时项目是自动创建好的,找一找初始页面,

页面文件在项目里/pages/index.index.vue,打开文件修改布局,

要在<template>...</template>标签中修改布局

布局结果显示如下图
在这里插入图片描述

可以看到,页面使用了表单组件form

  • 一个滑块slider,设置画板像素宽度,也就是列数;
  • 一个多行输入框textarea,这里放置输出的地图数据,可直接修改,复制;
  • 三个按钮button,见名知意,什么用途不用多说吧

点击编辑地图数据按钮,就会跳转到画板页面了,

要在<script>...</script>标签中去写页面跳转javascript逻辑代码,很简单,自己能做出来,这里就不讲

画板页面

这个画板页面文件是没有的,需要自己创建一个,

创建页面文件在项目里/pages/game/game.vue

然后打开,同样是在<template>标签中修改,写好布局,显示页面如下图
在这里插入图片描述

从页面上看,布局中只用了一个canvas,和复选框,还有7个迷你按钮组件,

  • 复选框checkbox-groupcheckbox是控制是否显示绘制网格线的;
  • 7个迷你按钮button size="mini",从中选择一个像素来绘制,每个像素点表示不同的颜色;
  • 像素点可以表示数字,例如0,1,2,3,4...e,f
  • 游戏地图是用字节数字来表示的,占用内存少;

初始化数据

同样也是在<script>标签里去写逻辑代码

写好初始化逻辑,代码如下,

const app = getApp()
export default {data() {return {isShowGrids: true, //是否显示网格//所有按钮数据:文本,数值,颜色buttons: [{text: '0',value: '0',color: 'transparent'},//...{text: '6',value: '6',color: '#909399'},],currentKey: '1' //定义选择的按钮,如不同的画笔按钮};},/** 页面加载完毕会执行到这里 */onReady() {let {map, //地图数据cols //列数} = app.getMapData() //获取初始页面保存好的数据this.cols = cols//执行加载初始化方法this.load(map)},methods:{//...onTouchStart(e){...},onTouchMove(e){...},onTouchEnd(e){...},}
}

data()方法返回的是页面布局中使用到的数据,

做到这里,上面的画布页面就会显示好底部的一排按钮了,

如果显示效果不一样,就要调整布局对应样式,就在<style>...</style>标签中写CSS样式,

初始化画布

还有就是画布,现在还没有显示出来,继续写初始化画布代码,

methods里写加载的load(map)方法,代码如下

load(map) {const {cols} = thisuni.createSelectorQuery().select('#' + canvasId).fields({size: true}, res => {//定义画布数据this.canvasData = {canvas: {width: res.width,height: res.height},ctx: uni.createCanvasContext(canvasId)};//调用初始化画布方法this.initCanvas(map, cols || 24)}).exec()
},

同样的,调用的initCanvas(map, cols)方法也是在methods里面写,代码如下

initCanvas(map, cols) {const {ctx,canvas} = this.canvasData//计算出每个单元格大小const size = Math.floor(canvas.width / cols)//计算出铺满网格的行数const rows = Math.floor(canvas.height / size)//...const grids = []//...// 绘制网格,r是行数,c是列数for (let r = 0, i = 0; r < rows; r++) {for (let c = 0; c < cols; c++, i++) {let g = {x: c * size + paddingLeft, //位置x paddingLeft是左边距y: r * size + paddingTop,//...v: '0' //像素初始数据}//...grids.push(g)}}//将计算出的数据放到canvasData数据中,下次会读取到Object.assign(this.canvasData, {grids, //这是网格的数据size,//...rows})//调用重新绘制方法this.redraw()
},

触摸操作

画布显示出来以后,就要实现触摸绘制,

看之前的代码,有如下三个方法,分别是触摸开始,移动,结束事件调用的方法,就在这方法中实现

export default {//...methods:{//...onTouchStart(e){...},onTouchMove(e){...},onTouchEnd(e){...},}
}

在布局中的canvas组件需要加上属性关联绑定上面的三个方法

当用户触摸画布时,就在画布中画出一个点就可以了,代码如下

onTouchStart(e) {let touch1 = e.touches[0]//调用此方法,根据第一个触摸点查找网格中单元格的索引let index = this.findGridIndex(touch1);//如果没有在网格内,就返回if (index < 0) return;//...这是第二个触摸点,如果有的话,就实现触摸拖动像素点,来达到准确绘制let touch2 = e.touches[1]//...省略了//如果是点击,直接调用触摸移动方法即可,避免重复写this.onTouchMove(e)
},

调用触摸移动方法里实现了如何绘制像素点,代码如下

onTouchMove(e) {//如果是同时存在两个触摸点,就是拖动操作let isMove = e.touches.length > 1let touch = isMove ? e.touches[1] : e.touches[0];const {grids} = this.canvasData;const {currentKey} = this;if (isMove && this.selectGrids.grid) {//...处理拖动操作的}let index = this.findGridIndex(touch);if (index < 0) return;let grid = grids[index];//...//更新指定的像素信息Object.assign(grid, {v: currentKey,color: this.findCurrentColor(currentKey) //将数值转换为按钮对应的颜色方法});//调用重绘方法this.redraw();
},

这个触摸移动方法可以实现连续绘制像素点,就像画一条线,

在触摸结束的方法这里,如下代码,

onTouchEnd(e) {if (!e || e.touches.length > 0) return//...触摸多点触摸操作的
},

这个触摸结束方法是可有可无的,如果实现多点触摸就要去写

绘制逻辑

知道为什么叫重绘方法吗,它就用刷新逻辑来实现的,

绘制方法redraw(),代码如下,先擦干净,再画上去

redraw() {const {canvas,ctx,grids,size,rows,cols} = this.canvasDataconst {isShowGrids} = this//擦画板ctx.clearRect(0, 0, canvas.width, canvas.height)//设置画笔颜色ctx.strokeStyle = '#000000'ctx.fillStyle = '#ffffff'//画背景色,如果想背景透明,就注释掉这一行ctx.fillRect(0, 0, canvas.width, canvas.height)//定义单元格的一半大小let r = size / 2;for (let r = 0; r < rows; r++) {for (let c = 0; c < cols; c++) {let g = grids[r * cols + c]ctx.beginPath()if (g.v != '0') {//画颜色的ctx.fillStyle = g.colorctx.fillRect(g.x, g.y, size, size)} else if (isShowGrids) {//画网格的ctx.strokeRect(g.x, g.y, size, size)}}}//最后调用这个方法就绘制出来了ctx.draw(true)
},

看上面的方法是不是很简单,容易理解呢

运行项目

讲到这里,像素画板的小程序项目基本上就算做好了,可以编译运行,接下来看看效果

像素画

想当像素画板用,看看作者随便画的一个二哈,如下图,
在这里插入图片描述

这是像素画,笔者画得好看吗 (^o^);
对画画感兴趣的话,就自己想象画出来也好看的

如果调整的像素太细的话,或者网格列数过多,这是不好控制的,

这样,就要用两个手指触摸操作,项目里实现多点触摸操作逻辑是有点复杂的,

实现操作就是用一个手指按住画板,另一个手指去拖动,就会发现按住的像素点拖出来了,继续拖动到指定的位置即可,这就准确绘制了

迷宫地图

要想用来绘制游戏地图,例如迷宫地图,运行效果动图如下,
请添加图片描述

底部最后边的按钮是作者在项目里新加的预览图片功能,可以保存为图片的;
绘制好返回初始页面,可以看到显示导出的地图数据,

从上图中可以看到画出来导出的一串数字,点击复制地图数据按钮,然后粘贴到自己编写的小游戏程序中当新关卡地图用,

还可以绘制出2d像素人,像素地图,瓦片地图等,能想到的你都能用得上吧

例如,给地下迷宫游戏项目添加新的游戏地图,用法同如下代码

// 迷宫地图数据
const mapData1 = {map:' 111111111111111111111111101100010001000000000001000101101010101110101111111010101101010100000101000000010101101010111111101011111110101101010000000100010000000001101011101110101111111111101101000101000101000000000101101110101011101111111110101100010001010100010000000101111011111010111010111111101100010100010001010000000001101110101110101011101111111100000101000101000101000001111011101111101110101111101100010100000100000100000001101110111111111111101111101100000100000001000101000001111110101111101110111011111100000101000001010000010001101111101011111011111010101100000001010000010001000101111111111010101110101111101100000000010101000100000001101111101110101111101111101100000100000100000101000001111111111111111110111111111'cols: 27
}

导出的地图数据很长很长,粘贴时把后面多出的一串数字0去掉即可

想要项目源码在点这里查看下载,或者直接点这里搜索:像素画板,在本博客站内请放心下载,感谢支持!

可能手机上看不到,请改用电脑浏览器查看

请添加图片描述

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

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

相关文章

Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线(实例分析)

Visual Studio 使用MFC 单文档工程从创建到实现绘制单一颜色直线和绘制渐变颜色的直线 本文主要从零开始创建一个MFC单文档工程然后逐步实现添加按键&#xff08;事件响应函数&#xff09;&#xff0c;最后实现单一颜色直线的绘制与渐变色直线的绘制o(&#xffe3;▽&#xffe…

一个用c#瞎写的sftp工具

0.下载地址 https://wwus.lanzouj.com/iOZUv1gkgpze 密码:123456 1.能进行单个和批量下载, 没有弄上传 2.速度奇差,可能是某些地方没弄好.有一定的进度显示,但是不太准. 3.很多地方没弄好,有能力的自己弄一下 4.在app.config文件配置sftp

在 ArcGIS 软件中添加左斜宋体(东体)的方法与步骤

河流水系在作图时一般设置为左斜宋体&#xff08;东体&#xff09;、蓝色&#xff0c;比如黄河、青海湖等&#xff0c;如下图所示&#xff1a; 标准地图水系注记 下面讲解如何在 ArcGIS 软件中添加左斜宋体&#xff08;东体&#xff09;&#xff0c;首先需要下载左斜宋体&#…

【合集】从Java基础到JavaWeb网络开发——Java基础文章合集 JavaWeb网络开发文章合集

前言 本篇博客是Java开发的合集文章&#xff0c;内容涵盖了Java基础相关的博客&#xff0c;JavaWeb开发相关的博客&#xff0c;并且给出了小项目的案例。 目录 前言引出Java基础1、基本数据类型2、数组和集合List3、运算符4、逻辑控制5、IO流6、面向对象初步7、数据库入门8、J…

笔记64:Bahdanau 注意力

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第10章&#xff1a;动手学深度学习~注意力机制 a a a a a a a a a a a

玩转大数据4:大数据的崛起与应用领域探索

图片来源网络 引言 在当今数字化时代&#xff0c;大数据正以前所未有的速度和规模崛起。大数据的出现不仅改变了企业和组织的经营模式&#xff0c;也对我们的社会生活带来了深刻的影响。Java作为一种广泛使用的编程语言&#xff0c;在大数据领域发挥着重要的作用。本文将重点…

计算机毕业设计 基于协同推荐的白酒销售管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

前端页面转pdf

首先&#xff0c;需要安装两个库 html2canvasjspdf 先引入这个公用的html转pdf的方法 /**path:src/utils/htmlToPdf.jsname:导出页面为pdf格式 **/ import html2Canvas from "html2canvas1.4.1"; import JsPDF from "jspdf2.5.1";const htmlToPdf {get…

机器学习笔记 - 什么是3D语义场景完成/补全?

一、什么是3D语义场景补全? 3D 语义场景完成(Semantic Scene Completion)是一种机器学习任务,涉及以体素化形式预测给定环境的完整3D场景(完成3D形状的同时推断场景的 3D 语义分割的任务)。这是通过使用深度图和为场景提供上下文的可选 RGB 图像来完成的。目标是以一种可轻…

android trace文件的抓取与查看方法

本地手机抓取trace 解压android trace抓取相关文件 找到config.pbtx文件&#xff0c;连接手机push进去 # push config.pbtx &#xff0c;/data/local/tmp/为自定义push到的目录 adb push config.pbtx /data/local/tmp/ adb shell # 抓取trace&#xff0c; /data/local/tmp/…

多线程(初阶七:阻塞队列和生产者消费者模型)

一、阻塞队列的简单介绍 二、生产者消费者模型 三、模拟实现阻塞队列 一、阻塞队列的简单介绍 首先&#xff0c;我们都知道&#xff0c;队列是先进先出的一种数据结构&#xff0c;而阻塞队列&#xff0c;是基于队列&#xff0c;做了一些扩展&#xff0c;在多线程有就非常有意…

【Node.js】笔记整理 3 -npm

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

Redis--14--BigKey 和 热点Key

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 BigKey1.什么是bigkey2.bigkey的危害3.发现bigkeyscan 4.解决bigkey 什么是热点Key&#xff1f;该如何解决1. 产生原因和危害原因危害 2.发现热点key预估发现客户端…

深入理解贝叶斯分类与朴素贝叶斯模型(Naive Bayes, NB):从基础到实战

目录 贝叶斯分类 公式 决策规则 优点 贝叶斯分类器的例子——垃圾邮件问题 1. 特征&#xff08;输入&#xff09;&#xff1a; 2. 类别&#xff1a; 3. 数据&#xff1a; 4. 模型训练&#xff1a; 注&#xff1a;类别先验概率 5. 模型预测&#xff1a; 朴素贝叶斯模…

基于SSM框架开发的酒店后台管理系统

基于SSM框架开发的酒店后台管理系统 文章目录 基于SSM框架开发的酒店后台管理系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 酒店管理系统是一个集客房预订、前台管理、客户服务、财务管理等功能于一体的综合性软件系统。它能够帮助酒店高效地…

爬虫-xpath篇

1.xpath的基础语法 表达式描述nodename选中该元素/从根节点选取、或者是元素和元素间的过渡//从匹配选择的当前节点选择文档中的节点&#xff0c;而不考虑它们的位置.选取当前节点…选取当前节点的父节点选取属性text()选取文本 举例&#xff1a; 路径表达式结果html选择html元…

shell编程系列(10)-使用paste拼接列

使用paste拼接列 前言使用paste拼接列拼接两个文件 结语 前言 在前面的文章中讲解了使用cut命令选择列&#xff0c;这篇文章我们介绍使用paste命令拼接列&#xff0c;其实这个命令的使用场景很有限&#xff0c;做科研的同学可能才会用到&#xff0c;但是却非常好用&#xff0c…

游戏被流量攻击会有什么样的影响,该用什么样的防护方式去处理

德迅云安全-领先云安全服务与解决方案提供商德迅云游戏盾专门针对游戏进行防护&#xff0c;可免费提供防护方案~ 如果游戏被流量攻击会产生以下影响&#xff1a; 服务器过载&#xff1a;流量攻击会导致游戏服务器接收到的请求数量急剧增加&#xff0c;超出服务器的处理能力。这…

vue3中如何实现事件总线eventBus

使用插件 由于vue3中 “$ on”&#xff0c;$ off 和 $ once 实例方法已被移除&#xff0c;组件实例不再实现事件触发接口 所以我们可以使用官方推荐的这个第三方库实现同样的效果 mitt https://github.com/developit/mitt 安装 pnpm install mitt -S挂载全局写法 main.ts 初始…

网络编程之套接字

端口 && IP 在学习套接字编程之前&#xff0c;我们必须了解一下前缀知识。首先是IP和端口的作用。 在这之前&#xff0c;我们要明白一件事。那就是把数据从一台主机发送到另一台主机&#xff0c;是目的吗&#xff1f;&#xff1f;&#xff1f;当然不是&#xff01;&a…