首页 / 电竞头条 / 游戏 / 正文

用 CocosCreator 快速开发推箱子游戏

时间:2019-08-14 12:18:52 作者:

游戏总共分为4个功能模块:

- 开始游戏(menuLayer

- 关卡选择(levelLayer

- 游戏(gameLayer

- 游戏结算(gameOverLayer

Creator内组件效果如下:

用 CocosCreator 快速开发推箱子游戏

游戏开始默认显示menuLayer,游戏中,通过控制各个层级的显示和隐藏,实现不同模块的切换。例如开始游戏,点击开始以后,触发回调函数,切换到游戏关卡选择界面,绑定关系如下图:

用 CocosCreator 快速开发推箱子游戏

实现代码如下:

// 开始按钮回调
startBtnCallBack(event, customEventData){
if(this.curLayer == 1){
return;
}
this.curLayer = 1;
this.playSound(sound.BUTTON);
this.menuLayer.runAction(cc.sequence(
cc.fadeOut(0.1),
cc.callFunc(() => {
this.startBtn.stopAllActions();
this.startBtn.scale = 1.0;
this.menuLayer.opacity = 255;
this.menuLayer.active = false;
}
)));
this.levelLayer.active = true;
this.levelLayer.opacity = 0;
this.levelLayer.runAction(cc.sequence(
cc.delayTime(0.1),
cc.fadeIn(0.1),
cc.callFunc(() => {
this.updateLevelInfo();
}
)));
},

其他功能模块实现类似。以下将分4个模块分别讲述各个模块的实现。

1. 开始游戏 menuLayer

开始游戏模块,开始游戏后默认显示,其他模块隐藏,功能实现相对简单,界面布局完成以后,开始游戏按钮添加响应事件即可,实现代码如上,在此界面添加了一个小动画,让开始游戏按钮不断的放大缩小,代码如下:

// 主界面动画
menuLayerAni(){
this.startBtn.scale = 1.0;
this.startBtn.runAction(cc.repeatForever(cc.sequence(
cc.scaleTo(0.6, 1.5),
cc.scaleTo(0.6, 1.0)
)));
},

实现后的效果:

用 CocosCreator 快速开发推箱子游戏

2. 关卡选择 levelLayer

关卡选择分两步:第一步,界面显示,通过配置文件,加载预制文件,显示所有关卡;第二步,根据游戏情况,更新每一关卡信息。

2.1 第一步显示关卡

游戏中所有关卡置于ScrollView控件上,每一个关卡,使用一个预制文件(levelItem),通过读取关卡配置文件,加载所有关卡,加载完成后重新计算ScrollView内容的高度,加载关卡代码如下:

// 创建关卡界面子元素
createLavelItem (){
// 进入关卡level
let callfunc = level => {
this.selectLevelCallBack(level);
};
for(let i = 0; i < this.allLevelCount; i++){
let node = cc.instantiate(this.levelItemPrefab);
node.parent = this.levelScroll;
let levelItem = node.getComponent("levelItem");
levelItem.levelFunc(callfunc);
this.tabLevel.push(levelItem);
}
// 设置容器高度
this.levelContent.height = Math.ceil(this.allLevelCount / 5) * 135 + 20;
},

下图即是所有关卡预制的父节点:

用 CocosCreator 快速开发推箱子游戏

预制脚本挂在到预制上:

用 CocosCreator 快速开发推箱子游戏

2.2 第二步更新关卡

每一个levelItem预制上挂一个levelItem脚本组件,levelItem脚本组件负责更新信息,主要控制是否可点击、通关星数、关卡等级、点击进入,levelItem脚本组件更新UI代码如下:

/**
* @description: 显示星星数量
* @param {boolean} isOpen 是否开启
* @param {starCount} 星星数量
* @param {cc.SpriteAtlas} levelImgAtlas 纹理图
* @param {number} level 关卡
* @return:
*/
showStar(isOpen, starCount, levelImgAtlas, level){
this.itemBg.attr({"_level_" : level});
if(isOpen){
this.itemBg.getComponent(cc.Sprite).spriteFrame = levelImgAtlas.getSpriteFrame("pass_bg");
this.starImg.active = true;
this.starImg.getComponent(cc.Sprite).spriteFrame = levelImgAtlas.getSpriteFrame("point" + starCount);
this.levelTxt.opacity = 255;
this.itemBg.getComponent(cc.Button).interactable = true;
}
else{
this.itemBg.getComponent(cc.Sprite).spriteFrame = levelImgAtlas.getSpriteFrame("lock");
this.starImg.active = false;
this.levelTxt.opacity = 125;
this.itemBg.getComponent(cc.Button).interactable = false;
}
this.levelTxt.getComponent(cc.Label).string = level;
},

玩家的通过的信息,通过配置存储文件,保存玩家通关信息,分为已通关、刚开启和未开启三种状态,具体实现如下:

// 刷新关卡上的信息
updateLevelInfo(){
let finishLevel = parseInt(cc.sys.localStorage.getItem("finishLevel") || 0); //已完成关卡
for(let i = 1; i <= this.allLevelCount; i++){
// 完成的关卡
if(i <= finishLevel){
let data = parseInt(cc.sys.localStorage.getItem("levelStar" + i) || 0);
this.tabLevel[i - 1].showStar(true, data, this.levelImgAtlas, i);
}
// 新开的关卡
else if(i == (finishLevel + 1)){
this.tabLevel[i - 1].showStar(true, 0, this.levelImgAtlas, i);
}
// 未开启关卡图
else{
this.tabLevel[i - 1].showStar(false, 0, this.levelImgAtlas, i);
}
}
},

最终的显示效果如下图:

用 CocosCreator 快速开发推箱子游戏

3. 游戏 gameLayer

游戏也分为两步:第一步,显示界面;第二步,游戏操作判断

3.1 显示界面

游戏内使用levelConfig.json配置每一关卡信息,每个关卡游戏部分由多行多列的方格组成,每一个关卡信息包含content、allRow、allCol、heroRow、heroCol、allBox属性,allRow和allCol记录总共行数和列数,heroRow、heroCol记录英雄所在位置,allBox记录箱子的总数,content是核心,记录每个方格的属性,根据不同的属性显示不同的物体,如墙面、地面、物体、箱子,可以通过修改配置,增加任意关卡。

读取关卡所有数据,并根据每一个位置的属性,显示不同的实物。

根据配置创建关卡信息:


// 创建关卡
createLevelLayer(level){
this.gameControlLayer.removeAllChildren();
this.setLevel();
this.setCurNum();
this.setBestNum();
let levelContent = this.allLevelConfig[level].content;
this.allRow = this.allLevelConfig[level].allRow;
this.allCol = this.allLevelConfig[level].allCol;
this.heroRow = this.allLevelConfig[level].heroRow;
this.heroCol = this.allLevelConfig[level].heroCol;
// 计算方块大小
this.boxW = this.allWidth / this.allCol;
this.boxH = this.boxW;
// 计算起始坐标
let sPosX = -(this.allWidth / 2) + (this.boxW / 2);
let sPosY = (this.allWidth / 2) - (this.boxW / 2);
// 计算坐标的偏移量,运算规则(宽铺满,设置高的坐标)
let offset = 0;
if(this.allRow > this.allCol){
offset = ((this.allRow - this.allCol) * this.boxH) / 2;
}
else{
offset = ((this.allRow - this.allCol) * this.boxH) /
相关资讯