今天网上发现了一段代码,只有界面,很不错,学习了并完成了逻辑。

效果图:

点击这里试玩

http://www.108js.com/article/canvas/6/play.html

欢迎访问博主的网站:

http://www.108js.com

代码:

请您将上面数字排成

1,2,3, 4

5, 6, 7, 8

9, 10,11,12

13,14,15

window.onload = function() {

var W = window.innerHeight/2, H = W;

var canvas = document.getElementById('15-puzzle');

var ctx = canvas.getContext('2d');

var frames, time;

canvas.width = W;

canvas.height = H;

var tileWidth = W/4, tileHeight = H/5;

ctx.font = tileHeight/2 + 'px Helvetica';

var I1=0;//记录鼠标点击和移动的位置

var I=0;

var J1=0;

var J=0;

var fillC=false;//用于改变文字的颜色

var tiles = {//界面对象

tiles: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]],

rightTiles: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]],

draw: function() {//绘制自己

var x = 0, y = 0;

ctx.strokeStyle = "#FFF";

var tile, width, height, posX, posY;

for (var i = 0; i < this.tiles.length; i++) {

for (var j = 0; j < this.tiles[0].length; j++) {

tile = this.tiles[i][j];

if(tile!= 0){

width = ctx.measureText(tile).width;

height = tileHeight/2;

posX = x * tileWidth + (tileWidth - width)/2;

posY = y * tileHeight + tileHeight - (height/2);

var fillStyle;

tile== this.rightTiles[i][j] ? fillStyle = "#0F0": fillStyle = "#FFF";

ctx.fillStyle = fillStyle;

ctx.fillText(this.tiles[i][j], posX, posY);

ctx.beginPath();

ctx.rect(x * tileWidth, y * tileHeight, tileWidth, tileHeight);

ctx.stroke();

}

x++;

}

x = 0;

y++;

}

},

//打乱二维数组

randomize: function() {

var aux = [];

for (var i = 0; i < this.tiles.length; i++) {

for (var j = 0; j < this.tiles[0].length; j++) {

aux.push(this.tiles[i][j]);

}

}

aux = shuffle(aux);

for (var i = 0; i < this.tiles.length; i++) {

for (var j = 0; j < this.tiles[0].length; j++) {

this.tiles[i][j] = aux[j+i*4];

}

}

}

}

//启动游戏

function init() {

tiles.randomize();

frames = 0, time = 0;

run();

}

function run() {

frames++;

update();

draw();

if(end()) document.getElementById("msg").innerHTML="你成功了!!!!";

window.requestAnimationFrame(run, canvas);

}

//更新

function update() {

if(frames % 60 === 0) {

if(time < 999){

time++;

}

}

if(inx(I,J)&&tiles.tiles[I][J]!=0){

if(inx(I-1,J)&&tiles.tiles[I-1][J]==0) swap(I,J,I-1,J);

if(inx(I+1,J)&&tiles.tiles[I+1][J]==0) swap(I,J,I+1,J);

if(inx(I,J-1)&&tiles.tiles[I][J-1]==0) swap(I,J,I,J-1);

if(inx(I,J+1)&&tiles.tiles[I][J+1]==0) swap(I,J,I,J+1);

}

}

//绘制

function draw() {

drawBackground();

tiles.draw();

}

//画背景

function drawBackground() {

ctx.fillStyle = "#000";

ctx.fillRect(0, 0, W, H);

ctx.fillStyle = "#AAA";

ctx.fillRect(0, tileHeight * 4, tileWidth*4, tileHeight);

drawRestart();

drawTime();

}

//画重新开始按钮

function drawRestart() {

ctx.strokeStyle ="#FFF";

ctx.beginPath();

ctx.rect(0, tileHeight * 4, tileWidth * 2.5, tileHeight);

ctx.stroke();

var text = "RESTART";

var width = ctx.measureText(text).width;

var height = tileHeight/2;

var textX = (tileWidth * 2.5 - width)/2;

var textY = tileHeight * 5 - (height/2);

ctx.fillStyle =fillC? "#FF0":"#FFF";

ctx.fillText(text, textX, textY);

}

//画游戏计时

function drawTime() {

ctx.strokeStyle = "#FFF";

ctx.beginPath();

ctx.rect(tileWidth * 2.5, tileHeight * 4, tileWidth * 1.5, tileHeight);

ctx.stroke();

var width = ctx.measureText(time).width;

var height = tileHeight/2;

var textX = tileWidth * 2.5 + (tileWidth * 1.5 - width)/2;

var textY = tileHeight * 5 - (height/2);

ctx.fillStyle = "#000";

ctx.fillText(time, textX, textY);

}

init();

function shuffle(array) {//打乱一个一维数组

array.sort(function(){ return 0.5 - Math.random() })

return array;

}

//鼠标点击

http://www.108js.com

canvas.onclick =function(e) {

var e = window.event || e;

var rect = this.getBoundingClientRect();

var mouseX =e.clientX - rect.left;//获取鼠标在canvsa中的坐标

var mouseY =e.clientY - rect.top;

J=Math.floor(mouseX/tileWidth);

I=Math.floor(mouseY/tileHeight);

if(I==4&J<3) init();

}

//鼠标移动

canvas.onmousemove = function(e){

var e = window.event || e;//

var rect = this.getBoundingClientRect();

var mouseX =e.clientX - rect.left;//获取鼠标在canvsa中的坐标

var mouseY =e.clientY - rect.top;

J1=Math.floor(mouseX/tileWidth);

I1=Math.floor(mouseY/tileHeight);

if(I1==4&J1<3) fillC=true;//改变重新开始按钮的颜色

else fillC=false;

}

