一个电脑游戏,完成拼图以获取验证码一关会得到一些拼图,这些拼图拼起来是一个地球的样子,这个游戏叫什么名字

最好玩的拼图小游戏_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
最好玩的拼图小游戏
上传于|0|0|文档简介
&&拼图游戏是广受欢迎的一种智力游戏,它的变化多端,难度不一,让人百玩不厌。每一片的单片都有它自己的位置,就像每段回忆都有它的故事,你要将它放在专属的地方,放对了就慢慢丰富起来,放错了就无法完整。
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢  拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:;
  因为使用canvas,所以某些浏览器是不支持的: you know; &
  为什么要用canvas(⊙o⊙)? &因为图片是一整张jpg或者png, 我们要用把图片导入到canvas画布, 然后再调用上下文context的getImageData方法, 把图片处理成小图, 这些小图就作为拼图的基本单位;
  如何判断游戏是否结束, 或者说如何判断用户拼成的大图是正确的? 我们就要在刚刚生成的小图上面添加自定义属性, 后期在小图被移动后再一个个判断,如果顺序是对的, 那么这张大图就拼接成功, 允许进入下一关;
  游戏一共有四个关卡, 不会有人通关的,真的....因为第四关把图片的宽高分别切成了6份, 看着都晕好吧(&_&);
  因为要考虑到移动端的效果, 所以主界面图片是根据屏幕适配, 拼图大图的大小是屏幕宽度和屏幕高度之间最小值的一半, 都是为了不出现滚动条。 比如:用户的手机是横屏模式, 这个横屏的宽度是1000px,高度是300px, 如果我们把主图片的宽设置为屏幕1000px的一半500, 那么垂直方向就出滚动条了;
  用户的事件只要考虑上下左右四个方向键即可, 要判断图片是否可以移动, 也要考虑到当图片移动的时候的动画效果 ,感兴趣的话考虑我的实现, 和我写的2048是一样的道理;;
  如果用户觉得这些图片不好看, 甚至可以上传自己手机的图片, 浏览器要支持FileReader的API, 移动是基于webkit的内核,可以不用考虑兼容性;
  代码包含工具方法和一些基本的配置, 比如, 图片地址的配置, 图片要切成的块数 , 加载图片的工具方法等:
