cocos creator制作一个简单的拼图游戏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cocos creator制作一个简单的拼图游戏相关的知识,希望对你有一定的参考价值。
参考技术A 简介使用cocos creator2.x版本制作的拼图游戏, 移动图块, 还原最终的样子开始, 我们分析一下这个游戏的几个要点 1, 是如何将一张完整的图片分成3*3 5*5个小图, 并且这些小图要可以保存自己的位置信息, 等一些属性 2, 是如何表示小图合集的位置, 用什么数据结构保存, 且怎么让图片逻辑, 与数据逻辑对应 3, 是如何判断游戏结束
上图是游戏的场景结构, 可以看到2.x版本和1.x版本有一些区别, 最突出的就是新增了一个默认的carmera结点 这个我会在别的帖子内仔细介绍, 这里不再多说
首先我们解决第一个问题, 如何将一个大图切成一个个小图, 并让这个小图保存一些属性值, 我们先新建一个脚本, puzzlePiece.ts,
const ccclass, property = cc._decorator;
@ccclass
exportclassPieceextendscc.Component
@property(
type: cc.Texture2D
)
privatetexture: cc.Texture2D =null;
publicoriCol: number;
publicoriRow: number;
publiccurCol: number;
publiccurRow: number;
publicisBlank:boolean;
publicgetisRight()
returnthis.curCol ===this.oriCol &&this.curRow ===this.oriRow;
publicinit(col: number, row: number, colNum: number, colWidth: number)
this.oriCol = col;
this.oriRow = row;
this.curCol = col;
this.curRow = row;
let sprite =this.node.addComponent(cc.Sprite);
// 升级2.0后setRect失效
// sprite.spriteFrame = new cc.SpriteFrame(this.texture);
// let rect = sprite.spriteFrame.getRect();
let rect = cc.rect(0,0,this.texture.width,this.texture.height);
let newRectWidth = rect.width / colNum;
let newRectHeight = rect.height / colNum;
let newRectX = col * newRectWidth;
let newRectY = (colNum - row -1) * newRectHeight;
let newRect = cc.rect(newRectX, newRectY, newRectWidth, newRectHeight);
// sprite.spriteFrame.setRect(newRect);
sprite.spriteFrame =newcc.SpriteFrame(this.texture, newRect);
this.node.width = colWidth;
this.node.height = colWidth;
this.isBlank =this.oriCol === colNum -1&&this.oriRow ===0;
if(this.isBlank)
this.node.active =false;
将小图看做一个类, 使用texture保存图片纹理,在通过new cc.SpriteFrame(this.texture, newRect);获取某一个矩形区域内的纹理, 这样就可以把一张大图切成一张张小图, 并添加几个属性, 保存位置和其他的信息
那么开始解决第二个问题, 我们可以采取二维数组的数据结构保存数据信息private pieceMap: Array; 讲一个个切好的小图保存在内, 然后随机移动(为了保证图片可以还原, 我采取的方法是将一个正确摆放好的小图数组, 按照游戏规定的移动方式随机移动1000次), 这样图片一定可以被还原
import Piece from"./PuzzlePiece";
import PuzzleScene from"./PuzzleScene";
const ccclass, property, executeInEditMode = cc._decorator;
@ccclass
// @executeInEditMode
exportclassPuzzleBoardextendscc.Component
@property(cc.Prefab)
privatepiecePrefab: cc.Prefab =null;
@property(cc.Integer)
privatecolNum: number =5;
@property(cc.Integer)
privatecolSpace: number =5;
privatecolWidth: number =0;
privatepieceMap: Array;
privateblankPiece: Piece =null;
privatepuzzleScene: PuzzleScene =null;
init(puzzleScene: PuzzleScene)
this.puzzleScene = puzzleScene;
this.addListeners();
publicreset(colNum?: number)
this.colNum = colNum;
this.colWidth = (this.node.width -this.colSpace * (this.colNum +1)) /this.colNum;
this.node.removeAllChildren();
this.pieceMap = [];
for(let x =0; x
this.pieceMap[x] = [];
for(let y =0; y
let pieceNode = cc.instantiate(this.piecePrefab);
this.node.addChild(pieceNode);
pieceNode.x = x * (this.colWidth +this.colSpace) +this.colSpace;
pieceNode.y = y * (this.colWidth +this.colSpace) +this.colSpace;
this.pieceMap[x][y] = pieceNode.getComponent(Piece);
this.pieceMap[x][y].init(x, y,this.colNum,this.colWidth);
if(this.pieceMap[x][y].isBlank)
this.blankPiece =this.pieceMap[x][y];
this.shuffle();
privateshuffle()
for(let i =0; i <1000; i++)
let nearPieces =this.getNearPieces(this.blankPiece);
let n = Math.floor(Math.random() * nearPieces.length);
this.exchangeTwoPiece(this.blankPiece, nearPieces[n]);
privateonBoadTouch(event: cc.Event.EventTouch)
let worldPos = event.getLocation();
let localPos =this.node.convertToNodeSpaceAR(worldPos);
let x = Math.floor((localPos.x -this.colSpace) / (this.colWidth +this.colSpace));
let y = Math.floor((localPos.y -this.colSpace) / (this.colWidth +this.colSpace));
this.puzzleScene.onBoardTouch(x, y);
publicmovePiece(x, y):boolean
let piece =this.pieceMap[x][y];
let nearPieces =this.getNearPieces(piece);
for(let nearPiece of nearPieces)
if(nearPiece.isBlank)
this.exchangeTwoPiece(piece, nearPiece);
returntrue;
returnfalse;
publicjudgeWin():boolean
for(let x =0; x
for(let y =0; y
if(!this.pieceMap[x][y].isRight)
returnfalse;
this.blankPiece.node.active =true;
returntrue;
privategetNearPieces(piece: Piece): Array
let nearPieces = [];
if(piece.curCol >0) // left
nearPieces.push(this.pieceMap[piece.curCol -1][piece.curRow]);
if(piece.curCol
nearPieces.push(this.pieceMap[piece.curCol +1][piece.curRow]);
if(piece.curRow >0) // bottom
nearPieces.push(this.pieceMap[piece.curCol][piece.curRow -1]);
if(piece.curRow
nearPieces.push(this.pieceMap[piece.curCol][piece.curRow +1]);
returnnearPieces;
publicexchangeTwoPiece(piece1: Piece, piece2: Piece)
this.pieceMap[piece2.curCol][piece2.curRow] = piece1;
this.pieceMap[piece1.curCol][piece1.curRow] = piece2;
[piece1.curCol, piece2.curCol] = [piece2.curCol, piece1.curCol];
[piece1.curRow, piece2.curRow] = [piece2.curRow, piece1.curRow];
[piece1.node.position, piece2.node.position] = [piece2.node.position, piece1.node.position];
privateaddListeners()
this.node.on(cc.Node.EventType.TOUCH_END,this.onBoadTouch,this);
privateremoveListeners()
解决第三个问题, 其实这个很简单, 因为我们已经在小图类中保存了小图本身的位置信息, 我们只需要,每次移动图片 都遍历一个二维数组判断其是否在正确的位置, 判断成功, 结束游戏 点击链接加入群聊【cocos/unity交流群】
声明 :发布此文是出于传递更多知识以供交流学习之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与我们联系,我们将及时更正、删除,谢谢
COCOS CREATOR 系列教程之四基于0.7.1先简单制作一个PAGEVIEW
本站文章均为 李华明Himi 原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/cocos-creator/1999.html
由于当前版本还没有发布1.0,因此还有不少组件没有发布,那么Himi也看到Cocos Creator群里有几个童鞋问起过PageView的问题,那么Himi正好借此练手,基于当前版本制作一个PageView。
本文分为两部分进行讲解: 1. 制作PageView 2. 如何使用
一. 制作PageView
由于都是基于当前cc版本提供的组件进行的,所以这里不进行详细的解释与介绍。
其实制作PageView,首先考虑要保证考虑如下几点:
1. 要能自动布局
2. 要能设置裁切区域
3. 提供用户参数设置。
那么回过头来想考虑当前CC版本提供的组件,是否可满足以上条件呢:
1. 自动布局?? CC里有Layout,并且可以设置布局横竖两方向、还提供了间隔的设定。
2. 设置裁切区域?? CC里有Mask。
OK,下面开始动手,步骤如下:
1. 首先我们创建一个空节点PageView,并添加Mask组件作为裁切视图。
2. 在PageView节点下,我们添加一个布局组件pLayout, 以后用户直接在pLayout下进行添加item即可实现自动布局。
3. 在根节点PageView挂自定义的脚本,其内容实现触摸滑动翻页的逻辑(对Layout的位置改变)等
4. Himi将PageView制作成了Prefab,便于使用(现在插件制作Himi还没仔细看 – -。)
完成效果如下图GIF所示:(点击可看到动态效果)
二. 如何使用:
1. 拷贝PageView(Prefab)和PvJs(脚本)到资源管理器中,拖PageView 的Prefab 到层级管理器中即可使用。
2. 参数设置:
选中根节点PageView,然后查看属性检查器中的脚本提供的参数,如下图:
Item_Count: Item 数量 (请保证这里的数量与你在pLayout下添加的子节点数量保证一致!)
Item_Width: 每个 Item 的宽度
Item_Height:每个 Item 的高度
Item_Move_Dis:设定触发翻页的距离(像素)
3. 设置剪切区域大小
选中根节点PageView,然后查看属性检查器中的节点Node的Size属性,让其宽高与每个Item的宽高保持一致!
4. 设置布局类型、排序类型以及间隔
选中 根节点PageView 下的pLayout 子节点的属性检查器中的Layout组件,如下图:
Layout Type: 布局的类型,三个类型:
NONE : 无 (既然要做PageView的效果,选这个不太讲道理了,请务必不要选这个)
HORIZONTAL:横向排版
VERTICAL: 纵向排版
Margin:空白的大小(横向可改宽度、纵向可改变高度)
Spacing X: 每个item X轴之间的间隔(选择横向排版时出现的属性)
Spacing Y: 每个item Y轴之间的间隔(选择纵向排版时出现的属性)
Horizontal Direction:有两个类型:
LEFT_TO_RIGHT:从左到右的顺序排列
RIGHT_TO_LEFT:从右到左的顺序排列
5. 在pLayout下添加item吧,想加多少请随意。只需记得其数量要保证与PageView脚本里的Item_Count参数设置的数量保持一致。
其实简化使用过程,就1步:
选中PageView,在属性检查器中,设置好Node 的Size 与你的Item大小保持一致,并对脚本暴露出来的参数进行合适设定。
(记得检查pLayout下的Layout Type 这个布局类型属性不可选NONE,因为Himi也不支持 -。 0)
下面放出源码: http://vdisk.weibo.com/s/yZxRoLm4MKqqU
项目结构:
资源管理器的HPV文件夹就是啦~
PageViewTest 是示例
PageView 是模板,大家用这个~
PvJs 是脚本
himi 是图片,大家可以无视
使用演示:(点击可看到动态效果)
那么年前就到这里,各位咱们年后见~
本文出自 “李华明Himi” 博客,请务必保留此出处http://xiaominghimi.blog.51cto.com/2614927/1741214
以上是关于cocos creator制作一个简单的拼图游戏的主要内容,如果未能解决你的问题,请参考以下文章