//鼠标移动,要改变文字颜色

http://www.108js.com

canvas.onmouseout = function(){

fillC=false;

}

//交换二维数组两个位置的值

function swap(a,b,x,y){

var temp=tiles.tiles[a][b];

tiles.tiles[a][b]=tiles.tiles[x][y];

tiles.tiles[x][y]=temp;

}

//是否出边界

function inx(x,y){

if(0<=x&&x

return false;

}

//是否完成游戏

function end(){

for(var m=0;m

for(var n=0;n

if(tiles.tiles[m][n]!=tiles.rightTiles[m][n]) return false;

}

}

return true;

}

}

下载源码:

HTML5中canvas实现拼图游戏,HTML5 Canvas学习笔记(6)拼图游戏(数字版)相关推荐

  1. 《游戏设计模式》学习笔记

    ** <游戏设计模式>学习笔记 ** 原作中文版传送门:<游戏设计模式> 原书作者:Bob Nystrom 阅读背景:最近担任了主程(惭愧,整个项目组就我一个人,2333),在 ...

  2. 【D3D11游戏编程】学习笔记十八:模板缓冲区的使用、镜子的实现

    (注:[D3D11游戏编程]学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~) 模板缓冲区(Stencil Buffe ...

  3. 【D3D11游戏编程】学习笔记十一:基本几何体绘制

    (注:[D3D11游戏编程]学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~) 这次我们来学习几种常见的基本几何体的绘 ...

  4. 【D3D11游戏编程】学习笔记九:编译Effect的方法

    (注:[D3D11游戏编程]学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~) 在D3D11应用程序中,对于写好的Ef ...

  5. [Unity学习笔记:FPS游戏制作(2)] 发射子弹————(2021.6.20学习笔记)

    往期博客 [Unity学习笔记:FPS游戏制作(1)]角色的移动,旋转与推进上升----(2021.6.13学习笔记) 文章目录 一,实现思路 二,实现代码 三,脚本的使用方法 四,最终效果 一,实现 ...

  6. 【D3D11游戏编程】学习笔记七:3D渲染管线

    (注:[D3D11游戏编程]学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~) 3D图形学研究的基本内容,即给定场景的 ...

  7. SVO中 Inverse Compositional Image Alignment方法的学习笔记

    SVO中 Inverse Compositional Image Alignment方法的学习笔记 这篇文章 光流法简介 逆向光流法 结尾 这篇文章  在SVO系统中的"Relaxation ...

  8. Unity学习笔记—二次元日系游戏制作(实践篇-游戏初始化场景制作)

    原教程:siki:二次元日系游戏制作工具 - live2dSDK入门教程 http://www.sikiedu.com/my/course/282 (上)Unity学习笔记-二次元日系游戏制作(理论篇 ...

  9. [Unity学习笔记:FPS游戏制作(3)]子弹拖尾,碰撞与枪口火焰效果

    往期博客[Unity学习笔记:FPS游戏制作(2)] 发射子弹----(2021.6.20学习笔记) 文章目录 一,实现思路 二,粒子效果的实现 (1)子弹拖尾特效的实现 (2)枪口火焰特效的实现 ( ...

  10. html5中提供的绘图元素,HTML5中Canvas元素的使用总结

    HTML5中Canvas元素的使用总结 Canvas提供了开发者自定义绘图的接口,我们可以公国getContext()函数来获取绘图上下文进行绘制操作,这个函数中可以传入两个参数,其中第1个参数设置绘 ...

最新文章

  1. 万能头文件#include<bits/stdc++.h>更新GCC10.2.0版本
  2. SQL语句——将Excel文档导入数据表中
  3. VS2017登陆不了,TFS无法连接成功的问题
  4. 三个基本原理和概念 - 计算机图形学、数据加密、数据挖掘
  5. PHP trim()函数详解
  6. 制作一个状态栏中跑马灯效果_图标设计指南(3)——制作一个图标集所需全部信息(中)...
  7. shell基础07 函数
  8. vb.net label 不要自动换行_自动驾驶小车——(四)数据采集
  9. linux,让网卡随着系统启动自动生效
  10. Ubuntu 15.04 或更新版 更新源/Ubuntu 15.04 Vivid Vervet更新源已可用
  11. 热点聚焦:企业上ERP之前是否需要先进行流程梳理?
  12. CCNA学习笔记-1 基础知识回顾
  13. paypal 支付接口 php,PHP整合PayPal支付
  14. java转码mp4的代码_JAVA视频格式转换 avi转mp4
  15. ubuntu安装wps后缺少字体无法打开
  16. 用友系统检查iis服务器不符,安装用友U8的时候已经安装了IIS但是环境检测的时候却通不过?...
  17. requests关于Exceeded 30 redirects
  18. 如何获取QQ邮箱授权码?
  19. 音频技术的下一个“热点”,会出现在哪个领域?丨一期一会 • 音频工程师专场
  20. 观李永乐老师《双蛋问题》解题后感

热门文章

  1. ESP8266 12F 点灯科技APP 控制两个舵机
  2. 单细胞论文记录(part9)--Spatial charting of single-cell transcriptomes in tissues
  3. android开机动画不播放,android 设置activity启动退出动画 | 解决设置activity 动画不生效问题...
  4. 高中数学公式总结:解析几何(非常全)
  5. 08-02-19pe_xscan 增加Windows启动模式和对SuperHidden值检测和报告
  6. Android9.0新特性
  7. java 搞笑的事情_一件搞笑的事作文(精选10篇)
  8. 判断一个人有没有管理能力,就看这1点!
  9. 【贪心算法】加勒比海盗船——最优装载问题
  10. 消费金融成新增长极,江苏银行零售转型如虎添翼