这次使用www.tangide.com制作了一款推广类拼图游戏 ,

这游戏复杂点在各种拖动, 滑动的动画实现上. 下面我主要分享下动画部分的实现方法.

0 在线运行: 

http://www.tangide.com/apprun.html?appid=previewupyunosgames1-241435729564104

1: 确认界面布局

首先是对游戏功能区域的设计和

划分

滑动选择区在屏幕最下方, 每一块小的拼图会出现在这里, 玩家可以左右滑动让整个滑动区域轮动以查看全部拼图块.

这里我放入了一张图片在屏幕最左下角,游戏开始时通过对这张图的自动复制, 随机排序, 插入图片等操作来

拼图放置区在计时器下方, 玩家需要吧小拼图从滑动选择区拖到这个区域的正确位置以完成游戏.

这里是4X4的游戏, 我放置了16张小图片用来确认16个格子的位置, 并让这16个格子以第一个格子为基准自动对齐.

这么做确认麻烦但由于我是首次开发此类型游戏,这样做利于调试.

可以看到滑动选择区和拼图放置区之间有一段空隙, 这主要是为不同分辨率的手机预留的.截图分辨率为480*800.

这样的布局可以在不同屏幕比的设备 例如ip4S,5S上都显示得体.

2: 滑动区域初始化


