基于canvas+uniapp的9宫格拼图游戏组件
基于 canvas+uniapp 的 9 宫格拼图游戏
涉及到的 canvas 基础知识
创建画布
<canvas id="’c1’"></canvas>
获取画笔
let context = uni.createCanvasContext(‘c1’)
绘图
/*** img原图片* x1,y1,w1,w2 从图片指定位置开始截取指定大小的图块* x2,y2,w2,h2 将截取的图片放置到画布指定位置,并设置大小*/ drawImage(img, x1, y1, w1, h1, x2, y2, w2, h2);
清除画布
/*** x,y 指定开始清除的位置* w,h 清除区域宽高*/ clearRect(x, y, w, h);
其他知识
获取 canvas 画布宽高,用于计算拼图图块大小
uni.createSelectorQuery().in(this).select('.canvas').boundingClientRect().exec(res => {if (res[0]) {// res[0].width;// res[0].height;}});
使用二维数组定义 9 宫格图块位置
num = [[1, 2, 3],[10, 11, 12],[20, 21, 22], ];
为保证拼图的随机性,需要将图块位置随机打乱,并定义标号为 22 的图块为空白图块,且始终保持在右下角,即 9 宫格游戏的第 9 个位置
移动滑块
- 当点击图块为空白图块相邻的图块时,交换两个图块的位置,即交换二维数组中对应的标号
- 位置更新后,重新绘制图块
判断游戏是否完成
- 每次交换完图块后,使用双层 for 循环,遍历 num 中数据,判断游戏是否完成
//判断游戏是否完成(每个图块位置顺序与num初始值相同即为完成拼图) checkWin() {let num = this.num;for (var i = 0; i < 3; i++) {for (var j = 0; j < 3; j++) {if (num[i][j] !== Number(i + '' + j)) {return false;}}}return true; }
整体代码
<template><view style="width: 100%; height: 100%"><canvas class="canvas" canvas-id="canvasId" @touchend="touchend" id="canvasId"></canvas></view>
</template>
<script>
export default {name: 'Jigsaw',props: ['url'],data() {return {context: '',isDone: false, //是否完成拼图canvasWidth: 0, //画布宽度canvasHeight: 0, //画布高度num: [[0, 1, 2], //[00, 01, 02],[10, 11, 12],[20, 21, 22],], //定义方块初始位置 22为空白图块};},mounted() {this.init();},methods: {init() {// 创建绘图对象let context = uni.createCanvasContext('canvasId');this.context = context;//获取画布大小uni.createSelectorQuery().in(this).select('.canvas').boundingClientRect().exec(res => {if (res[0]) {this.canvasWidth = res[0].width;this.canvasHeight = res[0].height;//画布大小获取成功后再画图this.generateNum();this.drawCanvas();}});},//打乱图块位置generateNum() {for (var i = 0; i < 50; i++) {//随机抽取其中一个数据var i1 = Math.round(Math.random() * 2);var j1 = Math.round(Math.random() * 2);//再随机抽取其中一个数据var i2 = Math.round(Math.random() * 2);var j2 = Math.round(Math.random() * 2);//最后一个图块位置不变if ((i1 == 2 && j1 == 2) || (i2 == 2 && j2 == 2)) {continue;}let tempNum = [].concat(this.num);var temp = tempNum[i1][j1];tempNum[i1][j1] = tempNum[i2][j2];tempNum[i2][j2] = temp;this.num = tempNum;}},//根据num图块位置,画图出拼图drawCanvas() {//远程图片需加载至本地uni.getImageInfo({src: this.url,success: img => {//清空画布this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);//画布宽高1/3 用于计算每个图块的位置及宽高let cw = this.canvasWidth / 3;let ch = this.canvasHeight / 3;//图片宽高1/3 用于计算每个图块的位置及宽高let iw = img.width / 3;let ih = img.height / 3;//使用双重for循环绘制3x3的拼图for (var i = 0; i < 3; i++) {for (var j = 0; j < 3; j++) {if (this.num[i][j] != 22) {//获取数值的十位数,即第几行var row = parseInt(this.num[i][j] / 10);//获取数组的个位数,即第几列var col = this.num[i][j] % 10;//在画布的相关位置上绘图this.context.drawImage(img.path,col * iw,row * ih,iw,ih,j * cw,i * ch,cw,ch);}}}this.context.draw(true);},fail(err) {console.log(err);},});},touchend(e) {if (this.isDone) {this.$u.toast('游戏已完成');return;}let x = e.changedTouches[0].x;let y = e.changedTouches[0].y;let w = this.canvasWidth / 3;var row = parseInt(y / w); //将x和y换算成几行几列var col = parseInt(x / w);if (this.num[row][col] != 22) {//如果当前点击的不是空白区域this.detectBox(row, col); //移动点击的方块this.drawCanvas(); //重新绘制画布this.isDone = this.checkWin(); //检查游戏是否成功if (this.isDone) {this.$emit('callback');}}},//判断游戏是否完成(每个图块位置顺序与num初始值相同即为完成拼图)checkWin() {let num = this.num;for (var i = 0; i < 3; i++) {for (var j = 0; j < 3; j++) {if (num[i][j] !== Number(i + '' + j)) {return false;}}}return true;},detectBox(i, j) {//如果点击的方块不在最上面一行if (i > 0) {//检测空白区域是否在当前方块的正上方if (this.num[i - 1][j] == 22) {//交换空白区域与当前方块的位置this.num[i - 1][j] = this.num[i][j];this.num[i][j] = 22;return;}}//如果点击的方块不在最下面一行if (i < 2) {//检测空白区域是否在当前方块的正下方if (this.num[i + 1][j] == 22) {//交换空白区域与当前方块的位置this.num[i + 1][j] = this.num[i][j];this.num[i][j] = 22;return;}}//如果点击的方块不在最左边一列if (j > 0) {//检测空白区域是否在当前方块的左边if (this.num[i][j - 1] == 22) {//交换空白区域与当前方块的位置this.num[i][j - 1] = this.num[i][j];this.num[i][j] = 22;return;}}//如果点击的方块不在最右边一列if (j < 2) {//检测空白区域是否在当前方块的右边if (this.num[i][j + 1] == 22) {//交换空白区域与当前方块的位置this.num[i][j + 1] = this.num[i][j];this.num[i][j] = 22;return;}}},},
};
</script>
<style lang="scss" scoped>
.canvas {height: 100%;width: 100%;
}
</style>
原文:https://blog.csdn.net/qq_38545425/article/details/128221249
基于canvas+uniapp的9宫格拼图游戏组件相关推荐
- A*算法实现9宫格拼图游戏最优解
目标:用A*算法解决拼图的最优路径解 A*算法介绍 A* (A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是许多其他问题的常用启发式算法. 在计算机科学中,A*算法作为Dij ...
- 基于Canvas的N宫格拼图
最近使用Canvas实现了一个N宫格拼图的游戏,感觉效果还是很不错的,不过我还是觉得九宫格就好了,太多了反而就复杂了.这里我就主要讲述九宫格的实现过程,其它的只是把数据结构扩大一下了. 实现效果 图片 ...
- JavaScript经典进阶:javascript – 9宫格 – 拼图
项目地址:javascript – 9宫格 – 拼图 总体思路 切图 ==>打乱顺序 ==>拖拽实现数据交换 实现过程中,遇到的问题 数据随机排序方法 Array.sort( functi ...
- 飞机大战HTML5游戏源码,基于Canvas制作的网页版飞机大战游戏+飞机大战手机端
简介: 飞机大战HTML5游戏源码是一款基于Canvas制作的网页版飞机大战游戏,画质精美的飞机大战手机端游戏源码 网盘下载地址: http://kekewangLuo.net/W1S2LQcqAT2 ...
- 十六宫格拼图(A*/IDA*)(曼哈顿距离)
传送门 迭代加深:通过单纯的深度优先搜索无法找出初始状态到最终状态的最短路径,但是重复进行限制最大深度的深度优先搜索(深度受限搜索)却可以.简单来说,就是在循环执行深度受限搜索的过程中逐步增加限制值l ...
- 1、迪文屏基于T5L_C51开发手势6宫格解锁
演示视频 1.概述 基于迪文屏DMG32240C028-03WTC屏的滑动手势6宫格解锁功能,该功能运用了触摸屏状态读取和坐标读取的功能(系统变量接口0x0016),绘图功能,需要配合变量图标显示等基 ...
- 使用自动化处理某手游四宫格拼图问题
今天玩游戏的时候碰到个四宫格的小游戏,想试试能不能通过自动化的方式自动完成. 游戏本身逻辑很简单,就是四个小块拼成一个完整图案,但让它自动点击完成的话,这个思考的过程比较有意思. 游戏图: 初始四个无 ...
- IDA*算法解十六宫格拼图问题
IDA*算法, ID(Iterative Deepening)指的是迭代加深. 它的思想是重复进行限制最大深度的深度优先搜索(此限制从某个最小值遍历到最大值), 也称为深度受限搜索. 一般情况下, 为 ...
- 【java】16宫格拼图游戏项目
这个游戏虽然不是很难,但是从中能帮我巩固很多多东西,比如接口的实现.类的继承等这些java面向对象的特点知识我都在写这个项目的过程中有了更深的理解. 这个游戏的机制就是监听到键盘中的上下左右方向键来对 ...
最新文章
- Ubuntu下常用命令
- AngularJS学习篇(十九)
- MySQL表完整性约束
- Spring MVC工作原理
- Java LocalDate类| getChronology()方法与示例
- 平均薪资29036的Python,零基础初学者如何入门?
- 微软符号服务器opencv的符号,Opencv Mat类详解和用法1
- PHP生成随机数;订单号唯一
- 吴恩达神经网络和深度学习-学习笔记-27-多任务学习
- PPT_设计师的十大秘诀
- java判断字符串是否是空,java判断字符串是否为空的方法
- 夜神模拟器怎么设置android版本号,adb连接夜神模拟器(包括安装adb,夜神模拟器)需要将夜神模拟器的版本号与adb版本一致...
- 0123能组成四位数c语言,用0123四个数字能组成多少个不同的三位数
- React中的SVG陷阱
- 基于asp.net742自驾游旅游服务网站的设计
- vue的组件的生命周期
- 人月神话 中文版 pdf
- 五种企业家,一定不要建自己的网站
- 关于宏的bypass学习
- MAX40026 280ps高速比较器
热门文章
- 中科院信工所考研经验整理(待更新)
- 微型机器学习,会是下一代AI革命吗?
- Linux系统监控命令整理汇总-掌握CPU,内存,磁盘IO等找出性能瓶颈
- 图片加载异常兜底方案
- 极具发展潜力的20项油气勘探开发新技术
- 福特汉姆大学计算机科学专业,福特汉姆大学计算机研究生
- OpenVINO整活(一) 输入分辨率
- sencha touch ajax params,sencha touch《实现ajax跨域请求》
- Bzoj 2563: 阿狸和桃子的游戏 题解
- 什么是局域网监控?是如何监控的...