整体思路

在15*15的棋盘上每一个可下棋子的地方都放置一个“隐形的棋子”,当要在某个位置下子时就将该位置的棋子显示出来,在判断输赢逻辑里,我们根据这225个”隐形棋子”的状态(黑,白,无)判断输赢

涉及知识点

  1. 场景切换
  2. 按钮事件监听
  3. 节点事件监听
  4. 节点数组
  5. 循环中闭包的应用
  6. 动态更换sprite图片
  7. 定时器

关于人机算法
参考了http://blog.csdn.net/onezeros/article/details/5542379

  • 新建工程

  • 在Menu.js里添加开始游戏方法
cc.Class({extends: cc.Component,startGame:function(){cc.director.loadScene('Game');}
});
  • 然后将其添加为Menu场景的Canvas的组件

现在我们在Menu场景里点击一下人机按钮就会跳转到游戏场景了

  • 将其改名为Chess拖入下面assets文件夹使其成为预制资源

  • 制作一个结束场景

  • 新建Game脚步添加到ChessBoard节点下
cc.Class({extends: cc.Component,properties: {overSprite:{default:null,type:cc.Sprite,},overLabel:{default:null,type:cc.Label},chessPrefab:{//棋子的预制资源default:null,type:cc.Prefab},chessList:{//棋子节点的集合,用一维数组表示二维位置default: [],type: [cc.node]},whiteSpriteFrame:{//白棋的图片default:null,type:cc.SpriteFrame},blackSpriteFrame:{//黑棋的图片default:null,type:cc.SpriteFrame},touchChess:{//每一回合落下的棋子default:null,type:cc.Node,visible:false//属性窗口不显示},gameState:'white',fiveGroup:[],//五元组fiveGroupScore:[]//五元组分数},//重新开始startGame(){cc.director.loadScene("Game");},//返回菜单toMenu(){cc.director.loadScene("Menu");},onLoad: function () {this.overSprite.node.x = 10000;//让结束画面位于屏幕外var self = this;//初始化棋盘上225个棋子节点,并为每个节点添加事件for(var y = 0;y<15;y++){for(var x = 0;x < 15;x++){var newNode = cc.instantiate(this.chessPrefab);//复制Chess预制资源this.node.addChild(newNode);newNode.setPosition(cc.p(x*40+20,y*40+20));//根据棋盘和棋子大小计算使每个棋子节点位于指定位置newNode.tag = y*15+x;//根据每个节点的tag就可以算出其二维坐标newNode.on(cc.Node.EventType.TOUCH_END,function(event){self.touchChess = this;if(self.gameState ===  'black' && this.getComponent(cc.Sprite).spriteFrame === null){this.getComponent(cc.Sprite).spriteFrame = self.blackSpriteFrame;//下子后添加棋子图片使棋子显示self.judgeOver();if(self.gameState == 'white'){self.scheduleOnce(function(){self.ai()},1);//延迟一秒电脑下棋}}});this.chessList.push(newNode);}}//开局白棋(电脑)在棋盘中央下一子this.chessList[112].getComponent(cc.Sprite).spriteFrame = this.whiteSpriteFrame;this.gameState = 'black';//添加五元数组//横向for(var y=0;y<15;y++){for(var x=0;x<11;x++){this.fiveGroup.push([y*15+x,y*15+x+1,y*15+x+2,y*15+x+3,y*15+x+4]);}  }//纵向for(var x=0;x<15;x++){for(var y=0;y<11;y++){this.fiveGroup.push([y*15+x,(y+1)*15+x,(y+2)*15+x,(y+3)*15+x,(y+4)*15+x]);}}//右上斜向for(var b=-10;b<=10;b++){for(var x=0;x<11;x++){if(b+x<0||b+x>10){continue;}else{this.fiveGroup.push([(b+x)*15+x,(b+x+1)*15+x+1,(b+x+2)*15+x+2,(b+x+3)*15+x+3,(b+x+4)*15+x+4]);}}}//右下斜向for(var b=4;b<=24;b++){for(var y=0;y<11;y++){if(b-y<4||b-y>14){continue;}else{this.fiveGroup.push([y*15+b-y,(y+1)*15+b-y-1,(y+2)*15+b-y-2,(y+3)*15+b-y-3,(y+4)*15+b-y-4]);}}}},//电脑下棋逻辑ai:function(){//评分for(var i=0;i<this.fiveGroup.length;i++){var b=0;//五元组里黑棋的个数var w=0;//五元组里白棋的个数for(var j=0;j<5;j++){this.getComponent(cc.Sprite).spriteFrameif(this.chessList[this.fiveGroup[i][j]].getComponent(cc.Sprite).spriteFrame == this.blackSpriteFrame){b++;}else if(this.chessList[this.fiveGroup[i][j]].getComponent(cc.Sprite).spriteFrame == this.whiteSpriteFrame){w++;}}if(b+w==0){this.fiveGroupScore[i] = 7;}else if(b>0&&w>0){this.fiveGroupScore[i] = 0;}else if(b==0&&w==1){this.fiveGroupScore[i] = 35;}else if(b==0&&w==2){this.fiveGroupScore[i] = 800;}else if(b==0&&w==3){this.fiveGroupScore[i] = 15000;}else if(b==0&&w==4){this.fiveGroupScore[i] = 800000;}else if(w==0&&b==1){this.fiveGroupScore[i] = 15;}else if(w==0&&b==2){this.fiveGroupScore[i] = 400;}else if(w==0&&b==3){this.fiveGroupScore[i] = 1800;}else if(w==0&&b==4){this.fiveGroupScore[i] = 100000;}}//找最高分的五元组var hScore=0;var mPosition=0;for(var i=0;i<this.fiveGroupScore.length;i++){if(this.fiveGroupScore[i]>hScore){hScore = this.fiveGroupScore[i];mPosition = (function(x){//js闭包return x;})(i);}}//在最高分的五元组里找到最优下子位置var flag1 = false;//无子var flag2 = false;//有子var nPosition = 0;for(var i=0;i<5;i++){if(!flag1&&this.chessList[this.fiveGroup[mPosition][i]].getComponent(cc.Sprite).spriteFrame == null){nPosition = (function(x){return x})(i);}if(!flag2&&this.chessList[this.fiveGroup[mPosition][i]].getComponent(cc.Sprite).spriteFrame != null){flag1 = true;flag2 = true;}if(flag2&&this.chessList[this.fiveGroup[mPosition][i]].getComponent(cc.Sprite).spriteFrame == null){nPosition = (function(x){return x})(i);break;}}//在最最优位置下子this.chessList[this.fiveGroup[mPosition][nPosition]].getComponent(cc.Sprite).spriteFrame = this.whiteSpriteFrame;this.touchChess = this.chessList[this.fiveGroup[mPosition][nPosition]];this.judgeOver();},judgeOver:function(){var x0 = this.touchChess.tag % 15;var y0 = parseInt(this.touchChess.tag / 15);//判断横向var fiveCount = 0;for(var x = 0;x < 15;x++){if((this.chessList[y0*15+x].getComponent(cc.Sprite)).spriteFrame === this.touchChess.getComponent(cc.Sprite).spriteFrame){fiveCount++; if(fiveCount==5){if(this.gameState === 'black'){this.overLabel.string = "你赢了";this.overSprite.node.x = 0;}else{this.overLabel.string = "你输了";this.overSprite.node.x = 0;}this.gameState = 'over';return;}}else{fiveCount=0;}}//判断纵向fiveCount = 0;for(var y = 0;y < 15;y++){if((this.chessList[y*15+x0].getComponent(cc.Sprite)).spriteFrame === this.touchChess.getComponent(cc.Sprite).spriteFrame){fiveCount++; if(fiveCount==5){if(this.gameState === 'black'){this.overLabel.string = "你赢了";this.overSprite.node.x = 0;}else{this.overLabel.string = "你输了";this.overSprite.node.x = 0;}this.gameState = 'over';return;}}else{fiveCount=0;}}//判断右上斜向var f = y0 - x0;fiveCount = 0;for(var x = 0;x < 15;x++){if(f+x < 0 || f+x > 14){continue;}if((this.chessList[(f+x)*15+x].getComponent(cc.Sprite)).spriteFrame === this.touchChess.getComponent(cc.Sprite).spriteFrame){fiveCount++; if(fiveCount==5){if(this.gameState === 'black'){this.overLabel.string = "你赢了";this.overSprite.node.x = 0;}else{this.overLabel.string = "你输了";this.overSprite.node.x = 0;}this.gameState = 'over';return;}}else{fiveCount=0;}}//判断右下斜向f = y0 + x0;fiveCount = 0;for(var x = 0;x < 15;x++){if(f-x < 0 || f-x > 14){continue;}if((this.chessList[(f-x)*15+x].getComponent(cc.Sprite)).spriteFrame === this.touchChess.getComponent(cc.Sprite).spriteFrame){fiveCount++; if(fiveCount==5){if(this.gameState === 'black'){this.overLabel.string = "你赢了";this.overSprite.node.x = 0;}else{this.overLabel.string = "你输了";this.overSprite.node.x = 0;}this.gameState = 'over';return;}}else{fiveCount=0;}}//没有输赢交换下子顺序if(this.gameState === 'black'){this.gameState = 'white';}else{this.gameState = 'black';}}});

最终效果


对于初学者几个建议

1.虽然官方说对JavaScript的要求不高,但我还是建议大家能找一本js的书从头到尾的学习一下,比如循环中闭包的应用,如果不了解就会走很多弯路

2.官方文档api里的教程其实很全面了,但并不适合从头到尾那样”读着学“,我们应该找一些简单的游戏,亲自上手做,需要哪些功能就到文档里去找,做游戏的多了,也就可以脱离文档了

工程源码链接:http://pan.baidu.com/s/1gf0gQjh 密码:59ns

微信号:xinshouit
更新会在里面通知

【Cocos Creator 实战教程(1)】——人机对战五子棋(节点事件相关)相关推荐

  1. slider节点透明背景_【Cocos Creator 实战教程(1)】——人机对战五子棋(节点事件相关)...

    一.涉及知识点 场景切换 按钮事件监听 节点事件监听 节点数组 循环中闭包的应用 动态更换sprite图片 定时器 预制资源 二.步骤 2.1 准备工作 首先,我们要新建一个空白工程,并在资源管理器中 ...

  2. 【Cocos Creator 实战教程(4)】——黄金矿工(上)(节点动作、碰撞体相关)

    准备工作: 我们新建一个工程,名字叫做GoldMiner,把相关资源导入,搭建一个游戏场景如下(灰色节点先不用看,那是后来加上的): 绳子伸缩思路: 在玩游戏时我们需要让绳子伸长去采矿,在制作游戏的时 ...

  3. 【COCOS CREATOR 系列教程之二】脚本开发篇事件监听、常用函数等示例整合

    本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/cocos-creator/1959.htm ...

  4. 【Cocos Creator实战教程(7)】——猴子摘月亮(平台动作,碰撞检测详解)

    最后一个寒假说没就没... 话说我等Creator 的物理引擎等了好久好久,终于......还是没等到...... 我们今天就用碰撞检测系统和一些算法简单的模拟一下2D平台动作的物理特性吧 先来看一下 ...

  5. 【Cocos Creator实战教程(6)】——get47(数字消除)

    先来看一下游戏效果 电脑端:http://www.potato47.cn/get47 手机端:http://www.potato47.cn/get47-m 微信扫描: 游戏玩法: 游戏操作仿的是天天爱 ...

  6. Cocos Creator实战教程(5)】——打砖块(物理引擎,碰撞检测)

    1. 知识点 物理引擎 碰撞检测 2. 步骤 2.1 准备工作 搭一个游戏背景 2.2 小球运动 再建一个物理层,用来装游戏里的带有物理属性的东西,设置锚点为左下角 wall:墙//小球碰到就会反弹的 ...

  7. 【Cocos Creator实战教程(3)】——TiledMap(瓦片地图)组件

    1. 前言 瓦片地图是由一张一张的正方形小图片拼接成的地图,例如炸弹人,QQ堂都是非常典型的瓦片游戏.瓦片地图(Tile Map) 不但生成简单,并且可以灵活的用于Cocos2d-x引擎.不论你的游戏 ...

  8. 【Cocos Creator 实战教程(2)】——天天酷跑(动画、动作相关)

    转载请保留原文链接,个人公众号:xinshouit(新手程序员),欢迎关注 准备工作 把背景图拉长,很长很长的那种....一会我们要让它滑动起来 背景动画 为背景节点添加滚动动画 现在背景就循环滚动起 ...

  9. 【Cocos Creator 实战】06 - 如何给拼图游戏添加计时器

    文章目录 概览 主要内容 项目资源 开搞 项目结构 字体 如何控制节点的显示&隐藏 如何设置节点的相对位置 & 自动大小 & 对齐策略 如何防止节点的点击穿透 如何倒计时 总结 ...

最新文章

  1. 深度学习11个实用技巧
  2. Typora输出表情 Typora_Smile
  3. Java学习笔记17
  4. JSON是什么,为什么这么流行?
  5. 《剑指offer》-- 构建乘积数组、求1+2+3+...+n、不用加减乘除做加法、包含min函数的栈、用两个栈实现队列
  6. 桌面快捷键和桌面livefolder
  7. Python第一天学习---基础语法
  8. 坯子库和suapp哪个好用_「双全科技」进销存软件哪个简单好用,管家婆进销存软件教程...
  9. Vue动态类名的实现
  10. 单链表的读取、插入与删除
  11. python字符串不可改变怎么理解_python的“不可变性”代表了什么?
  12. Linux学习笔记4 - Linux常用命令
  13. 怎么看vray渲染进度_3dmax渲染怎么看渲染时间
  14. (2)响应式流——响应式Spring的道法术器
  15. 北京轨道交通新机场线“无人驾驶” 最高时速160公里
  16. Django框架学习记录(3)
  17. Linux的numactl
  18. Zotero配合坚果云Web DAV同步那些坑
  19. 怎么批量把图片转文字?教你几招轻松完成
  20. 基础I/O【Linux】

热门文章

  1. 在美团工作是种什么样的体验?
  2. 苹果vs谷歌:与微软的战争教会了苹果什么
  3. android 融云 + 科大讯飞 实现仿微信语音消息转换为文字(附DEMO源码)
  4. “长光卫星”已完成2.5亿元天使轮融资,已是全国规模最大的民营商业卫星公司... 1
  5. CNCBK精准扶贫走进广东省暨全国代理商大会
  6. Confluent 源码学习 - SinkTask
  7. 同济大学计算机学硕无人录取,同济大学公布拟录取结果,学硕初试成绩410分,复试却不合格!...
  8. MySQL:生产误删除数据恢复方法
  9. call和calling的用法_call和calling的用法_英语词汇call的短语及用法
  10. java 导出答题卡_试题六(共15分) 阅读以下说明、图和Java代码,填补Java代码中的空缺(1)~(6),将解答写在答题纸的对 - 赏学吧...