creatjs拼图游戏流程分析
- 一行足够大的图片,导入到canvas里。
- 把图片分割成n块(n自定义)。
- 打乱图片(记住图片的坐标)。
- 点击图片,当有两张图片时,交换位置。
- 检测所有图片的坐标和保存的坐标是否一致,如果有一对图的坐标不一致,退出循环。
- 全部一致,胜利
- 如果不一致,清空检测数组
变量及函数分析
变量
- PUZZLE_COLUMNS (列数)
- PUZZLE_ROWS (行数)
- PUZZLE_SIZE (小图宽高)
- stage (场景)
- pieces (所有小图的数组)
- selectedPieces(选择小图的数组)
函数
- init (初始化函数)
- buildPuzzle (创造小图片块函数)
- shufflePuzzle (打乱顺序函数)
- onPieceClick (点击图片函数)
- evalSelectedPieces (交换位置函数)
- evalPuzzle (判断是否胜利函数)
- startGame (开始游戏函数)
知识点分析
- piece.sourceRect = new createjs.Rectangle(x,y,w,h)
创建一个图片的分隔块,x坐标,y坐标,w宽,h高。 - new createjs.ColorMatrix().adjustColor(15,10,100,180)
创建一个颜色矩阵,值为:亮度,饱和度,对比度,色相。 - piece.filters=[new createjs.ColorMatrixFilter(matrix)]
把创建好的颜色矩阵赋值给滤镜,必须使用[]中括号赋值。 - piece.cache(0,0,PUZZLE_SIZE,PUZZLE_SIZE)
创建缓存,如果不创建缓存,只保持一针,刷新后就没有了。如果想修改图片,调用uncache()就可以了。
详细解析代码
var PUZZLE_COLUMNS = 2,//列数
PUZZLE_ROWS = 2,//行数
PUZZLE_SIZE = 400,//小图宽高
stage = null,//场景
pieces = [],//所有小图的数组
selectedPieces = [],//选择小图的数组
select = null; //点击的元素
// 初始化
function init(){
stage = new createjs.Stage(document.getElementById("game"));
buildPuzzle();//导入图片并分割为大小相等的15小块
startGame();
// 过2秒打乱图片
setTimeout(function(){
shufflePuzzle()
},2000);
}
// 创造小图片
function buildPuzzle(){
var l = PUZZLE_COLUMNS * PUZZLE_ROWS;
var piece = null;
var col = 0;
var row = 0;
for(var i = 0 ; i < l ; i++){
piece= new createjs.Bitmap("../img/3.jpg");//导入大图片
piece.sourceRect = new createjs.Rectangle(col * PUZZLE_SIZE,row * PUZZLE_SIZE,PUZZLE_SIZE,PUZZLE_SIZE);
//生成小图片块
piece.homePoint = {x:col * PUZZLE_SIZE,y:row * PUZZLE_SIZE}
//将原始坐标值保存到小图片的自定义属性中。
piece.x = piece.homePoint.x;//定位x坐标
piece.y = piece.homePoint.y;//定位y坐标
piece.itm = i;//给元素编号
pieces.push(piece); //将小图片保存到数组中
stage.addChild(piece); //将小图片加入到场景
col++;
if(col === PUZZLE_COLUMNS){//一行结束后,进入下一行
col = 0;
row ++;
}
}
}
// 打乱顺序
function shufflePuzzle(){
var p = [].concat(pieces);
var romeIndex = 0;
var piece = null;
var col = 0;
var row = 0;
var l = p.length; //保存数组长度,保证遍历到每个元素
for(var i = 0; i < l; i ++){
romeIndex = Math.floor(Math.random() * p.length);
//每次删除p元素有,取新的长度,在留下来的元素中,随机取一个
piece = p[romeIndex];//取到元素
p.splice(romeIndex,1);//从数组中删除取到的元素
createjs.Tween.get(piece).to({x:col*PUZZLE_SIZE,y:row*PUZZLE_SIZE},200);
//从0的位置依次排列元素
piece.addEventListener('click',onPieceClick);//在每个元素上绑定点击事件
col++;
if(col === PUZZLE_COLUMNS){
col = 0;
row ++;
}
}
}
//点击的图片添加到一个数组中,并且给被点击的图片添加一个滤镜效果特别显示
function onPieceClick(ev){
if(selectedPieces.length === 2)return;//当选取元素有2个时,退出
select = ev.target;//获取当前点击的元素
if(selectedPieces.length === 1 && selectedPieces[0].itm === select.itm)return;
//如果选择了同一个元素,直接退出
select.sourceRect = new createjs.Rectangle(select.homePoint.x,select.homePoint.y,PUZZLE_SIZE,PUZZLE_SIZE);
//获取当前点击元素的分隔块
var matrix = new createjs.ColorMatrix().adjustColor(15,10,100,180);
//创建一个颜色矩阵,值为:亮度(15),饱和度(10),对比度(100),色相(180)。
select.filters=[new createjs.ColorMatrixFilter(matrix)];
//把创建好的颜色矩阵赋值给滤镜,必须使用[]中括号赋值
select.cache(0,0,PUZZLE_SIZE,PUZZLE_SIZE);//创建缓存
selectedPieces.push(select); //将选中的元素加入选中数组中
select = null;
if(selectedPieces.length === 2)evalSelectedPieces();
//选择数组中有2个时,交换位置
}
//交换图片的位置,这里使用了TweenJS来创建交换的动画效果
function evalSelectedPieces(){
var pices1 = selectedPieces[0];//获取选择数组中第一个元素
var pices2 = selectedPieces[1];//获取选择数组中第二个元素
createjs.Tween.get(pices1).to({x:pices2.x,y:pices2.y},200);
//第一个元素运动到第二个元素的位置
createjs.Tween.get(pices2).to({x:pices1.x,y:pices1.y},200).call(function(){
setTimeout(function(){
evalPuzzle()
},200)
});//第二个元素运动到第一个元素的位置,并回调判断胜负函数
}
// 判断是否胜利
function evalPuzzle(){
var l = PUZZLE_COLUMNS * PUZZLE_ROWS;
var piece = null;
var win = true;//设置赢的参数为true
selectedPieces[0].uncache();//清除元素上的缓存
selectedPieces[1].uncache();//清除元素上的缓存
for(var i = 0 ; i < l ; i++){
piece = pieces[i];
if(piece.x !== piece.homePoint.x || piece.y !== piece.homePoint.y){
//如有一个元素不在原位置,则判断失败,直接退出
win = false;//设置赢的值为false
break;
}
}
if(win){//当win为true时,证明全部元素在原来的位置上,就赢了
setTimeout(function(){
alert("恭喜胜利!!");
// location.reload();
},200)
}else{
selectedPieces = []; //清空选择数组
}
}
// 开始游戏
function startGame(){
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener('tick',function(){
stage.update();
})
}
本文参考了lanix516的文章,原文链接https://blog.csdn.net/lanix516/article/details/47282073