win.initPictrue = function() {var tempPicList = [];for (var i=1;i<=16;i++) {//排列图片picBar[i-1] = "图片"+i;tempPicList[i-1] = i-1;if (! win.find("图片"+i)) {win.dupChild("图片1").setName("图片"+i);}var x = (i-1)*basePic.w;win.find("图片"+i,true).setPosition(x,win.h-basePic.h);win.find("图片"+i,true).setVisible(true);}//打乱图片顺序var w = 404/4;var h = 404/4;for (i=0; i<16; i++) {var random = Math.floor(Math.random()*tempPicList.length);if (!DEBUG) {picOrder[i] = tempPicList[random];tempPicList.splice(random,1);}else {picOrder[i] = i;}var s = {xx:0,yy:0};coord.push(s);coord[i].xx = w*((i+1)%4 === 0 ? 3 : ((i+1)%4) - 1);coord[i].yy = h*(Math.ceil((i+1)/4) - 1);if (DEBUG) {console.log("dd_initPictrue x="+coord[i].xx+" y="+coord[i].yy);}}for (i=0;i<16;i++) {//给picBar的位置设置图片win.find(picBar[i]).setImageSrc(PUZZLEIMAGE);win.find(picBar[i]).setImageSrcRect(coord[picOrder[i]].xx, coord[picOrder[i]].yy, w, h);if (DEBUG) { win.find(picBar[i]).setText(picOrder[i]+1);}win.find(picBar[i]).key = picOrder[i]+1;}
};

通过对屏幕下方拖动栏的初始化完成了picBar的随机排序, 随机插入图片, 以及最终用来判断游戏结束的key值记录.

3: 图片放置区域初始化

win.initSeat = function() {for (var i=1; i<=16; i++) {var x = baseSeat.x + baseSeat.w*((i%4) === 0 ? 3: (i%4) -1) + GAP;var y = baseSeat.y + baseSeat.h*(Math.ceil(i/4) -1) + GAP;//console.log("dd_initSeat SEAT="+SEAT + i);win.find("座位"+i).setPosition(x,y);seatGuest[i-1] = "";}
};

这一步自动调整好座位位置.

4: 图片选择区滑动效果


OnSwipeLeft = function(args) {var win = this.getWindow();win.swipeMe("left");
};win.swipeMe = function(direction) {if(hold === ""|| hold.indexOf("图片") !== 0|| picHolding == 1|| hold.y < win.h-basePic.h) {return;}console.log("dd_swipeMe "+direction);//距离限制:if (win.moveOutOfRange(direction)) {direction = "shake";return;}win.swipeAnimation(direction);
};win.swipeAnimation = function(direction) {for (var i=1; i<=picBar.length ;i++) {var targetPic = win.find(picBar[i-1]);var swipe = {duration:500,xStart:targetPic.x,yStart:targetPic.y,xEnd:targetPic.x-3*targetPic.w,yEnd:targetPic.y,interpolator:"l"};if (direction == "left") {swipe.xEnd = targetPic.x-3*targetPic.w;}else if (direction == "right") {swipe.xEnd = targetPic.x+3*targetPic.w;}else if (direction == "shake") {swipe.xEnd = targetPic.x;swipe.interpolator = "l";}else {console.log("dd_swipeAnimation ERROR");return;}targetPic.animate(swipe,function onDone(_obj) {});}
}; 

通过获取窗口的滑动事件 并对其做出简单的位置判断后. 将整个picBar向左或向右使用animation移动.

如果picBar第一个元素已经在屏幕内则无法继续从左往右滑, 反之最后一个元素在屏幕内时 无法从右向左滑.

4: 图片拖动效果

游戏中对图片的选择,拖动, 放开 我使用指针按下, 移动, 松开事件来完成.

拖出动作的逻辑:

1: 判断指针按下时必须选中的是有效成员, 该有效成员将成为hold

2: 上一次指针按下以后又进行了指针移动(pointMove)且Y坐标移动到了一定范围以外, 此时将hold从picBar中删除

3: 对所选中的picBar成员使用setPositon来实现拖动他的效果.

4: 对仍然在屏幕底端的 且在发生移动时处于hold成员右侧的picBar成员播放向左移动的动画.

5: 根据指针抬起时所在的位置判断需要执行放下图片 还是重置图片位置.

图片放下的逻辑:

1:放下的位置如是正确则播放动画提示玩家,

2: 放下位置如是非正确的seat则没有动画效果,只是将图片移动到的合适位置.

3: 放下位置如是无效区域则hold的图片返回到屏幕下边栏,且已在屏幕下边栏的picBar成员全体向右移动一格.

win.pointDown = function(point) {if (picBarPlaying == 1|| picHolding == 1) {hold = "";return;}var targetElement = this.findChildByPoint(point, true);holdPoint = point;if (targetElement.name){if (targetElement.name == "图片0") {hold = "";return;}console.log("dd_you are point down at "+targetElement.name);if (targetElement.name == "游戏界面") {return;}if (targetElement.name.indexOf("图片") === 0) {hold = targetElement.name;}else {hold = "";return;}win.find(hold).setZIndex(50);}
};win.pointMove = function(point) {if(!win.pointerDown|| hold === "") {return;}if (point.y < win.h-basePic.h || picHolding === 1) {win.drawOutPic(point);//移动被hold的图片if (picHolding === 0) {//首次移动出范围需删除其位置数据picHolding = 1;if (holdPoint !== ""){//删除失效的seatGuestfor (var s=1;s<=16;s++) {var seat = win.find("座位"+s);if (   holdPoint.x >= seat.x&& holdPoint.x < seat.x+seat.w&& holdPoint.y >= seat.y&& holdPoint.y < seat.y+seat.h) {break;}}seatGuest[s-1] = "";}win.renewPicBar();}}
};win.pointUp = function(point) {if (hold === "") {return;}//放置在SEAT区域 var lastSeat = win.find("座位16");if (   point.x >= baseSeat.x && point.x < lastSeat.x+lastSeat.w&& point.y >= baseSeat.y&& point.y < lastSeat.y+lastSeat.h){var seatNum = 0;//获取hold的图放置的新位置for (var i=1;i<=16;i++) {var seat = win.find("座位"+i);if (   point.x >= seat.x&& point.x < seat.x+seat.w&& point.y >= seat.y&& point.y < seat.y+seat.h) {seatNum = i;break;}}if (seatNum < 1) {console.log("dd_pointUp : seatNum ERROR");return;}else {console.log("dd_pointUp : pointUp at 座位"+i);}//放置在有图片的SEAT,旧图被插回第一位if (seatGuest[i-1] !== ""&& seatGuest[i-1].indexOf("图片")===0) {win.waitForAnimation(0,seatGuest[i-1]);//播放旧图插回动画   }seatGuest[i-1] = hold;win.putPicInSeat(i);//新图放入seatconsole.log("dd_key="+win.find(hold).key);//播放拼图放对的特效if (win.find(hold).key == i) {console.log("dd_放对啦!!!!");picHolding = 1;win.playBlink(hold);}} else if (picHolding === 1 && hold !== "") {//放在了无意义的区域, 需要重置图片位置win.waitForAnimation(0,hold);} else {console.log("dd_pointUp : ELSE ??");}//检测是否游戏完成nowvar gameOver = win.gameOverCheck();if (gameOver == 1) {console.log ("dd_gameOver");win.find("计时器控件").pause();function overThisGame() {var initData = {};me.openWindow("游戏结束界面", function (retData) {console.log("window closed.");win.newGame();win.initGame();}, false, initData);}setTimeout(function() {overThisGame();}, 510);}picHolding = 0;hold = "";holdPoint = "";
};

pointDown中实现对按下图片的识别 并将有效控件的名称记录为hold,

pointMove中结合hold 判断玩家是否在移动一个图片到可移动区域,

如果图片被拖动出滑动选择区,则留在滑动选择去的picBar成语播放对其动画.

pointUp中结合上两种方法中收集的数据,判断正在被hold的图片是否需要播放动画.

动画主要包含,1:放置在无效区域时 图片返回屏幕最下方, 2:最下方的其他图片右移给新插入的图片腾出位置

3:picBar中被拖出的图片放入puzzle座位区域的动画效果 4: 放置在了有效的区域,判断是否放置正确并播放动画.

每一次opintUp会检测游戏是否结束.

4: 其他方法代码展示

setStroke 为图片添加边框效果

win.setStroke = function(picName,canvas) {console.log("dd_setStroke : name="+picName);if (picName == "图片0") {return;}var pic = win.find(picName);pic.view.canvas.strokeStyle = "#E3881F";pic.view.canvas.lineWidth = 1;pic.view.canvas.strokeRect(0, 0, this.w, this.h);
};

insertPic 将放置在无效区域的图片插入回屏幕最下方

win.insertPic = function(seat,hold) {if (seat > picBar.length || (seat == picBar.length && picBar.length !== 0)) {console.log("dd_insertPic : seat  ERROR = "+ seat);return;}var targetPic = win.find(hold);var targetSeat;if (win.find(picBar[seat])) {targetSeat = win.find(picBar[seat]);}var backToSeat = {duration:200,xStart:targetPic.x,yStart:targetPic.y,xEnd:targetSeat.x,yEnd:targetSeat.y,interpolator:"l"};if (picBar.length === 0) {backToSeat.xEnd = 0;backToSeat.yEnd = win.h-basePic.h,picBar.push(hold);}targetPic.animate(backToSeat,function onDone(_obj) {setTimeout(function() {picHolding = 0;}, 60);});
};

drawOutPic 完成对拖出图片的移动显示

win.drawOutPic = function(point) {//console.log("dd_pointMove : "+point.x+" "+point.y);var x = point.x-basePic.w/2;var y = point.y-basePic.h/2;win.find(hold).setPosition(x,y);
};

swapeAnimation 完成播放滑动选择区的滑动效果

win.swipeAnimation = function(direction) {for (var i=1; i<=picBar.length ;i++) {var targetPic = win.find(picBar[i-1]);var swipe = {duration:500,xStart:targetPic.x,yStart:targetPic.y,xEnd:targetPic.x-3*targetPic.w,yEnd:targetPic.y,interpolator:"l"};if (direction == "left") {swipe.xEnd = targetPic.x-3*targetPic.w;}else if (direction == "right") {swipe.xEnd = targetPic.x+3*targetPic.w;}else if (direction == "shake") {swipe.xEnd = targetPic.x;swipe.interpolator = "l";}else {console.log("dd_swipeAnimation ERROR");return;}targetPic.animate(swipe,function onDone(_obj) {});}
};

moveOutOfRange 判断是否可以继续滑动 滑动区域

win.moveOutOfRange = function(direction) {if (direction == "left"&& win.find(picBar[(picBar.length-1)]).x+basePic.w <= win.w) {//向左滑时,如队末图片已完整出现在视野内则不处理.return 1;} else if (direction == "right"&& win.find(picBar[0]).x >= 0 ){//向右滑时,如队末图片已完整出现在视野内则不处理.return 1;}return 0;
};

picBarRight 负责将滑动区域的picBar成员集体向右移动

win.picBarRight = function(seat,hold) {var i = seat;if (picBar.length === 0) {console.log("dd_picBarRight : picBar is enpty!!!");return;}for (i; i<picBar.length; i++) {win.newPicBarAnimation(picBar[i],"insert");}picBar.splice(seat, 0, hold);console.log("dd_picBarRight : picBar =");if (DEBUG) {for (var r=0;r<picBar.length;r++) {console.log(picBar[r]);}}
};

removeHoldFromPicBar 负责将被拖出的picBar成员从picBar列表中删除

win.removeHoldFromPicBar = function() {var index = -1;for (var i=0;i<picBar.length;i++) {if (hold == picBar[i]) {index = i;break;}}if (index >= 0) {picBar.splice(index,1);console.log("dd_removeHoldFromPicBar: index is "+index);}else {console.log("dd_removeHoldFromPicBar: index ERROR");}
};

playBlink 负责播放当玩家拖动图片到正确位置时的提示动画

win.playBlink = function(target){if ( !win.find(target,true) ) {console.log("dd_playBlink : target notFound");return;}targetPic = win.find(target,true);var opRate = 0.3;var zoom = 0.8;var blinkP1 = {duration:60,opacityStart:1,opacityEnd:opRate,scaleXStart:1,scaleXEnd:zoom,scaleYStart:1,scaleYEnd:zoom,};var blinkP2 = {duration:60,opacityStart:opRate,opacityEnd:1,scaleXStart:zoom,scaleXEnd:1,scaleYStart:zoom,scaleYEnd:1,};targetPic.animate(blinkP1,function onDone(_obj) {targetPic.animate(blinkP2,function onDone(_obj) {blinkP1.duration = 140;blinkP2.duration = 140;targetPic.animate(blinkP1,function onDone(_obj) {targetPic.animate(blinkP2,function onDone(_obj) {});});});});
};

gameOverCheck 负责检测游戏是否结束

win.gameOverCheck = function() {var i = 0;var key;seatGuest.length = 16;if (DEBUG) {for (i in seatGuest){key = win.find(seatGuest[i]).key-1;console.log("dd_seatGuest["+i+"]="+seatGuest[i]+"key="+key);}}i = 0;for (i in seatGuest){key = win.find(seatGuest[i]).key-1;if (seatGuest[i] === ""|| key == "undefined"|| key != i){return 0;}}return 1;
};

timmerGameRule 负责在进入游戏后显示游戏开始的倒计时,玩家有3秒钟去记忆拼图完成时该有的样子.

win.timmerGameRule = function() {var timePic = [];var add = "http://osgames1.b0.upaiyun.com/games/diwy_source/businessSample/timeLimitPuzzle/pic/number";for (var i=0;i<=3;i++){timePic[i]= add+i+".png";}var time = 3;function timmer() {if (!win.children) {clearInterval(Interval);return;}win.timmerView(true);win.find("计时板").setImageSrc(timePic[time]);if (time < 0) {clearInterval(Interval);win.timmerView(false);win.find("图片1").setVisible(true);win.initSeat();win.initPictrue();win.find("计时器控件").start();}time --;}var Interval = setInterval(timmer,1000);
};

这次的分享就到这里. 2015-07-13

HTML5游戏实战:计时拼图游戏制作相关推荐

  1. HTML5游戏实战之拼图游戏(包含关卡)

    拼图游戏是每个人小时候都玩过的经典休闲游戏,依托Hola Studio强大的图片功能和事件回调体系,实现一个游戏性十足的拼图游戏并不难.本文就介绍整个游戏的制作过程,本游戏包含完整的游戏元素,包括广告 ...

  2. 【微信小游戏实战】零基础制作《欢乐停车场》二、关卡设计

    1.游戏立项 微信小游戏中有一款<欢乐停车场Plus>的小游戏,大家可以搜索玩下.这是一款益智类的小游戏,游戏中有红.黄.绿.蓝.紫5辆豪车6个停车位,玩家通过可行走路线移动小车,最终让各 ...

  3. 【微信小游戏实战】零基础制作《欢乐停车场》三、游戏场景制作

    1.游戏立项 微信小游戏中有一款<欢乐停车场Plus>的小游戏,大家可以搜索玩下.这是一款益智类的小游戏,游戏中有红.黄.绿.蓝.紫5辆豪车6个停车位,玩家通过可行走路线移动小车,最终让各 ...

  4. 【微信小游戏实战】零基础制作《欢乐停车场》一、游戏设计

    1.游戏立项 微信小游戏中有一款<欢乐停车场>的小游戏,大家可以搜索玩下.这是一款益智类的小游戏,游戏中有红.黄.绿.蓝.紫5辆豪车6个停车位,玩家通过可行走路线移动小车,最终让各颜色的小 ...

  5. html5拼图游戏开题报告,拼图游戏开题报告-20210406005939.doc-原创力文档

    拼图游戏开题报告 拼图游戏不仅可以帮助 ___打发时间,还可以用于锻炼儿童脑力,帮助少儿 ___大脑思维是Android平台游戏的一个特点. 智能 ___作为一种兼具通讯.办公.娱乐为一体的便携式工具 ...

  6. 微信小游戏入门案例——拼图游戏

    微信小游戏入门案例--拼图游戏 涉及内容:canvas组件.小程序界面绘图API 目录结构: pages\game\game.js // pages/game/game.js // 方块的初始位置 v ...

  7. android怎实现拼图功能,Android实战开发——拼图游戏

    时间改变的实现 在 MainActivity.java 中的 onCreate 函数中添加如下内容: //一进来每隔1s就发一条空消息出去,接收到这个空消息并让TextView发生改变,形成计数器的效 ...

  8. Android 实战美女拼图游戏 你能坚持到第几关

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/40595385,本文出自: [张鸿洋的博客] 1.概述 继2048之后,今天给大 ...

  9. Android 实战美女拼图游戏 你能坚持到第几关

    1.概述 继2048之后,今天给大家带来一个拼图游戏,当然了不是很传统那个缺一块的拼图,那游戏我不会玩~~所有我们换个方式玩拼图,怎么玩呢,把图片且成很多份,点击交换拼成一张完整的:这样关卡也很容易设 ...

  10. linux 拼图游戏,立体艺术拼图游戏

    立体艺术拼图游戏是由淘腾互动制作的益智解谜游戏,游戏中为玩家带来了独特的视觉魅力,精致唯美的游戏画面,好听动人的背景音乐.立体艺术拼图游戏中,玩家需要解开200多个谜题,才能获得最终的胜利! 立体艺术 ...

最新文章

  1. Linux内核Makefile
  2. WEB安全基础-HTML相关知识
  3. node-gulp插件
  4. 阿里云、腾讯云、UCloud 、华为云云主机对比测试报告
  5. scrapy爬虫返回302,301,解决方法
  6. 熊猫关键词工具v2.8.1.0绿色版SEO工具
  7. 免费且好用的UML工具推荐
  8. 前端后台常见问题总结
  9. 2.4 大电路静态工作点的稳定
  10. java学习php(一)基础知识
  11. 机器学习预测时label错位对未来数据做预测
  12. 套利[题目][j2]
  13. postgres 删除 shema
  14. 计算机硬件是怎么影响性能的,哪些硬件影响电脑的性能
  15. 为远程群晖NAS的自定义域名配置SSL证书
  16. 【蓝桥杯选拔赛真题40】Scratch跳格子 少儿编程scratch蓝桥杯选拔赛真题讲解
  17. ResNet网络结构详解,网络搭建,迁移学习
  18. 很不错的免费电影网站中国影视库mdbchina.com
  19. 李现助阵定格夜色之美,荣耀最强自拍手机亲民开售
  20. Spark学习(1)-Spark基础

热门文章

  1. Unity3D学习之旅7-RPG游戏-更新与踩坑实录
  2. linux查看ubuntu版本命令,检查Ubuntu版本号的三种方法:从终端和设置中检查及使用Neofetch...
  3. UserWarning: Glyph 28857 (\N{CJK UNIFIED IDEOGRAPH-70B9}) missing from current font. FigureCanvasA
  4. python中最大值函数,python中如何获取最大值函数
  5. 微信小程序_(2022)微信小程序开发者后台管理登录/开发成员管理/开发设置中设置(云)服务器/数据拉取权限配置/appID查看/邮箱修改
  6. window 脚本文件.bat获取最高权限拷贝文件及c++调用.bat文件示例
  7. Potplayer + LAVFilters + madVR 配置教程
  8. VR球类游戏填坑总结
  9. CentOS7安装CA根证书
  10. 项目风险管理之风险分析