乱拼小游戏
概述:本次demo是我的选修期末作业,让我们完成一个项目,让我们独自发挥自我想象力和创造力写出自己的基于鸿蒙开发的小项目,于是我借鉴网上大佬,然后写出自己的项目。
前言:
本次开发所需要工具:DevEco Studio(主) Google 浏览器(次)以上工具下载安装使用简单。
成果展示:
创建项目
新建项目New Project,点击Empty Ability ,Next,选择Language选择JS,API版本这里用的是6,其余默认即可,点击Finish。
正文:
添加两个游戏模式入口按钮:跳转进入游戏页面,根据传值不同拼图格式也不同。,来设置出两种模式。
设置按钮监听机制进行不同模式下的跳转至jigsaw
设置首页图片:用background-image设置首页。
总体分两部分来,一是用两个canvas组件来显示原图和拼图,二是用stack布局设置游戏完成时显示的弹窗。
下面四个按钮:用于实现返回首页、换图片、重新开始和提示等功能。
设置一个计时器:进行通关计时。。
功能的逻辑实现
首页由前端就可以看到使用一个传值来进行游戏模式的选择,上面已经提到了。
根据上面传过来的值,进行游戏格子的分割, 进行初始化,根据当前图片序号与图片总数求余来使用指定图片,并使用二维数组来进行页面显示等。
进行画面格子线的分割:用canvas组件的drawImage方法裁切源图片分出格子,借鉴的大佬的。
//画网格 drawGrids() { context = this.$refs.canvas.getContext('2d'); for (let row = 0; row < this.block; row++) { for (let column = 0; column < this.block; column++) { let order = grids[row][column].toString(); context.fillStyle = "#BBADA0"; let leftTopX = column * (MARGIN + SIDELEN) + MARGIN; let leftTopY = row * (MARGIN + SIDELEN) + MARGIN; context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN); context.font = "28px"; if (order != "0") { context.fillStyle = "#000000"; let offsetX = (3 - order.length) * (SIDELEN / 8); let offsetY = (SIDELEN - 14); context.drawImage(this.img, (CUT_SID + MARGIN) * ((grids[row][column] - 1) % this.block) + MARGIN, //原图img的X轴裁剪起点 (CUT_SID + MARGIN) * (Math.floor((grids[row][column] - 1) / this.block)) + MARGIN, //原图img的Y轴裁剪起点 CUT_SID, CUT_SID, //原图X轴,Y轴方向的裁剪长度 leftTopX, leftTopY, //画布X轴,Y轴画图的起点 SIDELEN, SIDELEN); //画布X轴,Y轴画图的长度// console.info(JSON.stringify(this.img));// console.info("拼图——宽:" + this.img.width + ",高:" + this.img.height); if(true == this.tip) { context.fillText(order, leftTopX + offsetX, leftTopY + offsetY); } else { context.fillText("", leftTopX + offsetX, leftTopY + offsetY); } } else { if(true == this.isShow) { context.drawImage(this.img,(CUT_SID + MARGIN) * ((Math.pow(this.block, 2) - 1) % this.block) + MARGIN, //原图img的X轴裁剪起点(CUT_SID + MARGIN) * (Math.floor((Math.pow(this.block, 2) - 1) / this.block)) + MARGIN, //原图img的Y轴裁剪起点CUT_SID, CUT_SID, //原图X轴,Y轴方向的裁剪长度leftTopX, leftTopY, //画布X轴,Y轴画图的起点SIDELEN, SIDELEN); //画布X轴,Y轴画图的长度 } else { context.drawImage(this.img, 0, 0, 0, 0, 0, 0, SIDELEN, SIDELEN); } } } } },
游戏开始,随机进行拼图的打乱。
设置事件监听滑动机制:根据用户操作来相应进行格子交换。进行direction的交换,对模块四个1方向上进行一个判断,up代表上,down代表下,left代表左,right代表有,期间各模块交换时使用的是二维数组机制。添加一个函数slide()为布局layout添加一个滑动事件,分别调用对应的changeGrids(direction)函数实现空白方格周围对应位置的方格便会随之向对应的方向移动一格,并调用drawGrids(grids)函数用于绘制新的方阵。
//滑动网格 slide(event) { this.changeGrids(event.direction); if(this.gameover()){ clearInterval(timer); this.isShow = true; this.tip = false;} this.drawGrids();}, //滑动操作 changeGrids(direction) { let x; let y; for (let row = 0; row < this.block; row++) { for (let column = 0; column < this.block; column++) { if (grids[row][column] == 0) { x = row; y = column; break;}}} let temp; if(this.isShow==false){ if (direction == 'up' && (x + 1) -1) { temp = grids[x - 1][y]; grids[x - 1][y] = grids[x][y]; grids[x][y] = temp; } else if (direction == 'left' && (y + 1) -1) { temp = grids[x][y - 1]; grids[x][y - 1] = grids[x][y]; grids[x][y] = temp;}}},
当前拼图序列与初始状态相同时代表完成游戏成功
使用二维数组进行所有格子的输出,然后用girds[row][column]与originalgarid[row][column]行列格子进行判断,看是否与原图相同,不同则为false,相同则为true,代表游戏成功。
-
//游戏结束判断gameover(){ let originalgrids; if(4 == this.block) { originalgrids=[[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12],[13, 14, 15, 0]];} else { originalgrids=[[1, 2, 3, 4, 5],[6, 7, 8, 9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20],[21, 22, 23, 24, 0]];} for (let row = 0; row < this.block; row++) { for (let column = 0; column < this.block; column++) { if (grids[row][column] != originalgrids[row][column]){ return false; } } }return true;},
换张图玩:切换图片的序号,使用该值与总数求余,改变图片的路径。
结尾
最后,拼图的小游戏就讲解完了,通过这个小demo呢我也学到了很多,有借鉴大佬的成份,但依旧还是学会了很多东西,在以后的学习上,多多倾向于语言学习,深究一门语言,观察大佬与自己逻辑思路的区别,多多学习,多多进步。
参考链接:简单的JS鸿蒙小游戏——拼图(冬奥一起拼)-开源基础软件社区-51CTO.COM