demo下载:
https://download.csdn.net/download/K86338236/85836249
点击按钮切换界面
import Util from "./Util";
const { ccclass, property } = cc._decorator;
@ccclass
export default class mainTab extends cc.Component {
//gamelayer
@property(cc.Node)
gameLayer: cc.Node = null;
//按钮
@property([cc.Node])
buttoms: cc.Node[] = [];
//页面
@property([cc.Prefab || cc.Node])
pages: cc.Prefab[] | cc.Node[] = [];
//默认放在主界面中的界面
@property(cc.Prefab || cc.Node)
public mainPage: cc.Prefab | cc.Node = null;
_scenes: cc.Node[] = []
_scenes_now: string = "";
_lode_finish: boolean = false;
public _couldTouch: boolean = false;
onLoad(): void {
this.loadScene();
for (let i = 0; i < this.buttoms.length; i++) {
const element = this.buttoms[i];
if (!this.pages[i]) {
cc.error("mainTab---按钮和页面数量不对应");
return;
}
Util.registerBtnEvent(element, this.changePage, this, this.pages[i].name, { isScale: false });
}
this.onSceneChange({ pageName: this.mainPage.name });
}
loadScene() {
let sceneName = "mainPage";
this.loadScenes(sceneName, this.mainPage.name)
}
onChangeMainScene(data) {
let index = this.pages.findIndex((item) => { return item.name == data.pageName })
if (index == -1) {
cc.error("切换失败!未加载页面" + data.pageName);
return;
}
this.onChangeCheck(data);
this.onSceneChange(data);
}
onMainLoad() {
this._couldTouch = true;
// EventMgr.listen(GameEventType.CHANGE_MAIN_SCENE, this.onChangeMainScene, this);
}
/**
* 页面切换
* @param target
* @param name
* @returns
*/
changePage(target: cc.Node, name: string) {
if (!this._couldTouch) {
return;
}
// cc.log(target, name);
// EventMgr.trigger(GameEventType.CHANGE_MAIN_SCENE, { pageName: name });
this.onChangeMainScene({ pageName: name })
}
/**
* 加载tab场景
* @param SceneName
* @param firstScene
* @param cb
*/
loadScenes(SceneName: string, firstScene: string) {
this._lode_finish = false;
cc.resources.loadDir(SceneName, (e, res: cc.Prefab[]) => {
if (e) {
console.error(`加载mainPage错误`, e);
return;
}
for (let i = 0; i < res.length; i++) {
const element = res[i];
let index = this.pages.findIndex((item) => { return item.name == element.name })
if (index == -1) {
cc.assetManager.releaseAsset(element);
continue;
}
let node: cc.Node = cc.instantiate(element);
if (node) {
this._scenes.push(node);
node.active = false;
node.parent = this.gameLayer;
let js = Util.getScript(node);
if (element.name == firstScene) {
if (js) js._init && js._init();
node.active = true;
}
}
}
this._lode_finish = true;
this.onMainLoad()
});
this._scenes_now = firstScene;
}
//切换页面前处理
onChangeCheck(data) {
if (data.pageName == this._scenes_now || !this._lode_finish) return;
//页面拉取数据
// if (data.pageName == "") {
// }
this.onChangePage(data);
}
onChangePage(data) {
if (data.pageName == this._scenes_now || !this._lode_finish) return;
this._scenes_now = data.pageName;
for (let i = 0; i < this._scenes.length; i++) {
const element = this._scenes[i];
if (element.name == data.pageName) {
element.active = true;
let js = Util.getScript(element);
if (js) js._init && js._init(data.data);
}
else {
element.active = false;
}
}
}
onSceneChange(data) {
this.buttoms.forEach(element => {
let eventName = "";
if (element.getComponent(cc.Button) && element.getComponent(cc.Button).clickEvents.length) {
eventName = element.getComponent(cc.Button).clickEvents[0].customEventData;
}
//选中的按钮
if (eventName == data.pageName) {
element.scale = 1;
return;
}
//未选中的按钮
element.scale = 0.8;
});
}
onDestroy() {
// EventMgr.ignoreAll(this);
}
}
/**
*
*
* 工具类
*
*/
class Util {
private static _interface: Util = null;
public static _getInterface(): Util {
if (!Util._interface) Util._interface = new Util();
return Util._interface;
}
/***********************随机数************************/
randomKey(len) {
let arr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
let str = "";
let length = arr.length;
for (let i = 0; i < len; i++) {
let pos = this.randomInt(0, length - 1);
str += arr[pos];
}
return str;
}
/**
* 随机一个范围 min~max 的整数
* @param {*} min min为一个整数或者为一个2元素的数组
* @param {*} max max为整数或者没有
*/
randomInt(min, max?) {
if (min == max) return min;
if (!max && max != 0) {
max = min[1];
min = min[0];
}
let count = Math.floor(Math.random() * (max - min + 1)) + min;
return count;
}
/**
* 注册按钮事件
* @param {*} node 注册节点名
* @param {*} handlerName 函数名
* @param {*} socpe 组件
* @param {*} EventData 事件传的参数
* @param {*} buttonParam (可选)按钮属性列表,
* 必须和按钮组件属性名字一样或者自定义属性
* 例如:
* {
transition: cc.Button.Transition.SCALE,
duration: 0.1,
zoomScale: 1.1,
}
*/
registerBtnEvent(node: cc.Node, handlerName: string | Function, socpe, eventData = "", buttonParam = {}) {
if (!cc.isValid(node)) {
return;
}
if (handlerName) {
handlerName = handlerName["name"] ? handlerName["name"] : handlerName;
}
/**传入匿名函数的情况, 相当于动态在类增加一个方法 */
if (typeof (handlerName) == "function") {
let fnName = "__BtnClick__" + this.randomKey(16);
socpe[fnName] = handlerName;
handlerName = fnName;
}
let button: cc.Button = node.getComponent(cc.Button);
if (!button) {
node.addComponent(cc.Button);
button = node.getComponent(cc.Button);
button.transition = cc.Button.Transition.SCALE;
button.zoomScale = 0.95;
if (buttonParam["isScale"] == false) button.transition = cc.Button.Transition.NONE;
}
if (button && !button.clickEvents[0]) {
let eventHandler = new cc.Component.EventHandler();
eventHandler.target = socpe.node;
eventHandler.component = cc.js.getClassName(socpe);
eventHandler.handler = handlerName;
eventHandler.customEventData = eventData;
button.clickEvents[0] = eventHandler;
for (const key in buttonParam) {
if (buttonParam.hasOwnProperty(key)) {
button[key] = buttonParam[key];
}
}
}
}
getScript(node: cc.Node) {
if (!node) return null;
//@ts-ignore
let arr = node._components;
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
if (element && arr[i].hasOwnProperty("_super")) {
return arr[i];
}
}
return null;
}
}
export default Util._getInterface();