This commit is contained in:
2024-04-16 23:03:54 +08:00
commit 54580cc1b2
723 changed files with 103745 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "1f75e345-9236-4518-97a3-9862de267a19",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "79470a7f-2ce8-48ce-86d3-e2662124378f",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,11 @@
import { _decorator } from 'cc'
const { ccclass, property } = _decorator
@ccclass('CommonEvent')
export default class CommonEvent {
public static Event_FrameUpdate: string = 'Event_FrameUpdate'
public static Event_ConnectTimeOut: string = 'Event_ConnectTimeOut'
public static Event_ResourceLoader: string = 'Event_ResourceLoader'
public static Event_CheckUpdate: string = 'Event_CheckUpdate'
public static Event_Scene_Switch: string = 'Event_Scene_Switch'
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "76f96525-e455-4a24-9d2b-27a0cb2fdfd2",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,38 @@
import { _decorator } from 'cc'
import DateUtil from '../utils/DateUtil'
import NetConfig from './NetConfig'
export default class ManifestConfig {
public static packageUrl: string = ''
public static remoteManifestUrl: string = ''
public static remoteVersionUrl: string = ''
public static version: string = '1.0.0' //更新包要更新这里
public static assets: object = {}
public static searchPaths: Array<any> = []
public static getManifestStr(key: string) {
let obj: Object = {}
obj['packageUrl'] = `${NetConfig.hotupdateUrl}/hotupdate/${key}/`
obj['remoteManifestUrl'] =
NetConfig.hotupdateUrl +
'/hotupdate/' +
key +
'/project.manifest?t=' +
DateUtil.now()
obj['remoteManifestUrl'] = `${
NetConfig.hotupdateUrl
}/hotupdate/${key}/project.manifest?t=${DateUtil.now()}`
obj['remoteVersionUrl'] =
NetConfig.hotupdateUrl +
'/hotupdate/' +
key +
'/version.manifest?t=' +
DateUtil.now()
obj['remoteVersionUrl'] = `${
NetConfig.hotupdateUrl
}/hotupdate/${key}/version.manifest?t=${DateUtil.now()}`
obj['version'] = ManifestConfig.version
obj['assets'] = {}
obj['searchPaths'] = []
return JSON.stringify(obj)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "711d7240-649f-4cb4-9d0d-06e13979eb98",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,64 @@
import { _decorator, AudioClip } from 'cc'
import { GameConfig } from '../../game/config/GameConfig'
export default class MusicConfig {
public static musicKey2Path: Map<string, string> = new Map<string, string>() //资源预加载路径
public static musicKey2Cache: Map<string, AudioClip> = new Map<
string,
AudioClip
>() //资源加载后cache路径
public static init() {
if (
typeof GameConfig.GameName === 'undefined' ||
GameConfig.GameName === null
) {
console.error('GameConfig.GameName 未配置!')
return
}
const musicConfig = {
background_1: 'music/background_1',
background_2: 'music/background_2',
background_3: 'music/background_3',
deadfish_1: 'music/deadfish_1',
deadfish_2: 'music/deadfish_2',
deadfish_3: 'music/deadfish_3',
deadfish_4: 'music/deadfish_4',
deadfish_5: 'music/deadfish_5',
deadfish_6: 'music/deadfish_6',
deadfish_7: 'music/deadfish_7',
deadfish_8: 'music/deadfish_8',
deadfish_9: 'music/deadfish_9',
deadfish_10: 'music/deadfish_10',
deadfish_11: 'music/deadfish_11',
deadfish_12: 'music/deadfish_12',
deadfish_13: 'music/deadfish_13',
deadfish_14: 'music/deadfish_14',
deadfish_15: 'music/deadfish_15',
deadfish_16: 'music/deadfish_16',
deadfish_17: 'music/deadfish_17',
deadfish_18: 'music/deadfish_18',
deadfish_19: 'music/deadfish_19',
deadfish_20: 'music/deadfish_20',
deadfish_21: 'music/deadfish_21',
deadfish_22: 'music/deadfish_22',
deadfish_23: 'music/deadfish_23',
deadfish_24: 'music/deadfish_24',
deadfish_25: 'music/deadfish_25',
deadfish_26: 'music/deadfish_26',
deadfish_27: 'music/deadfish_27',
deadfish_28: 'music/deadfish_28',
deadfish_29: 'music/deadfish_29',
fire: 'music/fire',
}
// 音乐要预加载的配置
for (const key in musicConfig) {
if (musicConfig.hasOwnProperty(key)) {
const path = `${GameConfig.GameName}/${musicConfig[key]}`
MusicConfig.musicKey2Path.set(key, path)
}
}
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "92bd7fa0-c97e-4b6f-b518-d1d4d73c03f5",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,4 @@
import { _decorator } from 'cc'
export default class NetConfig {
public static hotupdateUrl: string = 'http://localhost:33/hotupdate'
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4e758c3c-41e2-4fe7-a0ea-43fe6be9b381",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "9c2b477c-5efb-432e-8d18-08cc17a2e103",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,58 @@
import {
_decorator,
Component,
Label,
Node,
tween,
Vec3,
instantiate,
} from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../utils/PrefabLoader'
import { GameConfig } from '../../game/config/GameConfig'
import DialogBase from './DialogBase'
@ccclass('CommonTips')
export default class CommonTips extends Component {
public static TipsZorderIndex: number = 999
@property({ type: Label })
txtContent: Label | null = null
private tips: string = ''
private static showingNameList: Array<string> = []
onLoad() {}
start() {
tween(this.node)
.by(1.5, { position: new Vec3(0, 100, 0) })
.to(0.2, { /* opacity: 0*/ scale: Vec3.ZERO })
.call(() => {
this.node.destroy()
})
.start()
}
onDestroy() {
let index: number = CommonTips.showingNameList.indexOf(this.tips)
CommonTips.showingNameList.splice(index, 1)
this.unscheduleAllCallbacks()
}
public static showMsg(msg: string, parentNode: Node = null) {
PrefabLoader.loadPrefab(
`${GameConfig.GameName}/share/uicomponent/CommonTips`,
(loadedResource) => {
parentNode = parentNode || DialogBase.GetRootCanvas()
if (CommonTips.showingNameList.indexOf(msg) === -1) {
CommonTips.showingNameList.push(msg)
}
let dialogNode = instantiate(loadedResource)
dialogNode.setPosition(0, 0)
let dialogScript: CommonTips = dialogNode.getComponent(CommonTips)
dialogScript.tips = msg
dialogScript.txtContent.string = msg
parentNode.insertChild(dialogNode, CommonTips.TipsZorderIndex)
}
)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4524f0ef-319a-4f20-9d62-fe359bbcbc71",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,30 @@
import { _decorator, Component, Prefab, Widget, instantiate, Node } from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../utils/PrefabLoader'
import { GameConfig } from '../../game/config/GameConfig'
import DialogBase from './DialogBase'
@ccclass('DarkLayer')
export default class DarkLayer extends Component {
private static prefab: Prefab
onLoad() {
this.getComponent(Widget).target = DialogBase.GetRootCanvas()
}
start() {}
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
`${GameConfig.GameName}/share/uicomponent/DarkLayer`,
(loadedResource) => {
DarkLayer.prefab = loadedResource
resolve()
}
)
})
}
public static getDarkLayer() {
let dialogNode: Node = instantiate(DarkLayer.prefab)
return dialogNode
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4fa811bd-9cd5-4ac6-ad87-d68f4a41dcdf",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,65 @@
import { _decorator, Component, Node, Widget, director } from 'cc'
const { ccclass } = _decorator
import DarkLayer from './DarkLayer'
import { UIRoot } from '../../game/utils/UIRoot'
@ccclass('DialogBase')
export default class DialogBase extends Component {
private static LocalZOrder: number = 5
private darkLayer: Node | null = null
//private static _canvas: Node;
public static GetRootCanvas(): Node {
//if(DialogBase._canvas == null)
// DialogBase._canvas = director.getScene().getChildByName('Canvas');
//return DialogBase._canvas;
return UIRoot.Instance.node
}
onLoad() {
DialogBase.LocalZOrder += 1
let closeLayer: Node = this.node.getChildByName('closeLayer')
if (closeLayer) {
let closeLayerWidget: Widget = closeLayer.getComponent(Widget)
if (closeLayerWidget) {
closeLayerWidget.target = DialogBase.GetRootCanvas()
closeLayerWidget.left = 0
closeLayerWidget.right = 0
closeLayerWidget.top = 0
closeLayerWidget.bottom = 0
}
}
this.onLoadMe()
}
onLoadMe() {}
start(isPlayMv: boolean = false) {
this.darkLayer = DarkLayer.getDarkLayer()
this.node.insertChild(this.darkLayer, 0) //this.node.addChild(this.darkLayer, -1);
if (isPlayMv) {
this.node.setScale(0, 0)
} else {
this.onStartMe()
}
}
onStartMe() {}
onClickClose() {
this.node.destroy()
}
update(dt) {
this.onUpdateMe(dt)
}
onUpdateMe(dt) {}
onDestroy() {
DialogBase.LocalZOrder -= 1
this.onDestroyMe()
}
onDestroyMe() {}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1fc7cf08-75c2-4ec4-b4c0-6f27eb483210",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,87 @@
import {
_decorator,
Component,
Node,
Prefab,
instantiate,
math,
Quat,
Vec3,
} from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../utils/PrefabLoader'
import { GameConfig } from '../../game/config/GameConfig'
import DialogBase from './DialogBase'
@ccclass('LoadingPrefab')
export default class LoadingPrefab extends Component {
public static instance: Node
private static prefab: Prefab
public static LoadingZorderIndex: number = 99
@property({ type: Node })
loadingSp: Node | null = null
private _quatCache: Quat
private _vec3Cache: Vec3
onLoad() {
this._quatCache = new Quat()
this._vec3Cache = new Vec3()
}
start() {}
public static close() {
if (!LoadingPrefab.instance) {
return
}
LoadingPrefab.instance.removeFromParent()
LoadingPrefab.instance.destroy()
LoadingPrefab.instance = null
}
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'share/uicomponent/LoadingPrefab',
(loadedResource) => {
LoadingPrefab.prefab = loadedResource
resolve()
}
)
})
}
private static createLoadingPrefab(parentNode: Node = null) {
let dialogNode: Node = instantiate(LoadingPrefab.prefab)
LoadingPrefab.instance = dialogNode
if (!parentNode) {
parentNode = DialogBase.GetRootCanvas()
}
parentNode.insertChild(dialogNode, LoadingPrefab.LoadingZorderIndex)
dialogNode.setPosition(0, 0)
}
public static async show(parentNode: Node = null) {
if (LoadingPrefab.instance) return
if (!LoadingPrefab.prefab) {
await LoadingPrefab.preLoad()
}
this.createLoadingPrefab(parentNode)
}
update(dt) {
this.loadingSp.getRotation(this._quatCache)
Quat.toEuler(this._vec3Cache, this._quatCache)
this._vec3Cache.z += 10
this.loadingSp.setRotationFromEuler(this._vec3Cache)
if (this._vec3Cache.z >= 360) {
this.loadingSp.getRotation(Quat.IDENTITY)
}
}
public static clear() {
LoadingPrefab.instance = null
LoadingPrefab.prefab = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "172559f4-6da9-4c5d-a0b4-af9f5116f021",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,90 @@
import { _decorator, Component, Node, Prefab, instantiate } from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../utils/PrefabLoader'
import Progress from './Progress'
import { GameConfig } from '../../game/config/GameConfig'
import DialogBase from './DialogBase'
@ccclass('LoadingScenePrefab')
export default class LoadingScenePrefab extends Component {
public static instance: Node
private static prefab: Prefab
public static LoadingZorderIndex: number = 99
@property({ type: Node })
private progressNode: Node | null = null
onLoad() {}
start() {}
public updateProgress(
completedCount: number,
totalCount: number,
item: any = null
) {
this.progressNode
.getComponent(Progress)
.updateProgress(
completedCount,
totalCount,
'消耗流量,预下载所有"鱼"类中,请耐心等待...'
)
}
public static updateLoading(
completedCount: number,
totalCount: number,
item: any = null
) {
if (LoadingScenePrefab.instance) {
let nodeTs: LoadingScenePrefab =
LoadingScenePrefab.instance.getComponent(LoadingScenePrefab)
if (nodeTs) {
nodeTs.updateProgress(completedCount, totalCount, item)
}
}
}
private static createPrefab(parentNode: Node = null) {
let dialogNode: Node = instantiate(LoadingScenePrefab.prefab)
LoadingScenePrefab.instance = dialogNode
if (!parentNode) {
parentNode = DialogBase.GetRootCanvas()
}
parentNode.insertChild(dialogNode, LoadingScenePrefab.LoadingZorderIndex)
dialogNode.setPosition(0, 0)
}
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'share/uicomponent/LoadingScenePrefab',
(loadedResource: Prefab) => {
LoadingScenePrefab.prefab = loadedResource
resolve()
}
)
})
}
public static close() {
if (!LoadingScenePrefab.instance) {
return
}
LoadingScenePrefab.instance.destroy()
LoadingScenePrefab.instance = null
}
public static async show(parentNode: Node = null) {
if (LoadingScenePrefab.instance) return
if (!LoadingScenePrefab.prefab) {
await LoadingScenePrefab.preLoad()
}
this.createPrefab(parentNode)
}
public static clear() {
LoadingScenePrefab.instance = null
LoadingScenePrefab.prefab = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e2e744b0-b723-4151-8de6-a2c222b8fe29",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,90 @@
import {
_decorator,
Component,
AssetManager,
AudioClip,
AudioSource,
instantiate,
Prefab,
} from 'cc'
const { ccclass, property } = _decorator
import { Logger } from '../utils/Logger'
import PrefabLoader from '../utils/PrefabLoader'
import LocalStorage from '../utils/LocalStorage'
import MusicConfig from '../config/MusicConfig'
import { GameConfig } from '../../game/config/GameConfig'
/**
* 背景音乐
*/
@ccclass('MusicPrefab')
export default class MusicPrefab extends Component {
private static instance: MusicPrefab
private static MUSIC_VOLUMN_KEY: string = 'musicVolumn'
public static musicVolumn: number = 1
public static play(key: string) {
let url: string = MusicConfig.musicKey2Path.get(key)
if (url) {
AssetManager.instance.resources.load(
url,
AudioClip,
(error: Error, clip: AudioClip) => {
if (error) {
Logger.warn(this, 'load music error===', error.message)
} else {
if (clip) {
this.instance.node.getComponent(AudioSource).clip = clip
this.instance.node.getComponent(AudioSource).volume =
this.musicVolumn
this.instance.node.getComponent(AudioSource).play()
this.instance.node.getComponent(AudioSource).loop = true
}
}
}
)
} else {
Logger.warn(this, '播放不存在的music=', key)
}
}
public static changeVolumn(nowVolumn: number) {
this.musicVolumn = nowVolumn
this.instance.node.getComponent(AudioSource).volume = nowVolumn
LocalStorage.setItem(
MusicPrefab.MUSIC_VOLUMN_KEY,
this.musicVolumn.toString()
)
}
private static preInit() {
this.musicVolumn = parseFloat(
LocalStorage.getItem(MusicPrefab.MUSIC_VOLUMN_KEY)
)
if (isNaN(this.musicVolumn)) {
this.musicVolumn = 1
}
}
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'share/uicomponent/MusicPrefab',
(loadedResource: Prefab) => {
MusicPrefab.instance =
instantiate(loadedResource).getComponent(MusicPrefab)
this.preInit()
resolve()
}
)
})
}
public static destory() {
if (MusicPrefab.instance) {
MusicPrefab.instance.getComponent(AudioSource).stop()
MusicPrefab.instance.destroy()
}
MusicPrefab.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e947ef07-b958-4471-b5a5-f0acd7e299d2",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,57 @@
import { _decorator, Component, Label, ProgressBar } from 'cc'
const { ccclass, property } = _decorator
import { Logger } from '../utils/Logger'
@ccclass('Progress')
export default class Progress extends Component {
@property(Label)
public percentLable: Label
@property(ProgressBar)
public bar: ProgressBar
onLoad() {
this.bar.node.active = false
this.bar.progress = 0
}
start() {}
updatePercent(current, filePercent) {
//this.percentLable.string = filePercent.toFixed(2);
}
updatefileTotal(current, filePercent) {
if (!this.bar.node.active) this.bar.node.active = true
var nowPercent = Math.round((current / filePercent) * 100)
var curMB = this.getMB(current)
var totalMB = this.getMB(filePercent)
// this.percentLable.string = "正在更新 " + nowPercent + "%" + " ( " + curMB + " / "+totalMB +" MB)";
nowPercent = Math.min(nowPercent, 100)
this.percentLable.string = '正在更新 ' + nowPercent + '%'
var percent = current / filePercent
this.bar.progress = percent
}
public updateProgress(
current,
total,
msg: string = '正在加载资源,此过程不消耗流量...'
) {
this.bar.node.active = true
// this.setMsg(msg+ current + "/" + total);
this.setMsg(msg)
this.bar.progress = current / total
}
getMB(bytes) {
bytes /= 1024
bytes /= 1024
return bytes.toFixed(2)
}
public setMsg(msg: string = '游戏加载中,请稍后...') {
this.percentLable.string = msg
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ba38c648-abb9-41f8-a06b-830bb5aea91d",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,144 @@
import {
_decorator,
Component,
Prefab,
NodePool,
Node,
instantiate,
AssetManager,
AudioClip,
AudioSource,
} from 'cc'
const { ccclass, property } = _decorator
import { Logger } from '../utils/Logger'
import PrefabLoader from '../utils/PrefabLoader'
import LocalStorage from '../utils/LocalStorage'
import EventManager from '../utils/EventManager'
import CommonEvent from '../config/CommonEvent'
import MusicConfig from '../config/MusicConfig'
import { GameConfig } from '../../game/config/GameConfig'
// /**
// * 音效
// * Ios暂时有bug弃用
// */
@ccclass('SoundPrefab')
export default class SoundPrefab extends Component {
private static prefab: Prefab | null = null
private static SOUND_VOLUMN_KEY: string = 'soundVolumn'
public static soundVolumn: number = 1
private static Pool_Init_Num: number = 30
private static pool: NodePool = new NodePool()
private static nowAudioNodeList: Array<Node> = []
private audioName: string = ''
private audioUrl: string = ''
private static getAudioNode() {
let node: Node = null
// if (this.pool.size() > 0) {
// node = this.pool.get();
// } else {
node = instantiate(this.prefab)
// }
return node
}
public static play(key: string) {
let url: string = MusicConfig.musicKey2Path.get(key)
if (url) {
AssetManager.instance.resources.load(url, AudioClip, (error: Error, clip: AudioClip) => {
if (error) {
Logger.warn(this, 'load sound error===', error.message)
} else {
if (clip) {
let audioNode: Node = this.getAudioNode()
if (audioNode) {
audioNode.getComponent(AudioSource).clip = clip
audioNode.getComponent(AudioSource).volume =
SoundPrefab.soundVolumn
audioNode.getComponent(AudioSource).loop = false
audioNode.getComponent(AudioSource).currentTime = 0 //rewind();
audioNode.getComponent(AudioSource).play()
audioNode.getComponent(SoundPrefab).audioName = key
audioNode.getComponent(SoundPrefab).audioUrl = url
this.nowAudioNodeList.push(audioNode)
}
}
}
})
} else {
Logger.warn(this, '播放不存在的music=', key)
}
}
public static changeVolumn(nowVolumn: number) {
this.soundVolumn = nowVolumn
for (let i = 0; i < this.nowAudioNodeList.length; i++) {
let audioNode: Node = this.nowAudioNodeList[i]
let audioSource: AudioSource = audioNode.getComponent(AudioSource)
if (audioSource.playing) {
audioSource.volume = nowVolumn
}
}
LocalStorage.setItem(
SoundPrefab.SOUND_VOLUMN_KEY,
SoundPrefab.soundVolumn.toString()
)
}
private static preInit() {
EventManager.instance.addListener(
CommonEvent.Event_FrameUpdate,
this.updateFrame,
this
)
SoundPrefab.soundVolumn = parseFloat(
LocalStorage.getItem(SoundPrefab.SOUND_VOLUMN_KEY)
)
if (isNaN(SoundPrefab.soundVolumn)) {
SoundPrefab.soundVolumn = 1
}
}
private static updateFrame() {
for (let i = 0; i < this.nowAudioNodeList.length; i++) {
let audioNode: Node = this.nowAudioNodeList[i]
let audioSource: AudioSource = audioNode.getComponent(AudioSource)
if (!audioSource.playing) {
SoundPrefab.nowAudioNodeList.splice(i, 1)
}
}
}
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'share/uicomponent/SoundPrefab',
(loadedResource: Prefab) => {
SoundPrefab.prefab = loadedResource
this.preInit()
// for (let i = 0; i < this.Pool_Init_Num; i++) {
// let tempNode: cc.Node = cc.instantiate(loadedResource);
// this.pool.put(tempNode);
// }
resolve()
}
)
})
}
public static destory() {
EventManager.instance.removeListener(
CommonEvent.Event_FrameUpdate,
this.updateFrame
)
for (let i = 0; i < this.nowAudioNodeList.length; i++) {
let audioNode: Node = this.nowAudioNodeList[i]
audioNode.getComponent(AudioSource).stop()
audioNode.getComponent(AudioSource).destroy()
}
this.nowAudioNodeList = []
this.pool.clear()
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d262f2b2-8af6-4db9-b1e4-0c08493efa10",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,20 @@
import { _decorator, Component, SpriteFrame } from 'cc'
const { ccclass, property } = _decorator
@ccclass('TextureMgr')
export default class TextureMgr extends Component {
@property({ type: [SpriteFrame] })
public Spriteset: SpriteFrame[] = []
@property({ type: [SpriteFrame] })
public Spriteset1: SpriteFrame[] = []
@property({ type: [SpriteFrame] })
public Spriteset2: SpriteFrame[] = []
@property({ type: [SpriteFrame] })
public Spriteset3: SpriteFrame[] = []
@property({ type: [SpriteFrame] })
public Spriteset4: SpriteFrame[] = []
onLoad() {
// // init logic
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1147cca4-2fe9-4d82-8850-0d97cb3318d5",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "a8097de0-2f13-4b1b-be6b-4635b5d8281d",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,38 @@
import { Canvas, error, log, ResolutionPolicy, sys, view, _decorator } from 'cc'
import DialogBase from '../uicomponent/DialogBase'
const { ccclass, property } = _decorator
import { Logger } from './Logger'
@ccclass('AdapterHelper')
export default class AdapterHelper {
public static winSizeWidth: number
public static winSizeHeiht: number
public static fixApdater() {
log('v3.6没找到接口修改 fitHeight、fitWidth, 先在项目里写死fitHeight=true')
return
let framesize = view.getFrameSize()
if (!this.winSizeWidth) {
this.winSizeWidth = screen.width
this.winSizeHeiht = screen.height
}
let designsize = view.getDesignResolutionSize()
let canvas: Canvas = DialogBase.GetRootCanvas().getComponent(Canvas)
let ratio: number = framesize.height / framesize.width
let designRatio: number = designsize.height / designsize.width
if (ratio > designRatio) {
//canvas.fitHeight = false;
//canvas.fitWidth = true;
error(
'v3.6没找到接口修改 fitHeight、fitWidth, 先在项目里写死fitHeight=true'
)
} else {
//canvas.fitHeight = true;
//canvas.fitWidth = false;
error(
'v3.6没找到接口修改 fitHeight、fitWidth, 先在项目里写死fitHeight=true'
)
}
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d2b64431-33c2-4fa1-83b0-0ece0e0a35e2",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,52 @@
import { _decorator } from 'cc'
const { ccclass, property } = _decorator
import { Logger } from './Logger'
@ccclass('BitUtil')
export default class BitUtil {
//index是二进制从右到左
public static isBitSet(value: number, index: number): boolean {
let str: string = value.toString(2)
if (parseInt(str[str.length - 1 - index]) == 1) {
return true
}
return false
}
//从右到左计算
public static setBitValue(value: number, index: number): number {
let newValue: number = value
let str: string = value.toString(2)
let newStr: string = ''
let maxIndex = Math.max(str.length - 1, index)
for (let i = 0; i <= maxIndex; i++) {
if (index == i) {
newStr = '1' + newStr
} else {
if (str[i] == undefined) {
newStr = '0' + newStr
} else {
newStr = str[i] + newStr
}
}
}
newValue = parseInt(newStr, 2)
return newValue
}
public static clearBitValue(value: number, index: number) {
let newValue: number = value
let str: string = value.toString(2)
let newStr: string = ''
for (let i = str.length - 1; i >= 0; i--) {
if (index == str.length - 1 - i) {
newStr = '0' + newStr
} else {
newStr = str[i] + newStr
}
}
newValue = parseInt(newStr, 2)
return newValue
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8a5aad8d-c1cf-4e6a-bbbe-bc0ef0b4d05f",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,10 @@
import { _decorator, Color } from 'cc'
const { ccclass, property } = _decorator
@ccclass('ColorHelper')
export default class ColorHelper {
public static getColor(hexStr: string): Color {
let color: Color = Color.BLACK
return color.fromHEX(hexStr)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d1bc656e-a928-4212-a2b4-408b73ef0ec9",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,139 @@
import { _decorator } from 'cc'
import { Logger } from './Logger'
export default class DateUtil {
public static formatNumStr(num: number) {
let str = '' + num
if (num < 10) {
str = '0' + num
}
return str
}
public static formateYearMonthDayStr(timestamp: number) {
let date: Date = new Date(timestamp)
return (
date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
)
}
public static formateMonthDayStr(timestamp: number) {
let date: Date = new Date(timestamp)
return date.getMonth() + 1 + '月' + date.getDate() + '日'
}
// timestamp:1453094034000 2018-1-31 19:53:44
//根据时间戳返回 2018-1-31 19:53:44
public static formatDateStr(timestamp: number) {
let date: Date = new Date(timestamp)
return (
date.getFullYear() +
'-' +
(date.getMonth() + 1) +
'-' +
date.getDate() +
' ' +
this.formatNumStr(date.getHours()) +
':' +
this.formatNumStr(date.getMinutes()) +
':' +
this.formatNumStr(date.getSeconds())
)
}
// timestamp:1453094034000 2018-1-31-19-53-44
//根据时间戳返回 2018-1-31-19-53-44
public static formatDateStr2(timestamp: number) {
let date: Date = new Date(timestamp)
return (
date.getFullYear() +
'-' +
(date.getMonth() + 1) +
'-' +
date.getDate() +
'-' +
this.formatNumStr(date.getHours()) +
'-' +
this.formatNumStr(date.getMinutes()) +
'-' +
this.formatNumStr(date.getSeconds())
)
}
// timestamp:1453094034000 2018-1-31
//根据时间戳返回 2018-1-31
public static formatDateStr3(timestamp: number) {
let date: Date = new Date(timestamp)
return (
date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
)
}
// timestamp:1453094034000
//根据时间戳返回 19:53
public static formatHourMinStr(timestamp: number) {
let date: Date = new Date(timestamp)
return (
this.formatNumStr(date.getHours()) +
':' +
this.formatNumStr(date.getMinutes())
)
}
// timestamp:1453094034000
//根据时间戳返回 19:53:11
public static formatHourMinSecondStr(timestamp: number) {
let date: Date = new Date(timestamp)
return (
this.formatNumStr(date.getHours()) +
':' +
this.formatNumStr(date.getMinutes()) +
':' +
this.formatNumStr(date.getSeconds())
)
}
public static now(): number {
let date: Date = new Date()
return date.getTime()
}
public static betweenTime(startTime: number, endTime: number) {
let date: Date = new Date()
if (date.getTime() >= startTime && date.getTime() <= endTime) {
return true
}
return false
}
//根据时间戳返回 1天19:53:11
public static formatLeftTime(timestamp: number) {
let result: string = ''
let day: number = Math.floor(timestamp / (1000 * 60 * 60 * 24))
let hour: number = Math.floor(timestamp / (1000 * 60 * 60)) % 24
let min: number = Math.floor(timestamp / (1000 * 60)) % 60
let second: number = Math.floor(timestamp / 1000) % 60
result =
day +
'天' +
this.formatNumStr(hour) +
':' +
this.formatNumStr(min) +
':' +
this.formatNumStr(second)
return result
}
public static isToday(dateTime: number): boolean {
let nowDate: Date = new Date()
let checkDate: Date = new Date(dateTime)
if (
checkDate.getFullYear() == nowDate.getFullYear() &&
checkDate.getMonth() == nowDate.getMonth() &&
checkDate.getDate() == nowDate.getDate()
) {
return true
}
return false
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b42f778f-ca3e-4982-bd84-c8a54d39ced4",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,131 @@
import { _decorator, Node, Color, Button, Component, Slider } from 'cc'
import { Logger } from './Logger'
import ColorHelper from './ColorHelper'
export class HaoEvent {
public callback: Function
public caller: any
public isStop: boolean
constructor(callback: Function, caller: any) {
this.callback = callback
this.caller = caller
this.isStop = false
}
}
export default class EventManager {
public static instance: EventManager = new EventManager()
private callbackList = {}
public constructor() {}
//注册事件
public addListener(eventName: string, callback: Function, caller: any) {
if (this.callbackList[eventName]) {
let eventList: Array<HaoEvent> = this.callbackList[eventName]
//不同元件才放入,相同元件覆蓋
let add: boolean = true
for (let i = 0; i < eventList.length; i++) {
let event: HaoEvent = eventList[i]
if (caller === event.caller) {
add = false
}
}
if (add) {
eventList.push(new HaoEvent(callback, caller))
this.callbackList[eventName] = eventList
}
} else {
// this.callbackList[eventName] = [[callback, caller]];
this.callbackList[eventName] = [new HaoEvent(callback, caller)]
}
}
public removeListener(eventName: string, callback: Function) {
if (this.callbackList[eventName]) {
for (let i = this.callbackList[eventName].length - 1; i >= 0; i--) {
let event: HaoEvent = this.callbackList[eventName][i]
if (event.callback == callback) {
this.callbackList[eventName].splice(i, 1)
break
}
}
}
}
public dispatchEvent(eventName, parameter?: any, ...restOfName: any[]) {
let eventList: Array<HaoEvent> = this.callbackList[eventName]
if (eventList) {
for (let i = eventList.length - 1; i >= 0; i--) {
let event: HaoEvent = eventList[i]
event.callback.call(event.caller, event, parameter, ...restOfName)
if (event.isStop) {
break
}
}
for (let i = eventList.length - 1; i >= 0; i--) {
let event: HaoEvent = eventList[i]
event.isStop = false
}
}
}
public addBtnEvent(
parentNode: Node,
objectNode: Node,
scriptName: string,
eventName: string,
data: any = null
) {
var btn: Button = objectNode.addComponent(Button)
var clickEventHandler = new Component.EventHandler()
clickEventHandler.target = parentNode //这个 node 节点是你的事件处理代码组件所属的节点
clickEventHandler.component = scriptName //这个是代码文件名
clickEventHandler.handler = eventName
clickEventHandler.customEventData = data
btn.clickEvents.push(clickEventHandler)
this.addBtnEffect(objectNode)
}
public removeBtnEvent(objectNode: Node) {
objectNode.removeComponent(Button)
}
public removeBtnEffect(objectNode: Node) {
var b = objectNode.getComponent(Button)
b.transition = Button.Transition.NONE
}
public addBtnEffect(objectNode: Node, scale: number = 1.1) {
var b = objectNode.getComponent(Button)
b.transition = Button.Transition.SCALE
b.zoomScale = scale
}
public addBtnEffect_color(
objectNode: Node,
normalC: Color = ColorHelper.getColor('#FFFFFF'),
pressC: Color = ColorHelper.getColor('#C0C0C0')
) {
var b = objectNode.getComponent(Button)
b.transition = Button.Transition.COLOR
b.normalColor = normalC
b.pressedColor = pressC
}
public addSliderEvent(
parentNode: Node,
objectNode: Node,
EventName: string,
data: any
) {
var b = objectNode.getComponent(Slider)
var clickEventHandler = new Component.EventHandler()
clickEventHandler.target = parentNode //这个 node 节点是你的事件处理代码组件所属的节点
clickEventHandler.component = parentNode.name //这个是代码文件名
clickEventHandler.handler = EventName
clickEventHandler.customEventData = data
b.slideEvents.push(clickEventHandler)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b7dbd2a3-1ad1-45b8-8cae-53c431e08789",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,13 @@
import { _decorator } from 'cc'
export default class Grid {
public row: number
public col: number
constructor(row: number, col) {
this.row = row
this.col = col
}
public static init(row: number, col: number) {
return new Grid(row, col)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "696c7042-c332-4a1a-a7f8-a898e63b35b4",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,34 @@
import { _decorator } from 'cc'
import { Logger } from './Logger'
export default class HaoEncrypt {
public static encode(str: string) {
let result: string = ''
for (let i = 0; i < str.length; i++) {
//遍历字符串
let code: number = str.charCodeAt(i) // //逐个提取每个字符并获取Unicode编码值
if (i % 2 == 0) {
code += 2
} else {
code += 1
}
result += String.fromCharCode(code)
}
return result
}
public static decode(str: string) {
let result: string = ''
for (let i = 0; i < str.length; i++) {
//遍历字符串
let code: number = str.charCodeAt(i) // //逐个提取每个字符并获取Unicode编码值
if (i % 2 == 0) {
code -= 2
} else {
code -= 1
}
result += String.fromCharCode(code)
}
return result
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "87a63258-3b93-48f6-945d-5bfd9959bb70",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,332 @@
import { sys, _decorator, native, System } from 'cc'
import { Logger } from './Logger'
import EventManager from './EventManager'
import VersionManager from './VersionManager'
import ManifestConfig from '../config/ManifestConfig'
import ResourcePreload from '../../game/utils/ResourcePreload'
import CommonTips from '../uicomponent/CommonTips'
export default class HotUpdate {
public static Event_CheckUpdate: string = 'Event_CheckUpdate'
public static Event_On_Progress: string = 'HotUpdate_Event_On_Progress'
public static Event_On_NeedUpdate: string = 'HotUpdate_Event_On_NeedUpdate'
public static Event_Finish_Update: string = 'HotUpdate_Event_Finish'
public static Event_On_ALREADY_UP_TO_DATE: string =
'HotUpdate_Event_On_ALREADY_UP_TO_DATE'
public static Event_On_Fail_Update: string = 'HotUpdate_Event_On_Fail_Update'
private _am: any
private _checkListener
private storagePath: string
private manifestUrl: string
private localBigVersion: number
private remoteBigVersion: number
public needUpdate: boolean = false
public isUpdating: boolean
public isFinishUpdate: boolean
public isCheck: boolean
private key: string
private hotupdateIndex: number
constructor() {}
public init(
index: number,
key: string = 'Code-remote-asset',
manifestUrl: string
) {
if (sys.isNative) {
this.hotupdateIndex = index
this.key = key
this.manifestUrl = manifestUrl
if (false) {
//暂时不想修 fileUtils 这个报错
//暂时注释
// this.storagePath = jsb.fileUtils.getWritablePath() + key;
// if (!jsb.fileUtils.isDirectoryExist(this.storagePath)) {
// jsb.fileUtils.createDirectory(this.storagePath)
// }
} else {
this.storagePath = '获取this.storagePath报错了'
}
Logger.log(this, 'init removeDirectory=', this.storagePath + '_temp')
}
this.needUpdate = false
this.isUpdating = false
this.isFinishUpdate = false
this.isCheck = false
}
private jumpToPack() {
let url: string
if (sys.isNative) {
if (sys.os == sys.OS.ANDROID) {
url = VersionManager.instance.apkStoreUrl
} else if (sys.os == sys.OS.IOS) {
url = VersionManager.instance.iosStoreUrl
}
}
Logger.info(
this,
'jumpToPack==androidurl===',
VersionManager.instance.apkStoreUrl
)
Logger.info(
this,
'jumpToPack==iosStoreUrl===',
VersionManager.instance.iosStoreUrl
)
Logger.info(this, 'jumpToPack=====', url)
sys.openURL(url)
// cc.game.end();
}
//显示强制更新,即更细包面板
private showPackUpdateDialog() {
CommonTips.showMsg(
'有新的版本需要更新,下载后请先卸载,以前的版本,再安装!'
)
this.jumpToPack()
this.showPackUpdateDialog()
}
private checkCb(event) {
Logger.log(this, 'checkCb Code: =================' + event.getEventCode())
switch (event.getEventCode()) {
case native.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
Logger.info(this, 'No local manifest file found, hot update skipped.')
this.failUpdate()
break
case native.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case native.EventAssetsManager.ERROR_PARSE_MANIFEST:
Logger.info(this, 'Fail to download manifest file, hot update skipped.')
this.failUpdate()
break
case native.EventAssetsManager.ALREADY_UP_TO_DATE:
Logger.info(this, 'Already up to date with the latest remote version.')
this.alreadyUpToDate()
break
case native.EventAssetsManager.NEW_VERSION_FOUND:
Logger.info(
this,
'new version found, please try to update.',
this.localBigVersion,
this.remoteBigVersion
)
if (
this.key == VersionManager.Config_Key[0] &&
this.localBigVersion < this.remoteBigVersion
) {
//更新大版本
Logger.info(
this,
'new version found, please try to update======packupdate=',
this.localBigVersion,
this.remoteBigVersion
)
this.showPackUpdateDialog()
} else {
Logger.info(
this,
'new version found, please try to update======hotupdate=',
this.localBigVersion,
this.remoteBigVersion
)
// this._am.update();
this.needUpdate = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_NeedUpdate,
this.key
)
}
break
case native.EventAssetsManager.UPDATE_PROGRESSION:
// var currentPercent = event.getPercent();
// var totalPercent = event.getPercentByFile();
// var fileprocess = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
// var byteprocess = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
Logger.info(
this,
'UPDATE_PROGRESSION2222==========',
this.key,
event.getDownloadedBytes(),
event.getTotalBytes()
)
if (event.getTotalBytes() > 0) {
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_Progress,
event.getDownloadedBytes(),
event.getTotalBytes(),
this.key
)
}
break
case native.EventAssetsManager.UPDATE_FINISHED:
Logger.info(this, 'UPDATE_FINISHED==============')
this.finishUpdate(true)
break
case native.EventAssetsManager.UPDATE_FAILED:
Logger.warn(this, 'Update failed==========', event.getMessage())
this.failUpdate()
break
case native.EventAssetsManager.ERROR_UPDATING:
let fullFilePath: string = this.storagePath + '/' + event.getAssetId()
let tempFilePath: string =
this.storagePath + '_temp/' + event.getAssetId()
Logger.warn(this, 'fullFilePath====', fullFilePath)
Logger.warn(this, 'tempFilePath====', tempFilePath)
// jsb.fileUtils.removeFile(tempFilePath);
Logger.warn(
this,
'ERROR_UPDATING=============',
event.getAssetId(),
event.getMessage()
)
this.failUpdate()
break
default:
// this.failUpdate();
return
}
}
public checkUpdate() {
if (this.isUpdating || this.isCheck) {
Logger.log(this, 'Checking or updating ...')
return
}
let hotupdateUrlKey: string =
VersionManager.Config_Url_Key[this.hotupdateIndex]
Logger.log(this, 'checkoutUpdate=====', this.manifestUrl, hotupdateUrlKey)
if (!this._am) {
this._am = new native.AssetsManager(
'',
this.storagePath,
this.versionCompareHandle.bind(this)
)
}
// this._am.setMaxConcurrentTask(1);
let manifestStr: string = ManifestConfig.getManifestStr(hotupdateUrlKey)
Logger.log(this, 'checkUpdate=======manifestStr=======', manifestStr)
let manifest = new native.Manifest(manifestStr, this.storagePath)
this._am.setVerifyCallback(function (filePath, asset) {
return true
// var md5 = calculateMD5(filePath);
// if (md5 === asset.md5)
// return true;
// else
// return false;
})
this._am.setEventCallback(this.checkCb.bind(this))
// 设置事件回调
this.isCheck = true
this._am.loadLocalManifest(manifest, this.storagePath)
this._am.checkUpdate()
}
/**
* @param versionA 本地版本 1.0.0
* @param versionB 服务器版本 1.0.1
* @param return -1需要更新 不用更新
*/
private versionCompareHandle(versionA, versionB) {
var vA = versionA.split('.')
var vB = versionB.split('.')
Logger.log(
this,
'versionCompareHandle======',
this.key,
VersionManager.Config_Key[0]
)
if (this.key == VersionManager.Config_Key[0]) {
Logger.log(this, 'versionCompareHandle22===', versionA, versionB)
VersionManager.instance.nowVersion = versionA
VersionManager.instance.targetVersion = versionB
}
this.localBigVersion = parseInt(vA[0])
this.remoteBigVersion = parseInt(vB[0])
for (var i = 0; i < vA.length; ++i) {
var a = parseInt(vA[i])
var b = parseInt(vB[i] || 0)
if (a === b) {
continue
} else {
return a - b
}
}
if (vB.length > vA.length) {
return -1
} else {
return 0
}
}
public startUpdate() {
if (this.isUpdating) return
let localManifest = this._am.getLocalManifest()
let remoteManifest = this._am.getRemoteManifest()
Logger.log(this, 'startUpdate111===', localManifest.getVersionFileUrl())
Logger.log(this, 'startUpdate2222===', localManifest.getManifestFileUrl())
Logger.log(this, 'startUpdate3333===', remoteManifest.getVersionFileUrl())
Logger.log(this, 'startUpdate4444===', remoteManifest.getManifestFileUrl())
this.isUpdating = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_Progress,
0,
100,
this.key
)
this._am.update()
}
public disposeUpdate() {
if (this._am) {
this._am.setVerifyCallback(null)
this._am.setEventCallback(null)
}
this._am = null
this._checkListener = null
this.isUpdating = false
this.needUpdate = false
}
private failUpdate() {
this.disposeUpdate()
this.isCheck = false
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_Fail_Update,
this.key
)
}
private alreadyUpToDate() {
this.disposeUpdate()
this.isFinishUpdate = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_ALREADY_UP_TO_DATE,
this.key
)
}
private finishUpdate(needRestart: boolean) {
Logger.info(this, '更新完成=====', needRestart)
this.disposeUpdate()
this.isFinishUpdate = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_Finish_Update,
this.key,
needRestart
)
if (false && needRestart) {
//暂时不想修 fileUtils 这个报错
var searchPaths = '' //jsb.fileUtils.getSearchPaths();暂时注释
Logger.info(this, '更新完成====searchPaths======', searchPaths)
sys.localStorage.setItem(
'HotUpdateSearchPaths',
JSON.stringify(searchPaths)
)
//jsb.fileUtils.setSearchPaths(searchPaths);暂时注释
if (this.key == VersionManager.Config_Key[0]) {
ResourcePreload.instance.restartGame()
}
}
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "a0006bd3-77dc-49ae-991e-77aa5a70f4a6",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,160 @@
import { _decorator } from 'cc'
const { ccclass } = _decorator
import LoadingPrefab from '../uicomponent/LoadingPrefab'
import VersionManager from './VersionManager'
import { Logger } from './Logger'
@ccclass('HttpClient')
export default class HttpClient {
public static instance: HttpClient //= new HttpClient();
//example
// HttpClient.instance.request("http://localhost:8080/haohttp/test", ()=>{
// console.log("http 请求 end=============");
// }, {"nickName":"jhao", "hh":1, "id":9527});
private methodType: string = 'GET'
private responseType: XMLHttpRequestResponseType = 'json'
private xhr: XMLHttpRequest
// --GET or POST
public setMethod(method: string = 'GET') {
this.methodType = method
}
public setParams(paramsObj: object): string {
let resParams = ''
let nowIndex = 1
for (const key in paramsObj) {
if (paramsObj.hasOwnProperty(key)) {
if (nowIndex == 1) {
resParams += key + '=' + paramsObj[key]
} else {
resParams += '&' + key + '=' + paramsObj[key]
}
nowIndex += 1
}
}
Logger.log(this, 'resParam===============', resParams)
return resParams
}
public setResponseType(responseType: XMLHttpRequestResponseType) {
this.responseType = responseType
}
public setContentType() {}
public request(
url: string,
callback: Function,
params: any = null,
timeOut: number = 5 * 1000
) {
if (params && this.methodType == 'GET') {
let getParams: string = this.setParams(params)
// getParams = StringUtil:encodeURI(params)
getParams = encodeURI(getParams)
url += '?' + getParams
}
this.xhr = new XMLHttpRequest() // http请求 fget
//this.xhr = cc.loader.getXMLHttpRequest();
let xhr: XMLHttpRequest = this.xhr
xhr.responseType = this.responseType
xhr.timeout = timeOut
// xhr.setRequestHeader("Content-Type", "text/plain");
xhr.onreadystatechange = () => {
Logger.log(
this,
'status======',
xhr.status,
xhr.readyState,
xhr.statusText
)
// if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = xhr.response
Logger.log(this, 'http response1============', xhr)
try {
let testJson = JSON.stringify(response)
Logger.log(this, 'http response json============', testJson)
if (callback) {
callback(true, response)
callback = null
}
} catch (error) {
Logger.error(this, 'http response json=====error=======', error)
if (callback) {
callback(false)
callback = null
}
}
} else if (xhr.readyState == 4 && xhr.status == 301) {
//域名转移
Logger.log(
this,
'http response222============',
xhr.getResponseHeader('Location')
)
// console.log("http response333============", xhr.getAllResponseHeaders());
if (HttpClient.instance == null) HttpClient.instance = new HttpClient()
HttpClient.instance.request(xhr.getResponseHeader('Location'), callback)
} else if (xhr.readyState == 4 && xhr.status == 404) {
Logger.log(this, 'http onError============')
if (callback) {
callback(false)
callback = null
}
} else {
Logger.log(
this,
'onreadystatechange else====',
xhr.status,
xhr.readyState,
xhr.response
)
if (xhr.readyState == 4) {
Logger.log(this, 'http onError else============')
if (callback) {
callback(false)
callback = null
}
}
}
}
xhr.onprogress = () => {
Logger.log(
this,
'http onprogress===',
xhr.status,
xhr.readyState,
xhr.response
)
}
xhr.onerror = () => {
Logger.log(this, 'http onError============')
if (callback) {
callback(false)
callback = null
}
}
xhr.ontimeout = () => {
Logger.log(this, 'http ontimeout============')
if (callback) {
callback(false)
callback = null
}
}
Logger.log(this, 'http request==============', url)
Logger.log(this, 'http request======method========', this.methodType)
Logger.log(this, 'http request======params========', params)
xhr.open(this.methodType, url, true)
xhr.setRequestHeader('content-type', 'text/plain;charset=UTF-8')
xhr.send(params)
}
public getInfo(callback: Function = null) {}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "97dba6a3-a0b7-42ef-9abc-de779e8bd220",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,64 @@
import { sys, _decorator } from 'cc'
import { Logger } from './Logger'
export default class LocalStorage {
public static GamePreFlag: string = 'fengshen-game-HaoLocalStorage'
public static setItem(key: string, value: string): void {
sys.localStorage.setItem(LocalStorage.GamePreFlag + key, value)
}
public static getItem(key: string): string {
return sys.localStorage.getItem(LocalStorage.GamePreFlag + key)
}
public static removeItem(key: string): void {
sys.localStorage.removeItem(LocalStorage.GamePreFlag + key)
}
public static getInt(key: string): number {
let tempValue: string = LocalStorage.getItem(key)
let result: number = 0
if (tempValue) {
result = parseInt(tempValue)
}
return result
}
public static setInt(key: string, value: number): void {
LocalStorage.setItem(key, value.toString())
}
public static getFloat(key: string): number {
let tempValue: string = LocalStorage.getItem(key)
let result: number = 0
if (tempValue) {
result = parseFloat(tempValue)
}
return result
}
public static setFloat(key: string, value: number): void {
LocalStorage.setItem(key, value.toString())
}
public static getBoolean(key: string): boolean {
let temp: number = LocalStorage.getInt(key)
if (temp == 1) {
return true
}
return false
}
public static setBoolean(key: string, value: boolean) {
if (value) {
LocalStorage.setInt(key, 1)
} else {
LocalStorage.setInt(key, 0)
}
}
public static clear() {
sys.localStorage.clear()
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "6ac377cd-dfa3-4928-ae69-ae600d9aabb1",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,133 @@
import { error, _decorator } from 'cc'
class LOG_LEVEL_TYPES {
public static DEBUG = 0
public static LOG = 1
public static INFO = 2
public static WARN = 3
public static ERROR = 4
}
const Log_Level_Names: Array<string> = ['debug', 'log', 'info', 'warn', 'error']
export class Logger {
public static tag: string = '[HaoJslog]' //可以设置当前游戏的前缀
public static LEVEL: number = LOG_LEVEL_TYPES.WARN //当前Logger等级
public static Log_Color_Config: Array<string> = [
'color:#890;font-size:10px;',
'color:#000;font-size:11px;',
'color:#09f;font-size:12px;',
'color:#f90;font-size:13px;',
'color:#f00;font-size:15px;',
]
private static Terminal_Log: boolean = false
public static formatNow() {
let date: Date = new Date() //后端返回的时间戳是秒
return (
date.getFullYear() +
'-' +
(date.getMonth() + 1) +
'-' +
date.getDate() +
' ' +
date.getHours() +
':' +
date.getMinutes() +
':' +
date.getSeconds() +
':' +
date.getMilliseconds()
)
}
private static getLogPreKey(nowLevel: number): string {
let str: string =
'[' +
Logger.formatNow() +
'] ' +
Logger.tag +
' [' +
Log_Level_Names[nowLevel] +
'] '
return str
}
public static debug(...params: any) {
if (Logger.LEVEL > LOG_LEVEL_TYPES.DEBUG) {
return
}
let str: string = this.getLogPreKey(LOG_LEVEL_TYPES.DEBUG)
let fileStr: string = str + params.join(' ')
// LogErrorFileUtil.debug(fileStr);
if (this.Terminal_Log) {
console.log(
'%c' + str,
this.Log_Color_Config[LOG_LEVEL_TYPES.DEBUG],
...params
)
} else {
console.info(fileStr)
}
}
public static log(...params: any) {
if (Logger.LEVEL > LOG_LEVEL_TYPES.LOG) {
return
}
let str: string = this.getLogPreKey(LOG_LEVEL_TYPES.LOG)
let fileStr: string = str + params.join(' ')
// LogErrorFileUtil.log(fileStr);
if (this.Terminal_Log) {
console.log(
'%c' + str,
this.Log_Color_Config[LOG_LEVEL_TYPES.DEBUG],
...params
)
} else {
console.info(fileStr) //console.log(str, ...params)
}
}
public static info(...params: any) {
if (Logger.LEVEL > LOG_LEVEL_TYPES.INFO) {
return
}
let str: string = this.getLogPreKey(LOG_LEVEL_TYPES.INFO)
let fileStr: string = str + params.join(' ')
if (this.Terminal_Log) {
console.info(
'%c' + str,
this.Log_Color_Config[LOG_LEVEL_TYPES.DEBUG],
...params
)
} else {
console.info(fileStr)
}
}
public static warn(...params: any) {
if (Logger.LEVEL > LOG_LEVEL_TYPES.WARN) {
return
}
let str: string = this.getLogPreKey(LOG_LEVEL_TYPES.WARN)
let fileStr: string = str + params.join(' ')
if (this.Terminal_Log) {
console.warn(
'%c' + str,
this.Log_Color_Config[LOG_LEVEL_TYPES.DEBUG],
...params
)
} else {
console.warn(fileStr)
}
}
public static error(...params: any) {
if (Logger.LEVEL > LOG_LEVEL_TYPES.ERROR) {
return
}
let str: string = this.getLogPreKey(LOG_LEVEL_TYPES.ERROR)
let fileStr: string = str + params.join(' ')
if (this.Terminal_Log) {
console.error(
'%c' + str,
this.Log_Color_Config[LOG_LEVEL_TYPES.DEBUG],
...params
)
} else {
console.error(fileStr)
}
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "64f5d910-1b40-421a-a57e-315335fd7b33",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,61 @@
import { _decorator, Vec2 } from 'cc'
export default class MathUtils {
/**
* 2个点之前的直线距离
* @param p1
* @param p2
*/
public static distance(x1: number, y1: number, x2: number, y2: number) {
// 设两点AX1,Y1,BX2,Y2
// 距离D=X2-X1的平方+Y2-Y1平方的和开平方
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))
}
/**
* 2点间的向量
* @param p1
* @param p2
*/
public static sub(p1: Vec2, p2: Vec2) {
return new Vec2(p1.x - p2.x, p1.y - p2.y)
}
/**
* 弧度转角度
* @param radians
*/
public static radiansToDegrees(radians: number) {
return (180 / Math.PI) * radians
}
/**
* 角度转弧度
* @param degrees
*/
public static degreesToRadians(degrees: number) {
return (Math.PI * degrees) / 180
}
/**
* 返回2点间的弧度
* @param startP
* @param endP
*/
public static p2pRad(startP: Vec2, endP: Vec2) {
let rad: number = Math.atan2(endP.y - startP.y, endP.x - startP.x)
return rad
}
/**
* 针对捕鱼鱼的方向特定实现的鱼方向转换
* @param rot
*/
public static rotation2Fish(rot: number) {
if (rot >= 0 && rot <= 180) {
rot = 180 - rot
} else {
rot = -180 - rot
}
return rot
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "93c7eb99-4e1c-4343-9017-b8511388166a",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,62 @@
import { _decorator, Node, Vec3, Vec2 } from 'cc'
import { Logger } from './Logger'
import MathUtils from './MathUtils'
export class MoveHelper {
public static _vec3: Vec3 = new Vec3()
public static _vec2_0: Vec2 = new Vec2()
public static _vec2_1: Vec2 = new Vec2()
public static moveNode(
moveNode: Node,
speed: number,
tx: number,
ty: number,
minSpeed: number = 0.01
) {
let isMoving: boolean = false
let times: number = 0
moveNode.getPosition(MoveHelper._vec3)
MoveHelper._vec2_0.x = MoveHelper._vec3.x
MoveHelper._vec2_0.y = MoveHelper._vec3.y
MoveHelper._vec2_1.x = tx
MoveHelper._vec2_1.y = ty
let rad: number = MathUtils.p2pRad(MoveHelper._vec2_0, MoveHelper._vec2_1)
let speedX: number = speed * Math.cos(rad)
let speedY: number = speed * Math.sin(rad)
if (Math.abs(MoveHelper._vec3.x - tx) > minSpeed) {
times = Math.floor(Math.abs(speedX / minSpeed))
for (let i = 0; i < times; i++) {
if (MoveHelper._vec3.x > tx) {
MoveHelper._vec3.x -= minSpeed
moveNode.setPosition(MoveHelper._vec3)
} else {
MoveHelper._vec3.x += minSpeed
moveNode.setPosition(MoveHelper._vec3)
}
if (Math.abs(MoveHelper._vec3.x - tx) <= minSpeed * 2) {
MoveHelper._vec3.x = tx
moveNode.setPosition(MoveHelper._vec3)
}
}
isMoving = true
}
if (Math.abs(MoveHelper._vec3.y - ty) > minSpeed) {
times = Math.floor(Math.abs(speedY / minSpeed))
for (let j = 0; j < times; j++) {
if (MoveHelper._vec3.y > ty) {
MoveHelper._vec3.y -= minSpeed
moveNode.setPosition(MoveHelper._vec3)
} else {
MoveHelper._vec3.y += minSpeed
moveNode.setPosition(MoveHelper._vec3)
}
if (Math.abs(MoveHelper._vec3.x - ty) <= minSpeed * 2) {
MoveHelper._vec3.y = ty
moveNode.setPosition(MoveHelper._vec3)
}
}
isMoving = true
}
return isMoving
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4304fd05-cb03-46da-a6a6-f742febe535e",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,30 @@
import { AssetManager, Prefab, _decorator } from 'cc'
const { ccclass, property } = _decorator
import { Logger } from './Logger'
@ccclass('PrefabLoader')
export default class PrefabLoader {
private static isLoading: boolean = false
public static loadPrefab(url: string, callback: Function) {
if (this.isLoading) return
this.isLoading = true
AssetManager.instance.resources.load(
url,
Prefab,
(error: Error, loadedResource) => {
if (error) {
Logger.warn(this, '载入Prefab失败, 原因:', url, error.message)
return
}
if (!(loadedResource instanceof Prefab)) {
Logger.warn(this, '你载入的不是Prefab, 你做了什么事?')
return
}
callback(loadedResource)
this.isLoading = false
}
)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "10db6736-1255-4a28-91a1-fe4c41312d29",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,50 @@
import { Vec2, _decorator } from 'cc'
export default class RandomUtil {
//随机minNum到maxNum的数字 包含maxNum
public static nextInt(minNum: number, maxNum: number) {
return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum)
}
public static nextNumber(minNum: number, maxNum: number) {
return Math.random() * (maxNum - minNum) + minNum
}
public static nextSign() {
let temp = Math.random()
if (temp < 0.5) {
return 1
}
return -1
}
public static nextBoolean() {
let temp = Math.random()
if (temp < 0.5) {
return true
}
return false
}
public static randomArr(nowArr: Array<any>, needNum: number) {
let tempArr: Array<any> = nowArr.concat()
let resultArr: Array<any> = []
for (let index = 0; index < needNum; index++) {
if (tempArr.length <= 0) {
break
}
let randomIndex: number = RandomUtil.nextInt(0, tempArr.length - 1)
resultArr.push(tempArr.splice(randomIndex, 1)[0])
}
return resultArr
}
public static randomItem(nowArr: Array<any>) {
return this.randomArr(nowArr, 1)[0]
}
public static randomP(left: number, right: number, up: number, down: number) {
let randomX: number = RandomUtil.nextNumber(left, right)
let randomY: number = RandomUtil.nextNumber(up, down)
return new Vec2(randomX, randomY)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "09813185-c544-4799-88cd-3134aa4da011",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,436 @@
import {
_decorator,
Node,
Material,
Color,
UIRenderer,
Vec2,
UITransform,
} from 'cc'
import ShaderMaterialPrefab from '../../game/prefab/ShaderMaterialPrefab'
import { Logger } from './Logger'
export default class ShaderHelper {
/**
* 清除所有shader
* @param showNode
* @param material
*/
public static clearAllEffect(
showNode: Node,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).default
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 设置图片灰白程度
* @param showNode
* @param material
* @param grayLevel [0.0, 1.0]
*/
public static setGrayEffect(
showNode: Node,
grayLevel: number = 1,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).grayMaterial
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('grayLevel', grayLevel)
renderComponent.setMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('grayLevel', grayLevel)
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 播放变灰过程动画
*/
public static showGrayMv(showNode: Node) {
let grayValue: number = 0.5
let intervalId = setInterval(() => {
grayValue += 0.01
if (grayValue >= 1) {
grayValue = 1
clearInterval(intervalId)
}
if (showNode) {
ShaderHelper.setGrayEffect(showNode, grayValue)
}
}, 1)
}
/**
* 设置图片老化
* @param showNode
* @param grayLevel [0.0, 1.0]
* @param material
*/
public static setOldPhotoEffect(
showNode: Node,
grayLevel: number = 1,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).oldPhoto
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('oldLevel', grayLevel)
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('oldLevel', grayLevel)
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 播放变灰过程动画
*/
public static showOldPhotoMv(showNode: Node) {
let grayValue: number = 0
let intervalId = setInterval(() => {
grayValue += 0.01
if (grayValue >= 1) {
grayValue = 1
clearInterval(intervalId)
}
if (showNode) {
ShaderHelper.setOldPhotoEffect(showNode, grayValue)
}
}, 1)
}
/**
* 增加内发光特效
* showNode:要增加特效的节点或者他的子节点
* material:发光特效材质
* materialParam: {}
* materialParam.glowColor:cc.v4(r,g,b,a) 颜色rbga值的结构体
* materialParam.glowColorSize:这里为约束一下值发光宽度值在 [0.0, 0.1] 因为 0.1+ 之后的效果可能不明显,也可以自己尝试修改,个人测试感觉0.01效果最佳
* materialParam.glowThreshold:这里为约束一下值发光阈值值在 [0.0, 0.5] 因为 0.5+ 之后的效果可能就是其他效果个人感觉0.1效果最佳
*/
public static setGlowInner(
showNode: Node,
materialParam: any,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).glowInner
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('glowColor', materialParam.glowColor)
material.setProperty('glowColorSize', materialParam.glowColorSize)
material.setProperty('glowThreshold', materialParam.glowThreshold)
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('glowColor', materialParam.glowColor)
material.setProperty('glowColorSize', materialParam.glowColorSize)
material.setProperty('glowThreshold', materialParam.glowThreshold)
renderComponent.setMaterial(material, 0)
})
})
}
/**
* 设置不同颜色的发光
* @param showNode
* @param color
*/
public static setCommonGlowInner(showNode: Node, color: Color = Color.WHITE) {
this.setGlowInner(showNode, {
glowColor: color,
glowColorSize: 0.015,
glowThreshold: 0.1,
})
}
/**
* 播放被攻击闪烁过程动画
*/
public static showFlash(showNode: Node, totalFlashTimes: number = 1) {
let timeCount: number = 0
let color: Color = Color.WHITE
let flashTimes: number = 0
let intervalId = setInterval(() => {
timeCount += 1
if (timeCount % 50 == 0) {
let tempCount: number = timeCount / 50
if (tempCount % 2 == 0) {
color.a = 100
this.setGlowInner(showNode, {
glowColor: color,
glowColorSize: 0.1,
glowThreshold: 0,
})
} else {
flashTimes++
this.setGlowInner(showNode, {
glowColor: color,
glowColorSize: 0,
glowThreshold: 0,
})
if (flashTimes > totalFlashTimes) {
clearInterval(intervalId)
}
}
}
}, 1)
}
/**
* 马赛克
* @param showNode
* @param materialParam
* @param material
*/
public static setMosaic(
showNode: Node,
materialParam: any,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).mosaic
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('xBlockCount', materialParam.xBlockCount)
material.setProperty('yBlockCount', materialParam.yBlockCount)
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('xBlockCount', materialParam.xBlockCount)
material.setProperty('yBlockCount', materialParam.yBlockCount)
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 播放被攻击闪烁过程动画
*/
public static showMosaicMv(showNode: Node, callback: Function = null) {
let masaicTimes: number = 500
let intervalId = setInterval(() => {
masaicTimes -= 2
this.setMosaic(showNode, {
xBlockCount: masaicTimes,
yBlockCount: masaicTimes,
})
if (masaicTimes <= 30) {
clearInterval(intervalId)
if (callback) {
callback()
}
}
}, 1)
}
/**
* 设置圆角剪切
* @param showNode
* @param roundCornerRadius [0, 1]
*/
public static setRoundCornerCrop(
showNode: Node,
roundCornerRadius: number = 0.1,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).roundCornerCrop
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
// material.setProperty("roundCornerRadius", roundCornerRadius);
material.setProperty('xRadius', roundCornerRadius)
material.setProperty('yRadius', roundCornerRadius)
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
// material.setProperty("roundCornerRadius", roundCornerRadius);
material.setProperty('xRadius', roundCornerRadius)
material.setProperty('yRadius', roundCornerRadius)
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 设置闪光
* @param showNode
* @param lightColor 光颜色
* @param lightWidth 光的宽度
* @param lightAngle 光的角度
* @param enableGradient
* @param cropAlpha
* @param enableFog
* @param material
*/
public static setFlashLight(
showNode: Node,
lightColor: Color,
lightWidth: number,
lightAngle: number = 0,
enableGradient: boolean = true,
cropAlpha: boolean = true,
enableFog: boolean = false,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).flashLight
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('lightColor', lightColor)
material.setProperty('lightWidth', lightWidth)
material.setProperty('lightAngle', lightAngle)
material.setProperty('enableGradient', enableGradient ? 1 : 0)
material.setProperty('cropAlpha', cropAlpha ? 1 : 0)
material.setProperty('enableFog', enableFog ? 1 : 0)
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
material.setProperty('lightColor', lightColor)
material.setProperty('lightWidth', lightWidth)
material.setProperty('lightAngle', lightAngle)
material.setProperty('enableGradient', enableGradient ? 1 : 0)
material.setProperty('cropAlpha', cropAlpha ? 1 : 0)
material.setProperty('enableFog', enableFog ? 1 : 0)
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 玩家升级shader动画
* @param showNode
* @param callback
*/
public static showFlashLightMv(showNode: Node, callback: Function = null) {
let nowClor: Color = new Color(0, 0, 0, 255)
let colorIndex: number = 0
let lightAngle: number = 0
let intervalId = setInterval(() => {
if (colorIndex == 0) {
nowClor.r = nowClor.r + 2
if (nowClor.r >= 255) {
colorIndex += 1
}
} else if (colorIndex == 1) {
nowClor.g = nowClor.g + 2
if (nowClor.g >= 255) {
colorIndex += 1
}
} else {
nowClor.b = nowClor.b + 2
if (nowClor.b >= 255) {
clearInterval(intervalId)
ShaderHelper.clearAllEffect(showNode)
if (callback) {
callback()
}
return
}
}
lightAngle += 1
this.setFlashLight(showNode, nowClor, 1, lightAngle)
}, 1)
}
public static setFlag(
showNode: Node,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).flag
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
renderComponent.setSharedMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
renderComponent.setSharedMaterial(material, 0)
})
})
}
/**
* 设置高斯模糊
* @param showNode
* @param material
*/
public static setGaussian(
showNode: Node,
material: Material = ShaderMaterialPrefab.instance.getComponent(
ShaderMaterialPrefab
).gaussian
) {
showNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
let tran = renderComponent.node.getComponent(UITransform)
material.setProperty(
'textureSize',
new Vec2(tran.contentSize.width, tran.contentSize.height)
)
renderComponent.setMaterial(material, 0)
})
showNode.children.forEach((childNode) => {
childNode
.getComponents(UIRenderer)
.forEach((renderComponent: UIRenderer) => {
let tran = renderComponent.node.getComponent(UITransform)
material.setProperty(
'textureSize',
new Vec2(tran.contentSize.width, tran.contentSize.height)
)
// material.setProperty("textureSize", cc.v2(showNode.width, showNode.height));
renderComponent.setSharedMaterial(material, 0)
})
})
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "347c6bb0-da88-4e18-b261-9298e6dcaa7a",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,139 @@
import { sys, _decorator } from 'cc'
import ManifestConfig from '../config/ManifestConfig'
import EventManager from './EventManager'
import HotUpdate from './HotUpdate'
export default class VersionManager {
public static instance: VersionManager = new VersionManager()
public static Config_Game_Name: Array<string> = ['游戏大厅']
//热更文件下载来后存放文件夹
public static Config_Key: Array<string> = ['main-remote-asset']
private static Config_ManifestName: string = 'project.manifest'
public static Config_Url_Key: Array<string> = ['main']
public iosStoreUrl: string = ''
public apkStoreUrl: string = ''
public nowVersion: string = ManifestConfig.version //网页显示版本号,如果是热更会替换改值
public targetVersion: string = '1.0.0'
public isOpenHotUpdate: boolean = true //是否打开热更
private hotUpdateList: Array<HotUpdate> = []
private noUpdateIndex: number = -1 //
public init() {
this.reInitAll()
}
public reInitAll() {
this.releaseAll()
for (let i = 0; i < VersionManager.Config_Key.length; i++) {
this.reInit(i)
}
}
public releaseAll() {
for (let i = 0; i < VersionManager.Config_Key.length; i++) {
if (this.hotUpdateList[i]) {
this.hotUpdateList[i].disposeUpdate()
}
}
}
public reInit(index: number) {
if (!this.hotUpdateList[index]) {
this.hotUpdateList[index] = new HotUpdate()
}
this.hotUpdateList[index].init(
index,
VersionManager.Config_Key[index],
VersionManager.Config_ManifestName
)
if (!this.isOpenHotUpdate) {
this.hotUpdateList[index].isCheck = true
this.hotUpdateList[index].isFinishUpdate = true
}
}
public checkUpdate(keyIndex: number) {
if (keyIndex < this.hotUpdateList.length) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
if (sys.isNative) {
if (keyIndex == this.noUpdateIndex) {
//在大厅热更,不用子游戏热更了
hotUpdate.isCheck = true
hotUpdate.isFinishUpdate = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_ALREADY_UP_TO_DATE,
VersionManager.Config_Key[keyIndex]
)
} else {
hotUpdate.checkUpdate()
}
} else {
hotUpdate.isCheck = true
hotUpdate.isFinishUpdate = true
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_ALREADY_UP_TO_DATE,
VersionManager.Config_Key[keyIndex]
)
}
} else {
EventManager.instance.dispatchEvent(
HotUpdate.Event_On_ALREADY_UP_TO_DATE,
VersionManager.Config_Key[keyIndex]
)
}
}
public startUpdate(keyIndex: number) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
hotUpdate.startUpdate()
}
public isCheck(keyIndex: number) {
if (keyIndex < this.hotUpdateList.length) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
if (keyIndex == this.noUpdateIndex) {
return true
}
return hotUpdate.isCheck
}
return true
}
public needUpdate(keyIndex: number) {
if (keyIndex < this.hotUpdateList.length) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
if (keyIndex == this.noUpdateIndex) {
return false
}
return hotUpdate.needUpdate
}
return false
}
public isUpdating(keyIndex: number) {
if (keyIndex < this.hotUpdateList.length) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
return hotUpdate.isUpdating
}
return false
}
public isFinishUpdate(keyIndex: number) {
if (keyIndex < this.hotUpdateList.length) {
let hotUpdate: HotUpdate = this.hotUpdateList[keyIndex]
if (keyIndex == this.noUpdateIndex) {
return true
}
return hotUpdate.isFinishUpdate
}
return true
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c79a6571-dc2f-4715-a5d6-151542eef238",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "2ac3d2c9-b418-4202-b672-736c533b89ea",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "37ac4184-546f-4fa8-9030-da49dbe4219c",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,44 @@
import { _decorator } from 'cc'
import { FishInfo } from './FishInfo'
export class FishConfig {
public static readonly config: ReadonlyArray<FishInfo> = [
new FishInfo(1, '蝴蝶鱼', 2, 2),
new FishInfo(2, '鲶鱼', 2, 1),
new FishInfo(3, '狮子鱼', 2, 2),
new FishInfo(4, '条纹鱼', 2, 2),
new FishInfo(5, '沙丁鱼', 2, 2),
new FishInfo(6, '石斑鱼', 2, 2),
new FishInfo(7, '河豚', 3, 1.2),
new FishInfo(8, '海螺', 3, 2),
new FishInfo(9, '接吻鱼', 3, 1.2),
new FishInfo(10, '海姆', 4, 1),
new FishInfo(11, '绿鳍鱼', 4, 1.2),
new FishInfo(12, '鲎', 4, 1.2),
new FishInfo(13, '魔鬼鱼', 5, 0.6),
new FishInfo(14, '小海龟', 5, 2),
new FishInfo(15, '锤头鲨', 6, 0.5),
new FishInfo(16, '金枪鱼', 6, 0.5),
new FishInfo(17, '大三元', 6, 0.5),
new FishInfo(18, '黄金鲎', 6, 1.2),
new FishInfo(19, '大四喜', 7, 0.5),
new FishInfo(20, '黄金锤头鲨', 7, 0.5),
new FishInfo(21, '金海姆', 7, 0.6),
new FishInfo(22, '五福临门', 8, 0.4),
new FishInfo(23, '金海龟', 8, 0.7),
new FishInfo(24, '金鲨', 8, 0.5),
new FishInfo(25, '蓝鲨', 8, 0.5),
new FishInfo(26, '美人鱼', 14, 0.4),
new FishInfo(27, '金龙', 14, 0.3),
new FishInfo(28, '章鱼', 10, 0.5),
new FishInfo(29, '电鳗鱼', 3, 0.8),
]
public static getFishInfoByType(fishType: number) {
for (let i = 0; i < this.config.length; i++) {
let fishInfo: FishInfo = this.config[i]
if (fishInfo.fishType == fishType) {
return fishInfo
}
}
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c7516237-7eb2-4767-8cc7-7ce0b2d5484e",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,18 @@
import { _decorator } from 'cc'
export class FishInfo {
public fishType: number
public name: string
public blood: number
public wikiScale: number
constructor(
fishType: number,
name: string,
blood: number,
wikiScale: number
) {
this.fishType = fishType
this.name = name
this.blood = blood
this.wikiScale = wikiScale
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "03f14923-6d67-4d91-97ad-a81bf4f1551f",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,11 @@
import { _decorator } from 'cc'
import { FishMapInfo } from './FishMapInfo'
export class FishMap {
public mapId: number
public fishMapInfoList: Array<FishMapInfo>
constructor(mapId: number, list: Array<FishMapInfo>) {
this.mapId = mapId
this.fishMapInfoList = list
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "f84ce3e3-8c47-43ff-a6f4-7cda4c320fcf",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,21 @@
import { _decorator } from 'cc'
export class FishMapInfo {
public fishType: number
public scale: number
public side: number //1: -1:
public x: number
public y: number
constructor(
fishType: number,
scale: number,
side: number,
x: number,
y: number
) {
this.fishType = fishType
this.scale = scale
this.side = side
this.x = x
this.y = y
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "5f3df30a-4677-4f9c-97a9-e80fcb5b8295",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,998 @@
import { Vec2, _decorator } from 'cc'
import { FishPathInfo } from './FishPathInfo'
import RandomUtil from '../../engine/utils/RandomUtil'
import { FishMapInfo } from './FishMapInfo'
import { FishMap } from './FishMap'
import { Logger } from '../../engine/utils/Logger'
export class FishPathConfig {
private static mapConfig: Array<Array<Array<number>>> = [
[
[1, 1, 1, -425, 387],
[1, 1, 1, -487, 352],
[1, 1, 1, -541, 307],
[1, 1, 1, -589, 263],
[1, 1, 1, -623, 232],
[1, 1, 1, -654, 172],
[1, 1, 1, -671, 134],
[1, 1, 1, -693, 92],
[1, 1, 1, -697, 35],
[1, 1, 1, -706, -19],
[1, 1, 1, -707, -92],
[1, 1, 1, -701, -136],
[1, 1, 1, -702, -177],
[1, 1, 1, -686, -230],
[1, 1, 1, -637, -257],
[1, 1, 1, -559, -272],
[1, 1, 1, -471, -278],
[1, 1, 1, -408, -259],
[1, 1, 1, -337, -226],
[1, 1, 1, -325, -170],
[1, 1, 1, -322, -99],
[1, 1, 1, -336, -39],
[1, 1, 1, -370, 7],
[1, 1, 1, -412, 59],
[1, 1, 1, -532, 69],
[1, 1, 1, -613, 82],
[1, 1, 1, -470, 63],
[1, 1, 1, 241, 402],
[1, 1, 1, 184, 357],
[1, 1, 1, 143, 335],
[1, 1, 1, 81, 285],
[1, 1, 1, 27, 229],
[1, 1, 1, -9, 167],
[1, 1, 1, -39, 126],
[1, 1, 1, -47, 57],
[1, 1, 1, -74, -10],
[1, 1, 1, -62, -66],
[1, 1, 1, -74, -118],
[1, 1, 1, -85, -201],
[1, 1, 1, -30, -240],
[1, 1, 1, 10, -271],
[1, 1, 1, 135, -273],
[1, 1, 1, 79, -280],
[1, 1, 1, 202, -280],
[1, 1, 1, 266, -276],
[1, 1, 1, 276, -274],
[1, 1, 1, 307, -259],
[1, 1, 1, 316, -244],
[1, 1, 1, 327, -226],
[1, 1, 1, 335, -195],
[1, 1, 1, 337, -142],
[1, 1, 1, 321, -53],
[1, 1, 1, 271, -13],
[1, 1, 1, 188, 27],
[1, 1, 1, 123, 46],
[1, 1, 1, 59, 57],
[1, 1, 1, 17, 60],
[1, 1, 1, 323, -101],
[1, 1, 1, 732, 329],
[1, 1, 1, 669, 283],
[1, 1, 1, 613, 218],
[1, 1, 1, 567, 185],
[1, 1, 1, 558, 163],
[1, 1, 1, 507, 95],
[1, 1, 1, 468, 35],
[1, 1, 1, 456, -18],
[1, 1, 1, 451, -80],
[1, 1, 1, 447, -164],
[1, 1, 1, 458, -234],
[1, 1, 1, 505, -267],
[1, 1, 1, 578, -281],
[1, 1, 1, 657, -291],
[1, 1, 1, 708, -291],
[1, 1, 1, 769, -291],
[1, 1, 1, 812, -290],
[1, 1, 1, 847, -275],
[1, 1, 1, 860, -236],
[1, 1, 1, 853, -160],
[1, 1, 1, 826, -95],
[1, 1, 1, 794, -46],
[1, 1, 1, 754, -7],
[1, 1, 1, 671, 26],
[1, 1, 1, 630, 59],
[1, 1, 1, 584, 80],
],
[
[2, 1, 1, -784, 353],
[2, 1, 1, -693, 356],
[2, 1, 1, -614, 354],
[2, 1, 1, -510, 354],
[2, 1, 1, -422, 354],
[2, 1, 1, -456, 287],
[2, 1, 1, -510, 199],
[2, 1, 1, -562, 139],
[2, 1, 1, -600, 82],
[2, 1, 1, -636, 38],
[2, 1, 1, -688, -17],
[2, 1, 1, -745, -92],
[2, 1, 1, -764, -152],
[2, 1, 1, -815, -216],
[2, 1, 1, -166, 341],
[2, 1, 1, -17, 343],
[2, 1, 1, 89, 343],
[2, 1, 1, 246, 331],
[2, 1, 1, 326, 348],
[2, 1, 1, -180, 310],
[2, 1, 1, -144, 209],
[2, 1, 1, -112, 151],
[2, 1, 1, -74, 55],
[2, 1, 1, -48, 0],
[2, 1, 1, 4, -91],
[2, 1, 1, 40, -153],
[2, 1, 1, 85, -201],
[2, 1, 1, 102, -247],
[3, 1, 1, 595, 319],
[3, 1, 1, 664, 322],
[3, 1, 1, 799, 318],
[3, 1, 1, 968, 319],
[3, 1, 1, 963, 107],
[3, 1, 1, 955, -21],
[3, 1, 1, 948, -157],
[3, 1, 1, 940, -231],
[3, 1, 1, 795, -245],
[3, 1, 1, 685, -248],
[3, 1, 1, 610, -252],
[3, 1, 1, 523, -253],
[3, 1, 1, 172, 128],
[3, 1, 1, -357, 30],
[3, 1, 1, 582, 23],
],
[
[5, 1, 1, -888, 405],
[5, 1, 1, -806, 410],
[5, 1, 1, -718, 404],
[5, 1, 1, -658, 406],
[5, 1, 1, -661, 286],
[5, 1, 1, -661, 224],
[5, 1, 1, -664, 142],
[5, 1, 1, -688, -2],
[5, 1, 1, -687, -69],
[5, 1, 1, -697, -120],
[5, 1, 1, -981, 410],
[5, 1, 1, -503, 150],
[5, 1, 1, -432, 146],
[5, 1, 1, -362, 149],
[5, 1, 1, -259, 148],
[5, 1, 1, -192, 149],
[5, 1, 1, -341, 359],
[5, 1, 1, -353, 256],
[5, 1, 1, -354, 203],
[5, 1, 1, -361, 72],
[5, 1, 1, -371, -23],
[5, 1, 1, -387, -79],
[5, 1, 1, 18, 277],
[5, 1, 1, 7, 159],
[5, 1, 1, -7, 94],
[5, 1, 1, -19, -3],
[5, 1, 1, -27, -80],
[5, 1, 1, 177, 164],
[5, 1, 1, 248, 172],
[5, 1, 1, 355, 170],
[5, 1, 1, 153, 29],
[5, 1, 1, 230, 30],
[5, 1, 1, 327, 32],
[6, 1, 1, 548, 371],
[6, 1, 1, 682, 374],
[6, 1, 1, 833, 373],
[6, 1, 1, 942, 374],
[6, 1, 1, 935, 289],
[6, 1, 1, 924, 143],
[6, 1, 1, 903, 65],
[6, 1, 1, 887, -44],
[6, 1, 1, 857, -157],
[6, 1, 1, 526, 109],
[6, 1, 1, 612, 108],
[6, 1, 1, 761, 94],
[6, 1, 1, 710, 260],
[6, 1, 1, 673, 177],
[6, 1, 1, 661, 10],
[6, 1, 1, 634, -61],
[6, 1, 1, 617, -138],
[7, 1, 1, 340, -259],
[7, 1, 1, 485, -254],
[7, 1, 1, 622, -254],
[7, 1, 1, 816, -251],
],
[
[9, 1, 1, -513, 150],
[9, 1, 1, -636, 237],
[9, 1, 1, -811, 250],
[9, 1, 1, -860, 145],
[9, 1, 1, -850, -54],
[9, 1, 1, -801, -154],
[9, 1, 1, -673, -268],
[9, 1, 1, -498, -294],
[9, 1, 1, -358, -223],
[9, 1, 1, -207, -127],
[9, 1, 1, -72, 15],
[9, 1, 1, -88, 196],
[9, 1, 1, -240, 285],
[9, 1, 1, -334, 185],
[9, 1, 1, 466, 151],
[9, 1, 1, 310, 202],
[9, 1, 1, 213, 246],
[9, 1, 1, 106, 83],
[9, 1, 1, 141, -54],
[9, 1, 1, 241, -252],
[9, 1, 1, 388, -285],
[9, 1, 1, 605, -295],
[9, 1, 1, 771, -226],
[9, 1, 1, 846, -125],
[9, 1, 1, 893, 51],
[9, 1, 1, 865, 195],
[9, 1, 1, 665, 207],
[17, 1, 1, -461, 2],
[17, 1, 1, 515, -49],
],
[
[19, 1, 1, -785, 31],
[19, 1, 1, 905, 16],
[20, 1, 1, -242, 34],
[20, 1, 1, 228, 12],
[20, 1, 1, -30, 303],
[20, 1, 1, -109, -292],
[20, 1, 1, 425, -301],
[20, 1, 1, 537, 265],
[20, 1, 1, -604, 317],
[20, 1, 1, -634, -285],
],
[
[21, 1, 1, -757, 94],
[21, 1, 1, 646, 55],
[21, 1, 1, -41, 376],
[21, 1, 1, -102, -315],
[21, 1, 1, -76, 83],
[21, 1, 1, -437, 300],
[21, 1, 1, -434, -155],
[21, 1, 1, 314, -154],
[21, 1, 1, 435, 249],
],
[
[22, 1, 1, -548, 65],
[22, 1, 1, 747, 61],
[22, 1, 1, 95, 63],
],
[
[23, 1, 1, -431, 384],
[23, 1, 1, -766, 89],
[23, 1, 1, -415, -232],
[23, 1, 1, -72, 135],
[23, 1, 1, 721, 414],
[23, 1, 1, 328, 77],
[23, 1, 1, 1025, 60],
[23, 1, 1, 677, -247],
[23, 1, 1, 104, 390],
[23, 1, 1, 84, -265],
],
[
[24, 1, 1, -429, 353],
[24, 1, 1, 241, 323],
[24, 1, 1, -472, 46],
[24, 1, 1, -27, 35],
[24, 1, 1, 563, 39],
[24, 1, 1, -268, -245],
[24, 1, 1, 172, -260],
],
[
[25, 1, 1, -595, 276],
[25, 1, 1, 115, 291],
[25, 1, 1, -192, -64],
[25, 1, 1, 464, -46],
[25, 1, 1, 191, -280],
[25, 1, 1, 884, -319],
],
[
[26, 1, 1, -681, 441],
[26, 1, 1, 685, 426],
[26, 1, 1, -46, 140],
[26, 1, 1, -494, -207],
[26, 1, 1, 497, -238],
],
[
[27, 1, 1, -431, 345],
[27, 1, 1, 569, 311],
[27, 1, 1, 112, -12],
[27, 1, 1, -298, -271],
[27, 1, 1, 678, -244],
],
[
[28, 1, 1, -454, 8],
[28, 1, 1, 597, 1],
[28, 1, 1, 46, 431],
[28, 1, 1, 44, -227],
],
[
[2, 1, 1, -557, 409],
[2, 1, 1, -648, 382],
[2, 1, 1, -732, 338],
[2, 1, 1, -809, 236],
[2, 1, 1, -861, 157],
[2, 1, 1, -865, 18],
[2, 1, 1, -835, -37],
[2, 1, 1, -787, -86],
[2, 1, 1, -746, -115],
[2, 1, 1, -683, -181],
[2, 1, 1, -575, -206],
[2, 1, 1, -494, -204],
[2, 1, 1, -442, -157],
[2, 1, 1, -403, -111],
[2, 1, 1, -387, 11],
[2, 1, 1, -356, 94],
[2, 1, 1, -472, 330],
[2, 1, 1, -407, 260],
[2, 1, 1, -395, 195],
[2, 1, 1, -214, 51],
[2, 1, 1, -139, 52],
[2, 1, 1, -77, 51],
[2, 1, 1, -21, 51],
[2, 1, 1, 67, 50],
[2, 1, 1, 107, 50],
[2, 1, 1, -40, 332],
[2, 1, 1, -43, 207],
[2, 1, 1, -60, 154],
[2, 1, 1, -60, 5],
[2, 1, 1, -82, -71],
[2, 1, 1, -77, -195],
[5, 1, 1, 427, 311],
[5, 1, 1, 578, 314],
[5, 1, 1, 779, 315],
[5, 1, 1, 862, 315],
[5, 1, 1, 884, 123],
[5, 1, 1, 879, -108],
[5, 1, 1, 778, -183],
[5, 1, 1, 672, -181],
[5, 1, 1, 564, -179],
[5, 1, 1, 407, -178],
[5, 1, 1, 297, 8],
[5, 1, 1, 625, 48],
[5, 1, 1, 379, 92],
],
]
private static formatMapConfig: Array<FishMap> = []
private static config: Array<Array<Array<number>>> = [
// 左边开始
[
[-1309, 528],
[-1144, 438],
[-1081, 411],
[-947, 327],
[-801, 241],
[-683, 154],
[-539, 69],
[-394, -23],
[-230, -115],
[-115, -207],
[45, -280],
[247, -364],
[497, -457],
[627, -511],
[762, -578],
[885, -667],
[1068, -773],
],
[
[-1295, 534],
[-1144, 438],
[-1081, 411],
[-906, 326],
[-696, 274],
[-462, 223],
[-213, 198],
[-1, 172],
[156, 178],
[396, 194],
[576, 216],
[753, 233],
[936, 279],
[1182, 350],
[1314, 418],
],
[
[-1295, 534],
[-1144, 438],
[-1081, 411],
[-906, 326],
[-696, 274],
[-462, 223],
[-213, 198],
[-1, 172],
[199, 150],
[417, 111],
[635, 10],
[827, -42],
[1020, -131],
[1189, -170],
[1309, -198],
],
[
[-1295, 534],
[-1111, 514],
[-1015, 454],
[-864, 403],
[-671, 387],
[-450, 354],
[-219, 311],
[11, 274],
[213, 270],
[471, 212],
[642, 172],
[835, 88],
[1013, -2],
[1212, -99],
[1309, -198],
],
[
[-1275, -118],
[-1129, -19],
[-1024, 42],
[-858, 129],
[-677, 225],
[-448, 277],
[-219, 311],
[11, 274],
[213, 270],
[510, 320],
[596, 350],
[772, 391],
[887, 426],
[1066, 513],
[1164, 710],
],
[
[-1299, -618],
[-1143, -521],
[-1033, -496],
[-726, -425],
[-489, -360],
[-245, -293],
[-8, -210],
[212, -134],
[385, -65],
[552, 7],
[705, 96],
[904, 176],
[1090, 273],
[1208, 355],
[1308, 435],
],
[
[-1275, -118],
[-1060, -69],
[-938, -85],
[-729, -59],
[-551, -48],
[-397, -2],
[-203, -1],
[46, 61],
[228, 105],
[506, 159],
[630, 208],
[784, 266],
[935, 228],
[1157, 174],
[1329, 163],
],
[
[-1288, -220],
[-1113, -194],
[-945, -195],
[-709, -162],
[-502, -200],
[-313, -211],
[-144, -186],
[128, -135],
[314, 14],
[571, 56],
[727, 132],
[851, 203],
[1050, 141],
[1255, 58],
[1326, 20],
],
[
[-1288, -220],
[-1113, -194],
[-945, -195],
[-709, -162],
[-502, -200],
[-313, -211],
[-144, -186],
[132, -144],
[406, -196],
[644, -272],
[884, -272],
[993, -283],
[1090, -319],
[1242, -341],
[1329, -396],
],
[
[-1288, -220],
[-1113, -194],
[-916, -213],
[-710, -238],
[-501, -273],
[-297, -289],
[-101, -312],
[173, -324],
[419, -339],
[653, -362],
[889, -390],
[1011, -407],
[1095, -418],
[1238, -539],
[1317, -663],
],
[
[-1314, -508],
[-1123, -480],
[-917, -443],
[-708, -379],
[-514, -361],
[-300, -319],
[-101, -307],
[155, -256],
[398, -248],
[645, -219],
[787, -178],
[980, -165],
[1086, -103],
[1093, 280],
[1026, 371],
[868, 631],
[648, 787],
],
[
[-1314, -508],
[-1130, -281],
[-898, -160],
[-693, -141],
[-561, -91],
[-384, -43],
[-187, 48],
[119, 32],
[298, -95],
[519, -135],
[744, -156],
[868, -97],
[1033, 55],
[1093, 280],
[1026, 371],
[868, 631],
[648, 787],
],
[
[-1314, -508],
[-1130, -281],
[-898, -160],
[-693, -141],
[-561, -91],
[-384, -43],
[-187, 48],
[119, 32],
[298, -95],
[519, -135],
[744, -156],
[872, -200],
[1060, -391],
[1150, -492],
[1301, -461],
],
//右边开始
[
[1286, -293],
[1149, -184],
[952, -147],
[795, -130],
[536, -45],
[476, 57],
[467, 300],
[408, 500],
[405, 701],
],
[
[1345, 34],
[1189, -69],
[978, -94],
[820, -115],
[443, -66],
[267, -29],
[66, -79],
[-219, -287],
[-271, -693],
],
[
[1345, 34],
[1189, -69],
[978, -94],
[820, -115],
[443, -66],
[267, -29],
[66, -79],
[-215, -156],
[-444, -100],
[-725, -92],
[-963, -68],
[-1169, -46],
[-1325, -40],
],
[
[1345, 34],
[1189, -69],
[978, -94],
[820, -115],
[443, -66],
[267, -29],
[66, -79],
[-215, -156],
[-454, -156],
[-719, -199],
[-981, -264],
[-1180, -291],
[-1320, -367],
],
[
[1345, 34],
[1189, -69],
[978, -94],
[820, -115],
[413, -128],
[258, -147],
[60, -161],
[-254, -250],
[-493, -278],
[-707, -320],
[-961, -408],
[-1160, -449],
[-1309, -524],
],
[
[1345, 34],
[1189, -69],
[978, -94],
[820, -115],
[439, -173],
[267, -185],
[109, -251],
[-211, -307],
[-428, -408],
[-596, -448],
[-847, -604],
[-1019, -589],
[-1241, -695],
],
[
[1345, 34],
[1189, -69],
[951, -68],
[512, -86],
[159, -142],
[-56, -144],
[-362, -160],
[-569, -143],
[-772, -35],
[-898, 66],
[-1070, 219],
[-1181, 292],
[-1289, 558],
],
[
[1345, 34],
[1189, -69],
[951, -68],
[512, -86],
[159, -142],
[-56, -144],
[-310, -118],
[-530, -84],
[-654, -2],
[-806, 84],
[-905, 246],
[-1008, 375],
[-1021, 750],
],
[
[1297, 542],
[1181, 330],
[1041, 250],
[676, 110],
[429, -12],
[5, -105],
[-310, -118],
[-530, -84],
[-654, -2],
[-806, 84],
[-905, 246],
[-1008, 375],
[-1021, 750],
],
[
[1297, 542],
[1181, 330],
[1041, 250],
[676, 110],
[429, -12],
[7, -105],
[-310, -118],
[-530, -84],
[-655, -18],
[-806, 84],
[-927, 189],
[-1073, 291],
[-1318, 474],
],
[
[1297, 542],
[1181, 330],
[1041, 250],
[676, 110],
[429, -12],
[7, -105],
[-310, -118],
[-530, -84],
[-631, -85],
[-775, -77],
[-923, -28],
[-1133, -46],
[-1294, -10],
],
[
[1297, 542],
[1181, 330],
[1041, 250],
[676, 110],
[429, -12],
[243, -126],
[-141, -203],
[-340, -201],
[-500, -218],
[-616, -254],
[-854, -240],
[-1115, -272],
[-1312, -336],
],
[
[1297, 542],
[1181, 330],
[1041, 250],
[676, 110],
[429, -12],
[243, -126],
[-141, -203],
[-307, -229],
[-398, -281],
[-562, -321],
[-647, -446],
[-930, -540],
[-1073, -726],
],
[
[1293, -558],
[1192, -467],
[1069, -395],
[948, -305],
[733, -245],
[243, -126],
[-141, -203],
[-307, -229],
[-398, -281],
[-562, -321],
[-647, -446],
[-930, -540],
[-1073, -726],
],
[
[1293, -558],
[1192, -467],
[1069, -395],
[948, -305],
[733, -245],
[243, -126],
[-141, -203],
[-307, -229],
[-398, -281],
[-568, -262],
[-857, -301],
[-1055, -406],
[-1353, -380],
],
[
[1293, -558],
[1192, -467],
[1069, -395],
[948, -305],
[733, -245],
[243, -126],
[-141, -203],
[-307, -229],
[-426, -197],
[-590, -195],
[-905, -120],
[-1100, -72],
[-1300, 225],
],
[
[1293, -558],
[1192, -467],
[1069, -395],
[948, -305],
[733, -245],
[243, -126],
[-141, -203],
[-307, -229],
[-497, -179],
[-633, -130],
[-917, 33],
[-1079, 184],
[-1220, 412],
],
[
[1293, -558],
[1192, -467],
[1069, -395],
[948, -305],
[733, -245],
[243, -126],
[-141, -203],
[-307, -229],
[-461, -55],
[-602, -25],
[-857, 181],
[-921, 416],
[-909, 805],
],
//下往上
[
[-279, -786],
[-92, -667],
[45, -582],
[618, -388],
[436, -239],
[176, -173],
[-141, -203],
[-307, -229],
[-461, -55],
[-602, -25],
[-857, 181],
[-921, 416],
[-909, 805],
],
[
[-279, -786],
[-92, -667],
[45, -582],
[618, -388],
[436, -239],
[176, -173],
[126, -95],
[-26, -92],
[-157, 40],
[-362, 152],
[-543, 358],
[-721, 502],
[-401, 770],
],
[
[-279, -786],
[-78, -718],
[133, -652],
[618, -388],
[436, -239],
[392, -130],
[254, -77],
[194, -49],
[79, 44],
[60, 214],
[-85, 418],
[-140, 630],
[-401, 770],
],
[
[-279, -786],
[-78, -718],
[133, -652],
[618, -388],
[459, -232],
[392, -130],
[304, -80],
[267, -2],
[222, 130],
[253, 319],
[330, 465],
[544, 684],
[858, 803],
],
[
[841, -837],
[683, -745],
[672, -600],
[618, -388],
[459, -232],
[392, -130],
[304, -80],
[267, -2],
[222, 130],
[253, 319],
[330, 465],
[544, 684],
[858, 803],
],
]
private static formatConfig: Array<FishPathInfo> = []
public static init() {
this.initNormalConfig()
this.initMapConfig()
}
private static initMapConfig() {
this.formatMapConfig = []
for (let i = 0; i < this.mapConfig.length; i++) {
let arr: Array<Array<number>> = this.mapConfig[i]
let fishMapInfoList: Array<FishMapInfo> = []
for (let j = 0; j < arr.length; j++) {
let temp: Array<number> = arr[j]
let fishMapInfo: FishMapInfo = new FishMapInfo(
temp[0],
temp[1],
temp[2],
temp[3],
temp[4]
)
fishMapInfoList.push(fishMapInfo)
}
let fishMap: FishMap = new FishMap(i, fishMapInfoList)
this.formatMapConfig.push(fishMap)
}
}
public static randomFishMap() {
let randomIndex: number = RandomUtil.nextInt(
0,
this.formatMapConfig.length - 1
)
let map: FishMap = this.formatMapConfig[randomIndex]
return map
}
private static initNormalConfig() {
this.formatConfig = []
let pathId: number = 1
for (let i = 0; i < this.config.length; i++) {
let path: Array<Vec2> = []
let flipXPath: Array<Vec2> = []
let flipYPath: Array<Vec2> = []
for (let j = 0; j < this.config[i].length; j++) {
let p: Vec2 = new Vec2(this.config[i][j][0], this.config[i][j][1])
path.push(p)
let flipXP: Vec2 = new Vec2(-p.x, p.y)
let flipYP: Vec2 = new Vec2(p.x, -p.y)
flipXPath.push(flipXP)
flipYPath.push(flipYP)
}
this.formatConfig.push(new FishPathInfo(pathId++, path))
this.formatConfig.push(new FishPathInfo(pathId++, flipXPath))
this.formatConfig.push(new FishPathInfo(pathId++, flipYPath))
}
}
public static getPathInfo(pathId: number) {
for (let i = 0; i < this.formatConfig.length; i++) {
let pathInfo: FishPathInfo = this.formatConfig[i]
if (pathInfo.pathId == pathId) {
return pathInfo
}
}
}
public static randomPathInfo() {
let randomIndex: number = RandomUtil.nextInt(
0,
this.formatConfig.length - 1
)
// let randomIndex: number = 0
let pathInfo: FishPathInfo = this.formatConfig[randomIndex]
return pathInfo
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "704e17b3-0f7b-478a-8ad1-1cb2f5d89a8f",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,9 @@
import { _decorator, Vec2 } from 'cc'
export class FishPathInfo {
public pathId: number
public path: Array<Vec2> = []
constructor(pathId: number, path: Array<Vec2>) {
this.pathId = pathId
this.path = path
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "01cc78a7-9862-45b4-ad09-ebb92c01de58",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,4 @@
import { _decorator } from 'cc'
export class GameConfig {
public static GameName: string = 'FishSingle'
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8b274344-0b4c-4ac5-a289-2f8cd7a5596b",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,2 @@
import { _decorator } from 'cc'
export default class GameEvent {}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "71a46444-1a80-435f-b02e-0fe6acf71155",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "1e8eeb35-adbc-485b-879b-bf95de554cfd",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,160 @@
import {
_decorator,
Component,
Prefab,
NodePool,
Event,
Node,
Vec3,
Vec2,
EventTouch,
UITransform,
instantiate,
sys,
error,
} from 'cc'
const { ccclass, property } = _decorator
import { Logger } from '../../engine/utils/Logger'
import FishBulletBase from '../../../fish/script/FishBulletBase'
import MathUtils from '../../engine/utils/MathUtils'
import CannonManager from './CannonManager'
import { MoveHelper } from '../../engine/utils/MoveHelper'
import FishNetManager from './FishNetManager'
import GameMusicHelper from '../utils/GameMusicHelper'
import FishUI from '../../../fish/script/FishUI'
import CommonTips from '../../engine/uicomponent/CommonTips'
@ccclass('BulletManager')
export default class BulletManager extends Component {
public static instance: BulletManager = null
@property({ type: [Prefab] })
private bulletPrefabList: Prefab[] = []
private bulletPool: Array<NodePool> = []
private bulletList: Array<FishBulletBase> = []
private bulletMoveSpeed: number = 30
private _vec3Cache
private _vec2Cache
private _fireTime: number = 0
private _fireTimeNew: number
onLoad() {
this._vec3Cache = new Vec3()
this._vec2Cache = new Vec2()
BulletManager.instance = this
this.node.on(Node.EventType.TOUCH_START, this.onShootBullet, this)
// this.node.on(Node.EventType.TOUCH_MOVE, this.onShootBullet, this)
}
start() {}
update() {
this.checkMoveBullet()
}
private checkMoveBullet() {
for (let i = this.bulletList.length - 1; i >= 0; i--) {
let bullet: FishBulletBase = this.bulletList[i]
let isMoving: boolean = MoveHelper.moveNode(
bullet.node,
this.bulletMoveSpeed,
bullet.targetP.x,
bullet.targetP.y
)
if (!isMoving) {
bullet.node.getPosition(this._vec3Cache)
this._vec2Cache.x = this._vec3Cache.x
this._vec2Cache.y = this._vec3Cache.y
FishNetManager.instance.addFishNet(bullet.bulletType, this._vec2Cache)
this.bulletList.splice(i, 1)
this.destroyBullet(bullet)
}
}
}
private onShootBullet(event: EventTouch) {
//TOUCH_START 在Editor上连续触发2次导致发2次炮弹bug
if (sys.platform == 'EDITOR_PAGE') {
this._fireTimeNew = new Date().getTime()
if (this._fireTimeNew - this._fireTime < 100) {
return
}
this._fireTime = this._fireTimeNew
}
let tran = this.node.getComponent(UITransform)
let location = event.getUILocation()
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
let localP: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
FishUI.instance.playClickEffect(localP)
// 子弹发射
if (FishUI.instance.dz_score >= CannonManager.instance.cannonType) {
FishUI.instance.dz_score -= CannonManager.instance.cannonType
FishUI.instance.refreshScore()
this._vec3Cache = CannonManager.instance.getCannonPosition()
let rad: number = MathUtils.p2pRad(
new Vec2(this._vec3Cache.x, this._vec3Cache.y),
localP
)
let rot: number = MathUtils.radiansToDegrees(rad)
let bullet: FishBulletBase = this.createBullet(
CannonManager.instance.cannonType - 1
)
bullet.targetP = localP
this.node.addChild(bullet.node)
bullet.node.setPosition(CannonManager.instance.getCannonPosition())
this._vec3Cache.x = 1
this._vec3Cache.y = 1
this._vec3Cache.y = 1
Vec3.multiplyScalar(this._vec3Cache, this._vec3Cache, 2)
bullet.node.setScale(this._vec3Cache)
bullet.node.angle = rot
this.bulletList.push(bullet)
GameMusicHelper.playFire()
//旋转炮台
CannonManager.instance.rotateCannon(location)
} else {
CommonTips.showMsg('豆子不足!')
}
}
private createBullet(bulletType: number) {
let bulletNode: Node
if (this.bulletPool[bulletType] && this.bulletPool[bulletType].size() > 0) {
bulletNode = this.bulletPool[bulletType].get()
} else {
bulletNode = instantiate(this.bulletPrefabList[bulletType])
}
bulletNode.getComponent(FishBulletBase).bulletType = bulletType
return bulletNode.getComponent(FishBulletBase)
}
public killBullet(bullet: FishBulletBase) {
let index: number = this.bulletList.indexOf(bullet)
if (index >= 0) {
this.bulletList.splice(index, 1)
this.destroyBullet(bullet)
}
}
private destroyBullet(bullet: FishBulletBase) {
//临时代码,因为回收在内存卡顿。后面在优化 2023-2-10
if (sys.platform == 'EDITOR_PAGE') {
bullet.node.destroy()
return
}
if (!this.bulletPool[bullet.bulletType]) {
this.bulletPool[bullet.bulletType] = new NodePool()
}
this.bulletPool[bullet.bulletType].put(bullet.node)
}
onDestroy() {
BulletManager.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "bd065d0b-0b60-4981-aea0-75d2f209b7ea",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,66 @@
import {
_decorator,
Component,
Node,
SpriteFrame,
Event,
EventMouse,
Sprite,
Vec2,
UITransform,
Vec3,
} from 'cc'
const { ccclass, property } = _decorator
import MathUtils from '../../engine/utils/MathUtils'
@ccclass('CannonManager')
export default class CannonManager extends Component {
public static instance: CannonManager = null
@property({ type: Node })
private view: Node | null = null
@property({ type: [SpriteFrame] })
private cannonSpriteFrame: Array<SpriteFrame> = []
// 炮塔倍数
public cannonType: number = 1
private _vec3Cache
onLoad() {
this._vec3Cache = new Vec3()
CannonManager.instance = this
this.node.parent.on(Node.EventType.MOUSE_MOVE, this.onMeMove.bind(this))
this.refreshCannon()
}
private onMeMove(event: EventMouse) {
this.rotateCannon(event.getUILocation())
}
public rotateCannon(uilocation: Vec2) {
let location = uilocation
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
let tran = this.node.getComponent(UITransform)
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
let localTouch: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
this.view.getPosition(this._vec3Cache)
let rad: number = MathUtils.p2pRad(
new Vec2(this._vec3Cache.x, this._vec3Cache.y),
localTouch
)
let rot: number = MathUtils.radiansToDegrees(rad)
this.view.angle = rot - 90
}
public refreshCannon() {
this.view.getComponent(Sprite).spriteFrame =
this.cannonSpriteFrame[this.cannonType - 1]
}
public getCannonPosition() {
return this.view.getPosition()
}
onDestroy() {
CannonManager.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d03d3fa0-9f23-4106-be05-9d106bd8f8c8",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,222 @@
import {
_decorator,
Component,
Node,
Prefab,
NodePool,
game,
Vec3,
sys,
instantiate,
Animation,
Vec2,
} from 'cc'
const { ccclass, property } = _decorator
import RandomUtil from '../../engine/utils/RandomUtil'
import FishBase from '../../../fish/script/FishBase'
import { FishPathInfo } from '../config/FishPathInfo'
import { FishPathConfig } from '../config/FishPathConfig'
import FishMover from '../../../fish/script/FishMover'
import { Logger } from '../../engine/utils/Logger'
import { FishInfo } from '../config/FishInfo'
import { FishConfig } from '../config/FishConfig'
import GameMusicHelper from '../utils/GameMusicHelper'
import ScoreManager from './ScoreManager'
import { FishMap } from '../config/FishMap'
import { FishMapInfo } from '../config/FishMapInfo'
import FishUI from '../../../fish/script/FishUI'
import TimeHelper from '../utils/TimeHelper'
@ccclass('FishManager')
export default class FishManager extends Component {
public static instance: FishManager = null
@property({ type: Node })
private fishContainer: Node | null = null
@property({ type: [Prefab] })
public fishPrefabList: Array<Prefab> = []
private fishPool: Array<NodePool> = []
private fishList: Array<FishBase> = []
private nextRandomFishTime: number = 0
private minRandomTime: number = 2 * (game.frameRate as number)
private maxRandomTime: number = 5 * (game.frameRate as number)
private isFishMap: boolean = false
private mapCount: number = 0
private minMapCount: number = 30 * (game.frameRate as number)
private maxMapCount: number = 60 * (game.frameRate as number)
// // private minMapCount: number = 2 * cc.game.getFrameRate();
// // private maxMapCount: number = 5 * cc.game.getFrameRate();
private _fishPosCache
onLoad() {
FishManager.instance = this
this._fishPosCache = new Vec3()
Logger.log(
'maxRandomTime=',
this.minRandomTime,
this.maxRandomTime,
game.frameRate
)
}
start() {
this.randomFish()
}
update() {
this.checkRandomFish()
this.checkFishMoveEnd()
this.checkFishMap()
}
private checkFishMap() {
if (!this.isFishMap) {
if (this.mapCount > 0) {
this.mapCount--
if (this.mapCount <= 0) {
FishUI.instance.playWaveEffect()
}
}
}
}
private checkRandomFish() {
if (!this.isFishMap) {
if (this.nextRandomFishTime > 0) {
this.nextRandomFishTime--
if (this.nextRandomFishTime == 0) {
this.randomFish()
}
}
}
}
private checkFishMoveEnd() {
for (let i = this.fishList.length - 1; i >= 0; i--) {
let fish: FishBase = this.fishList[i]
if (this.isFishMap) {
if (!fish.isDead) {
fish.node.getPosition(this._fishPosCache)
this._fishPosCache.x -= 2
fish.node.setPosition(this._fishPosCache)
if (this._fishPosCache.x <= -screen.width / 2) {
//winSize.width
this.destroyFish(fish)
this.fishList.splice(i, 1)
this.checkEndFishMap()
}
}
} else if (!fish.getComponent(FishMover).isMoving) {
this.destroyFish(fish)
this.fishList.splice(i, 1)
}
}
}
private checkEndFishMap() {
Logger.log('checkEndFishMap==', this.isFishMap, this.fishList)
if (this.isFishMap && this.fishList.length <= 0) {
this.isFishMap = false
this.randomFish()
}
}
private randomFish() {
if (this.isFishMap) return
let randomNum: number = RandomUtil.nextInt(1, 10)
// let randomNum: number = RandomUtil.nextInt(1, 1);
for (let i = 0; i < randomNum; i++) {
let fishType: number = RandomUtil.nextInt(1, 29)
// let fishType: number = RandomUtil.nextInt(1, 1);
let fish: FishBase = this.createFishByType(fishType)
fish.fishPathInfo = FishPathConfig.randomPathInfo()
this._fishPosCache.z = 0
this._fishPosCache.x = fish.fishPathInfo.path[0].x
this._fishPosCache.y = fish.fishPathInfo.path[0].y
fish.node.setPosition(this._fishPosCache)
fish.getComponent(FishMover).bezierPList = fish.fishPathInfo.path
fish.getComponent(FishMover).startMove()
this.fishList.push(fish)
this.fishContainer.addChild(fish.node)
}
Logger.log('checkFishMoveEnd=randomFish=', this.fishList)
this.nextRandomFishTime = RandomUtil.nextInt(
this.minRandomTime,
this.maxRandomTime
)
if (this.mapCount <= 0) {
this.mapCount = RandomUtil.nextInt(this.minMapCount, this.maxMapCount)
}
}
public createFishByType(fishType: number): FishBase {
let fishNode: Node
if (this.fishPool[fishType - 1] && this.fishPool[fishType - 1].size() > 0) {
fishNode = this.fishPool[fishType - 1].get()
} else {
fishNode = instantiate(this.fishPrefabList[fishType - 1])
}
//fishNode.getComponent(Animation).play() //v3 当前帧 不能播放
TimeHelper.exeNextFrame(fishNode, () =>
fishNode.getComponent(Animation).play()
)
let fishInfo: FishInfo = FishConfig.getFishInfoByType(fishType)
fishNode.getComponent(FishBase).fishInfo = fishInfo
fishNode.getComponent(FishBase).fishType = fishType
fishNode.getComponent(FishBase).blood = fishInfo.blood
fishNode.getComponent(FishBase).isDead = false
return fishNode.getComponent(FishBase)
}
public killFish(fish: FishBase) {
let index: number = this.fishList.indexOf(fish)
if (index >= 0) {
// console.log("鱼挂了")
GameMusicHelper.playFishDead(fish.fishType)
fish.node.getPosition(this._fishPosCache)
let vec2 = new Vec2(this._fishPosCache.x, this._fishPosCache.y)
ScoreManager.instance.addScore(fish.fishInfo.blood, vec2)
this.fishList.splice(index, 1)
this.destroyFish(fish)
this.checkEndFishMap()
}
}
private destroyFish(fish: FishBase) {
if (!this.fishPool[fish.fishType - 1]) {
this.fishPool[fish.fishType - 1] = new NodePool()
}
this.fishPool[fish.fishType - 1].put(fish.node)
}
public playFishMap() {
this.isFishMap = true
for (let i = this.fishList.length - 1; i >= 0; i--) {
let fish: FishBase = this.fishList[i]
this.destroyFish(fish)
this.fishList.splice(i, 1)
}
}
public startFishMap() {
// this.playFishMap();
// this.fishList = [];
let map: FishMap = FishPathConfig.randomFishMap()
let fishMapInfoList: Array<FishMapInfo> = map.fishMapInfoList
Logger.log('startFishMap==', this.isFishMap, this.fishList, map)
for (let i = 0; i < fishMapInfoList.length; i++) {
let fishMapInfo: FishMapInfo = fishMapInfoList[i]
let fish: FishBase = this.createFishByType(fishMapInfo.fishType)
fish.node.angle = 0
// fish.node.setScale(fishMapInfo.scale);
this.fishContainer.addChild(fish.node)
fish.node.setPosition(fishMapInfo.x + screen.width, fishMapInfo.y)
this.fishList.push(fish)
}
}
onDestroy() {
FishManager.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b20609a9-5a1b-4119-9fb1-399b45155aab",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,53 @@
import {
_decorator,
Component,
Prefab,
NodePool,
Vec2,
instantiate,
Vec3,
Node,
} from 'cc'
const { ccclass, property } = _decorator
import FishNetBase from '../../../fish/script/FishNetBase'
@ccclass('FishNetManager')
export default class FishNetManager extends Component {
public static instance: FishNetManager = null
@property({ type: [Prefab] })
private netPrefabList: Prefab[] = []
private fishNetPool: Array<NodePool> = []
onLoad() {
FishNetManager.instance = this
}
public addFishNet(netType: number, p: Vec2) {
let fishNet: FishNetBase = this.createFishNet(netType)
this.node.addChild(fishNet.node)
fishNet.node.setPosition(new Vec3(p.x, p.y, 0))
fishNet.playMv()
}
private createFishNet(netType: number) {
let fishNetNode: Node
if (this.fishNetPool[netType] && this.fishNetPool[netType].size() > 0) {
fishNetNode = this.fishNetPool[netType].get()
} else {
fishNetNode = instantiate(this.netPrefabList[netType])
}
fishNetNode.getComponent(FishNetBase).netType = netType
return fishNetNode.getComponent(FishNetBase)
}
public destroyFishNet(fishNet: FishNetBase) {
if (!this.fishNetPool[fishNet.netType]) {
this.fishNetPool[fishNet.netType] = new NodePool()
}
this.fishNetPool[fishNet.netType].put(fishNet.node)
}
onDestroy() {
FishNetManager.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fec491b0-4f6f-4a17-928d-a4ee3c2bb567",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,57 @@
import {
_decorator,
Component,
Prefab,
NodePool,
Vec2,
instantiate,
Node,
Vec3,
} from 'cc'
const { ccclass, property } = _decorator
import ScorePrefab from '../prefab/ScorePrefab'
import FishUI from '../../../fish/script/FishUI'
@ccclass('ScoreManager')
export default class ScoreManager extends Component {
public static instance: ScoreManager = null
@property({ type: Prefab })
private scrorePrefab: Prefab | null = null
private scorePool: NodePool
onLoad() {
ScoreManager.instance = this
this.scorePool = new NodePool()
}
public addScore(score: number, p: Vec2) {
let scorePrefab: ScorePrefab = this.createScore(score)
this.node.addChild(scorePrefab.node)
scorePrefab.node.setPosition(new Vec3(p.x, p.y, 0))
scorePrefab.init(score)
scorePrefab.playMoveEffect(new Vec2(-472.398, -547.481), () => {
this.destroyScore(scorePrefab)
FishUI.instance.jf_score += score
FishUI.instance.refreshScore()
})
}
private createScore(score: number): ScorePrefab {
let scoreNode: Node
if (this.scorePool && this.scorePool.size() > 0) {
scoreNode = this.scorePool.get()
} else {
scoreNode = instantiate(this.scrorePrefab)
}
return scoreNode.getComponent(ScorePrefab)
}
private destroyScore(scorePrefab: ScorePrefab) {
this.scorePool.put(scorePrefab.node)
}
onDisable() {}
onDestroy() {
ScoreManager.instance = null
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ff2defbe-9c85-4632-b16a-021567da1bdd",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "a52a8a98-fc73-4bb3-9081-157a181af0a9",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,34 @@
import { _decorator, Component, Prefab, Node, instantiate } from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../../engine/utils/PrefabLoader'
import { GameConfig } from '../config/GameConfig'
@ccclass('ResourcePrefab')
export default class ResourcePrefab extends Component {
private static prefab: Prefab | null = null
public static instance: Node
@property({ type: Prefab })
private scorePrefab: Prefab | null = null
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'game/prefab/ResourcePrefab',
(loadedResource: Prefab) => {
ResourcePrefab.prefab = loadedResource
ResourcePrefab.instance = instantiate(loadedResource)
resolve()
}
)
})
}
public static clear() {
ResourcePrefab.instance = null
ResourcePrefab.prefab = null
}
public static getScorePrefab() {
return ResourcePrefab.instance.getComponent(ResourcePrefab).scorePrefab
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e0c999fe-5635-4caa-8c3b-d16793848320",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,30 @@
import { _decorator, Component, Label, Vec2, tween, Vec3, Tween } from 'cc'
const { ccclass, property } = _decorator
@ccclass('ScorePrefab')
export default class ScorePrefab extends Component {
@property({ type: Label })
private txtScore: Label | null = null
public init(score: number) {
if (score <= 0) {
this.txtScore.string = 'Miss'
} else {
this.txtScore.string = score + ''
}
}
public playMoveEffect(p: Vec2, callback: Function = null) {
tween(this.node)
.to(0.5, { scale: new Vec3(3, 3, 3), position: new Vec3(p.x, p.y, 0) })
.call(() => {
if (callback) {
callback()
}
})
.start()
}
onDisable() {
Tween.stopAllByTarget(this.node)
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "465f63cc-b6fe-4ea9-9a10-79254fbe67cc",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -0,0 +1,41 @@
import { _decorator, Component, Node, Material, instantiate, Prefab } from 'cc'
const { ccclass, property } = _decorator
import PrefabLoader from '../../engine/utils/PrefabLoader'
import { GameConfig } from '../config/GameConfig'
@ccclass('ShaderMaterialPrefab')
export default class ShaderMaterialPrefab extends Component {
public static instance: Node
@property({ type: Material })
public default: Material | null = null
@property({ type: Material })
public grayMaterial: Material | null = null
@property({ type: Material })
public oldPhoto: Material | null = null
@property({ type: Material })
public glowInner: Material | null = null
@property({ type: Material })
public mosaic: Material | null = null
@property({ type: Material })
public roundCornerCrop: Material | null = null
@property({ type: Material })
public flashLight: Material | null = null
@property({ type: Material })
public flag: Material | null = null
@property({ type: Material })
public gaussian: Material | null = null
public static preLoad(): Promise<void> {
return new Promise((resolve, reject) => {
PrefabLoader.loadPrefab(
GameConfig.GameName + '/' + 'game/prefab/ShaderMaterialPrefab',
(loadedResource: Prefab) => {
ShaderMaterialPrefab.instance = instantiate(loadedResource)
resolve()
}
)
})
}
}

View File

@@ -0,0 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "7c56c670-6b06-4cf1-a606-7af6226a3cb6",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

Some files were not shown because too many files have changed in this diff Show More