//游戏关卡的图片和游戏每一个关卡要切成的图片快个数
var levels = ["lake.jpg","cat.jpg","follower.jpg","view.jpg"];
var numbers = [3,4,5,6];
//工具方法
var util = {
* @desc 图片加载成功的话就执行回调函数
* @param 图片地址 || 图片的DataUrl数据;
loadImg : function(e, fn) {
var img = new I
if( typeof e !== "string" ) {
img.src = ( e.srcElement || e.target ).
img.onload = function() {//document.body.appendChild( canvas );
//document.getElementById("content").appendChild( canvas );
  代码是基于面向对象(oop), 包含了两个类 :ClipImage 类,&Block 类:&
  ClipImage类
@desc 把图片通过canvas切成一块块;
function ClipImage(canvas , number) {
$.extend(ClipImage.prototype, {
* @desc 根据关卡把图片canvas切成块canvas
* 然后渲染到DOM;
function () {
* @param 把canvas块混排, 打乱排序;
//使用底线库的方法shuffle打乱排序;
random : function( ) {
* @desc 把canvas渲染到DOM;
renderToDom : function () {
updataDom : function(cav, obj) {
this.updataMap();
$(cav).animate({top:obj.y*this.avH,left:obj.x*this.avW});
updataMap : function () {
testSuccess : function () {
  Block类
* @desc 对每一个canvas进行包装;
* @param canvas
* @param left
* @param top
* @param avW
* @param avH
* @constructor Block
var Block = function(canvas, left, top,avW, avH) {
$.extend(Block.prototype, {
* @desc 对每一个canvas进行定位, 然后添加到界面中;
init : function () {
* @desc 对每一个canvas进行定位
setPosition : function() {
* @desc 向上移动会执行的函数
,通过判断maps下有没有对应的key值判断, 界面中的固定位置是否被占用;
upF : function(maps,numbers,cb) {
* @desc 同上
rightF : function(maps, numbers, cb) {
* @desc 同上
downF : function (maps,numbers,cb) {
* @desc 同上
leftF : function(maps,numbers,cb) {
  为了考虑移动端,我们使用了zepto封装的swipe系列事件, 默认并没有这个模块, 我们要通过script标签引用进来, github的地址为 :
$(document).swipeLeft(function() {
run(clipImage,"leftF")
}).swipeUp(function() {
run(clipImage,"upF")
}).swipeRight(function() {
run(clipImage,"rightF")
}).swipeDown(function() {
run(clipImage,"downF")
  虽然是一个小游戏,都是要考虑的东西真的不少,包括动画效果, 是否可以移动, 更改数据模型, 是否成功进入下一个关卡等, 包含挺多的判断;
  全部代码, 提供思路, 代码可以作为参考:
&!DOCTYPE html&
&head lang="en"&
&meta charset="UTF-8"&
&title&&/title&
&meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&
&link rel="stylesheet" href="/bootstrap/3.3.5/css/bootstrap.min.css"/&
&script src="/zepto/1.0rc1/zepto.min.js"&&/script&
&script src="/underscore.js/1.8.3/underscore.js"&&/script&
border:1px solid #f0f0f0;
box-shadow: 2px 2px 2px #
&input type="file" name="file" id="file"/&
&div class="container"&
&div class="row"&
&div class="progress"&
&div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 25%"&
&span class&当前是第&span id="now"&1&/span&关,共4关&/span&
&div class="row"&
&div id="content" class="clearfix "&
(function(fn) {
})(function($) {
//这个canvas是缓存图片用的;
var canvas = document.createElement("canvas");
var minScreenWidth = Math.min( document.documentElement.clientWidth/ 2, document.documentElement.clientHeight/2 );
canvas.width = minScreenW
canvas.height = minScreenW
document.getElementById("content").style.width =
minScreenWidth + "px";
//保存了所有的
var blocks = [];
//工具方法
var util = {
* @desc 图片加载成功的话就执行回调函数
* @param 图片地址 || 图片的DataUrl数据;
loadImg : function(e, fn) {
var img = new I
if( typeof e !== "string" ) {
img.src = ( e.srcElement || e.target ).
img.onload = function() {
//canvas.width = img.
//canvas.height = img.
canvas.getContext("2d").drawImage( img, 0, 0 ,canvas.width, canvas.height);
//document.body.appendChild( canvas );
//document.getElementById("content").appendChild( canvas );
//绑定事件;
function bindEvents () {
var file = $("#file");
file.bind("change", function(ev) {
var reader = new FileR
reader.onload = function(e) {
util.loadImg(e, function() {
window.clipImage = new ClipImage(canvas, numbers[window.lev]);
window.clipImage.random();
Controller( window.clipImage, numbers[window.lev]);
reader.readAsDataURL(this.files[0]);
//游戏关卡的图片和游戏每一个关卡要切成的图片快个数
var levels = ["http://sqqihao.github.io/games/jigsaw/lake.jpg","http://sqqihao.github.io/games/jigsaw/cat.jpg","http://sqqihao.github.io/games/jigsaw/follower.jpg","http://sqqihao.github.io/games/jigsaw/view.jpg"];
var numbers = [3,4,5,6];
@desc 把图片通过canvas切成一块块;
function ClipImage(canvas , number) {
//blocks是一个二维数组,保存的是所有的canvas方块;
this.blocks = [];
//instances是一维数组,保存的是实例化的数组;
this.instances = [];
this.maps = {};
this.canvas =
this.context = this.canvas.getContext("2d");
this.number =
this.clip();
$.extend(ClipImage.prototype, {
* @desc 根据关卡把图片canvas切成块canvas
* 然后渲染到DOM;
function () {
var avW = this.avW = this.canvas.width/this.
var avH = this.avH = this.canvas.height/this.
for(var i=0; i& this. i++ ) {
for(var j=0; j&this. j++ ) {
this.blocks[i] = this.blocks[i] || [];
var canvas = document.createElement("canvas");
canvas.width = avW;
canvas.height = avH;
canvas.x =
canvas.y =
canvas.map = i+"_"+j;
canvas.correctMap = i+"_"+j;
var imageData = this.context.getImageData(j*avW, i*avH, avW, avH);
canvas.getContext("2d").putImageData( imageData, 0, 0 );
if( i === j && j=== (this.number-1) )break;
// 把canvas放到二维数组blocks中;
this.blocks[i][j] =
this.renderToDom();
* @param 把canvas块混排, 打乱排序;
random : function( ) {
var len = this.instances.
while(len--) {
$(this.instances[len].canvas).remove();
//使用底线库的方法shuffle打乱排序;
this.blocks = _.shuffle(this.blocks);
for(var i=0 ;i &this.blocks. i++) {
this.blocks[i] = _.shuffle(this.blocks[i]);
this.renderToDom();
* @desc 把canvas渲染到DOM;
renderToDom : function () {
document.getElementById("content").innerHTML = "";
this.maps = {};
this.doms = [];
this.instances = [];
for(var i=0; i&this.blocks. i++ ) {
for(var j=0; j&this.blocks[i]. j++) {
var instance = new Block( this.blocks[i][j], j, i ,this.avW, this.avH);
//把实例化的数据保存到instances
this.instances.push( instance );
this.maps[i+"_"+j] = true;
updataDom : function(cav, obj) {
this.updataMap();
$(cav).animate({top:obj.y*this.avH,left:obj.x*this.avW});
updataMap : function () {
this.maps = {};
var len = this.instances.
while(len--) {
this.maps[this.instances[len].canvas.y + "_" + this.instances[len].canvas.x] = true;
this.instances[len].canvas.map = this.instances[len].canvas.y + "_" + this.instances[len].canvas.x;
for(var i=0; i&this.blocks. i++ ) {
for (var j = 0; j & this.blocks[i]. j++) {
this.maps[this.blocks[i][j].y + "_" + this.blocks[i][j].x] =
testSuccess : function () {
var len = this.instances.
while(len--) {
//只要有一个不等就无法成功;
if(this.instances[len].canvas.correctMap !== this.instances[len].canvas.map) {
console.log("成功");
if( ++window.lev &=4 ) {
alert("已经通关");
$("#now").html( window.lev + 1 );
$(".progress-bar").width( (window.lev+ 1) * 25 + "%" );
init(window.lev);
* @desc 对每一个canvas进行包装;
* @param canvas
* @param left
* @param top
* @param avW
* @param avH
* @constructor Block
var Block = function(canvas, left, top,avW, avH) {
this.canvas =
this.left =
this.top =
this.avW = avW;
this.avH = avH;
this.init();
$.extend(Block.prototype, {
* @desc 对每一个canvas进行定位, 然后添加到界面中;
init : function () {
this.canvas.style.position = "absolute";
this.canvas.style.left = this.avW*this.left +"px";
this.canvas.style.top = this.avH*this.top +"px";
this.canvas.x = this.
this.canvas.y = this.
document.getElementById("content").appendChild( this.canvas );
* @desc 对每一个canvas进行定位
setPosition : function() {
this.canvas.style.left = this.avW*this.canvas.x +"px";
this.canvas.style.top = this.avH*this.canvas.y +"px";
* @desc 向上移动会执行的函数
,通过判断maps下有没有对应的key值判断, 界面中的固定位置是否被占用;
upF : function(maps,numbers,cb) {
//如果目标有
var temp = (this.canvas.y&0 ? (this.canvas.y-1) : this.canvas.y);
var targetXY =
temp+"_"+this.canvas.x;
if( !maps[targetXY] ) {
this.canvas.y =
this.canvas.map = targetXY;
//alert("可以走")
cb(this.canvas, {
x : this.canvas.x,
y : this.canvas.y
return true;
* @desc 同上
rightF : function(maps, numbers, cb) {
var temp = ((this.canvas.x+1&numbers-1) ? this.canvas.x : this.canvas.x+1);
var targetXY = this.canvas.y+"_"+
if( !maps[targetXY] ) {
this.canvas.x =
this.canvas.map = targetXY;
//alert("可以走")
cb(this.canvas, {
x : this.canvas.x,
y : this.canvas.y
return true;
* @desc 同上
downF : function (maps,numbers,cb) {
var temp = ((this.canvas.y+1&numbers-1) ? this.canvas.y : this.canvas.y+1);
var targetXY = temp+"_"+this.canvas.x
if( !maps[targetXY] ) {
this.canvas.y =
this.canvas.map = targetXY;
cb(this.canvas, {
x : this.canvas.x,
y : this.canvas.y
//alert("可以走");
return true;
* @desc 同上
leftF : function(maps,numbers,cb) {
var temp = ( (this.canvas.x-1)&=0 ? this.canvas.x-1 : this.canvas.x );
var targetXY = this.canvas.y+"_"+
if( !maps[targetXY] ) {
this.canvas.x =
this.canvas.map = targetXY;
//alert("可以走")
cb(this.canvas, {
x : this.canvas.x,
y : this.canvas.y
return true;
* @desc 主要控制器;
function Controller( clipImage, number) {
var run = function( clipImage, name ) {
//window.clipImage.doms ,window.clipImage.maps, numbers[level], window.clipImage.updataDom.bind(window.clipImage)
for(var i=0; i&clipImage.instances. i++ ) {
var instance = clipImage.instances[i];
if( instance[name].bind(instance)(clipImage.maps, number, clipImage.updataDom.bind(clipImage)) ) {
clipImage.testSuccess();
$(window).unbind("keydown");
$(window).bind("keydown", function(ev) {
switch(ev.keyCode) {
name = "leftF";
name = "upF";
name = "rightF";
name = "downF";
ev.preventDefault();
return false
run( clipImage, name );
ev.preventDefault();
$(document).swipeLeft(function() {
run(clipImage,"leftF")
}).swipeUp(function() {
run(clipImage,"upF")
}).swipeRight(function() {
run(clipImage,"rightF")
}).swipeDown(function() {
run(clipImage,"downF")
function init(level) {
util.loadImg( levels[level] ,function() {
window.clipImage = new ClipImage(canvas, numbers[level]);
window.clipImage.random();
Controller( window.clipImage, numbers[level] || 3);
$(function() {
window.lev = 0;
init(lev);
bindEvents();
& & & & 如果有bug直接评论, 我会修正, 提git的issue也行,
  DEMO地址查看:
阅读(...) 评论()
再过一百年, 我会在哪里?

我要回帖

更多关于 块 拖动完成上方拼图 的文章

 

随机推荐