数字华容道是个很简单的小游戏,今天就尝试使用canvas+js做个简单的数字华容道小游戏。有关于游戏的具体规则请上网查阅。

一如既往先写个html页面,这里我把游戏的界面水平居中了,这里预留了一个动画,在后面时间跳动的时候使用。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>canvas,#time,h1 {display: block;margin: 10px auto;width: 400px;text-align: center;}#time {font-size: 20px;text-align: center;}#time::after {content: "s";}.animate {animation: fontChange 0.4s linear 0s infinite none;}@keyframes fontChange {0% {transform: rotateX(0deg);}50% {transform: rotateX(90deg);}100% {transform: rotateX(0deg);}}</style>
</head><body><h1>数字华容道</h1><canvas id="canvas"></canvas><span id="time">0</span><script src="js/main.js"></script>
</body></html>

然后我们要设置canvas的宽高以及绘制方法的操作对象,还设置了一个用以判断当前是否完成游戏的布尔类型变量,这在后面可以用于判断停止计时。

let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 400;
var successFlag = false;

接下来是要将数字存储在对应的位置上,这里我用二维数组来存储各个位置上的数字。而要存储数字,就得给各个位置随机分配不重复的数字。并将生成的数组用一个全局变量arr存储。

//生成所需的二维数组
function arrProduce(n) {let arr = Array(4);arr.fill(0);let index = 1;arr = arr.map(item => {return Array(4).fill(0); //生成一个二维数组});while (true) {let randomC = Math.floor(Math.random() * Math.pow(16, 1 / 2)); //在随机位置填充数字let randomL = Math.floor(Math.random() * Math.pow(16, 1 / 2));if (arr[randomC][randomL] > 0) //重复时跳到下一个循环continue;else {arr[randomC][randomL] = index;index++;}if (index === n) //数字填充个数到达时跳出循环break;}return arr;
}let arr = arrProduce(16);

写好存储位置信息的数组后,接下来就是将内容绘制出来。

//画出圆角正方形
function drawRct(x, y, l, r) {context.beginPath();context.moveTo(x + r, y);context.lineTo(x + l - r, y);context.arcTo(x + l, y, x + l, y + r, r);context.lineTo(x + l, y + l - r);context.arcTo(x + l, y + l, x + l - r, y + l, r);context.lineTo(x + r, y + l);context.arcTo(x, y + l, x, y + l - r, r);context.lineTo(x, y + r);context.arcTo(x, y, x + r, y, r);context.fillStyle = 'rgba(102,102,102,0.6)';context.closePath();context.fill();context.stroke();
}//画出数字容器
function drawContainer() {drawRct(0, 0, 400, 10);for (var i = 0; i < 4; i++) {for (var j = 0; j < 4; j++) {drawRct(10 + 100 * i, 10 + 100 * j, 80, 5);}}
}//填充容器内容
function numbersWrite(arr) {for (var i = 0; i < arr.length; i++) {for (var j = 0; j < arr[i].length; j++) {context.beginPath();if (arr[i][j] === 0)arr[i][j] = '';context.textAlign = 'center';context.textBaseline = 'middle';context.font = '28px Adobe Ming Std';context.fillStyle = 'rgb(0,0,0)';context.fillText(arr[i][j], 50 + i * 100, 50 + j * 100);context.fill();}}
}

容器绘制好了,接下来就是操作了。这里我先找出空的位置,在按下按键时将块移动到空的位置,而第一次按下按键就开始计时

//找出空的位置
function findSpance(arr) {for (var i = 0; i < arr.length; i++) {for (var j = 0; j < arr[i].length; j++) {if (arr[i][j] === '')return { i, j };//返回空的位置}}
}//计时
function timeCount(start, time) {setInterval(function() {if (!successFlag) { //还未成功继续计时time.className = 'animate';setTimeout(() => { time.innerHTML = Math.floor((new Date().getTime() - start) / 1000) }, 200);//在动画一半的时候改变数字,正好是翻转到水平时setTimeout(() => { time.className = '' }, 400);}}, 1000);
}//位置移动
function posMove(pos) {var flag = false;document.onkeydown = event => {var e = event || window.event;switch (e.keyCode) {if (!flag) {//开始计时flag = true;let start = new Date().getTime();let time = document.getElementById('time');timeCount(start, time);}case 38: //上if (pos.j !== 3) {arr[pos.i][pos.j] = arr[pos.i][pos.j + 1];arr[pos.i][pos.j + 1] = '';pos.j++;}break;case 37: //左if (pos.i !== 3) {arr[pos.i][pos.j] = arr[pos.i + 1][pos.j];arr[pos.i + 1][pos.j] = '';pos.i++;}break;case 39: //右if (pos.i !== 0) {arr[pos.i][pos.j] = arr[pos.i - 1][pos.j];arr[pos.i - 1][pos.j] = '';pos.i--;}break;case 40: //下if (pos.j !== 0) {arr[pos.i][pos.j] = arr[pos.i][pos.j - 1];arr[pos.i][pos.j - 1] = '';pos.j--;}break;}context.clearRect(0, 0, canvas.width, canvas.height);//重置画面drawContainer();numbersWrite(arr);signTrue();//标记当前正确位置的数字,会在下面写出该方法if (judgeSuccess()) {//游戏成功,会在下面写出该方法alert(`恭喜你成功了 用时${document.getElementById('time').innerHTML}s`);successFlag = true;document.onkeydown = null;}}
}

操作写好后,就是写出成功条件了,只要数字全在对应的位置上,就算是游戏通关了,而为了让玩家更好地观察到当前还有几个位置不是正确的数字,我写了个方法将正确的位置用红色标出来。

//成功时的判断
function judgeSuccess() {let index = 1;for (let i = 0; i < arr.length; i++) {for (let j = 0; j < arr.length; j++) {if (index === 16)return true;if (arr[i][j] !== index)return false;index++;}}return true;
}//标记正确位置
function signTrue() {let index = 1;for (let i = 0; i < arr.length; i++) {for (let j = 0; j < arr.length; j++) {if (arr[i][j] === index) {context.beginPath();context.textAlign = 'center';context.textBaseline = 'middle';context.font = '28px Adobe Ming Std';context.fillStyle = 'rgb(255,0,0)';context.fillText(arr[i][j], 50 + i * 100, 50 + j * 100);context.fill();}index++;}}
}

最后调用写过的方法。

drawContainer();
numbersWrite(arr);
posMove(findSpance(arr));

大功告成,下面上图看游戏成功结果。

当然这个游戏还有很多可以扩展的内容,比如在方向移动时可以使用动画效果的移动,加个移动的声音,这里是简单的小游戏就不扩展了,大家可以尝试去完成这些功能,相信能学到更多。

canvas+js实现简单的数字华容道小游戏相关推荐

  1. JS自制简易版数字华容道小游戏

    最近复习了下前端基础知识HTML+JS(是真的非常基础那种,久不用,基本忘完了). 复习了一小部分内容,闲暇之余打算利用刚复习的js基础知识做个小游戏,刚好手机上下载的游戏集中就有一个数字益智游戏-- ...

  2. canvas+js实现简单的坦克大战小游戏

    使用canvas和js实现经典的坦克大战并不难,坦克和炮弹的绘制可以使用canvas的里API画出,而坦克的移动和炮弹的发射可以依赖于键盘事件和定时器来实现. 在这里我要实现的坦克大战是双人模式,有木 ...

  3. CreateJS实现【益智类数字华容道小游戏】

    系列文章 微信小程序(游戏)----拖拽拼图(图片分块和打乱顺序) 微信小程序(游戏)----五子棋 [taro react](游戏) ---- 类2048游戏,看看在秦朝,功勋爵位你能到哪一级 [t ...

  4. 数字华容道java的代码_jQuery实现数字华容道小游戏(实例代码)

    数字华容道 *{ padding: 0px; margin: 0px; } #btns>button{ width: 100px; height: 30px; border: none; bac ...

  5. C语言开发数字华容道实现,jQuery实现数字华容道小游戏(实例代码)

    数字华容道 *{ padding: 0px; margin: 0px; } #btns>button{ width: 100px; height: 30px; border: none; bac ...

  6. python快速实现数字华容道小游戏

    华容道,中国历史地名.据<资治通鉴>注释中的说法,就是"从此道可至华容也".这里所说的华容,当然是指华容县城.华容道也就是赤壁战争中曹军逃入华容县界后向华容县城逃跑的路 ...

  7. c语言实现数字华容道编程,【JIONEY】掌控版+遥传感器 实现数字华容道小游戏...

    数字华容道--掌控版+遥杆例程 自小就喜欢玩拼图游戏,一个小板板上通过一个缺少的方块,移动其余的方块打乱拼图,通过一定的移动方法将方块放回到位置.这次就借助掌控版,来设计一个数字华容道. 任务: 1. ...

  8. unity3d 华容道_Android数字华容道小游戏开发

    目的 上周新一期的最强大脑出来了,虽然上季被称为最强黑幕,不过呢.我决定还是看看= =.它里面第一关是叫做数字华容道.说白了,就是和拼图差不多.一开始我准备下一个玩玩的.结果没搜到.所以决定写了一个. ...

  9. Jquery实现数字华容道小游戏

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

最新文章

  1. 2021年热门临床研究盘点
  2. Linux下C语言使用openssl库进行MD5校验
  3. java tostring方法_Java虚拟机如执行方法调用的(二)?
  4. python编写加密程序_用Python实现一个简单的加密程序
  5. 深圳电子地图 深圳高清电子地图 来自谷歌电子地图 最高19级地图
  6. python学习------面向对象进阶
  7. pro缺点和不足 一加7t_看点满满,一用难忘:一加7T上手体验全方位测评
  8. Java安装以后为什么打不开java打不开一闪而过如何解决
  9. 计算机管理员英语怎么说,电脑管理员英文administrator写法
  10. 消息称微软Windows暂停接受华为新订单;2019 Q1 亚太区公有云IaaS、PaaS服务收入排名现已揭晓……...
  11. 【零售知识】商品库存成本计算的几种方式
  12. 筑巢引凤 - 男人25后是蓝筹股
  13. macOS用的是linux系统吗
  14. Golang中使用Qt库(therecipe/qt)+QtDesigner + Goland (二) UI继承
  15. 信息收集——Google Hacking
  16. metinfo 5.3.19密码重置漏洞
  17. 【CAD .NET】设置保存为pdf文件的页面参数 边距,横向竖向
  18. Excel转PDF如何解决显示不全的问题?
  19. 大雁牌计算机在线使用,用大雁牌计算器解决有关计算问题
  20. Android小红书发帖api接口,小红书Android客户端演进之路

热门文章

  1. Opencv值core组件(二):感兴趣区域选取与计算数组加权和
  2. python读取ymal文件
  3. 前端之HTML常用标签
  4. 如何使用(免费软件)Microsoft ICE轻松扫描大图片
  5. 成功的 Git 分支模型
  6. /proc/mtd 各个参数含义 -- linux内核
  7. 深度linux任务栏在哪,更新Deepin 20后任务栏dde-dock消失不见的暂时解决
  8. GANSynth论文翻译
  9. 西游记中观世音菩萨为什么能与如来佛祖同为五方五老之一?
  10. Ubuntu 查看电脑配置