1.适用的情况
左右滑动式滚动区的关卡界面
2.实现的思路
关卡按钮使用预制文件,在进入关卡时动态生成。
根据关卡总数计算滚动区的大小。
根据当前关卡序号设置滚动区的位置和表示分页的点的显示。
3.控件布局
Canvas
--scrollView
--view
--content
--pointNode
--point1
--red
--black
--point2
--point3
--point4
--point5
--point6
4.代码
Common.js-------------------
module.exports = {
currentLevel: 1, //当前关卡
maxLevel: 29, //关卡总数
};
Level.js-------------------
var common = require('zqddn_zhb_Common');
cc.Class({
extends: cc.Component,
properties: {
scrollViewNode: cc.Node, //滚动区节点
scrollViewContentNode: cc.Node, //滚动区内容节点
linePrefab: cc.Prefab, //线预制
levelBtnPrefab: cc.Prefab, //关卡按钮预制
pointNode: { default: [], type: cc.Node }, //点节点
},
onLoad: function() {
this.first = true; //第1次
this.only1 = true; //只一次
this.only2 = true;
this.only3 = true;
this.currentPageIndex = 0; //当前滚动页序号
this.direction = 0; //滚动方向(0默认,1左,2右)
this.startOffset = 0; //开始滚动时第1帧
this.endOffset = 0; //开始滚动时第2帧
//根据关卡数设置滚动区大小
this.pageCount = Math.ceil(common.maxLevel / 12);
this.scrollViewContentNode.width = 750 * this.pageCount;
//添加线
for(var i = 0; i < this.pageCount; i++){
for(var j = 0; j < 4; j++){
var line = cc.instantiate(this.linePrefab);
this.scrollViewContentNode.addChild(line);
line.setPosition(375 + 750 * i, 460 - j * 255);
}
}
//添加关卡按钮
var currentLevel = cc.sys.localStorage.getItem('zqddn_zhb_currentLevel') || 1; //当前关卡
//currentLevel = common.currentLevel; //测试用
common.currentLevel = currentLevel;
var pos = [[140, 372], [375, 381], [613, 390], [140, 118], [375, 126], [613, 134], [140, -136], [375, -129], [613, -121], [140, -390], [375, -384], [613, -375]];
for(var i = 0; i < common.maxLevel; i++){
var btnNode = cc.instantiate(this.levelBtnPrefab);
this.scrollViewContentNode.addChild(btnNode);
btnNode.setPosition(pos[i % 12][0] + 750 * Math.floor(i / 12), pos[i % 12][1]);
//设置按钮
if(i < currentLevel - 1){ //已过关
btnNode.getChildByName("select").active = false;
btnNode.getChildByName("image1").active = false;
btnNode.getChildByName("num").active = true;
btnNode.getChildByName("num").getComponent(cc.Label).string = (i + 1 < 10) ? ("0" + (i + 1)) : (i + 1);
btnNode.getChildByName("star0").active = true;
btnNode.getChildByName("star1").active = false;
btnNode.getChildByName("lock").active = false;
}else if(i == currentLevel - 1){ //当前关
btnNode.getChildByName("select").active = true;
btnNode.getChildByName("image1").active = false;
btnNode.getChildByName("num").active = true;
btnNode.getChildByName("num").getComponent(cc.Label).string = (i + 1 < 10) ? ("0" + (i + 1)) : (i + 1);
btnNode.getChildByName("star0").active = false;
btnNode.getChildByName("star1").active = true;
btnNode.getChildByName("lock").active = false;
}else{ //未解锁
btnNode.getChildByName("select").active = false;
btnNode.getChildByName("image1").active = true;
btnNode.getChildByName("num").active = false;
btnNode.getChildByName("num").getComponent(cc.Label).string = (i + 1 < 10) ? ("0" + (i + 1)) : (i + 1);
btnNode.getChildByName("star0").active = false;
btnNode.getChildByName("star1").active = false;
btnNode.getChildByName("lock").active = true;
}
//绑定事件
var clickEventHandler = new cc.Component.EventHandler();
clickEventHandler.target = this.node;
clickEventHandler.component = "zqddn_zhb_Level";
clickEventHandler.handler = "onLevelBtn";
clickEventHandler.customEventData = (i + 1).toString();
var btn = btnNode.getComponent(cc.Button);
btn.clickEvents.push(clickEventHandler);
}
//设置点位置(目前只添加了6个点,以后根据需要再添加)
for(var i = 0; i < this.pointNode.length; i++){
this.pointNode[i].active = i < this.pageCount ? true : false;
}
var isEvenNumber = this.pageCount % 2 == 0 ? true : false;
if(isEvenNumber){ //偶数
var half = Math.floor(this.pageCount / 2);
for(var i = 0; i < this.pageCount; i++){
this.pointNode[i].x = -(half - i - 1) * 40 - 20;
}
}else{ //奇数
var half = Math.ceil(this.pageCount / 2);
for(var i = 0; i < this.pageCount; i++){
this.pointNode[i].x = -(half - i - 1) * 40;
}
}
//设置滚动区为当前关按钮所在页面
for(var i = 0; i < this.pageCount; i++){
if(currentLevel - 1 >= i * 12 && currentLevel - 1 <= (i + 1) * 12 - 1){
this.currentPageIndex = i;
break;
}
}
console.log("currentPageIndex=" + this.currentPageIndex);
this.scheduleOnce(function(){ //延迟到滚动区设置完毕(不延迟会出现页面一直在第1页)
this.scrollToPage(this.currentPageIndex); //滚动到指定百分比位置
}, 0.1);
if(cc.sys.platform === cc.sys.WECHAT_GAME){ //微信平台
this.scheduleOnce(function(){
this.setMoreGameBtnImage();
}, 0.1); //延迟0.1秒
}
this.scrollViewNode.on("scrolling", function(){ //滚动中事件
if(this.only3 && !this.first){
this.only3 = false;
this.startOffset = this.scrollViewContentNode.x;
}
}, this);
this.scrollViewNode.on("scroll-ended", function(){ //滚动结束事件
if(this.only2 && !this.first){
this.only2 = false;
this.scrollToTarget();
}
}, this);
},
scrollToTarget: function(){
this.endOffset = this.scrollViewContentNode.x;
var t = Math.ceil(Math.abs(this.endOffset)) % 750;
if(t >= 0 && t <= 10){ //太小的滚动,直接忽略
this.only2 = true;
this.only3 = true;
return;
}
this.direction = this.endOffset - this.startOffset < 0 ? 1 : 2;
if(this.direction == 1){ //向左
this.currentPageIndex = this.currentPageIndex + 1 <= (this.pageCount - 1) ? (this.currentPageIndex + 1) : this.pageCount - 1;
}else if(this.direction == 2){ //向右
this.currentPageIndex = this.currentPageIndex - 1 >= 0 ? (this.currentPageIndex - 1) : 0;
}
this.scrollToPage(this.currentPageIndex); //滚动到指定百分比位置
},
scrollToPage: function(pageIndex){
this.only2 = this.only3 = false;
var percent = 0;
if(this.pageCount == 1){ //滚动区只有1页
return;
}else if(this.pageCount == 2){ //滚动区只有2页
percent = pageIndex;
}else if(this.pageCount >= 3){ //滚动区有超过3页
if(pageIndex == 0){ //第1页
percent = 0;
}else if(pageIndex == this.pageCount - 1){ //最后一页
percent = 1;
}else{
percent = pageIndex / (this.pageCount - 1);
}
}
console.log("percent=" + percent);
this.scrollViewNode.getComponent(cc.ScrollView).scrollToPercentHorizontal(percent, 0.2); //滚动到指定百分比位置
for(var i = 0; i < this.pageCount; i++){
this.pointNode[i].getChildByName("black").active = pageIndex == i ? false : true; //黑色点
}
this.scheduleOnce(function(){ //初始化
this.only2 = this.only3 = true;
this.direction = 0;
this.first = false;
}, 0.2);
},
});