init
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { _decorator, Component } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('SingletonBase')
|
||||
export abstract class SingletonBase<T extends Component> extends Component {
|
||||
private static _instance: any = null;
|
||||
|
||||
public static getInstance<T extends Component>(this: new () => T): T {
|
||||
if ((this as any)._instance === null) {
|
||||
return null
|
||||
}
|
||||
return (this as any)._instance;
|
||||
}
|
||||
|
||||
protected onLoad(): void {
|
||||
if ((this.constructor as any)._instance) {
|
||||
this.node.destroy();
|
||||
return;
|
||||
}
|
||||
(this.constructor as any)._instance = this;
|
||||
}
|
||||
|
||||
protected onDestroy(): void {
|
||||
if ((this.constructor as any)._instance === this) {
|
||||
(this.constructor as any)._instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "983a715a-eeef-4200-b74e-dd8bcedd02d9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "cb900d01-52b7-475d-b554-7090c0bcd1b0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { _decorator, Component, easing, Node, tween, Vec2, Vec3 } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('MoveComponent')
|
||||
export class MoveComponent extends Component {
|
||||
|
||||
|
||||
@property
|
||||
startPos: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
@property
|
||||
endPos: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
@property
|
||||
delay: number = 0;
|
||||
|
||||
|
||||
@property
|
||||
moveTimer: number = 0;
|
||||
|
||||
|
||||
@property({ displayName: "线性" })
|
||||
line: boolean = true;
|
||||
|
||||
@property({ displayName: "先慢后快" })
|
||||
sineIn: boolean = true;
|
||||
|
||||
@property({ displayName: "先快后慢" })
|
||||
sineOut: boolean = true;
|
||||
|
||||
@property({ displayName: "设置为初始值" })
|
||||
setToStart: boolean = false;
|
||||
|
||||
|
||||
protected onEnable(): void {
|
||||
console.log("触发动画z")
|
||||
let easeFunc = easing.linear;
|
||||
|
||||
if (this.sineIn) {
|
||||
easeFunc = easing.sineIn
|
||||
}
|
||||
|
||||
if (this.sineOut) {
|
||||
easeFunc = easing.sineOut
|
||||
}
|
||||
|
||||
if (this.setToStart) {
|
||||
this.node.setPosition(this.startPos)
|
||||
}
|
||||
|
||||
|
||||
tween(this.node)
|
||||
.delay(this.delay)
|
||||
.call(() => {
|
||||
this.node.setPosition(this.startPos)
|
||||
})
|
||||
.to(this.moveTimer, { position: this.endPos }, { easing: easeFunc })
|
||||
.start()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "19cd6700-3735-446f-8b08-79fed0ed5cb3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { _decorator, Component, easing, Node, tween, Vec2, Vec3 } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('ScaleComponent')
|
||||
export class ScaleComponent extends Component {
|
||||
|
||||
@property
|
||||
startPos: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
@property
|
||||
endPos: Vec3 = new Vec3(1, 1, 1);
|
||||
|
||||
@property
|
||||
delay: number = 0;
|
||||
|
||||
@property
|
||||
moveTimer: number = 0.1;
|
||||
|
||||
@property({ displayName: "线性" })
|
||||
line: boolean = true;
|
||||
|
||||
@property({ displayName: "先慢后快" })
|
||||
sineIn: boolean = true;
|
||||
|
||||
@property({ displayName: "先快后慢" })
|
||||
sineOut: boolean = true;
|
||||
|
||||
|
||||
@property({ displayName: "设置为初始值" })
|
||||
setToStart: boolean = false;
|
||||
|
||||
|
||||
protected onEnable(): void {
|
||||
|
||||
|
||||
let easeFunc = easing.linear;
|
||||
|
||||
if (this.sineIn) {
|
||||
easeFunc = easing.sineIn
|
||||
}
|
||||
|
||||
if (this.sineOut) {
|
||||
easeFunc = easing.sineOut
|
||||
}
|
||||
|
||||
if (this.setToStart) {
|
||||
this.node.setScale(this.startPos)
|
||||
}
|
||||
|
||||
|
||||
tween(this.node)
|
||||
.delay(this.delay)
|
||||
.call(() => {
|
||||
this.node.setScale(this.startPos)
|
||||
})
|
||||
.to(this.moveTimer, { scale: this.endPos }, { easing: easeFunc })
|
||||
.start()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f63e6af0-009f-444e-a875-237d4f0f0dec",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "041bfa80-d8ec-4950-bf85-5d4ba663e36f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "55d8c43c-f2ec-4534-b019-963d3660e12b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
//AudioMgr.ts
|
||||
import { Node, AudioSource, AudioClip, resources, director } from 'cc';
|
||||
/**
|
||||
* @en
|
||||
* this is a sington class for audio play, can be easily called from anywhere in you project.
|
||||
* @zh
|
||||
* 这是一个用于播放音频的单件类,可以很方便地在项目的任何地方调用。
|
||||
*/
|
||||
export class AudioMgr {
|
||||
private static _inst: AudioMgr;
|
||||
public static get inst(): AudioMgr {
|
||||
if (this._inst == null) {
|
||||
this._inst = new AudioMgr();
|
||||
}
|
||||
return this._inst;
|
||||
}
|
||||
|
||||
private _soundAudioSource: AudioSource;
|
||||
private _musicAudioSource: AudioSource;
|
||||
// private _soundaudioSource: AudioSource;
|
||||
constructor() {
|
||||
//@en create a node as audioMgr
|
||||
//@zh 创建一个节点作为 audioMgr
|
||||
let audioMgr = new Node();
|
||||
audioMgr.name = '__audioMgr__';
|
||||
|
||||
//@en add to the scene.
|
||||
//@zh 添加节点到场景
|
||||
director.getScene().addChild(audioMgr);
|
||||
|
||||
//@en make it as a persistent node, so it won't be destroied when scene change.
|
||||
//@zh 标记为常驻节点,这样场景切换的时候就不会被销毁了
|
||||
director.addPersistRootNode(audioMgr);
|
||||
|
||||
//@en add AudioSource componrnt to play audios.
|
||||
//@zh 添加 AudioSource 组件,用于播放音频。
|
||||
this._soundAudioSource = audioMgr.addComponent(AudioSource);
|
||||
this._musicAudioSource = audioMgr.addComponent(AudioSource);
|
||||
}
|
||||
|
||||
public get soundAudioSource() {
|
||||
return this._soundAudioSource;
|
||||
}
|
||||
|
||||
public get musicAudioSource() {
|
||||
return this._musicAudioSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* play short audio, such as strikes,explosions
|
||||
* @zh
|
||||
* 播放短音频,比如 打击音效,爆炸音效等
|
||||
* @param sound clip or url for the audio
|
||||
* @param volume
|
||||
*/
|
||||
playOneShot(sound: AudioClip | string, volume: number = 1.0) {
|
||||
if (sound instanceof AudioClip) {
|
||||
this._soundAudioSource.playOneShot(sound, (this.muteSound ? 0 : 1) * volume);
|
||||
}
|
||||
else {
|
||||
resources.load(sound, (err, clip: AudioClip) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
this._soundAudioSource.playOneShot(clip, (this.muteSound ? 0 : 1) * volume);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* play long audio, such as the bg music
|
||||
* @zh
|
||||
* 播放长音频,比如 背景音乐
|
||||
* @param sound clip or url for the sound
|
||||
* @param volume
|
||||
*/
|
||||
play(sound: AudioClip, isLoop: boolean = true, volume: number = 1.0) {
|
||||
if (sound instanceof AudioClip) {
|
||||
this.musicAudioSource.stop();
|
||||
this.musicAudioSource.clip = sound;
|
||||
this.musicAudioSource.loop = isLoop
|
||||
this.musicAudioSource.play();
|
||||
this.musicAudioSource.volume = (this.muteMusic ? 0 : 1) * volume;
|
||||
}
|
||||
else {
|
||||
resources.load(sound, (err, clip: AudioClip) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
this.musicAudioSource.clip = clip;
|
||||
this.musicAudioSource.play();
|
||||
this.musicAudioSource.volume = (this.muteMusic ? 0 : 1) * volume;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
muteMusic: boolean = false
|
||||
muteSound: boolean = false
|
||||
|
||||
activeMusic(active: boolean) {
|
||||
this.musicAudioSource.volume = active ? 1 : 0
|
||||
this.muteMusic = !active
|
||||
}
|
||||
|
||||
activeSound(active: boolean) {
|
||||
this.soundAudioSource.volume = active ? 1 : 0
|
||||
this.muteSound = !active
|
||||
}
|
||||
|
||||
/**
|
||||
* stop the audio play
|
||||
*/
|
||||
stop() {
|
||||
this._soundAudioSource.stop();
|
||||
this._musicAudioSource.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* pause the audio play
|
||||
*/
|
||||
pause() {
|
||||
this._soundAudioSource.pause();
|
||||
this._musicAudioSource.pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* resume the audio play
|
||||
*/
|
||||
resume() {
|
||||
this._soundAudioSource.play();
|
||||
this._musicAudioSource.play();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6a056372-7417-4161-8ac0-a9a85b0827de",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "11ac2b62-4bd2-4687-ac60-dd58493d189a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { _decorator, Component, js, JsonAsset, Node, resources, TypeScript } from 'cc';
|
||||
import { SingletonBase } from '../SingletonBase';
|
||||
import { setClassName } from '../../data/ConfigData';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('DataMgr')
|
||||
export class DataMgr extends SingletonBase<DataMgr> {
|
||||
|
||||
protected start(): void {
|
||||
setClassName()
|
||||
this.initAllConfig()
|
||||
}
|
||||
|
||||
datas: Map<string, Array<any>> = new Map();
|
||||
|
||||
|
||||
createInstance(className: string): any {
|
||||
const Constructor = (window as any).ConfigData[className];
|
||||
|
||||
if (typeof Constructor === 'function') {
|
||||
return new Constructor();
|
||||
} else {
|
||||
console.error(`Class ${className} is not a constructor`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
initAllConfig() {
|
||||
resources.loadDir(`data`, null, null, (err, assets) => {
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let jsonAsset = assets[i] as JsonAsset
|
||||
let className = jsonAsset.name
|
||||
let array = new Array<any>()
|
||||
// this.datas.set((window as any)[className].name, array)
|
||||
console.log("是否有类", (window as any).ConfigData, className, (window as any).ConfigData[className])
|
||||
this.datas.set(js.getClassName((window as any).ConfigData[className]), array)
|
||||
|
||||
console.log("设置data", className, js.getClassName((window as any).ConfigData[className]))
|
||||
|
||||
for (let j = 0; j < jsonAsset.json.length; j++) {
|
||||
let myClassInstance = new (window as any).ConfigData[className]();
|
||||
let targetData: Record<string, any> = jsonAsset.json[j]
|
||||
this.initDataItem(myClassInstance, targetData)
|
||||
array.push(myClassInstance)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public GetDataById<T>(dataClass: new () => T, id: number): T {
|
||||
let name = js.getClassName(dataClass)
|
||||
console.log("GetDataById", name)
|
||||
let datas = this.datas.get(name) as Array<T>
|
||||
for (let i = 0; i < datas.length; i++) {
|
||||
if (datas[i].id == id) {
|
||||
return datas[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initDataItem(obj, record: Record<string, any>) {
|
||||
for (const key in record) {
|
||||
if (record.hasOwnProperty(key) && obj.hasOwnProperty(key)) {
|
||||
obj[key] = record[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GetDatas<T>(dataClass: new () => T): Array<T> {
|
||||
let name = js.getClassName(dataClass)
|
||||
console.log(this.datas.get(name))
|
||||
console.log(dataClass)
|
||||
console.log(name)
|
||||
console.log(this.datas)
|
||||
return this.datas.get(name) as Array<T>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "70a16c4c-5e41-460a-87b0-4b4090db6c3c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
import { _decorator, Component, math, Node, EventTarget } from 'cc';
|
||||
import { EventCenter } from '../../EventCenter';
|
||||
import { AudioMgr } from '../audio/AudioMgr';
|
||||
import { Config } from '../../data/GameConfig';
|
||||
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
const eventTarget = new EventTarget();
|
||||
@ccclass('LocalSaveMgr')
|
||||
export class LocalSaveMgr extends Component {
|
||||
static instance: LocalSaveMgr;
|
||||
playerData: PlayerData = null
|
||||
|
||||
protected onLoad(): void {
|
||||
LocalSaveMgr.instance = this
|
||||
let value = localStorage.getItem("playerData")
|
||||
|
||||
if (value != null || value != "") {
|
||||
|
||||
this.playerData = new PlayerData()
|
||||
try {
|
||||
this.playerData.jsonDataInit(JSON.parse(value))
|
||||
} catch (err) {
|
||||
//…
|
||||
}
|
||||
} else {
|
||||
this.playerData = new PlayerData()
|
||||
}
|
||||
this.initSound()
|
||||
}
|
||||
|
||||
passLevel() {
|
||||
this.playerData.levelIndex += 1
|
||||
this.save()
|
||||
}
|
||||
|
||||
addCoin(count: number) {
|
||||
console.log("addCoin", count)
|
||||
this.playerData.coin += count
|
||||
EventCenter.coinCountChange.emit("coinCountChange")
|
||||
this.save()
|
||||
}
|
||||
|
||||
|
||||
save() {
|
||||
localStorage.setItem("playerData", JSON.stringify(this.playerData))
|
||||
}
|
||||
|
||||
clearData() {
|
||||
localStorage.clear()
|
||||
}
|
||||
|
||||
initSound() {
|
||||
AudioMgr.inst.activeSound(!this.playerData.muteSound)
|
||||
AudioMgr.inst.activeMusic(!this.playerData.muteMusic)
|
||||
}
|
||||
|
||||
activeSound(active: boolean) {
|
||||
this.playerData.muteSound = !active
|
||||
AudioMgr.inst.activeSound(active)
|
||||
this.save()
|
||||
|
||||
}
|
||||
activeMusic(active: boolean) {
|
||||
this.playerData.muteMusic = !active
|
||||
AudioMgr.inst.activeMusic(active)
|
||||
this.save()
|
||||
}
|
||||
|
||||
equipWeapon(index: number) {
|
||||
this.playerData.equipedWeapon = index
|
||||
this.save()
|
||||
}
|
||||
|
||||
buyWeapon(index: number) {
|
||||
this.playerData.ownWeapon.push(index)
|
||||
console.log("购买武器", index, this.playerData.ownWeapon[this.playerData.ownWeapon.length - 1])
|
||||
this.save()
|
||||
}
|
||||
|
||||
timerAddPower(count: number) {
|
||||
this.playerData.power += count
|
||||
if (this.playerData.power > Config.maxHp) {
|
||||
this.playerData.power = Config.maxHp
|
||||
}
|
||||
EventCenter.powerChange.emit("powerChange")
|
||||
this.save()
|
||||
}
|
||||
|
||||
usePower() {
|
||||
this.playerData.power -= 1
|
||||
EventCenter.powerChange.emit("powerChange")
|
||||
this.save()
|
||||
}
|
||||
|
||||
setSideTip() {
|
||||
this.playerData.haveGetSideReward = true
|
||||
this.save()
|
||||
}
|
||||
|
||||
adsAddPower() {
|
||||
this.playerData.power += 3
|
||||
EventCenter.powerChange.emit("powerChange")
|
||||
this.save()
|
||||
}
|
||||
|
||||
completeTutorial() {
|
||||
this.playerData.haveTutorial = true
|
||||
this.save()
|
||||
}
|
||||
|
||||
getPowerCD() {
|
||||
let passTime = (Date.now() - this.playerData.lastAddPowerTimer) / 1000
|
||||
return Config.powerCD - passTime
|
||||
}
|
||||
|
||||
setShareTime() {
|
||||
const date: Date = new Date();
|
||||
const dayOfMonth: number = date.getDate();
|
||||
this.playerData.day = dayOfMonth
|
||||
this.save()
|
||||
console.log(dayOfMonth)
|
||||
}
|
||||
|
||||
protected update(dt: number): void {
|
||||
if (this.playerData.power < Config.maxHp) {
|
||||
if (this.playerData.isOnTimerRun == false) {
|
||||
this.playerData.isOnTimerRun = true
|
||||
this.playerData.lastAddPowerTimer = Date.now()
|
||||
this.save()
|
||||
}
|
||||
|
||||
if (this.playerData.isOnTimerRun) {
|
||||
let passTime = (Date.now() - this.playerData.lastAddPowerTimer) / 1000
|
||||
// console.log(passTime)
|
||||
if ((passTime > Config.powerCD)) {
|
||||
console.log("倒计时足够")
|
||||
this.playerData.lastAddPowerTimer = Date.now()
|
||||
this.timerAddPower(Math.floor(passTime / Config.powerCD))
|
||||
}
|
||||
|
||||
if (this.playerData.power >= Config.maxHp) {
|
||||
console.log("体力超过上线")
|
||||
this.playerData.isOnTimerRun = false
|
||||
this.save()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PlayerData {
|
||||
muteMusic: boolean = false
|
||||
muteSound: boolean = false
|
||||
levelIndex: number = 1
|
||||
equipedWeapon: number = 1
|
||||
power: number = Config.maxHp
|
||||
coin: number = 100
|
||||
ownWeapon: number[] = [1]
|
||||
lastAddPowerTimer: number = null
|
||||
isOnTimerRun: boolean = false
|
||||
haveGetSideReward: boolean = false
|
||||
haveShare: boolean = false
|
||||
haveTutorial: boolean = false
|
||||
day: number = -1
|
||||
jsonDataInit(obj) {
|
||||
if (obj == null) return
|
||||
if (obj.muteMusic != null)
|
||||
this.muteMusic = obj.muteMusic
|
||||
if (obj.muteSound != null)
|
||||
this.muteSound = obj.muteSound
|
||||
if (obj.levelIndex != null)
|
||||
this.levelIndex = obj.levelIndex
|
||||
if (obj.equipedWeapon != null)
|
||||
this.equipedWeapon = obj.equipedWeapon
|
||||
if (obj.ownWeapon != null)
|
||||
this.ownWeapon = obj.ownWeapon
|
||||
if (obj.coin != null)
|
||||
this.coin = obj.coin
|
||||
if (obj.lastAddPowerTimer != null)
|
||||
this.lastAddPowerTimer = obj.lastAddPowerTimer
|
||||
if (obj.power != null)
|
||||
this.power = obj.power
|
||||
if (obj.isOnTimerRun != null)
|
||||
this.isOnTimerRun = obj.isOnTimerRun
|
||||
if (obj.haveGetSideReward != null)
|
||||
this.haveGetSideReward = obj.haveGetSideReward
|
||||
if (obj.haveShare != null)
|
||||
this.haveShare = obj.haveShare
|
||||
if (obj.day != null)
|
||||
this.day = obj.day
|
||||
if (obj.haveTutorial != null)
|
||||
this.haveTutorial = obj.haveTutorial
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f0143096-0558-4925-a73a-0b91753e5038",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "15e0e6aa-552c-4d01-b773-6ed04a74f944",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
import { _decorator, Component, director, game, Node, sys } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('DYSdk')
|
||||
export class DYSdk extends Component {
|
||||
|
||||
@property({ displayName: "bannner广告uid" })
|
||||
bannerId: string = "test";
|
||||
|
||||
@property({ displayName: "视频奖励广告uid" })
|
||||
videoUid: string = "test";
|
||||
|
||||
@property({ displayName: "插屏广告uid" })
|
||||
interstitialUid: string = "test";
|
||||
|
||||
@property({ displayName: "分享图url" })
|
||||
shareImageUrl: string = "https://mmocgame.qpic.cn/wechatgame/fNvVoACuBEOmNhzE802RLqnUuQyZ4rXTicDqz7OlVKypjYcHHo7nyfoYe7Urvdk6T/0";
|
||||
|
||||
@property({ displayName: "分享tile文本" })
|
||||
shareTilt: string = "分享文本";
|
||||
|
||||
bannerAdv = null
|
||||
videoAdv = null
|
||||
interstitialAd = null
|
||||
|
||||
|
||||
static instance: DYSdk;
|
||||
|
||||
protected onLoad(): void {
|
||||
DYSdk.instance = this
|
||||
}
|
||||
successCallback = null
|
||||
failedCallback = null
|
||||
|
||||
initBanner() {
|
||||
let winSize = window["tt"].getSystemInfoSync();//获取像素size
|
||||
// 创建 Banner 广告实例,提前初始化
|
||||
let bannerWidth = 300
|
||||
let bannerHeight = 80
|
||||
console.error("bannerId:", this.bannerId)
|
||||
this.bannerAdv = window["tt"].createBannerAd({
|
||||
adUnitId: this.bannerId,//传入自己的id,此处为banner广告位ID
|
||||
adIntervals: 30,//定时刷新,最低30S
|
||||
style: {
|
||||
left: (winSize.windowWidth - bannerWidth) / 2,
|
||||
top: winSize.windowHeight - bannerHeight,
|
||||
width: bannerWidth,
|
||||
},
|
||||
})
|
||||
//重新定banner位置
|
||||
this.bannerAdv.onResize((res) => {
|
||||
this.bannerAdv.style.top = winSize.windowHeight - this.bannerAdv.style.realHeight - 1;
|
||||
})
|
||||
|
||||
this.bannerAdv.onError((err) => {
|
||||
console.log("banner", err);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
navigateToScene() {
|
||||
window["tt"].navigateToScene({
|
||||
scene: 'sidebar',
|
||||
fail: console.log,
|
||||
success: console.log
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
initVideo() {
|
||||
let self = this
|
||||
// 创建激励视频广告实例,提前初始化
|
||||
console.log("激励视频广告id:", this.videoUid)
|
||||
this.videoAdv = window["tt"].createRewardedVideoAd({
|
||||
adUnitId: this.videoUid//传入自己的id,此处为视频广告位ID
|
||||
})
|
||||
|
||||
this.videoAdv.onLoad(() => {
|
||||
console.log("广告加载完成");
|
||||
});
|
||||
|
||||
this.videoAdv.onError(() => {
|
||||
console.log("广告错误");
|
||||
if (self.failedCallback) {
|
||||
self.failedCallback();
|
||||
}
|
||||
});
|
||||
|
||||
function listener(res) {
|
||||
if (res && res.isEnded) {
|
||||
if (self.successCallback) {
|
||||
self.successCallback();
|
||||
self.successCallback = null
|
||||
}
|
||||
} else {
|
||||
if (self.failedCallback) {
|
||||
self.failedCallback();
|
||||
self.failedCallback = null
|
||||
}
|
||||
}
|
||||
}
|
||||
this.videoAdv.onClose(listener); //这里监听广告的close 事件
|
||||
}
|
||||
|
||||
initInterstitial() {
|
||||
if (window["tt"].createInterstitialAd) {
|
||||
console.error("插屏广告id:", this.interstitialUid)
|
||||
this.interstitialAd = window["tt"].createInterstitialAd({
|
||||
adUnitId: this.interstitialUid//传入自己的id,此处为插屏广告位ID
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
|
||||
this.initBanner()
|
||||
this.initVideo()
|
||||
// 创建插屏广告实例,提前初始化
|
||||
this.initInterstitial()
|
||||
this.passivityShare()
|
||||
|
||||
|
||||
window["tt"].onShow(op => {
|
||||
if (op.location == "sidebar_card") {
|
||||
console.log("应用侧边栏启动");
|
||||
}
|
||||
console.log("监听应用启动", op);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 主动分享
|
||||
public initativeShare(callBack?: any) {
|
||||
let shareTitle = this.shareTilt
|
||||
let imageUrl = this.shareImageUrl
|
||||
// 主动拉起转发,进入选择通讯录界面
|
||||
window["tt"].shareAppMessage({
|
||||
// 转发标题, 没有则默认使用小游戏的昵称
|
||||
title: shareTitle,
|
||||
// 图片链接,
|
||||
imageUrl: imageUrl
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
passivityShare(callBack?: any) {
|
||||
// 授权显示菜单
|
||||
window["tt"].showShareMenu({
|
||||
withShareTicket: false,
|
||||
// 显示菜单
|
||||
menus: ['shareAppMessage', 'shareTimeline'],
|
||||
success: (res) => {
|
||||
console.log("开始被动转发shareMenu成功");
|
||||
},
|
||||
fail: () => {
|
||||
console.log("开始被动转发shareMenu失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
showBanner() {
|
||||
this.bannerAdv.show()
|
||||
}
|
||||
|
||||
hideBanner() {
|
||||
this.bannerAdv.hide()
|
||||
}
|
||||
|
||||
showInterstitial() {
|
||||
// 在适合的场景显示插屏广告
|
||||
if (this.interstitialAd) {
|
||||
this.interstitialAd.show().catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
showVideo(successCallback, failCallback) {
|
||||
// 用户触发广告后,显示激励视频广告
|
||||
let self = this
|
||||
|
||||
this.successCallback = successCallback
|
||||
this.failedCallback = failCallback
|
||||
|
||||
self.videoAdv.onError((res) => {
|
||||
console.log('广告出错监听', res)
|
||||
})
|
||||
// /**展示 */
|
||||
self.videoAdv
|
||||
.show()
|
||||
.then(() => {
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('打印激励视频错误', err)
|
||||
// 可以手动加载一次
|
||||
self.videoAdv.load().then(() => {
|
||||
// 加载成功后需要再显示广告
|
||||
return self.videoAdv.show();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e50a24d5-8754-4829-87a9-f39e0213fe5e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { _decorator, Button, Component, director, game, Label, Node, sys, Tween } from 'cc';
|
||||
import { WXSdk } from './WXSdk';
|
||||
import { DYSdk } from './DYSdk';
|
||||
import { AudioMgr } from '../audio/AudioMgr';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('SdkMgr')
|
||||
export class SdkMgr extends Component {
|
||||
|
||||
static instance: SdkMgr;
|
||||
|
||||
protected onLoad(): void {
|
||||
SdkMgr.instance = this
|
||||
|
||||
}
|
||||
protected start(): void {
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.init()
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
playerRewardAds(successCallBack) {
|
||||
AudioMgr.inst.pause()
|
||||
director.pause()
|
||||
console.log("广告开启", "pause")
|
||||
let callBack = () => {
|
||||
console.log("广告开启", "resume")
|
||||
if (successCallBack != null)
|
||||
successCallBack()
|
||||
director.resume()
|
||||
AudioMgr.inst.resume()
|
||||
}
|
||||
let failCallback = () => {
|
||||
director.resume()
|
||||
AudioMgr.inst.resume()
|
||||
}
|
||||
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.showVideo(callBack, failCallback)
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.showVideo(callBack, failCallback)
|
||||
} else {
|
||||
callBack()
|
||||
}
|
||||
}
|
||||
|
||||
initativeShare() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.initativeShare()
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.initativeShare()
|
||||
}
|
||||
}
|
||||
|
||||
showBanner() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.showBanner()
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.showBanner()
|
||||
}
|
||||
}
|
||||
|
||||
hideBanner() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.hideBanner()
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.hideBanner()
|
||||
}
|
||||
}
|
||||
|
||||
showInterstitial() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
WXSdk.instance.showInterstitial()
|
||||
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
|
||||
DYSdk.instance.showInterstitial()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6fbd6471-03d7-4ecc-911a-a30c321f573a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
import { _decorator, Component, director, game, Node, sys } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('WXSdk')
|
||||
export class WXSdk extends Component {
|
||||
|
||||
@property({ displayName: "原生广告uid" })
|
||||
bannerId: string = "";
|
||||
|
||||
@property({ displayName: "视频奖励广告uid" })
|
||||
videoUid: string = "";
|
||||
|
||||
@property({ displayName: "插屏广告uid" })
|
||||
interstitialUid: string = "";
|
||||
|
||||
@property({ displayName: "分享图url" })
|
||||
shareImageUrl: string = "https://mmocgame.qpic.cn/wechatgame/fNvVoACuBEOmNhzE802RLqnUuQyZ4rXTicDqz7OlVKypjYcHHo7nyfoYe7Urvdk6T/0";
|
||||
|
||||
@property({ displayName: "分享tile文本" })
|
||||
shareTilt: string = "超好玩解压停车场";
|
||||
|
||||
bannerAdv = null
|
||||
videoAdv = null
|
||||
interstitialAd = null
|
||||
|
||||
|
||||
static instance: WXSdk;
|
||||
|
||||
protected onLoad(): void {
|
||||
WXSdk.instance = this
|
||||
}
|
||||
successCallback = null
|
||||
|
||||
initBanner() {
|
||||
let winSize = wx.getSystemInfoSync();//获取像素size
|
||||
let bannerWidth = 300
|
||||
let bannerHeight = 80
|
||||
// 创建 原生模板 广告实例,提前初始化
|
||||
let CustomAd = wx.createCustomAd({
|
||||
adUnitId: 'adunit-dbdd10d1ca3690d2',
|
||||
style: {
|
||||
left: (winSize.windowWidth - bannerWidth) / 2,
|
||||
top: winSize.windowHeight - bannerHeight,
|
||||
width: bannerWidth,
|
||||
}
|
||||
})
|
||||
// // 在适合的场景显示 原生模板 广告
|
||||
// CustomAd.show()
|
||||
|
||||
// 监听 原生模板 广告错误事件
|
||||
CustomAd.onError(err => {
|
||||
console.error(err.errMsg)
|
||||
});
|
||||
|
||||
this.bannerAdv = CustomAd
|
||||
|
||||
}
|
||||
|
||||
initVideo() {
|
||||
// 创建激励视频广告实例,提前初始化
|
||||
this.videoAdv = wx.createRewardedVideoAd({
|
||||
adUnitId: this.videoUid//传入自己的id,此处为视频广告位ID
|
||||
})
|
||||
}
|
||||
|
||||
initInterstitial() {
|
||||
if (wx.createInterstitialAd) {
|
||||
this.interstitialAd = wx.createInterstitialAd({
|
||||
adUnitId: this.interstitialUid//传入自己的id,此处为插屏广告位ID
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (sys.platform == sys.Platform.WECHAT_GAME) {
|
||||
|
||||
this.initBanner()
|
||||
this.initVideo()
|
||||
// 创建插屏广告实例,提前初始化
|
||||
this.initInterstitial()
|
||||
this.passivityShare()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 主动分享
|
||||
public initativeShare(callBack?: any) {
|
||||
let shareTitle = this.shareTilt
|
||||
let imageUrl = this.shareImageUrl
|
||||
// 主动拉起转发,进入选择通讯录界面
|
||||
wx.shareAppMessage({
|
||||
// 转发标题, 没有则默认使用小游戏的昵称
|
||||
title: shareTitle,
|
||||
// 图片链接,
|
||||
imageUrl: imageUrl
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
passivityShare(callBack?: any) {
|
||||
// 授权显示菜单
|
||||
wx.showShareMenu({
|
||||
withShareTicket: false,
|
||||
// 显示菜单
|
||||
menus: ['shareAppMessage', 'shareTimeline'],
|
||||
success: (res) => {
|
||||
console.log("开始被动转发shareMenu成功");
|
||||
},
|
||||
fail: () => {
|
||||
console.log("开始被动转发shareMenu失败");
|
||||
}
|
||||
});
|
||||
let shareTitle = this.shareTilt
|
||||
let imageUrl = this.shareImageUrl
|
||||
// 好友点击回调
|
||||
wx.onShareAppMessage(() => {
|
||||
return {
|
||||
// 转发标题, 没有则默认使用小游戏的昵称
|
||||
title: shareTitle,
|
||||
// 图片链接,
|
||||
imageUrl: imageUrl
|
||||
};
|
||||
});
|
||||
// 朋友圈点击回调
|
||||
wx.onShareTimeline(() => {
|
||||
return {
|
||||
title: shareTitle,
|
||||
imageUrl: imageUrl
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
showBanner() {
|
||||
this.bannerAdv.show()
|
||||
}
|
||||
|
||||
hideBanner() {
|
||||
this.bannerAdv.hide()
|
||||
}
|
||||
|
||||
showInterstitial() {
|
||||
// 在适合的场景显示插屏广告
|
||||
if (this.interstitialAd) {
|
||||
this.interstitialAd.show().catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
showVideo(successCallback, failCallback) {
|
||||
// 用户触发广告后,显示激励视频广告
|
||||
|
||||
if (this.videoUid == "test" || this.videoUid == "") {
|
||||
successCallback()
|
||||
return
|
||||
}
|
||||
let self = this
|
||||
self.videoAdv.show().catch(() => {
|
||||
// 失败重试
|
||||
self.videoAdv.load()
|
||||
.then(() => self.videoAdv.show())
|
||||
.catch(err => {
|
||||
console.log('激励视频 广告显示失败')
|
||||
failCallback()
|
||||
})
|
||||
})
|
||||
//拉取异常处理
|
||||
self.videoAdv.onError((err) => {
|
||||
console.log(err);
|
||||
failCallback()
|
||||
})
|
||||
self.videoAdv.onClose((res) => {
|
||||
if (!self.videoAdv) return;
|
||||
self.videoAdv.offClose();//需要清除回调,否则第N次广告会一次性给N个奖励
|
||||
//关闭
|
||||
if (res && res.isEnded || res === undefined) {
|
||||
//正常播放结束,需要下发奖励
|
||||
successCallback()
|
||||
} else {
|
||||
//播放退出,不下发奖励
|
||||
failCallback()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "73835816-1977-46d1-ac3b-0a0843758eae",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "26379931-a443-4bc5-bcc1-d606bb11c2e5",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { _decorator, Component, Node, director, resources, instantiate, Prefab, js } from 'cc';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('PanelBase')
|
||||
export class PanelBase extends Component {
|
||||
protected isOpen: boolean = false;
|
||||
|
||||
public async open(): Promise<void> {
|
||||
if (this.isOpen) return;
|
||||
this.node.active = true
|
||||
this.isOpen = true;
|
||||
this.onOpen();
|
||||
}
|
||||
|
||||
static async LoadPanel(prefabPath: string, parentNode: Node) {
|
||||
|
||||
let panelNode: Node = null
|
||||
resources.load(prefabPath, Prefab, (err, prefabAsset) => {
|
||||
if (prefabAsset) {
|
||||
const node = instantiate(prefabAsset);
|
||||
node.parent = parentNode;
|
||||
node.getComponent(PanelBase).open()
|
||||
panelNode = node
|
||||
} else {
|
||||
console.error(`Failed to load UI prefab: ${prefabPath}`);
|
||||
}
|
||||
});
|
||||
|
||||
await this.waitUntil(() => panelNode != null);
|
||||
return panelNode
|
||||
}
|
||||
|
||||
|
||||
static waitUntil(condition: () => boolean): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const checkCondition = () => {
|
||||
if (condition()) {
|
||||
resolve(); // 条件成立,结束等待
|
||||
} else {
|
||||
// 条件不成立,继续轮询
|
||||
requestAnimationFrame(checkCondition);
|
||||
}
|
||||
};
|
||||
checkCondition(); // 开始检查条件
|
||||
});
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
console.log("close panel", this.node.name)
|
||||
if (!this.isOpen) return;
|
||||
if (!this.isValid) return;
|
||||
|
||||
if (this.node && this.node.parent) {
|
||||
this.node.removeFromParent();
|
||||
this.node.destroy();
|
||||
this.isOpen = false;
|
||||
this.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
protected getPrefabPath(): string {
|
||||
let panelName = js.getClassName(this)
|
||||
return `ui/${panelName}`; // 生成预制件路径
|
||||
}
|
||||
|
||||
protected onOpen(): void {
|
||||
// 子类可以重写此方法以执行打开后的操作
|
||||
}
|
||||
|
||||
protected onClose(): void {
|
||||
// 子类可以重写此方法以执行关闭后的操作
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "54c67e67-8f73-4a8c-9e7d-3b861a5aa6b8",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { _decorator, Component, Node, ResolutionPolicy, screen, Screen, view } from 'cc';
|
||||
import { WINDOWS } from 'cc/env';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('UIAdapt')
|
||||
export class UIAdapt extends Component {
|
||||
start() {
|
||||
screen.on('window-resize', this.adaptScreenSize, this);
|
||||
this.adaptScreenSize()
|
||||
let self = this
|
||||
this.scheduleOnce(() => {
|
||||
self.adaptScreenSize()
|
||||
}, 0.1)
|
||||
}
|
||||
|
||||
adaptScreenSize() {
|
||||
let screenWidth = view.getViewportRect().width
|
||||
let screenHeight = view.getViewportRect().height
|
||||
// let screenWidth = view.getVisibleSize().width;
|
||||
// let screenHeight = view.getVisibleSize().height;
|
||||
let screenRatio = screenHeight / screenWidth;
|
||||
|
||||
console.log("修改屏幕分辨率", screenRatio, view.getViewportRect(), view)
|
||||
|
||||
if (screenRatio > 18 / 9) {
|
||||
// 适配屏幕高度
|
||||
console.log("修改屏幕分辨率", "适配高度")
|
||||
|
||||
|
||||
let designWidth = 1080;
|
||||
let designHeight = screenHeight * (designWidth / screenWidth);
|
||||
|
||||
view.setDesignResolutionSize(designWidth, designHeight, ResolutionPolicy.FIXED_WIDTH);
|
||||
} else if (screenRatio > 16 / 9) {
|
||||
// 适配屏幕宽度
|
||||
console.log("修改屏幕分辨率", "适配屏幕宽度")
|
||||
let designHeight = 1920;
|
||||
let designWidth = screenWidth * (designHeight / screenHeight);
|
||||
view.setDesignResolutionSize(designWidth, designHeight, ResolutionPolicy.FIXED_HEIGHT);
|
||||
} else {
|
||||
console.log("修改屏幕分辨率", "适配屏幕宽高")
|
||||
let designWidth = 1080;
|
||||
let designHeight = screenHeight * (designWidth / screenWidth);
|
||||
view.setDesignResolutionSize(designWidth, designHeight, ResolutionPolicy.EXACT_FIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "48e510f8-e35c-4d1b-9af5-c70766c06f36",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { _decorator, Node, director, resources, instantiate, Canvas, Component, js } from 'cc';
|
||||
import { PanelBase } from './PanelBase';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('UIManager')
|
||||
export class UIManager extends Component {
|
||||
static instance: UIManager
|
||||
|
||||
|
||||
|
||||
private panels: Map<string, PanelBase> = new Map();
|
||||
|
||||
@property({ type: Node })
|
||||
uiRoot: Node = null;
|
||||
|
||||
onLoad() {
|
||||
UIManager.instance = this;
|
||||
}
|
||||
|
||||
|
||||
// 打开UI面板
|
||||
public async openPanel<T extends PanelBase>(panelClass: new () => T): Promise<T> {
|
||||
const panelName = js.getClassName(panelClass);
|
||||
|
||||
if (!this.panels.has(panelName)) {
|
||||
let panelNode = PanelBase.LoadPanel(`ui/${js.getClassName(panelClass)}`, this.uiRoot)
|
||||
let newPanel = (await panelNode).getComponent(PanelBase)
|
||||
this.panels.set(panelName, newPanel);
|
||||
}
|
||||
const existingPanel = this.panels.get(panelName);
|
||||
if (existingPanel) {
|
||||
existingPanel.open();
|
||||
return existingPanel as T;
|
||||
}
|
||||
|
||||
}
|
||||
// 关闭UI面板
|
||||
public closePanel<T extends PanelBase>(panelClass: new () => T): void {
|
||||
const panelName = js.getClassName(panelClass);
|
||||
if (this.panels.has(panelName)) {
|
||||
const panel = this.panels.get(panelName);
|
||||
if (panel) {
|
||||
panel.close();
|
||||
this.panels.delete(panelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭所有面板
|
||||
public closeAllPanels(): void {
|
||||
this.panels.forEach(panel => {
|
||||
console.log("关闭页面", panel.node.name)
|
||||
panel.close();
|
||||
});
|
||||
this.panels.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9f00c206-3eb4-4ff5-8144-c63b426eebc0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { _decorator, Button, Component, Node, Sprite, SpriteFrame, Toggle } from 'cc';
|
||||
import { AudioMgr } from '../audio/AudioMgr';
|
||||
import { AssetController } from '../../AssetController';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('UISwitcher')
|
||||
export class UISwitcher extends Component {
|
||||
toggle: Button
|
||||
value: boolean
|
||||
sprite: Sprite;
|
||||
|
||||
@property({ type: SpriteFrame })
|
||||
onSelect: SpriteFrame = null;
|
||||
|
||||
@property({ type: SpriteFrame })
|
||||
onNoSelect: SpriteFrame = null;
|
||||
|
||||
|
||||
protected onLoad(): void {
|
||||
this.toggle = this.getComponent(Button)
|
||||
this.sprite = this.getComponent(Sprite)
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
this.toggle.node.on(Button.EventType.CLICK, this.onClickToggleBtn, this);
|
||||
}
|
||||
|
||||
onSwitchCallBack
|
||||
|
||||
addCallBack(callBack) {
|
||||
this.onSwitchCallBack = callBack
|
||||
}
|
||||
|
||||
SetValue(v: boolean) {
|
||||
this.value = v
|
||||
this.switchSprite(this.value)
|
||||
}
|
||||
|
||||
switchSprite(v: boolean) {
|
||||
if (v) {
|
||||
this.sprite.spriteFrame = this.onSelect
|
||||
} else {
|
||||
this.sprite.spriteFrame = this.onNoSelect
|
||||
}
|
||||
}
|
||||
|
||||
onClickToggleBtn() {
|
||||
AudioMgr.inst.playOneShot(AssetController.instance.click)
|
||||
// AudioMgr.inst.playOneShot(AssetController.instance.buttonClip)
|
||||
this.value = !this.value
|
||||
|
||||
this.switchSprite(this.value)
|
||||
|
||||
if (this.onSwitchCallBack != null) {
|
||||
this.onSwitchCallBack(this.value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "0167bafe-2e3a-4f24-89c3-2b7dbb48fd24",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user