Compare commits
No commits in common. "main" and "YiZiTing" have entirely different histories.
|
|
@ -0,0 +1,2 @@
|
|||
[InternetShortcut]
|
||||
URL=https://docs.cocos.com/creator/manual/en/scripting/setup.html#custom-script-template
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"image": {
|
||||
"type": "sprite-frame"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#///////////////////////////
|
||||
# Cocos Creator 3D Project
|
||||
#///////////////////////////
|
||||
library/
|
||||
temp/
|
||||
local/
|
||||
build/
|
||||
profiles/
|
||||
native
|
||||
assets/ImagePacks
|
||||
#//////////////////////////
|
||||
# NPM
|
||||
#//////////////////////////
|
||||
node_modules/
|
||||
|
||||
#//////////////////////////
|
||||
# VSCode
|
||||
#//////////////////////////
|
||||
.vscode/
|
||||
|
||||
#//////////////////////////
|
||||
# WebStorm
|
||||
#//////////////////////////
|
||||
.idea/
|
||||
assets/ImagePack/!幻想模拟战.NPK
|
||||
assets/ImagePack/!幻想模拟战.NPK.meta
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "5208f390-cc46-487e-ab55-1158ca41e9fe",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "822d6861-f210-4760-bd10-0fd9fc2cae86",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-11 12:16:36
|
||||
* @LastEditTime: 2024-03-26 15:40:23
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import { _decorator, Node } from 'cc';
|
||||
import { ScriptMyAnimation } from './ScriptMyAnimation';
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass('AnimationNode')
|
||||
export class AnimationNode extends Node{
|
||||
|
||||
constructor(AnimationPath: string,aniDone?:Function) {
|
||||
super();
|
||||
|
||||
let aniNode = new Node();
|
||||
let ani = aniNode.addComponent( ScriptMyAnimation)
|
||||
ani.AnimationPath = AnimationPath;
|
||||
ani.onAniDone = aniDone;
|
||||
|
||||
this.addChild(aniNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "158c563d-2556-4c10-a9e1-f0d9b62db198",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { _decorator, Component, Node, Animation, Sprite, resources, SpriteFrame, CCString, CCInteger, Vec2 } from 'cc';
|
||||
import { MyAnimation } from './MyAnimation';
|
||||
|
||||
const { ccclass, property, requireComponent, executeInEditMode } = _decorator;
|
||||
|
||||
@ccclass('BaseMyAnimation')
|
||||
@requireComponent(Sprite)//依赖组件 精灵
|
||||
export default class BaseMyAnimation extends MyAnimation {
|
||||
|
||||
@property({ type: CCInteger, displayName: 'Ani帧数', tooltip: "Ani总共有多少帧" })
|
||||
AnimationFrameCount: number = 0;
|
||||
NowSettingCount = 0;
|
||||
|
||||
@property({ type: CCString, displayName: '默认img路径', tooltip: "img路径" })
|
||||
DefaultImgPath = "";
|
||||
|
||||
@property({ type: [CCString], displayName: 'img路径', tooltip: "img路径" })
|
||||
ImgPath: string[] = Array<string>();
|
||||
|
||||
@property({ type: [CCInteger], displayName: 'img编号', tooltip: "img编号" })
|
||||
ImgIndex: number[] = Array<number>();
|
||||
|
||||
@property({ type: [CCInteger], displayName: '每帧时间', tooltip: "每一帧的持续时间" })
|
||||
FrameDelay: Array<number> = Array<number>();
|
||||
|
||||
|
||||
ChangeArr(Aobj, Bobj, FillData) {
|
||||
if (Aobj.length < Bobj) {
|
||||
for (let index = 0; index < (Bobj - Aobj.length); index++) {
|
||||
Aobj.push(FillData);
|
||||
}
|
||||
} else if (Aobj.length > Bobj) {
|
||||
for (let index = 0; index < (Aobj.length - Bobj); index++) {
|
||||
Aobj.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAnimationFrameCountChanged() {
|
||||
|
||||
//如果更改了设置
|
||||
if (this.NowSettingCount != this.AnimationFrameCount) {
|
||||
this.ChangeArr(this.ImgPath, this.AnimationFrameCount, '`NoImgPath`0');
|
||||
this.ChangeArr(this.FrameDelay, this.AnimationFrameCount, 0);
|
||||
this.NowSettingCount = this.AnimationFrameCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "46191008-0f8c-41fa-916e-29c656c36c99",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
import {
|
||||
_decorator, Color, Component, math, Node, resources, Sprite, SpriteFrame, Texture2D, UITransform, v2, v3, Vec2, Vec3,
|
||||
} from "cc";
|
||||
import { GameState } from "../GlobalGameState/GameState";
|
||||
import { ImagePack } from "../ImagePack/ImagePack";
|
||||
import { Ani_Frame, Img, ScriptAni } from "../GlobalInterface/GlobalInterface";
|
||||
import { GameScript } from "../GameScript/GameScript";
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
|
||||
@ccclass("MyAnimation")
|
||||
@requireComponent(Sprite)
|
||||
export class MyAnimation extends Component {
|
||||
|
||||
/// 动画完成回调
|
||||
public onAniDone : Function;
|
||||
|
||||
//Ani加载精灵帧初始化状态
|
||||
InitState: boolean = false;
|
||||
|
||||
SpriteObj: Sprite = null;
|
||||
|
||||
//Ani帧数
|
||||
AnimationFrameCount: number = 1;
|
||||
|
||||
//默认img路径
|
||||
DefaultImgPath: string = "";
|
||||
|
||||
//img路径的数组
|
||||
ImgPath: string[] = Array<string>();
|
||||
ImgIndex: number[] = Array<number>();
|
||||
//img帧的数组
|
||||
FrameArr: Array<Ani_Frame> = [];
|
||||
|
||||
//实际用到的Img路径数组 可能用于以后的释放NPK
|
||||
RealUseImgPath: string[] = Array<string>();
|
||||
|
||||
//播放计时器时间
|
||||
PlayTimer: number = 0;
|
||||
|
||||
//每帧延迟时间
|
||||
FrameDelay: number[] = Array<number>();
|
||||
|
||||
//当前帧
|
||||
NowFrame: number = 0;
|
||||
|
||||
|
||||
//Ani播放状态 0未播放 1播放中 2暂停中 3播放完成
|
||||
PlayState = 0;
|
||||
|
||||
//Ani对象
|
||||
AniObject: ScriptAni;
|
||||
|
||||
|
||||
//初始化路径
|
||||
InitPath() {
|
||||
//首先push默认路径
|
||||
this.RealUseImgPath.push(this.DefaultImgPath);
|
||||
|
||||
//遍历img路径数组
|
||||
this.ImgPath.forEach((Path, index) => {
|
||||
//如果没填写说明为空
|
||||
if (Path == "") {
|
||||
Path = this.DefaultImgPath;
|
||||
} else {
|
||||
if (!this.RealUseImgPath.includes(Path)) {
|
||||
this.RealUseImgPath.push(Path);
|
||||
}
|
||||
}
|
||||
this.FrameArr.push({
|
||||
Img_Path: Path,
|
||||
Img_Index: this.ImgIndex[index],
|
||||
Delay: this.FrameDelay[index],
|
||||
Frame: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
LoadSuccessImgCount: number = 0;
|
||||
ImgTable: Map<string, Img> = new Map<string, Img>();
|
||||
//读取Img
|
||||
InitImg() {
|
||||
//遍历img路径数组
|
||||
this.RealUseImgPath.forEach((Path, index) => {
|
||||
ImagePack.getInstance().ReadNpkTable(Path, (ImgObj) => {
|
||||
this.LoadSuccessImgCount++;
|
||||
//记录路径对应的Img对象
|
||||
this.ImgTable.set(Path, ImgObj);
|
||||
//如果已加载数量等于总数量 说明Img初始化完成
|
||||
if (this.LoadSuccessImgCount == this.RealUseImgPath.length) {
|
||||
//都加载完成以后 把精灵帧初始化出来
|
||||
this.FrameArr.forEach((FrameObj, Index) => {
|
||||
const Png = this.ImgTable.get(FrameObj.Img_Path)
|
||||
.Png_List[FrameObj.Img_Index];
|
||||
let spriteFrame = new SpriteFrame();
|
||||
let tex = new Texture2D();
|
||||
tex.reset({
|
||||
width: Png.Width,
|
||||
height: Png.Height,
|
||||
format: Texture2D.PixelFormat.RGBA8888,
|
||||
mipmapLevel: 0,
|
||||
});
|
||||
tex.uploadData(Png.PNGdata, 0, 0);
|
||||
// 更新 0 级 Mipmap。
|
||||
tex.updateImage();
|
||||
spriteFrame.texture = tex;
|
||||
spriteFrame.offset = v2(Png.Xpos, -Png.Ypos);
|
||||
|
||||
this.FrameArr[Index].Frame = spriteFrame;
|
||||
});
|
||||
this.InitState = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Init() {
|
||||
this.InitPath();
|
||||
|
||||
this.InitImg();
|
||||
}
|
||||
|
||||
start() {
|
||||
//判断是否有精灵 如果没有 就给他搞一个
|
||||
if (this.node.getComponent(Sprite))
|
||||
this.SpriteObj = this.node.getComponent(Sprite);
|
||||
else
|
||||
this.SpriteObj = this.node.addComponent(Sprite);
|
||||
|
||||
|
||||
//初始化构造内容
|
||||
this.Init();
|
||||
|
||||
//设置节点锚点为左上角
|
||||
this.node.getComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
//设置类型
|
||||
this.SpriteObj.sizeMode = Sprite.SizeMode.RAW;
|
||||
//设置
|
||||
this.SpriteObj.trim = false;
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
|
||||
//如果游戏世界处于暂停的模式下 不再继续播放
|
||||
if (GameState.getInstance().IsPauseState()) return;
|
||||
//如果初始化未完成,不播放
|
||||
if (!this.InitState) return;
|
||||
//如果不在播放中
|
||||
if (this.PlayState != 1) return;
|
||||
|
||||
let FrameObj = this.FrameArr[this.NowFrame];
|
||||
if (FrameObj) {
|
||||
//当前帧播放时间大于本帧延迟时间时
|
||||
if (this.PlayTimer > FrameObj.Delay) {
|
||||
|
||||
//需要初始化还原的东西
|
||||
//缩放
|
||||
this.node.setScale(1, 1);
|
||||
//染色
|
||||
this.SpriteObj.color = new Color(255, 255, 255, 255);
|
||||
|
||||
|
||||
|
||||
|
||||
//帧数加1
|
||||
this.NowFrame++;
|
||||
//Ani播放完了
|
||||
if (this.NowFrame >= this.FrameArr.length) {
|
||||
if (this.AniObject && this.AniObject.Flag && this.AniObject.Flag.get("LOOP"))
|
||||
this.NowFrame = 0;
|
||||
else this.PlayState = 3;
|
||||
if (this.PlayState == 3 && this.onAniDone) this.onAniDone();
|
||||
}
|
||||
|
||||
//设置精灵对象更换图片
|
||||
this.SpriteObj.spriteFrame = FrameObj.Frame;
|
||||
|
||||
//设置坐标
|
||||
if (FrameObj.Pos) this.node.setPosition(FrameObj.Pos);
|
||||
|
||||
if (FrameObj.Flag) {
|
||||
if (FrameObj.Flag.get("INTERPOLATION")) {
|
||||
|
||||
} else {
|
||||
FrameObj.Flag.forEach((Value, Key) => {
|
||||
if (Key == "RGBA") {
|
||||
this.SpriteObj.color = new Color(Value[0], Value[1], Value[2], Value[3]);
|
||||
}
|
||||
else if (Key == "IMAGE_RATE") {
|
||||
this.node.setScale(parseFloat(Value.x), parseFloat(Value.y));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//重置计时器
|
||||
this.PlayTimer = 0;
|
||||
}
|
||||
}
|
||||
this.PlayTimer += deltaTime * 1000;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "7134a119-c41c-4947-9191-d7def689bdd4",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
import { _decorator, CCInteger, CCString, Component, Node, Sprite, SpriteFrame, Texture2D, UITransform, v2 } from 'cc';
|
||||
import { MyAnimation } from './MyAnimation';
|
||||
import { GameScript } from '../GameScript/GameScript';
|
||||
import { ImagePack } from '../ImagePack/ImagePack';
|
||||
import { ScriptAls, ScriptAni } from '../GlobalInterface/GlobalInterface';
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
@ccclass('ScriptMyAnimation')
|
||||
@requireComponent(Sprite)//依赖组件 精灵
|
||||
export class ScriptMyAnimation extends MyAnimation {
|
||||
|
||||
|
||||
@property({ type: CCString, displayName: 'Ani路径', tooltip: "Ani在PVF中的路径" })
|
||||
AnimationPath = "";
|
||||
|
||||
// @property({ type: CCInteger, displayName: '是否显示', tooltip: "1为显示 0为不显示" })
|
||||
// PlayState = 0;
|
||||
|
||||
//是否有替换符
|
||||
Replace: Array<string>;
|
||||
|
||||
//读取Img
|
||||
InitImg() {
|
||||
//遍历img路径数组
|
||||
this.AniObject.Img_List.forEach((Path, index) => {
|
||||
ImagePack.getInstance().ReadNpkTable("sprite/" + Path.toLocaleLowerCase(), (ImgObj) => {
|
||||
this.LoadSuccessImgCount++;
|
||||
//记录路径对应的Img对象
|
||||
this.ImgTable.set(Path, ImgObj);
|
||||
//如果已加载数量等于总数量 说明Img初始化完成
|
||||
if (this.LoadSuccessImgCount == this.AniObject.Img_List.length) {
|
||||
//都加载完成以后 把精灵帧初始化出来
|
||||
this.FrameArr.forEach((FrameObj, Index) => {
|
||||
const Png = this.ImgTable.get(FrameObj.Img_Path).Png_List[FrameObj.Img_Index];
|
||||
|
||||
let spriteFrame = new SpriteFrame();
|
||||
let tex = new Texture2D();
|
||||
tex.reset({
|
||||
width: Png.Width,
|
||||
height: Png.Height,
|
||||
format: Texture2D.PixelFormat.RGBA8888,
|
||||
mipmapLevel: 0,
|
||||
});
|
||||
tex.uploadData(Png.PNGdata);
|
||||
// 更新 0 级 Mipmap。
|
||||
tex.updateImage();
|
||||
spriteFrame.texture = tex;
|
||||
spriteFrame.offset = v2(Png.Xpos, -Png.Ypos);
|
||||
|
||||
this.FrameArr[Index].Frame = spriteFrame;
|
||||
});
|
||||
this.InitState = true;
|
||||
//开始播放
|
||||
this.PlayState = 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Decompile_als(str: string) {
|
||||
const strbuf = str.split("\n");
|
||||
let Flag = 0;
|
||||
let AniobjArr: Array<string> = new Array<string>;
|
||||
let AniaddArr: Array<string[]> = new Array<string[]>;
|
||||
strbuf.forEach((lstr, line) => {
|
||||
if (Flag == 0) {
|
||||
if (lstr.indexOf("[use animation]") != -1) {
|
||||
Flag = 1;
|
||||
} else if (lstr.indexOf("[none effect add]") != -1 || lstr.indexOf("[add]") != -1) {
|
||||
Flag = 5;
|
||||
}
|
||||
} else if (Flag == 1) {
|
||||
AniobjArr.push(lstr);
|
||||
Flag = 2;
|
||||
} else if (Flag == 2) {
|
||||
AniobjArr.push(lstr);
|
||||
Flag = 0;
|
||||
} else if (Flag == 5) {
|
||||
let buf = lstr.split("\t");
|
||||
AniaddArr.push(buf);
|
||||
Flag = 0;
|
||||
}
|
||||
});
|
||||
|
||||
let AniArr: Array<ScriptAls> = new Array<ScriptAls>;
|
||||
|
||||
for (let index = 0; index < AniobjArr.length; index += 2) {
|
||||
let ScriptAlsBuf: ScriptAls = {};
|
||||
ScriptAlsBuf.Path = AniobjArr[index];
|
||||
ScriptAlsBuf.Name = AniobjArr[index + 1];
|
||||
AniArr.push(ScriptAlsBuf);
|
||||
}
|
||||
// console.log(AniobjArr);
|
||||
// console.log(AniaddArr);
|
||||
return AniArr;
|
||||
}
|
||||
|
||||
//判断是否有Als
|
||||
CheckAnimotionAls() {
|
||||
let Ret = GameScript.getInstance().GetDataByPath(this.AnimationPath + ".als");
|
||||
if (Ret) {
|
||||
let Als = this.Decompile_als(Ret);
|
||||
Als.forEach(aniobj => {
|
||||
let NodeBuf = new Node();
|
||||
// let SpriteBuf = NodeBuf.addComponent(Sprite);
|
||||
let Ani = NodeBuf.addComponent(ScriptMyAnimation);
|
||||
|
||||
Ani.AnimationPath = this.AnimationPath.substring(0, this.AnimationPath.lastIndexOf("/") + 1) + aniobj.Path.match(/`(.*?)`/)[1].toLowerCase();
|
||||
// Ani.PlayState = this.PlayState;
|
||||
// console.log(Ani.AnimationPath);
|
||||
this.node.parent.addChild(NodeBuf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//通过路径初始化Ani对象
|
||||
InitAnimotionObject() {
|
||||
this.CheckAnimotionAls();
|
||||
this.AniObject = GameScript.getInstance().GetDataByPath(this.AnimationPath);
|
||||
|
||||
}
|
||||
|
||||
Init() {
|
||||
if (!this.AniObject) this.InitAnimotionObject();
|
||||
|
||||
//如果有替换符则替换
|
||||
if (this.Replace) {
|
||||
this.AniObject.Frame.forEach((FrameObj, Index) => {
|
||||
this.AniObject.Frame[Index].Img_Path = FrameObj.Img_Path.replace(this.Replace[0], this.Replace[1]);
|
||||
});
|
||||
}
|
||||
|
||||
this.FrameArr = this.AniObject.Frame;
|
||||
|
||||
this.InitImg();
|
||||
}
|
||||
|
||||
|
||||
start() {
|
||||
super.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "da8cb249-923c-42fa-a55d-a66f7ffbc2d3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "f177f8e4-aca5-4209-ab04-8be793eaeb16",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
import { _decorator, CCInteger, CCString, Component, Node, Sprite, SpriteFrame, input, Input, __private, NodeEventType, EventTouch, EventMouse, UITransform, v2 } from 'cc';
|
||||
import { BaseSpriteFrame } from './BaseSpriteFrame';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
export enum BaseButtonState{
|
||||
// 普通
|
||||
Normal = 0,
|
||||
// 悬停
|
||||
Hover = 1,
|
||||
// 按下
|
||||
Press = 2,
|
||||
//失效
|
||||
Disable = 8
|
||||
}
|
||||
|
||||
@ccclass('BaseButton')
|
||||
export class BaseButton extends Component {
|
||||
|
||||
@property({ type: CCString, displayName: 'img路径', tooltip: "img路径" })
|
||||
ImgPath: string;
|
||||
|
||||
@property({ type: [CCInteger], displayName: '普通img编号', tooltip: "普通img编号" })
|
||||
NormalImgIndex: number;
|
||||
|
||||
@property({ type: [CCInteger], displayName: '悬停img编号', tooltip: "悬停img编号" })
|
||||
HoverImgIndex: number;
|
||||
|
||||
@property({ type: [CCInteger], displayName: '按下img编号', tooltip: "按下img编号" })
|
||||
PressImgIndex: number;
|
||||
|
||||
@property({ type: [CCInteger], displayName: '失效img编号', tooltip: "失效img编号" })
|
||||
DisableImgIndex: number;
|
||||
|
||||
//普通精灵帧
|
||||
NormalImgSpriteFrame: SpriteFrame;
|
||||
|
||||
//悬停精灵帧
|
||||
HoverImgSpriteFrame: SpriteFrame;
|
||||
|
||||
//按下精灵帧
|
||||
PressImgSpriteFrame: SpriteFrame;
|
||||
|
||||
//失效精灵帧
|
||||
DisableImgSpriteFrame: SpriteFrame;
|
||||
|
||||
//精灵对象
|
||||
SpriteObj: Sprite;
|
||||
|
||||
//初始化状态
|
||||
InitState = false;
|
||||
|
||||
//按钮状态
|
||||
ButtonState = BaseButtonState.Normal; // 0 普通 1悬停 2按下 8失效
|
||||
|
||||
/**
|
||||
* @description: BaseButton初始化设置
|
||||
* @param {string} ImgPath: npk中的路径
|
||||
* @param {number} NormalIndex: 普通 在npk.img 中的idnex 其他状态自动+1
|
||||
*/
|
||||
init(ImgPath:string,NormalIndex:number): void;
|
||||
init(ImgPath:string,NormalIndex:number,HoverIndex:number,PressIndex:number,DisableIndex:number,auto:boolean): void;
|
||||
|
||||
/**
|
||||
* @description: BaseButton初始化设置
|
||||
* @param {string} ImgPath: npk中的路径
|
||||
* @param {number} NormalIndex: 普通 在npk.img 中的idnex
|
||||
* @param {number} HoverIndex: 悬停
|
||||
* @param {number} PressIndex 按下
|
||||
* @param {number} DisableIndex 失效
|
||||
* @param {number} Disable 是否启用失效状态
|
||||
* @return {*}
|
||||
*/
|
||||
init(ImgPath:string,NormalIndex:number,HoverIndex?:number,PressIndex?:number,DisableIndex?:number,Disable:boolean = true): void{
|
||||
this.ImgPath = ImgPath;
|
||||
this.NormalImgIndex = NormalIndex;
|
||||
this.HoverImgIndex = HoverIndex ? HoverIndex : NormalIndex + 1;
|
||||
this.PressImgIndex = PressIndex ? PressIndex : NormalIndex + 2;
|
||||
if (Disable){ this.DisableImgIndex = DisableIndex ? DisableIndex : NormalIndex + 3; }
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
//判断是否有精灵 如果没有 就给他搞一个
|
||||
if (this.node.getComponent(Sprite))
|
||||
this.SpriteObj = this.node.getComponent(Sprite);
|
||||
else
|
||||
this.SpriteObj = this.node.addComponent(Sprite);
|
||||
|
||||
//设置节点锚点为左上角
|
||||
this.node.getComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
//设置类型
|
||||
this.SpriteObj.sizeMode = Sprite.SizeMode.RAW;
|
||||
//设置
|
||||
this.SpriteObj.trim = false;
|
||||
|
||||
new BaseSpriteFrame(this.ImgPath, this.NormalImgIndex, _SpriteFrame => { this.NormalImgSpriteFrame = _SpriteFrame });
|
||||
new BaseSpriteFrame(this.ImgPath, this.HoverImgIndex, _SpriteFrame => { this.HoverImgSpriteFrame = _SpriteFrame });
|
||||
new BaseSpriteFrame(this.ImgPath, this.PressImgIndex, _SpriteFrame => { this.PressImgSpriteFrame = _SpriteFrame });
|
||||
new BaseSpriteFrame(this.ImgPath, this.DisableImgIndex, _SpriteFrame => { this.DisableImgSpriteFrame = _SpriteFrame });
|
||||
|
||||
}
|
||||
|
||||
UploadSpriteFrame(_SpriteFrame) {
|
||||
if (this.SpriteObj.spriteFrame != _SpriteFrame) {
|
||||
this.SpriteObj.spriteFrame = _SpriteFrame;
|
||||
}
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
if (!this.InitState) {
|
||||
if (this.NormalImgSpriteFrame && this.HoverImgSpriteFrame && this.PressImgSpriteFrame) {
|
||||
this.InitState = true;
|
||||
this.UploadSpriteFrame(this.NormalImgSpriteFrame);
|
||||
|
||||
// this.node.on(Input.EventType.TOUCH_START, this.OnPress, this);
|
||||
// this.node.on(Input.EventType.TOUCH_END, this.OnEnd, this);
|
||||
this.node.on(Node.EventType.MOUSE_ENTER, this.OnHever, this);
|
||||
this.node.on(Node.EventType.MOUSE_LEAVE, this.OffHever, this);
|
||||
this.node.on(Node.EventType.MOUSE_DOWN, this.OnPress, this);
|
||||
this.node.on(Node.EventType.MOUSE_UP, this.OnEnd, this);
|
||||
}
|
||||
} else {
|
||||
switch (this.ButtonState) {
|
||||
case BaseButtonState.Normal:
|
||||
this.UploadSpriteFrame(this.NormalImgSpriteFrame);
|
||||
break;
|
||||
case BaseButtonState.Hover:
|
||||
this.UploadSpriteFrame(this.HoverImgSpriteFrame);
|
||||
break;
|
||||
case BaseButtonState.Press:
|
||||
this.UploadSpriteFrame(this.PressImgSpriteFrame);
|
||||
break;
|
||||
case BaseButtonState.Disable:
|
||||
this.UploadSpriteFrame(this.DisableImgSpriteFrame);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OffHever(event) {
|
||||
if (this.ButtonState == BaseButtonState.Disable) return;
|
||||
this.ButtonState = BaseButtonState.Normal;
|
||||
}
|
||||
OnHever(event) {
|
||||
if (this.ButtonState == BaseButtonState.Disable) return;
|
||||
this.ButtonState = BaseButtonState.Hover;
|
||||
}
|
||||
OnEnd(event: EventMouse) {
|
||||
if (this.ButtonState == BaseButtonState.Disable) return;
|
||||
if (event.getButton() != EventMouse.BUTTON_LEFT) return;
|
||||
this.ButtonState = BaseButtonState.Normal;
|
||||
}
|
||||
|
||||
OnPress(event: EventMouse) {
|
||||
if (this.ButtonState == BaseButtonState.Disable) return;
|
||||
//必须是鼠标左键
|
||||
if (event.getButton() != EventMouse.BUTTON_LEFT) return;
|
||||
|
||||
this.ButtonState = BaseButtonState.Press;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "227e9de9-da6c-4457-9ce3-bc6d687c990b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
import { _decorator, Component, EventMouse, Node } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('BaseButtonAction')
|
||||
export class BaseButtonAction extends Component {
|
||||
|
||||
onMouseUp?: Function;
|
||||
onMouseLeftUp?: Function;
|
||||
onMouseRightUp?: Function;
|
||||
|
||||
onMouseDown?: Function;
|
||||
onMouseLeftDown?: Function;
|
||||
onMouseRightDown?: Function;
|
||||
|
||||
start() {
|
||||
this.node.on(Node.EventType.MOUSE_UP,this._onMouseUp,this);
|
||||
this.node.on(Node.EventType.MOUSE_DOWN,this._onMouseDown,this);
|
||||
}
|
||||
|
||||
private _onMouseUp(event:EventMouse){
|
||||
if (this.onMouseUp) this.onMouseUp();
|
||||
|
||||
switch (event.getButton()) {
|
||||
case EventMouse.BUTTON_LEFT:
|
||||
if (this.onMouseLeftUp) this.onMouseLeftUp();
|
||||
break;
|
||||
case EventMouse.BUTTON_RIGHT:
|
||||
if (this.onMouseRightUp) this.onMouseRightUp();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private _onMouseDown(event:EventMouse){
|
||||
if (this.onMouseDown) this.onMouseDown();
|
||||
|
||||
switch (event.getButton()) {
|
||||
case EventMouse.BUTTON_LEFT:
|
||||
if (this.onMouseLeftDown) this.onMouseLeftDown();
|
||||
break;
|
||||
case EventMouse.BUTTON_RIGHT:
|
||||
if (this.onMouseRightDown) this.onMouseRightDown();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "297493e6-04d1-4d0f-a06b-0c8bd259ad71",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import { _decorator, CCInteger, CCString, Component, Node, Sprite, SpriteFrame, Texture2D, UITransform, v2 } from 'cc';
|
||||
import { ImagePack } from '../ImagePack/ImagePack';
|
||||
import { BaseSpriteFrame } from './BaseSpriteFrame';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('BaseSprite')
|
||||
export class BaseSprite extends Component {
|
||||
|
||||
@property({ type: CCString, displayName: 'img路径', tooltip: "img路径" })
|
||||
ImgPath = "";
|
||||
|
||||
@property({ type: CCInteger, displayName: 'img编号', tooltip: "img编号" })
|
||||
ImgIndex = 0;
|
||||
|
||||
//精灵对象
|
||||
SpriteObj: Sprite;
|
||||
|
||||
start() {
|
||||
if (this.ImgPath.length > 0 ){
|
||||
this.updateSpriteFrame(this.ImgPath,this.ImgIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateSpriteFrame(imgPath: string, imgIndex: number){
|
||||
|
||||
this.ImgIndex = imgIndex;
|
||||
this.ImgPath = imgPath;
|
||||
|
||||
//判断是否有精灵 如果没有 就给他搞一个
|
||||
if (this.node.getComponent(Sprite))
|
||||
this.SpriteObj = this.node.getComponent(Sprite);
|
||||
else
|
||||
this.SpriteObj = this.node.addComponent(Sprite);
|
||||
|
||||
//设置节点锚点为左上角
|
||||
this.node.getComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
//设置类型
|
||||
this.SpriteObj.sizeMode = Sprite.SizeMode.RAW;
|
||||
//设置
|
||||
this.SpriteObj.trim = false;
|
||||
|
||||
new BaseSpriteFrame(imgPath.toLocaleLowerCase(), imgIndex, (_SpriteFrame) => {
|
||||
this.SpriteObj.spriteFrame = _SpriteFrame;
|
||||
});
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a8046df1-6c92-4ce6-a53c-1548472bce1e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { _decorator, Component, Node, SpriteFrame, Texture2D, v2 } from 'cc';
|
||||
import { ImagePack } from '../ImagePack/ImagePack';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('BaseSpriteFrame')
|
||||
export class BaseSpriteFrame {
|
||||
|
||||
//初始化状态
|
||||
InitState: boolean = false;
|
||||
//精灵帧
|
||||
_SpriteFrame: SpriteFrame;
|
||||
//回调函数
|
||||
CallBackFunc: Function;
|
||||
|
||||
constructor(ImgPath: string, ImgIndex: number, CallBack?: Function) {
|
||||
if (CallBack) this.CallBackFunc = CallBack;
|
||||
ImagePack.getInstance().ReadNpkTable("sprite/" + ImgPath.toLocaleLowerCase(), (ImgObj) => {
|
||||
const Png = ImgObj.Png_List[ImgIndex];
|
||||
this._SpriteFrame = new SpriteFrame();
|
||||
let tex = new Texture2D();
|
||||
tex.reset({
|
||||
width: Png.Width,
|
||||
height: Png.Height,
|
||||
format: Texture2D.PixelFormat.RGBA8888,
|
||||
mipmapLevel: 0,
|
||||
});
|
||||
tex.uploadData(Png.PNGdata);
|
||||
// 更新 0 级 Mipmap。
|
||||
tex.updateImage();
|
||||
this._SpriteFrame.texture = tex;
|
||||
this._SpriteFrame.offset = v2(Png.Xpos, -Png.Ypos);
|
||||
|
||||
this.CallBackFunc(this._SpriteFrame);
|
||||
this.InitState = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ab5b488b-feb1-48e2-a426-d0ce0d4b59b7",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-23 13:22:27
|
||||
* @LastEditTime: 2024-03-24 16:04:20
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: node坐标控制
|
||||
*/
|
||||
import {
|
||||
_decorator,
|
||||
Color,
|
||||
Component,
|
||||
EditBox,
|
||||
Font,
|
||||
HorizontalTextAlignment,
|
||||
Node,
|
||||
Size,
|
||||
Sprite,
|
||||
UITransform,
|
||||
v2,
|
||||
VerticalTextAlignment,
|
||||
} from "cc";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("LocationImportComponent")
|
||||
/**
|
||||
* @description: node坐标控制
|
||||
*/
|
||||
export class LocationImportComponent extends Component {
|
||||
editBox: EditBox;
|
||||
|
||||
onLoad(): void {
|
||||
const node = new Node();
|
||||
node.setPosition(0, 30);
|
||||
|
||||
const uit = node.addComponent(UITransform);
|
||||
uit.anchorPoint = v2(0, 1);
|
||||
uit.setContentSize(new Size(150, 30));
|
||||
|
||||
const sp = node.addComponent(Sprite);
|
||||
sp.color = Color.WHITE;
|
||||
|
||||
const editBox = node.addComponent(EditBox);
|
||||
editBox.inputMode = EditBox.InputMode.SINGLE_LINE;
|
||||
this.editBox = editBox;
|
||||
|
||||
this.node.addChild(node);
|
||||
|
||||
//* 修改 node 的坐标
|
||||
editBox.node.on("editing-did-ended", (text: EditBox) => {
|
||||
const los = text.textLabel.string.split(',');
|
||||
this.node.setPosition(Number(los[0]),Number(los[1]));
|
||||
});
|
||||
}
|
||||
|
||||
start() {
|
||||
const placeholderLabel = this.editBox.placeholderLabel;
|
||||
placeholderLabel.string = "坐标";
|
||||
placeholderLabel.horizontalAlign = HorizontalTextAlignment.LEFT;
|
||||
placeholderLabel.verticalAlign = VerticalTextAlignment.TOP;
|
||||
placeholderLabel.fontSize = 20;
|
||||
placeholderLabel.color = Color.RED;
|
||||
placeholderLabel.node.setPosition(0, 50);
|
||||
placeholderLabel.node.getComponent(UITransform).anchorPoint = v2(0, 2);
|
||||
|
||||
const textLabel = this.editBox.textLabel;
|
||||
textLabel.horizontalAlign = HorizontalTextAlignment.LEFT;
|
||||
textLabel.verticalAlign = VerticalTextAlignment.TOP;
|
||||
textLabel.fontSize = 20;
|
||||
textLabel.color = Color.RED;
|
||||
textLabel.node.setPosition(0, 50);
|
||||
textLabel.node.getComponent(UITransform).anchorPoint = v2(0, 2);
|
||||
|
||||
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "08408ae9-019a-4902-9bc2-002e2e663cb6",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-24 16:09:55
|
||||
* @LastEditTime: 2024-03-24 16:30:46
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 通过边框显示node的位置和大小,默认锚点(0,1)
|
||||
*/
|
||||
import { _decorator, Color, Component, Graphics, Node, UITransform } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('ShowNodeBorder')
|
||||
/**
|
||||
* @description: 通过边框显示node的位置和大小,默认锚点(0,1)
|
||||
*/
|
||||
export class ShowNodeBorder extends Component {
|
||||
|
||||
graphics: Graphics;
|
||||
|
||||
onLoad() {
|
||||
if(this.node.getComponent(Graphics)){
|
||||
this.graphics = this.node.getComponent(Graphics);
|
||||
}else{
|
||||
this.graphics = this.node.addComponent(Graphics);
|
||||
}
|
||||
|
||||
this.updateBorder();
|
||||
}
|
||||
|
||||
updateBorder() {
|
||||
const borderColor = Color.YELLOW;
|
||||
const borderWidth = 4;
|
||||
|
||||
const contentSize = this.node.getComponent(UITransform).contentSize;
|
||||
|
||||
this.graphics.clear();
|
||||
this.graphics.strokeColor = borderColor;
|
||||
this.graphics.lineWidth = borderWidth;
|
||||
// this.graphics.rect(-contentSize.width / 2, -contentSize.height / 2, contentSize.width, contentSize.height);// 锚点 (0,0)
|
||||
this.graphics.rect(0, 0, contentSize.width, -contentSize.height); //锚点 (0,1)
|
||||
this.graphics.stroke();
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9ef9c0ff-8d63-448d-b95f-89b02e1455f3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "f4d1fffa-ecc3-491b-8125-0f4a41ba705a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,844 @@
|
|||
import {
|
||||
_decorator,
|
||||
Asset,
|
||||
assetManager,
|
||||
BufferAsset,
|
||||
Component,
|
||||
Node,
|
||||
resources,
|
||||
TextAsset,
|
||||
v2,
|
||||
v3,
|
||||
Vec2,
|
||||
} from "cc";
|
||||
import { ReadStream } from "../Tool/ReadStream";
|
||||
import { Ani_Frame, ScriptAni, ScriptFile } from "../GlobalInterface/GlobalInterface";
|
||||
import { GlobalTool } from "../Tool/GlobalTool";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
class ScriptTree {
|
||||
//PVF文件头数据
|
||||
Index_Header_Data: Uint8Array;
|
||||
//PVF原始数据
|
||||
Script_Data_Buffer: Uint8Array;
|
||||
|
||||
//文件头读取流
|
||||
Index_Header_Read_Object: ReadStream;
|
||||
|
||||
//树Map
|
||||
TreeMap: Map<string, ScriptFile> = new Map<string, ScriptFile>();
|
||||
|
||||
constructor(gIndex_Header_Data, gScript_Data_Buffer) {
|
||||
this.Index_Header_Data = gIndex_Header_Data;
|
||||
this.Script_Data_Buffer = gScript_Data_Buffer;
|
||||
this.Index_Header_Read_Object = new ReadStream(this.Index_Header_Data);
|
||||
}
|
||||
|
||||
ReadTree(currPos, startPos, Index) {
|
||||
this.Index_Header_Read_Object.Seekg(currPos);
|
||||
const FileNumber = this.Index_Header_Read_Object.GetInt();
|
||||
const FilePathLength = this.Index_Header_Read_Object.GetInt();
|
||||
const FilePath = this.Index_Header_Read_Object.GetBufferByLength(FilePathLength);
|
||||
const FileLength = this.Index_Header_Read_Object.GetInt();
|
||||
const Cre32 = this.Index_Header_Read_Object.GetInt();
|
||||
//数据偏移
|
||||
const RelativeOffset = this.Index_Header_Read_Object.GetInt();
|
||||
if (FileLength > 0) {
|
||||
//数据长度
|
||||
const RealFileLength = (FileLength + 3) & 4294967292;
|
||||
//文件路径
|
||||
const RealFilePath = GlobalTool.uint8ArrayToString(FilePath).replace("\\", "/");
|
||||
//建立索引Map
|
||||
this.TreeMap.set(RealFilePath, { Cre32: Cre32, StartPos: startPos, Offset: RelativeOffset, Length: RealFileLength });
|
||||
}
|
||||
return FilePathLength + 20;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//原数据
|
||||
StringtableBaseBuf;
|
||||
//CRE key
|
||||
StringtableCre32;
|
||||
//读取Bin文件
|
||||
StringTable: Map<number, string> = new Map<number, string>();
|
||||
|
||||
//当前索引位置
|
||||
StringtableCurrentIndex: number = 0;
|
||||
//当前读取索引位置
|
||||
StringtableReadCurrentIndex: number = 0;
|
||||
|
||||
//本类用的特殊解密 分段解密
|
||||
CrcDecodeSpecial(): boolean {
|
||||
const num: number = 2175242257; // 2175242257L in hexadecimal
|
||||
const dataView = new DataView(
|
||||
this.StringtableBaseBuf.buffer,
|
||||
this.StringtableBaseBuf.byteOffset,
|
||||
this.StringtableBaseBuf.byteLength,
|
||||
);
|
||||
|
||||
//开始时间
|
||||
const StartTime = new Date().getTime();
|
||||
//死循环读取树文件数据 但是每一次最多只读15毫秒 为了保证UI线程刷新
|
||||
while (true) {
|
||||
// Ensure we don't read beyond the end of the data //如果当前索引位置加上4大于数组长度 说明读取完毕 返回true
|
||||
if (this.StringtableCurrentIndex >= this.StringtableBaseBuf.length) return true;
|
||||
//当前时间减去开始时间
|
||||
const NowTime = new Date().getTime();
|
||||
//如果本轮循环已经读取了15毫秒了 就先返回刷新ui
|
||||
if (NowTime - StartTime >= 15) return false;
|
||||
// Read a 32-bit integer (little endian) from the buffer
|
||||
let anInt = dataView.getUint32(this.StringtableCurrentIndex, true);
|
||||
// Perform the XOR operations
|
||||
let val = anInt ^ num ^ this.StringtableCre32;
|
||||
// Rotate right 6 bits
|
||||
let jiemi = (val >>> 6) | (val << (32 - 6));
|
||||
// Write the result back into the buffer
|
||||
dataView.setUint32(this.StringtableCurrentIndex, jiemi, true);
|
||||
this.StringtableCurrentIndex = this.StringtableCurrentIndex + 4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
InitStringBin() {
|
||||
//如果这个是空就读取一下
|
||||
if (this.StringtableBaseBuf == undefined) {
|
||||
const FileObject = this.TreeMap.get("stringtable.bin");
|
||||
if (FileObject == undefined) return true;
|
||||
this.StringtableBaseBuf = this.Script_Data_Buffer.slice(
|
||||
FileObject.StartPos + FileObject.Offset,
|
||||
FileObject.StartPos + FileObject.Offset + FileObject.Length
|
||||
);
|
||||
this.StringtableCre32 = FileObject.Cre32;
|
||||
}
|
||||
|
||||
const Flag = this.CrcDecodeSpecial();
|
||||
|
||||
if (Flag) {
|
||||
let Ro = new ReadStream(this.StringtableBaseBuf);
|
||||
const Count = Ro.GetInt();
|
||||
//开始时间
|
||||
const StartTime = new Date().getTime();
|
||||
while (true) {
|
||||
//当前时间减去开始时间
|
||||
const NowTime = new Date().getTime();
|
||||
//如果本轮循环已经读取了15毫秒了 就先返回刷新ui
|
||||
if (NowTime - StartTime >= 15) return false;
|
||||
|
||||
if (this.StringtableReadCurrentIndex < Count) {
|
||||
Ro.Seekg(this.StringtableReadCurrentIndex * 4 + 4);
|
||||
const StartPos = Ro.GetInt();
|
||||
const EndPos = Ro.GetInt();
|
||||
const Len = EndPos - StartPos;
|
||||
Ro.Seekg(StartPos + 4);
|
||||
const Str = Ro.GetString(Len);
|
||||
this.StringTable.set(this.StringtableReadCurrentIndex, Str);
|
||||
this.StringtableReadCurrentIndex++;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//读取字符串索引
|
||||
Load_StringTable: Map<string, string> = new Map<string, string>();
|
||||
InitLoad_String() {
|
||||
const FileObject = this.TreeMap.get("n_string.lst");
|
||||
if (FileObject == undefined) return;
|
||||
let RealBuf = this.Script_Data_Buffer.slice(
|
||||
FileObject.StartPos + FileObject.Offset,
|
||||
FileObject.StartPos + FileObject.Offset + FileObject.Length
|
||||
);
|
||||
|
||||
GlobalTool.CrcDecode(RealBuf, FileObject.Cre32);
|
||||
let Ro = new ReadStream(RealBuf);
|
||||
|
||||
const Count = Ro.GetUShort();
|
||||
if (Count != 53424) return;
|
||||
|
||||
let i = 2;
|
||||
while (i < Ro.len()) {
|
||||
if (Ro.len() - i >= 10) {
|
||||
Ro.Seekg(i + 6);
|
||||
const Key = this.StringTable.get(Ro.GetInt());
|
||||
if (Key) {
|
||||
const File = this.TreeMap.get(Key.toLocaleLowerCase());
|
||||
let FileBuf = this.Script_Data_Buffer.slice(
|
||||
File.StartPos + File.Offset,
|
||||
File.StartPos + File.Offset + File.Length
|
||||
);
|
||||
GlobalTool.CrcDecode(FileBuf, File.Cre32);
|
||||
|
||||
let Str = GlobalTool.uint8ArrayToString(FileBuf, 'big5');
|
||||
let StrArr = Str.split('\r\n');
|
||||
StrArr.forEach((strobj, index) => {
|
||||
if (strobj.indexOf('>')) {
|
||||
let strobjarr = strobj.split('>', 2);
|
||||
this.Load_StringTable.set(strobjarr[0], strobjarr[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else break;
|
||||
i += 10;
|
||||
}
|
||||
}
|
||||
|
||||
//Pvf文件数据
|
||||
ScriptFileData = new Map();
|
||||
GetFileData(Path: string) {
|
||||
//检查路径是否存在
|
||||
const FileObject = this.TreeMap.get(Path);
|
||||
if (FileObject == undefined) return false;
|
||||
//如果读过直接返回数据
|
||||
const FileData = this.ScriptFileData.get(Path);
|
||||
if (FileData != undefined) return FileData;
|
||||
|
||||
|
||||
//获取文件数据字节数组
|
||||
let RealBuf = this.Script_Data_Buffer.slice(
|
||||
FileObject.StartPos + FileObject.Offset,
|
||||
FileObject.StartPos + FileObject.Offset + FileObject.Length
|
||||
);
|
||||
|
||||
GlobalTool.CrcDecode(RealBuf, FileObject.Cre32);
|
||||
|
||||
//Ani的处理逻辑
|
||||
if (Path.indexOf(".ani") != -1) {
|
||||
if (Path.indexOf(".als") != -1) {
|
||||
const Ro = new ReadStream(RealBuf);
|
||||
const Str = Ro.GetString();
|
||||
this.ScriptFileData.set(Path, Str);
|
||||
return Str;
|
||||
} else {
|
||||
let Buf = this.Decompile_ani(RealBuf);
|
||||
this.ScriptFileData.set(Path, Buf);
|
||||
return Buf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
let Buf = this.Decompile_script(RealBuf);
|
||||
this.ScriptFileData.set(Path, Buf);
|
||||
|
||||
return Buf;
|
||||
} catch (error) {
|
||||
// console.log(RealFilePath);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Decompile_script(RealBuf: any) {
|
||||
const Ro = new ReadStream(RealBuf);
|
||||
let out: string = "";
|
||||
if (Ro.len() >= 7) {
|
||||
//以5为单步从第二位开始遍历字节
|
||||
let i = 2;
|
||||
while (i < Ro.len()) {
|
||||
//到最后了就不处理了防止内存越界
|
||||
if (Ro.len() - i >= 5) {
|
||||
Ro.Seekg(i); //内容指示位
|
||||
let currentByte = Number(Ro.GetBufferByLength(1)); //内容指示位
|
||||
|
||||
|
||||
let after = Ro.GetInt();
|
||||
switch (currentByte) {
|
||||
case 10:
|
||||
{
|
||||
Ro.Seekg(i - 4);
|
||||
const Before = Ro.GetInt();
|
||||
let Buf = this.StringTable.get(after);
|
||||
if (!Buf) {
|
||||
Buf = "";
|
||||
} else {
|
||||
Buf = "<" + Before + "::" + Buf + "`" + this.Load_StringTable.get(Buf) + "`>";
|
||||
}
|
||||
Buf = Buf + "\r\n";
|
||||
out += Buf;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
out += after + '\t';
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
view.setInt32(0, after, true);
|
||||
const Buf = view.getFloat32(0);
|
||||
out += after + '\t';
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
case 8:
|
||||
case 7:
|
||||
case 5:
|
||||
{
|
||||
let Buf = this.StringTable.get(after);
|
||||
if (!Buf) Buf = "";
|
||||
|
||||
if (currentByte == 5) {
|
||||
Buf = "\r\n" + Buf + "\r\n";
|
||||
}
|
||||
else if (currentByte == 7) {
|
||||
Buf = "`" + Buf + "`\r\n";
|
||||
}
|
||||
else if (currentByte == 6 || currentByte == 8) {
|
||||
Buf = "{{" + currentByte + "=`" + Buf + "`}}\r\n";
|
||||
}
|
||||
out += Buf;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
out += "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += 5;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
//解包数据
|
||||
Unpack_Chr(pvfData, curr: number, after: number, before: number): string {
|
||||
switch (curr) {
|
||||
case 2:
|
||||
return after.toString(); //整数型
|
||||
case 4:
|
||||
// return new Float32Array([after]).buffer.slice(0, 4).readFloatLE().toString();
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
if (pvfData.str_bin_map.has(after)) {
|
||||
return pvfData.str_bin_map.get(after);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
case 10:
|
||||
if (!pvfData.str_bin_map.has(after)) {
|
||||
return "";
|
||||
}
|
||||
let tempstr = pvfData.str_bin_map.get(after);
|
||||
// return `<${before}::\`${tempstr}\`${_getNString(pvfData, before, tempstr)}.toString()}>`;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
//读取Ani
|
||||
Decompile_ani(RealBuf: any): any {
|
||||
let AniObject: ScriptAni = {
|
||||
Img_List: new Array<string>(),
|
||||
Flag: new Map<string, number>(),
|
||||
Frame: new Array<Ani_Frame>(),
|
||||
};
|
||||
|
||||
|
||||
const Ro = new ReadStream(RealBuf);
|
||||
//总帧数
|
||||
const Frame_Max = Ro.GetUShort();
|
||||
//总共调用了多少个Img
|
||||
const Img_Count = Ro.GetUShort();
|
||||
|
||||
//Img的路径读取 存入数组
|
||||
for (let index = 0; index < Img_Count; index++) {
|
||||
const Buf = Ro.GetInt();
|
||||
//有可能Img有空路径
|
||||
AniObject.Img_List.push(Ro.GetString(Buf).toLowerCase());
|
||||
}
|
||||
|
||||
//Ani头部标签数量
|
||||
const Ani_H_Item_Count = Ro.GetUShort();
|
||||
|
||||
//处理标签
|
||||
for (let index = 0; index < Ani_H_Item_Count; index++) {
|
||||
//标签类型
|
||||
const Type = Ro.GetUShort();
|
||||
|
||||
switch (Type) {
|
||||
case 0:
|
||||
case 1: {
|
||||
const Key = this.Get_Ani_Flag(Type);
|
||||
const Value = Number(Ro.GetBufferByLength(1));
|
||||
AniObject.Flag.set(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 28: {
|
||||
const Key = this.Get_Ani_Flag(Type);
|
||||
const Value = Ro.GetUShort();
|
||||
AniObject.Flag.set(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
//此处无解析 暂时先保证运行 残影功能暂时用不上
|
||||
Ro.GetBufferByLength(1);
|
||||
Ro.GetInt();
|
||||
Ro.GetInt();
|
||||
Ro.GetInt();
|
||||
Ro.Get256();
|
||||
Ro.Get256();
|
||||
Ro.Get256();
|
||||
Ro.Get256();
|
||||
Ro.GetUShort();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//读取每一个Img
|
||||
for (let index = 0; index < Frame_Max; index++) {
|
||||
//帧结构体对象
|
||||
let FrameObject: Ani_Frame = {
|
||||
Box: new Map<number, Array<number>>(),
|
||||
Img_Path: null,
|
||||
Img_Index: null,
|
||||
Pos: null,
|
||||
Flag: new Map<string, any>(),
|
||||
Delay: null,
|
||||
};
|
||||
|
||||
//碰撞框项目数量
|
||||
const Ani_Box_Item_Count = Ro.GetUShort();
|
||||
for (let _i = 0; _i < Ani_Box_Item_Count; _i++) {
|
||||
const Box_Type = Ro.GetUShort();
|
||||
let D_Box_b = [];
|
||||
for (let _k = 0; _k < 6; _k++) {
|
||||
D_Box_b.push(Ro.GetInt());
|
||||
}
|
||||
//0是攻击框 1是受击框
|
||||
FrameObject.Box.set(15 - Box_Type, D_Box_b);
|
||||
}
|
||||
|
||||
//调用的第几个Img
|
||||
const Index_Buf = Ro.GetShort();
|
||||
//如果等于-1说明是img路径为空
|
||||
if (Index_Buf >= 0) {
|
||||
FrameObject.Img_Path = AniObject.Img_List[Index_Buf];
|
||||
//Img中的PNG下标
|
||||
FrameObject.Img_Index = Ro.GetUShort();
|
||||
}
|
||||
else {
|
||||
FrameObject.Img_Path = "";
|
||||
FrameObject.Img_Index = 0;
|
||||
}
|
||||
|
||||
//坐标
|
||||
FrameObject.Pos = v3(Ro.GetInt(), -Ro.GetInt(), 0);
|
||||
|
||||
//Img中的项目数量
|
||||
const Img_Flag_Count = Ro.GetUShort();
|
||||
for (let _o = 0; _o < Img_Flag_Count; _o++) {
|
||||
const Img_Flag_Type = Ro.GetUShort();
|
||||
let Key;
|
||||
let Value;
|
||||
switch (Img_Flag_Type) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 10:
|
||||
Key = this.Get_Ani_Flag(Img_Flag_Type);
|
||||
Value = Number(Ro.GetBufferByLength(1));
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 3:
|
||||
Key = "COORD";
|
||||
Value = Ro.GetUShort();
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 17:
|
||||
Key = "PRELOAD";
|
||||
Value = 1;
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 7:
|
||||
Key = "IMAGE_RATE";
|
||||
Value = { x: Ro.GetFloat(), y: Ro.GetFloat() };
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 8:
|
||||
Key = "IMAGE_ROTATE";
|
||||
Value = Ro.GetFloat();
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 9:
|
||||
Key = "RGBA";
|
||||
Value = [
|
||||
Ro.Get256(),
|
||||
Ro.Get256(),
|
||||
Ro.Get256(),
|
||||
Ro.Get256(),
|
||||
];
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 11:
|
||||
const Effect_Type = Ro.GetUShort();
|
||||
Key = "GRAPHIC_EFFECT_" + this.Get_Ani_Effect_Type(Effect_Type);
|
||||
switch (Effect_Type) {
|
||||
case 5:
|
||||
Value = [Ro.Get256(), Ro.Get256(), Ro.Get256()];
|
||||
break;
|
||||
case 6:
|
||||
Value = [Ro.GetShort(), Ro.GetShort()];
|
||||
break;
|
||||
}
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 12:
|
||||
Value = Ro.GetInt();
|
||||
FrameObject.Delay = Value;
|
||||
break;
|
||||
case 13:
|
||||
Key = "DAMAGE_TYPE";
|
||||
Value = this.Get_Ani_Damage_Type(Ro.GetUShort());
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 16:
|
||||
const SoundTempSize = Ro.GetInt();
|
||||
Key = "PLAY_SOUND";
|
||||
Value = Ro.GetString(SoundTempSize);
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 23:
|
||||
Key = "SET_FLAG";
|
||||
Value = Ro.GetInt();
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 24:
|
||||
Key = "FLIP_TYPE";
|
||||
Value = this.Get_Ani_Flip_Type(Ro.GetUShort());
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 25:
|
||||
Key = "LOOP_START";
|
||||
FrameObject.Flag.set(Key, 1);
|
||||
break;
|
||||
case 26:
|
||||
Key = "LOOP_END";
|
||||
Value = Ro.GetInt();
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
case 27:
|
||||
Key = "CLIP";
|
||||
Value = [
|
||||
Ro.GetShort(),
|
||||
Ro.GetShort(),
|
||||
Ro.GetShort(),
|
||||
Ro.GetShort(),
|
||||
];
|
||||
FrameObject.Flag.set(Key, Value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//每一帧都是一个结构体 存入数组中
|
||||
AniObject.Frame.push(FrameObject);
|
||||
}
|
||||
return AniObject;
|
||||
}
|
||||
|
||||
Get_Ani_Flip_Type(data: number): string {
|
||||
switch (data) {
|
||||
case 1:
|
||||
return "HORIZON";
|
||||
case 2:
|
||||
return "VERTICAL";
|
||||
case 3:
|
||||
return "ALL";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Get_Ani_Effect_Type(data: number): string {
|
||||
switch (data) {
|
||||
case 0:
|
||||
return "NONE";
|
||||
case 1:
|
||||
return "DODGE";
|
||||
case 2:
|
||||
return "LINEARDODGE";
|
||||
case 3:
|
||||
return "DARK";
|
||||
case 4:
|
||||
return "XOR";
|
||||
case 5:
|
||||
return "MONOCHROME";
|
||||
case 6:
|
||||
return "SPACEDISTORT";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Get_Ani_Damage_Type(data: number): any {
|
||||
switch (data) {
|
||||
case 0:
|
||||
return "NORMAL";
|
||||
case 1:
|
||||
return "SUPERARMOR";
|
||||
case 2:
|
||||
return "UNBREAKABLE";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Get_Ani_Flag(data: number): string {
|
||||
switch (data) {
|
||||
case 0:
|
||||
return "LOOP";
|
||||
case 1:
|
||||
return "SHADOW";
|
||||
case 3:
|
||||
return "COORD";
|
||||
case 7:
|
||||
return "IMAGE_RATE";
|
||||
case 8:
|
||||
return "IMAGE_ROTATE";
|
||||
case 9:
|
||||
return "RGBA";
|
||||
case 10:
|
||||
return "INTERPOLATION";
|
||||
case 11:
|
||||
return "GRAPHIC_EFFECT";
|
||||
case 12:
|
||||
return "DELAY";
|
||||
case 13:
|
||||
return "DAMAGE_TYPE";
|
||||
case 14:
|
||||
return "DAMAGE_BOX";
|
||||
case 15:
|
||||
return "ATTACK_BOX";
|
||||
case 16:
|
||||
return "PLAY_SOUND";
|
||||
case 17:
|
||||
return "PRELOAD";
|
||||
case 18:
|
||||
return "SPECTRUM";
|
||||
case 23:
|
||||
return "SET_FLAG";
|
||||
case 24:
|
||||
return "FLIP_TYPE";
|
||||
case 25:
|
||||
return "LOOP_START";
|
||||
case 26:
|
||||
return "LOOP_END";
|
||||
case 27:
|
||||
return "CLIP";
|
||||
case 28:
|
||||
return "OPERATION";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptData {
|
||||
//Pvf数据
|
||||
ScriptDataBuffer;
|
||||
//读取UUID的长度
|
||||
UUID_LENGTH;
|
||||
//UUID 读 1 - 36位 构造 UTF8 string
|
||||
UUID;
|
||||
//版本号
|
||||
Version;
|
||||
// 文件路径数据的大小
|
||||
AlignedIndexHeaderSize;
|
||||
// 解密密钥
|
||||
IndexHeaderCrc;
|
||||
// 文件数量
|
||||
IndexSize;
|
||||
// 存放文件路径数据
|
||||
Index_Header_Data;
|
||||
|
||||
//Pvf解密出的数据
|
||||
ScriptDataObject: ScriptTree = null;
|
||||
|
||||
constructor(
|
||||
public buffer: Uint8Array,
|
||||
public uuidLength: number,
|
||||
public uuid: string,
|
||||
public version: number,
|
||||
public alignedIndexHeaderSize: number,
|
||||
public indexHeaderCrc: number,
|
||||
public indexSize: number,
|
||||
public indexHeaderData: Uint8Array
|
||||
) {
|
||||
//Pvf数据
|
||||
this.ScriptDataBuffer = buffer;
|
||||
//读取UUID的长度
|
||||
this.UUID_LENGTH = uuidLength;
|
||||
//UUID 读 1 - 36位 构造 UTF8 string
|
||||
this.UUID = uuid;
|
||||
//版本号
|
||||
this.Version = version;
|
||||
// 文件路径数据的大小
|
||||
this.AlignedIndexHeaderSize = alignedIndexHeaderSize;
|
||||
// 解密密钥
|
||||
this.IndexHeaderCrc = indexHeaderCrc;
|
||||
// 文件数量
|
||||
this.IndexSize = indexSize;
|
||||
// 存放文件路径数据
|
||||
this.Index_Header_Data = indexHeaderData;
|
||||
}
|
||||
|
||||
//初始化路径树 把所有文件路径建立起来还没有读
|
||||
InitPathTree() {
|
||||
//先进行Crc解密
|
||||
GlobalTool.CrcDecode(this.Index_Header_Data, this.IndexHeaderCrc);
|
||||
//构造PVF数据类
|
||||
this.ScriptDataObject = new ScriptTree(
|
||||
//文件数据
|
||||
this.Index_Header_Data,
|
||||
//整个Pvf的原始数据
|
||||
this.ScriptDataBuffer
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//当期读取树数据的Pos
|
||||
CurrentTreePos = 0;
|
||||
//当前读取文件下标
|
||||
CurrentIndex = 0;
|
||||
ReadPathTree() {
|
||||
//开始时间
|
||||
const StartTime = new Date().getTime();
|
||||
//死循环读取树文件数据 但是每一次最多只读15毫秒 为了保证UI线程刷新
|
||||
while (true) {
|
||||
//当前时间减去开始时间
|
||||
const NowTime = new Date().getTime();
|
||||
if ((NowTime - StartTime) >= 15) break;
|
||||
//当前读取的下标小于总数量
|
||||
if (this.CurrentIndex < this.IndexSize) {
|
||||
const Length = this.ScriptDataObject.ReadTree(
|
||||
this.CurrentTreePos,
|
||||
this.AlignedIndexHeaderSize + 56,
|
||||
this.CurrentIndex
|
||||
);
|
||||
this.CurrentTreePos += Length;
|
||||
this.CurrentIndex++;
|
||||
}
|
||||
//如果不小于 说明读完了
|
||||
else {
|
||||
//读取bin文件 bin Map
|
||||
const Flag = this.ScriptDataObject.InitStringBin();
|
||||
if (Flag) {
|
||||
//读取字符串索引
|
||||
this.ScriptDataObject.InitLoad_String();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GetDataByPath(Path: string) {
|
||||
return this.ScriptDataObject.TreeMap.get(Path);
|
||||
}
|
||||
}
|
||||
|
||||
@ccclass("GameScript")
|
||||
export class GameScript extends Component {
|
||||
//全局单例类
|
||||
private static instance: GameScript;
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance(): GameScript {
|
||||
if (!GameScript.instance) {
|
||||
GameScript.instance = new GameScript();
|
||||
}
|
||||
return GameScript.instance;
|
||||
}
|
||||
|
||||
//Pvf对象
|
||||
PvfData: ScriptData;
|
||||
//加载完成后的回调函数
|
||||
LoadCallBack: Function;
|
||||
|
||||
//初始化Pvf
|
||||
Init(Func: Function) {
|
||||
//储存回调
|
||||
this.LoadCallBack = Func;
|
||||
//读取Pvf
|
||||
this.ReadPvf();
|
||||
}
|
||||
|
||||
//读取原始数据
|
||||
ReadPvf() {
|
||||
resources.load("Script/Rindro_Script", BufferAsset, (err, content) => {
|
||||
//转化原始数据为Uint8数组
|
||||
const Buf = new Uint8Array(content.buffer());
|
||||
//构造一个 读取流对象
|
||||
const ScriptObj = new ReadStream(Buf);
|
||||
//读取UUID的长度
|
||||
const UUID_LENGTH = ScriptObj.GetInt();
|
||||
//UUID 读 1 - 36位 构造 UTF8 string
|
||||
const UUID = ScriptObj.GetString(UUID_LENGTH);
|
||||
//版本号
|
||||
const Version = ScriptObj.GetInt();
|
||||
// 文件路径数据的大小
|
||||
const AlignedIndexHeaderSize = ScriptObj.GetInt();
|
||||
// 解密密钥
|
||||
const IndexHeaderCrc = ScriptObj.GetInt();
|
||||
// 文件数量
|
||||
const IndexSize = ScriptObj.GetInt();
|
||||
// 存放文件路径数据
|
||||
const Index_Header_Data = ScriptObj.GetBufferByLength(AlignedIndexHeaderSize);
|
||||
|
||||
this.PvfData = new ScriptData(
|
||||
Buf,
|
||||
UUID_LENGTH,
|
||||
UUID,
|
||||
Version,
|
||||
AlignedIndexHeaderSize,
|
||||
IndexHeaderCrc,
|
||||
IndexSize,
|
||||
Index_Header_Data
|
||||
);
|
||||
|
||||
//建立文件索引树
|
||||
this.PvfData.InitPathTree();
|
||||
//可以开始读取PVF数据
|
||||
this.StartInitFlag = true;
|
||||
});
|
||||
}
|
||||
|
||||
//可以开始读取PVF数据
|
||||
StartInitFlag = false;
|
||||
//是否已经读取完成
|
||||
InitFlag = false;
|
||||
Update() {
|
||||
if (!this.InitFlag && this.StartInitFlag) {
|
||||
const Flag = this.PvfData.ReadPathTree();
|
||||
if (Flag) {
|
||||
this.LoadCallBack();
|
||||
this.InitFlag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetDataByPath(Path: string) {
|
||||
const Ret = this.PvfData.ScriptDataObject.GetFileData(Path);
|
||||
if (Ret) return Ret;
|
||||
else console.error("索引路径不存在: " + Path);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "00363c32-9301-40ae-9cec-bfbeabf44c51",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "f264c8dc-cc2a-4860-871b-18e75f0a85f6",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
import { Node, AudioSource, AudioClip, resources, director, _decorator, TextAsset, error, JsonAsset } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* this is a sington class for audio play, can be easily called from anywhere in you project.
|
||||
* @zh
|
||||
* 这是一个用于播放音频的单件类,可以很方便地在项目的任何地方调用。
|
||||
*/
|
||||
export class GlobalAudio {
|
||||
|
||||
AudioManager: object;
|
||||
|
||||
//@zh 创建一个节点作为 GlobalAudio
|
||||
private static instance: GlobalAudio;
|
||||
|
||||
public static getInstance(): GlobalAudio {
|
||||
if (!GlobalAudio.instance) {
|
||||
GlobalAudio.instance = new GlobalAudio();
|
||||
}
|
||||
return GlobalAudio.instance;
|
||||
}
|
||||
|
||||
private _audioSource: AudioSource;
|
||||
constructor() {
|
||||
//@en create a node as GlobalAudio
|
||||
//@zh 创建一个节点作为 GlobalAudio
|
||||
let GlobalAudio = new Node();
|
||||
GlobalAudio.name = '__GlobalAudio__';
|
||||
|
||||
//@en add to the scene.
|
||||
//@zh 添加节点到场景
|
||||
director.getScene().addChild(GlobalAudio);
|
||||
|
||||
//@en make it as a persistent node, so it won't be destroied when scene change.
|
||||
//@zh 标记为常驻节点,这样场景切换的时候就不会被销毁了
|
||||
director.addPersistRootNode(GlobalAudio);
|
||||
|
||||
//@en add AudioSource componrnt to play audios.
|
||||
//@zh 添加 AudioSource 组件,用于播放音频。
|
||||
this._audioSource = GlobalAudio.addComponent(AudioSource);
|
||||
}
|
||||
|
||||
|
||||
//初始化完成以后的回调方法
|
||||
LoadCallBack: Function;
|
||||
Init(Func: Function) {
|
||||
//储存回调
|
||||
this.LoadCallBack = Func;
|
||||
this.LoadAudioXml();
|
||||
}
|
||||
|
||||
|
||||
//加载音频Map
|
||||
LoadAudioXml() {
|
||||
resources.load("Sound/audio", (err, json: JsonAsset) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
this.AudioManager = json.json!;
|
||||
this.LoadCallBack();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
PlaySound(sound: string, volume: number = 1.0) {
|
||||
if (this.AudioManager.hasOwnProperty(sound)) {
|
||||
this.playOneShot(this.AudioManager[sound], volume);
|
||||
}
|
||||
else {
|
||||
console.error("音频不存在,路径: " + sound);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public get audioSource() {
|
||||
return this._audioSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* play short audio, such as strikes,explosions
|
||||
* @zh
|
||||
* 播放短音频,比如 打击音效,爆炸音效等
|
||||
* @param sound clip or url for the audio
|
||||
* @param volume
|
||||
*/
|
||||
playOneShot(sound: AudioClip | string, volume: number = 1.0) {
|
||||
if (sound instanceof AudioClip) {
|
||||
this._audioSource.playOneShot(sound, volume);
|
||||
}
|
||||
else {
|
||||
resources.load(sound, (err, clip: AudioClip) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
this._audioSource.playOneShot(clip, volume);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* play long audio, such as the bg music
|
||||
* @zh
|
||||
* 播放长音频,比如 背景音乐
|
||||
* @param sound clip or url for the sound
|
||||
* @param volume
|
||||
*/
|
||||
play(sound: AudioClip | string, volume: number = 1.0) {
|
||||
if (sound instanceof AudioClip) {
|
||||
this._audioSource.clip = sound;
|
||||
this._audioSource.play();
|
||||
this.audioSource.volume = volume;
|
||||
}
|
||||
else {
|
||||
resources.load(sound, (err, clip: AudioClip) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
this._audioSource.clip = clip;
|
||||
this._audioSource.play();
|
||||
this.audioSource.volume = volume;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop the audio play
|
||||
*/
|
||||
stop() {
|
||||
this._audioSource.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* pause the audio play
|
||||
*/
|
||||
pause() {
|
||||
this._audioSource.pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* resume the audio play
|
||||
*/
|
||||
resume() {
|
||||
this._audioSource.play();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "558c9b23-b4be-4a87-8017-8c41659d1a14",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "42592cb2-3cce-4c2b-a354-ba95a624d365",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import { _decorator, Component, Node } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
type ResumeCallback<T> = (arg: T) => void;
|
||||
|
||||
@ccclass('GameState')
|
||||
export class GameState extends Component {
|
||||
|
||||
private static instance: GameState;
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance(): GameState {
|
||||
if (!GameState.instance) {
|
||||
GameState.instance = new GameState();
|
||||
}
|
||||
return GameState.instance;
|
||||
}
|
||||
|
||||
|
||||
/** 当前是否处于暂停状态 */
|
||||
PauseState: boolean = false;
|
||||
/** 改变暂停状态的回调函数 */
|
||||
ResumeCallBackFunc: ResumeCallback<any>[] = [];
|
||||
|
||||
|
||||
/** 获取暂停状态 */
|
||||
IsPauseState(): boolean {
|
||||
return this.PauseState;
|
||||
}
|
||||
|
||||
/** 设置暂停状态 */
|
||||
SetCurrentPauseState(State: boolean) {
|
||||
//不等于时 设置一次
|
||||
if (State != this.PauseState) {
|
||||
this.PauseState = State;
|
||||
|
||||
//调用恢复游戏的逻辑回调函数
|
||||
this.ResumeCallBackFunc.forEach(callback => {
|
||||
callback(State);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** 注册恢复游戏的逻辑回调函数 */
|
||||
RegisterResumeCallBack(Func: ResumeCallback<any>) {
|
||||
this.ResumeCallBackFunc.push(Func);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d9a7592d-eb74-437b-a38e-e3381e9965a2",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "d3628f81-a33c-4562-a26a-218f4c193c6c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
export enum ENUM_CHARACTER {
|
||||
SWORDMAN = 0,
|
||||
FIGHTER = 1,
|
||||
GUNNER = 2,
|
||||
MAGE = 3,
|
||||
PRIEST = 4,
|
||||
ATGUNNER = 5,
|
||||
THIEF = 6,
|
||||
ATFIGHTER = 7,
|
||||
ATMAGE = 8,
|
||||
DEMONICSWORDMAN = 9,
|
||||
CREATORMAGE = 10
|
||||
}
|
||||
|
||||
export enum ENUM_SKIN_ANIMATION_JOB {
|
||||
SWORDMAN = "Character/Swordman/Equipment/Avatar/skin/sm_body%04d.img",
|
||||
FIGHTER = 1,
|
||||
GUNNER = 2,
|
||||
MAGE = 3,
|
||||
PRIEST = 4,
|
||||
ATGUNNER = 5,
|
||||
THIEF = 6,
|
||||
ATFIGHTER = 7,
|
||||
ATMAGE = 8,
|
||||
DEMONICSWORDMAN = 9,
|
||||
CREATORMAGE = 10
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "40479425-c3f8-43b0-a879-1b8aa1e9f619",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import { SpriteFrame, Vec2, Vec3 } from "cc";
|
||||
|
||||
//PNG结构体
|
||||
export interface ImgInfo {
|
||||
Type?: number; //图片格式
|
||||
CmpType?: number; //压缩类型
|
||||
Width?: number; //宽度
|
||||
Height?: number; //高度
|
||||
Size?: number; //大小
|
||||
Xpos?: number; //Xpos
|
||||
Ypos?: number; //Ypos
|
||||
FrameXpos?: number; //帧域X
|
||||
FrameYpos?: number; //帧域Y
|
||||
Offset?: number; //偏移
|
||||
PNGdata?: Uint8Array; //Png位图数据
|
||||
QuoteIndex?: number;//引用贴图编号
|
||||
}
|
||||
|
||||
//NPK结构体
|
||||
export interface NpkInfo {
|
||||
Offset: number;
|
||||
Length: number;
|
||||
Path: string;
|
||||
}
|
||||
|
||||
//Img结构体
|
||||
export interface Img {
|
||||
ImgName: string; //img文件的路径
|
||||
Img_Index: number; //img文件在npk文件里的序号
|
||||
ImgOffset: number; //img偏移
|
||||
ImgSize: number; //img大小
|
||||
BelongsFile: string; //img属于哪个文件
|
||||
Png_Count: number; //img有多少张png文件
|
||||
Png_List: ImgInfo[] | null; //img的Png文件数组
|
||||
}
|
||||
|
||||
//Ani_Frame结构体
|
||||
export interface Ani_Frame {
|
||||
Box?: Map<number, Array<number>>; //碰撞框
|
||||
Img_Path?: string;//Img路径
|
||||
Img_Index?: number; //调用的Png下标 去Img中索引
|
||||
Pos?: Vec3; //坐标
|
||||
Flag?: Map<string, any>; //标签数组
|
||||
Delay?: number;//帧延时
|
||||
Frame?: SpriteFrame; //精灵帧
|
||||
}
|
||||
|
||||
//Ani结构体
|
||||
export interface ScriptAni {
|
||||
Img_List: Array<string>; //调用的Img路径数组
|
||||
Flag: Map<string, number>; //标签数组
|
||||
Frame: Array<Ani_Frame>; //帧对象
|
||||
}
|
||||
|
||||
//Ani结构体
|
||||
export interface ScriptAls {
|
||||
Name?: string; //Ani的名字
|
||||
Path?: string;//Ani的路径
|
||||
Layer?: Number;//图层
|
||||
FrameIndex?: Number;//开始播放帧数
|
||||
}
|
||||
|
||||
|
||||
//Pvf文件结构图
|
||||
export interface ScriptFile {
|
||||
StartPos?: number;//开始位置
|
||||
Cre32?: number;//校验数据
|
||||
Offset?: number; //数据偏移
|
||||
Length?: number; //数据长度
|
||||
Data?: any; //数据
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a1cdc96d-640e-43ca-bab1-410318f5a83b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "efd7a226-b044-490c-ba21-d6a508f5e54e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
import { _decorator, Asset, assetManager, BufferAsset, Component, error, Node, resources, TextAsset, Texture2D } from 'cc';
|
||||
import { ReadStream } from '../Tool/ReadStream';
|
||||
import * as pako from 'pako';
|
||||
import { Img, ImgInfo, NpkInfo } from '../GlobalInterface/GlobalInterface';
|
||||
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
type NewType = Img;
|
||||
|
||||
@ccclass('ImagePack')
|
||||
export class ImagePack extends Component {
|
||||
|
||||
//全局单例类
|
||||
private static instance: ImagePack;
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance(): ImagePack {
|
||||
if (!ImagePack.instance) {
|
||||
ImagePack.instance = new ImagePack();
|
||||
}
|
||||
return ImagePack.instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Key: Array<number> = [112, 117, 99, 104, 105, 107, 111, 110, 64, 110, 101, 111, 112, 108, 101, 32, 100, 117, 110, 103, 101, 111, 110, 32, 97, 110, 100, 32, 102, 105, 103, 104, 116, 101, 114, 32, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 68, 78, 70, 0];
|
||||
|
||||
|
||||
//NPK加载完成后的回调函数
|
||||
LoadCallBack = undefined;
|
||||
//NPK文件数量
|
||||
private NpkCount = 0;
|
||||
//已加载NPK文件数量
|
||||
private LoadNpkCount = 0;
|
||||
//Img的map Key:img路径 Value:Img结构体
|
||||
private Map_Img: Map<string, NewType> = new Map<string, Img>();
|
||||
//NPK的本地路径 对应的 NPK名字
|
||||
private Npk_URL_Table: Map<string, string> = new Map<string, string>();
|
||||
|
||||
|
||||
|
||||
start() {
|
||||
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
initSuccess(): void {
|
||||
if (this.LoadCallBack) this.LoadCallBack();
|
||||
}
|
||||
|
||||
BundleObject;
|
||||
init(Func: Function): void {
|
||||
//储存回调
|
||||
this.LoadCallBack = Func;
|
||||
|
||||
assetManager.loadBundle('ImagePacks', (err, bundle) => {
|
||||
this.BundleObject = bundle;
|
||||
this.LoadNpk();
|
||||
});
|
||||
}
|
||||
|
||||
NpkHasImg: Map<string, Array<string>> = new Map<string, Array<string>>();
|
||||
LoadNpk(): void {
|
||||
this.BundleObject.loadDir("", BufferAsset, (err, contents: Array<BufferAsset>) => {
|
||||
//记录NPK文件数量
|
||||
this.NpkCount = contents.length;
|
||||
console.log(this.NpkCount);
|
||||
|
||||
contents.forEach(content => {
|
||||
let ImgArr: Array<string> = [];
|
||||
const Buf = new Uint8Array(content.buffer());
|
||||
const Ro = new ReadStream(Buf);
|
||||
//文件头
|
||||
const Header = Ro.GetString();
|
||||
if (Header == "NeoplePack_Bill") {
|
||||
//读取img数量
|
||||
const ImageCount = Ro.GetInt();
|
||||
let ImgList: NpkInfo[] = new Array<NpkInfo>(ImageCount);
|
||||
for (let i = 0; i < ImageCount; i++) {
|
||||
ImgList[i] = {
|
||||
Offset: Ro.GetInt(),
|
||||
Length: Ro.GetInt(),
|
||||
Path: Ro.ReadInfo(this.Key),
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < ImageCount; i++) {
|
||||
ImgArr.push(ImgList[i].Path);
|
||||
let Buf: Img = {
|
||||
ImgOffset: ImgList[i].Offset,
|
||||
ImgSize: ImgList[i].Length,
|
||||
Img_Index: i,
|
||||
BelongsFile: content.nativeUrl,
|
||||
ImgName: ImgList[i].Path,
|
||||
Png_List: null,
|
||||
Png_Count: 0
|
||||
}
|
||||
this.Map_Img.set(ImgList[i].Path, Buf);
|
||||
}
|
||||
|
||||
this.NpkHasImg.set(content.name, ImgArr);
|
||||
}
|
||||
|
||||
//完成一个加载
|
||||
this.LoadNpkCount = this.LoadNpkCount + 1;
|
||||
//把本地路径和NPK名称挂钩一下
|
||||
this.Npk_URL_Table.set(content.nativeUrl, content.name);
|
||||
//载入完成以后需要释放
|
||||
assetManager.releaseAsset(content);
|
||||
//加载完成
|
||||
if (this.LoadNpkCount == this.NpkCount) {
|
||||
this.initSuccess();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
LoadImgToMem(ImgObj: Img, func: Function) {
|
||||
|
||||
//获取路径 如果不存在直接返回
|
||||
const Path = this.Npk_URL_Table.get(ImgObj.BelongsFile);
|
||||
if (!Path) return;
|
||||
this.BundleObject.load(Path, BufferAsset, (err, content) => {
|
||||
const Buf = new Uint8Array(content.buffer());
|
||||
const Ro = new ReadStream(Buf);
|
||||
|
||||
Ro.Seekg(ImgObj.ImgOffset);
|
||||
//Img头
|
||||
const Header = Ro.GetString();
|
||||
//开始读图片
|
||||
if (Header == "Neople Img File") {
|
||||
//索引表大小
|
||||
const TableLength = Ro.GetLongInt();
|
||||
|
||||
//img 版本 4字节
|
||||
const ver = Ro.GetInt();
|
||||
//img 帧数
|
||||
const IndexCount = Ro.GetInt();
|
||||
|
||||
ImgObj.Png_Count = IndexCount;
|
||||
|
||||
let PngArr: ImgInfo[] = [];
|
||||
for (let index = 0; index < IndexCount; index++) {
|
||||
|
||||
let ImgBuf: ImgInfo = {};
|
||||
|
||||
//图片格式
|
||||
ImgBuf.Type = Ro.GetInt();
|
||||
if (ImgBuf.Type == 17) {
|
||||
//引用贴图
|
||||
const IndexBuf = Ro.GetInt();
|
||||
ImgBuf.Offset = PngArr[index - 1].Offset;
|
||||
ImgBuf.Type = 17;
|
||||
ImgBuf.QuoteIndex = IndexBuf;
|
||||
ImgBuf.Size = PngArr[index - 1].Size;
|
||||
PngArr.push(ImgBuf);
|
||||
continue;
|
||||
}
|
||||
//压缩类型
|
||||
ImgBuf.CmpType = Ro.GetInt();
|
||||
//宽度
|
||||
ImgBuf.Width = Ro.GetInt();
|
||||
//高度
|
||||
ImgBuf.Height = Ro.GetInt();
|
||||
//大小
|
||||
ImgBuf.Size = Ro.GetInt();
|
||||
//Xpos
|
||||
ImgBuf.Xpos = Ro.GetInt();
|
||||
//Ypos
|
||||
ImgBuf.Ypos = Ro.GetInt();
|
||||
//帧域X
|
||||
ImgBuf.FrameXpos = Ro.GetInt();
|
||||
//帧域Y
|
||||
ImgBuf.FrameYpos = Ro.GetInt();
|
||||
|
||||
if (index == 0) {
|
||||
ImgBuf.Offset = 0 + ImgObj.ImgOffset + Number(TableLength) + 32;
|
||||
} else {
|
||||
ImgBuf.Offset = PngArr[index - 1].Offset + PngArr[index - 1].Size;
|
||||
}
|
||||
PngArr.push(ImgBuf);
|
||||
}
|
||||
|
||||
for (let index = 0; index < IndexCount; index++) {
|
||||
let PngObj = PngArr[index];
|
||||
//引用贴图
|
||||
if (PngObj.Type == 17) {
|
||||
const QuoteIndexBuf = PngObj.QuoteIndex;
|
||||
PngArr[index] = PngArr[QuoteIndexBuf];
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < IndexCount; index++) {
|
||||
let PngObj = PngArr[index];
|
||||
|
||||
|
||||
Ro.Seekg(PngObj.Offset);
|
||||
//PNG压缩原始数据
|
||||
let DataBuf = Ro.GetBufferByLength(PngObj.Size);
|
||||
|
||||
//图片数据应有大小
|
||||
let PngBufSize = PngObj.Width * PngObj.Height * 4;
|
||||
// 使用pako 解压 zlib的inflate函数解压缩数据
|
||||
let Bsf;
|
||||
try {
|
||||
Bsf = pako.inflate(DataBuf);
|
||||
}
|
||||
catch (error) {
|
||||
Bsf = DataBuf;
|
||||
}
|
||||
|
||||
if (PngObj.Type != 16) {
|
||||
let PngByteSize = Bsf.length * 2;
|
||||
PngObj.PNGdata = new Uint8Array(PngByteSize);
|
||||
for (let e = 0; e < PngByteSize; e += 4) {
|
||||
let BarBuf = new Uint8Array(2);
|
||||
|
||||
let Pos = (e / 4) * 2;
|
||||
BarBuf[0] = Bsf[Pos];
|
||||
BarBuf[1] = Bsf[Pos + 1];
|
||||
this.ReadColor(BarBuf, PngObj, e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PngObj.PNGdata = new Uint8Array(Bsf.length);
|
||||
for (let index = 0; index < Bsf.length; index += 4) {
|
||||
PngObj.PNGdata[index] = Bsf[index + 2];
|
||||
PngObj.PNGdata[index + 1] = Bsf[index + 1];
|
||||
PngObj.PNGdata[index + 2] = Bsf[index];
|
||||
PngObj.PNGdata[index + 3] = Bsf[index + 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
ImgObj.Png_List = PngArr;
|
||||
func(ImgObj);
|
||||
}
|
||||
|
||||
//载入完成以后需要释放
|
||||
assetManager.releaseAsset(content);
|
||||
});
|
||||
}
|
||||
|
||||
ReadColor(Bar: Uint8Array, PngObj: ImgInfo, Offset: number) {
|
||||
let a: number = 0;
|
||||
let r: number = 0;
|
||||
let g: number = 0;
|
||||
let b: number = 0;
|
||||
switch (PngObj.Type) {
|
||||
case 0x0e:
|
||||
a = Bar[1] >> 7;
|
||||
r = (Bar[1] >> 2) & 0x1f;
|
||||
g = (Bar[0] >> 5) | ((Bar[1] & 3) << 3);
|
||||
b = Bar[0] & 0x1f;
|
||||
a = a * 0xff;
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 3) | (g >> 2);
|
||||
b = (b << 3) | (b >> 2);
|
||||
break;
|
||||
case 0x0f:
|
||||
a = Bar[1] & 0xf0;
|
||||
r = (Bar[1] & 0xf) << 4;
|
||||
g = Bar[0] & 0xf0;
|
||||
b = (Bar[0] & 0xf) << 4;
|
||||
break;
|
||||
default:
|
||||
console.log(PngObj.Type);
|
||||
break;
|
||||
}
|
||||
PngObj.PNGdata[Offset + 0] = r;
|
||||
PngObj.PNGdata[Offset + 1] = g;
|
||||
PngObj.PNGdata[Offset + 2] = b;
|
||||
PngObj.PNGdata[Offset + 3] = a;
|
||||
}
|
||||
|
||||
|
||||
//读取Img数据
|
||||
ReadNpkTable(imgname: string, func: Function): boolean {
|
||||
let ImgObj: Img = this.Map_Img.get(imgname);
|
||||
if (ImgObj) {
|
||||
//没有图片数据 需要加载
|
||||
if (ImgObj.Png_List == null) {
|
||||
//加载Img进内存
|
||||
this.LoadImgToMem(ImgObj, func);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
func(ImgObj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadNpkImgCount = 0;
|
||||
//读取Npk数据
|
||||
ReadNpkFile(npkname: string, func: Function): number {
|
||||
let ImgArr = this.NpkHasImg.get(npkname);
|
||||
|
||||
ImgArr.forEach(imgname => {
|
||||
let ImgObj: Img = this.Map_Img.get(imgname);
|
||||
if (ImgObj) {
|
||||
//没有图片数据 需要加载
|
||||
if (ImgObj.Png_List == null) {
|
||||
//加载Img进内存
|
||||
this.LoadImgToMem(ImgObj, func);
|
||||
}
|
||||
else {
|
||||
func(ImgObj);
|
||||
}
|
||||
}
|
||||
});
|
||||
return ImgArr.length;
|
||||
}
|
||||
|
||||
ReleaseNpkTable(p: Img): void {
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f7d818a6-8209-4350-9000-21ecbb294559",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "e8cc263d-e946-466c-946c-cc228badc633",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import { _decorator, Component, Node } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
@ccclass('GlobalTool')
|
||||
export class GlobalTool {
|
||||
|
||||
public static CrcDecode(data: Uint8Array, crc32: number): void {
|
||||
const num: number = 2175242257; // 2175242257L in hexadecimal
|
||||
const dataView = new DataView(
|
||||
data.buffer,
|
||||
data.byteOffset,
|
||||
data.byteLength
|
||||
);
|
||||
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
// Ensure we don't read beyond the end of the data
|
||||
if (i + 4 > data.length) break;
|
||||
|
||||
// Read a 32-bit integer (little endian) from the buffer
|
||||
let anInt = dataView.getUint32(i, true);
|
||||
|
||||
// Perform the XOR operations
|
||||
let val = anInt ^ num ^ crc32;
|
||||
|
||||
// Rotate right 6 bits
|
||||
let jiemi = (val >>> 6) | (val << (32 - 6));
|
||||
|
||||
// Write the result back into the buffer
|
||||
dataView.setUint32(i, jiemi, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//字节数组转string
|
||||
public static uint8ArrayToString(data: Uint8Array, Code?: string): string {
|
||||
if (!Code) Code = 'utf-8';
|
||||
const decoder = new TextDecoder(Code); // 默认使用 'utf-8' 编码
|
||||
return decoder.decode(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "7ceba3e6-9582-4e7c-b045-63cb904ed4a3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
import { _decorator, Component, Node } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('ReadStream')
|
||||
export class ReadStream {
|
||||
|
||||
Buffer: Uint8Array;
|
||||
|
||||
//当前读取位置
|
||||
Pos: number = 0;
|
||||
|
||||
constructor(public buffer: Uint8Array) {
|
||||
this.Buffer = buffer;
|
||||
}
|
||||
|
||||
//string转字节数组
|
||||
static StringToUint8Array(str) {
|
||||
const encoder = new TextEncoder();
|
||||
return encoder.encode(str);
|
||||
}
|
||||
|
||||
//字节数组转string
|
||||
static Uint8ArrayToString(data: Uint8Array): string {
|
||||
const decoder = new TextDecoder(); // 默认使用 'utf-8' 编码
|
||||
return decoder.decode(data);
|
||||
}
|
||||
|
||||
Seekg(Pos: number) {
|
||||
this.Pos = Pos;
|
||||
}
|
||||
|
||||
//读取数字 默认小端序读取
|
||||
GetShort(littleEndian: boolean = true) {
|
||||
//读2个字节
|
||||
const Buf = new DataView(this.GetBufferByLength(2).buffer);
|
||||
const view = new DataView(Buf.buffer);
|
||||
return Number(view.getInt16(0, true));
|
||||
}
|
||||
|
||||
GetUShort(littleEndian: boolean = true) {
|
||||
//读2个字节
|
||||
const Buf = new DataView(this.GetBufferByLength(2).buffer);
|
||||
const view = new DataView(Buf.buffer);
|
||||
return Number(view.getUint16(0, true));
|
||||
}
|
||||
|
||||
//读取数字 默认小端序读取
|
||||
GetInt(littleEndian: boolean = true) {
|
||||
//读4个字节
|
||||
const Buf = new DataView(this.GetBufferByLength(4).buffer);
|
||||
return Buf.getInt32(0, littleEndian);
|
||||
}
|
||||
|
||||
//读取浮点数 默认小端序读取
|
||||
GetFloat(littleEndian: boolean = true) {
|
||||
//读4个字节
|
||||
const Buf = new DataView(this.GetBufferByLength(4).buffer);
|
||||
return Buf.getFloat32(0, littleEndian);
|
||||
}
|
||||
|
||||
//特殊方法
|
||||
Get256(): any {
|
||||
const Buf = Number(this.GetBufferByLength(1));
|
||||
return (256.0 + Buf) % 256.0;
|
||||
}
|
||||
|
||||
//读取数字 默认小端序
|
||||
GetLongInt(littleEndian: boolean = true) {
|
||||
//读8个字节
|
||||
const Buf = this.GetBufferByLength(8);
|
||||
|
||||
const view = new DataView(Buf.buffer);
|
||||
return Number(view.getBigInt64(0, true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//读取字符串
|
||||
GetString(Length?: number) {
|
||||
if (Length) {
|
||||
//读指定字节
|
||||
const Buf = this.GetBufferByLength(Length);
|
||||
return ReadStream.Uint8ArrayToString(Buf);
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < this.Buffer.length - this.Pos; i++) {
|
||||
if (this.Buffer[i + this.Pos] == 0) {
|
||||
const truncatedArray = this.Buffer.subarray(this.Pos, i + this.Pos);
|
||||
this.Pos += i + 1;
|
||||
return ReadStream.Uint8ArrayToString(truncatedArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//读取指定长度流
|
||||
GetBufferByLength(Length: number) {
|
||||
const Buf = this.Buffer.slice(this.Pos, this.Pos + Length);
|
||||
this.Pos += Length;
|
||||
return Buf;
|
||||
}
|
||||
|
||||
//读取信息 通过Key
|
||||
ReadInfo(Key): string {
|
||||
let PathUA: Uint8Array = new Uint8Array(256);
|
||||
for (let i = 0; i < 256; i++) {
|
||||
PathUA[i] = this.Buffer[i + this.Pos] ^ Key[i];
|
||||
}
|
||||
// let Spos = 0;
|
||||
// for (let i = 0; i < PathUA.length; i++) {
|
||||
// if (PathUA[i] == 0) Spos = i;
|
||||
// }
|
||||
|
||||
// const truncatedArray = PathUA.subarray(0, Spos);
|
||||
|
||||
this.Pos += 256;
|
||||
let str = ReadStream.Uint8ArrayToString(PathUA);
|
||||
str = str.substring(0, str.indexOf(".img") + 4);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
len() {
|
||||
return this.Buffer.length;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "4ec26641-bab8-41b3-aedc-0c51a9499a03",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "5b32215f-78d7-4705-baaa-53792dcadf16",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"isBundle": true,
|
||||
"bundleName": "ImagePacks"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"ver": "1.0.3",
|
||||
"importer": "buffer",
|
||||
"imported": true,
|
||||
"uuid": "6aba7d31-7435-4f59-b5aa-79256df4ede9",
|
||||
"files": [
|
||||
".bin",
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "c48db437-e006-4733-98c9-041b5842c734",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-16 15:26:27
|
||||
* @LastEditTime: 2024-03-28 21:13:04
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 最底层的地图 图层Component
|
||||
*/
|
||||
import { _decorator, Component, Node } from "cc";
|
||||
import { MapTileType, MapTileTypes } from "./MapTile/MapTileType";
|
||||
import { MapTileNode } from "./MapTile/MapTileNode";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass("BoardRoot")
|
||||
/**
|
||||
* @description: 最底层的地图 图层Component
|
||||
*/
|
||||
export class BoardRoot extends Component {
|
||||
|
||||
//* 地块nodeMap
|
||||
mapNodeMap: Map<MapTileType, Node> = new Map<MapTileType, Node>();
|
||||
|
||||
start() {
|
||||
this.initMapTile();
|
||||
}
|
||||
|
||||
/// 初始化 地图快
|
||||
initMapTile() {
|
||||
// 从枚举类型 添加所有地块
|
||||
MapTileTypes.forEach((type) => {
|
||||
const node = new MapTileNode(type);
|
||||
this.node.addChild(node);
|
||||
this.mapNodeMap.set(type, node);
|
||||
});
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "51518b7f-2c20-4641-9eab-bf32f62367b9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "2e9de9a6-2874-4cba-bb52-b2c87dbf9abd",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-22 19:50:30
|
||||
* @LastEditTime: 2024-03-24 17:09:16
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 选择卡片节点
|
||||
*/
|
||||
|
||||
import {
|
||||
_decorator,
|
||||
EventMouse,
|
||||
Node,
|
||||
Sprite,
|
||||
SpriteFrame,
|
||||
UITransform,
|
||||
v2,
|
||||
tween,
|
||||
Component,
|
||||
Label,
|
||||
Color,
|
||||
Size,
|
||||
v3,
|
||||
} from "cc";
|
||||
import { NpkImage } from "../../Tool/NPKImage";
|
||||
import { BaseSpriteFrame } from "../../GlobalScript/CommonComponent/BaseSpriteFrame";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("CardNode")
|
||||
export class CardNode extends Node {
|
||||
//普通精灵帧
|
||||
private NormalSpriteFrame: SpriteFrame;
|
||||
|
||||
// 高亮精灵帧1
|
||||
private oneSpriteFrame: SpriteFrame;
|
||||
|
||||
//高亮精灵帧2
|
||||
private twoSpriteFrame: SpriteFrame;
|
||||
|
||||
// 翻转动画
|
||||
flipsAnimation:CardFlipsAnimation;
|
||||
|
||||
//精灵对象
|
||||
private SpriteObj: Sprite;
|
||||
|
||||
// 是否按钮失效
|
||||
Disable = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const trf = this.addComponent(UITransform);
|
||||
trf.anchorPoint = v2(0.5, 1)
|
||||
trf.contentSize = new Size(178,113);
|
||||
|
||||
this.flipsAnimation = this.addComponent(CardFlipsAnimation);
|
||||
|
||||
this.initBackgroundNode();
|
||||
this.initSpriteFrame();
|
||||
this.initEvent();
|
||||
}
|
||||
|
||||
initBackgroundNode(){
|
||||
// const node = new Node();
|
||||
// this.addChild(node);
|
||||
|
||||
// const trf = node.addComponent(UITransform);
|
||||
// trf.contentSize = new Size(178,113);
|
||||
// trf.anchorPoint = v2(0,1);
|
||||
|
||||
// this.SpriteObj = node.addComponent(Sprite);
|
||||
this.SpriteObj = this.addComponent(Sprite);
|
||||
}
|
||||
|
||||
|
||||
initSpriteFrame() {
|
||||
/// 不同亮度的卡片
|
||||
new BaseSpriteFrame(NpkImage.ingame, 47, (SpriteFrame: SpriteFrame) => {
|
||||
this.NormalSpriteFrame = SpriteFrame;
|
||||
this.SpriteObj.spriteFrame = SpriteFrame;
|
||||
});
|
||||
new BaseSpriteFrame(NpkImage.ingame, 48, (SpriteFrame: SpriteFrame) => {
|
||||
this.oneSpriteFrame = SpriteFrame;
|
||||
});
|
||||
new BaseSpriteFrame(NpkImage.ingame, 49, (SpriteFrame: SpriteFrame) => {
|
||||
this.twoSpriteFrame = SpriteFrame;
|
||||
});
|
||||
}
|
||||
|
||||
initEvent() {
|
||||
this.on(Node.EventType.MOUSE_ENTER, this.OnHever, this);
|
||||
this.on(Node.EventType.MOUSE_LEAVE, this.OffHever, this);
|
||||
this.on(Node.EventType.MOUSE_DOWN, this.OnDown, this);
|
||||
}
|
||||
|
||||
OffHever() {
|
||||
if (this.Disable) return;
|
||||
this.SpriteObj.spriteFrame = this.NormalSpriteFrame;
|
||||
}
|
||||
OnHever() {
|
||||
if (this.Disable) return;
|
||||
this.SpriteObj.spriteFrame = this.oneSpriteFrame;
|
||||
}
|
||||
|
||||
OnDown(event: EventMouse) {
|
||||
//必须是鼠标左键
|
||||
if (event.getButton() != EventMouse.BUTTON_LEFT || this.Disable) return;
|
||||
this.SpriteObj.spriteFrame = this.twoSpriteFrame;
|
||||
this.Disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description: 卡片的翻转动画
|
||||
*/
|
||||
export class CardFlipsAnimation extends Component {
|
||||
// 数字1精灵帧
|
||||
oneSpriteFrame: SpriteFrame;
|
||||
|
||||
//数字2精灵帧
|
||||
twoSpriteFrame: SpriteFrame;
|
||||
|
||||
//数字2精灵帧
|
||||
threeSpriteFrame: SpriteFrame;
|
||||
|
||||
// 数字
|
||||
value: number;
|
||||
|
||||
// 单次缓动时间
|
||||
tweenTime: number = 0.5;
|
||||
|
||||
// 玩家名称
|
||||
nameNode: Node;
|
||||
|
||||
scale = {x:1};
|
||||
|
||||
onLoad() {
|
||||
/// 数字卡片
|
||||
new BaseSpriteFrame(NpkImage.ingame, 50, (SpriteFrame: SpriteFrame) => {
|
||||
this.oneSpriteFrame = SpriteFrame;
|
||||
});
|
||||
new BaseSpriteFrame(NpkImage.ingame, 51, (SpriteFrame: SpriteFrame) => {
|
||||
this.twoSpriteFrame = SpriteFrame;
|
||||
});
|
||||
new BaseSpriteFrame(NpkImage.ingame, 52, (SpriteFrame: SpriteFrame) => {
|
||||
this.threeSpriteFrame = SpriteFrame;
|
||||
});
|
||||
|
||||
|
||||
// this.nameLabel = this.node.addComponent(Label);
|
||||
|
||||
}
|
||||
|
||||
start() {}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 翻转动画
|
||||
* @param {1} value: 这个卡牌反转后是几
|
||||
*/
|
||||
animationStart(value: number,name:string) {
|
||||
this.value = value;
|
||||
if (value > 2) this.value = 2;
|
||||
|
||||
this.initNmaeNode(name);
|
||||
|
||||
tween(this.scale).to(this.tweenTime, { x: 0,},{onComplete:()=>{
|
||||
this.flipsTweenBack();
|
||||
},onUpdate:()=>{
|
||||
this.node.scale = v3(this.scale.x,1,1);
|
||||
},easing:'linear'}).start();
|
||||
}
|
||||
|
||||
flipsTweenBack(){
|
||||
const spriteFrames = [this.oneSpriteFrame,this.twoSpriteFrame,this.threeSpriteFrame];
|
||||
this.node.getComponent(Sprite).spriteFrame = spriteFrames[this.value];
|
||||
this.nameNode.active = true;
|
||||
|
||||
tween(this.scale).to(this.tweenTime, { x: 1,},{onUpdate:()=>{
|
||||
this.node.scale = v3(this.scale.x,1,1);
|
||||
},easing:'linear'}).start();
|
||||
}
|
||||
|
||||
|
||||
initNmaeNode(name:string){
|
||||
const nameNode = new Node('label');
|
||||
this.node.addChild(nameNode);
|
||||
this.nameNode = nameNode;
|
||||
|
||||
nameNode.active = false;
|
||||
nameNode.setPosition(0,-75);
|
||||
|
||||
const trf = nameNode.addComponent(UITransform);
|
||||
trf.anchorPoint = v2(0.5,1);
|
||||
trf.contentSize = new Size(178,20);
|
||||
|
||||
const label = nameNode.addComponent(Label);
|
||||
label.overflow = Label.Overflow.CLAMP;
|
||||
label.string = name;
|
||||
label.fontSize = 15;
|
||||
label.color = Color.RED;
|
||||
label.horizontalAlign = Label.HorizontalAlign.CENTER;
|
||||
label.verticalAlign = Label.VerticalAlign.CENTER;
|
||||
|
||||
}
|
||||
|
||||
update(dt: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d249ab2c-fe35-459a-915d-a40a053488e2",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-19 17:44:59
|
||||
* @LastEditTime: 2024-03-29 14:00:11
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 弹窗
|
||||
*/
|
||||
import { _decorator, Component } from "cc";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("DialogRoot")
|
||||
/**
|
||||
* @description: 弹窗
|
||||
*/
|
||||
export class DialogRoot extends Component {
|
||||
|
||||
|
||||
start() {}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "11718503-cecd-42ad-add9-e4e3abe19e2b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-26 11:44:58
|
||||
* @LastEditTime: 2024-03-29 14:02:43
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 幸运硬币效果类型
|
||||
*/
|
||||
import {
|
||||
_decorator,
|
||||
Sprite,
|
||||
Director,
|
||||
director,
|
||||
Node,
|
||||
tween,
|
||||
UITransform,
|
||||
v2,
|
||||
Color,
|
||||
} from "cc";
|
||||
import { AnimationNode } from "../../GlobalScript/Animation/AnimationNode";
|
||||
import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite";
|
||||
import { NpkImage } from "../../Tool/NPKImage";
|
||||
import { CloseButtonNode } from "../Common/CloseButtonNode";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* @description: 幸运硬币效果类型
|
||||
*/
|
||||
export enum LuckyType {
|
||||
/** 前进三格 */
|
||||
GoThree = 0,
|
||||
/** 移动到月光酒馆 */
|
||||
YeGuangJiuGuan,
|
||||
/** 移动到决斗场 */
|
||||
JueDouChang,
|
||||
/** 移动到海上列车 */
|
||||
HaiShangLieChe,
|
||||
/** 我要双倍,点数x2 */
|
||||
Double,
|
||||
/** 这是我的钱,点数减半 */
|
||||
Halve,
|
||||
/** 骑士马战 ,点数+2w */
|
||||
HorseCombat,
|
||||
/** 装备修理, 点数-2w */
|
||||
Servicing,
|
||||
/** 收取费用,夺取其他人 2w 点数 */
|
||||
Charge,
|
||||
}
|
||||
|
||||
@ccclass("LuckyCoinsNode")
|
||||
export class LuckyCoinsNode extends Node {
|
||||
luckyType: LuckyType;
|
||||
|
||||
/** 幸运硬币的结果节点 */
|
||||
resultNode: Node;
|
||||
|
||||
/** 动画完成回调 */
|
||||
aniDoneBack: Function;
|
||||
|
||||
constructor(type: LuckyType,aniDone:Function) {
|
||||
super();
|
||||
this.luckyType = type;
|
||||
this.aniDoneBack = aniDone;
|
||||
|
||||
this.addComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
|
||||
this.initResultNode();
|
||||
this.initLuckyAni();
|
||||
this.delayShowResult();
|
||||
}
|
||||
|
||||
initActionButton() {
|
||||
const node = new CloseButtonNode(() => {
|
||||
this.initLuckyAni();
|
||||
});
|
||||
this.addChild(node);
|
||||
}
|
||||
|
||||
initResultNode() {
|
||||
const node = new Node();
|
||||
this.addChild(node);
|
||||
|
||||
node.setPosition(443, -200);
|
||||
this.resultNode = node;
|
||||
|
||||
node.active = false;
|
||||
|
||||
const bs = node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(NpkImage.luckycoin, this.luckyType);
|
||||
}
|
||||
|
||||
initLuckyAni() {
|
||||
const lucky = new AnimationNode("ani/luckycoin01.ani", () => {
|
||||
/// 这一帧结束之后调用
|
||||
director.once(Director.EVENT_END_FRAME, () => {
|
||||
// 销毁,销毁节点只能在当前帧结束后
|
||||
lucky.destroy();
|
||||
});
|
||||
});
|
||||
lucky.setPosition(318.5, -107.5);
|
||||
this.addChild(lucky);
|
||||
}
|
||||
|
||||
// 延迟显示结果
|
||||
delayShowResult() {
|
||||
setTimeout(() => {
|
||||
this.resultNode.active = true;
|
||||
setTimeout(() => {
|
||||
this.resultTweenDestroy();
|
||||
}, 1000);
|
||||
}, 1600);
|
||||
}
|
||||
|
||||
// 透明度缓动消失
|
||||
resultTweenDestroy() {
|
||||
|
||||
let obj = { x: 255 };
|
||||
|
||||
tween(obj)
|
||||
.to(0.5, { x: 1 }, { onUpdate: () => {
|
||||
const spr = this.resultNode.getComponent(Sprite);
|
||||
spr.color = new Color(255,255,255,obj.x);
|
||||
}, onComplete: () => {
|
||||
/// 缓动完成
|
||||
this.resultNode.active = false;
|
||||
// 动画完成回调
|
||||
this.aniDoneBack();
|
||||
// 销毁节点
|
||||
director.once(Director.EVENT_END_FRAME, () => {
|
||||
this.destroy();
|
||||
});
|
||||
},easing:'linear'})
|
||||
.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "0039c2de-95ce-49a6-aa91-0ca7ee85ecc3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-21 13:28:47
|
||||
* @LastEditTime: 2024-03-25 19:44:01
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-21 13:28:47
|
||||
* @LastEditTime: 2024-03-22 21:24:13
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 顺序选择卡片节点
|
||||
*/
|
||||
import { _decorator, Director, director, Node } from "cc";
|
||||
import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite";
|
||||
import { NpkImage } from "../../Tool/NPKImage";
|
||||
import { BaseButtonAction } from "../../GlobalScript/CommonComponent/BaseButtonAction";
|
||||
import { CardNode } from "./CardNode";
|
||||
import { TimingProgressBar } from "../Common/TimingProgressBar";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/// 选择顺序卡牌Node
|
||||
@ccclass("SelectNumberNode")
|
||||
export class SelectNumberNode extends Node {
|
||||
oneCard: CardNode;
|
||||
twoCard: CardNode;
|
||||
threeCard: CardNode;
|
||||
doneFunc: Function;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.initBackground();
|
||||
this.initCards();
|
||||
this.initTiming();
|
||||
}
|
||||
|
||||
initBackground() {
|
||||
const node = new Node();
|
||||
node.setPosition(184.5, -181.5);
|
||||
|
||||
const bs = node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(NpkImage.ingame, 46);
|
||||
this.addChild(node);
|
||||
}
|
||||
|
||||
initCards() {
|
||||
this.oneCard = new CardNode();
|
||||
this.oneCard.setPosition(339, -220);
|
||||
this.addChild(this.oneCard);
|
||||
const Onebba = this.oneCard.addComponent(BaseButtonAction);
|
||||
Onebba.onMouseLeftDown = () => {
|
||||
this.onMouseLeftDown(0);
|
||||
};
|
||||
|
||||
this.twoCard = new CardNode();
|
||||
this.twoCard.setPosition(533.5, -220);
|
||||
this.addChild(this.twoCard);
|
||||
const twoBba = this.twoCard.addComponent(BaseButtonAction);
|
||||
twoBba.onMouseLeftDown = () => {
|
||||
this.onMouseLeftDown(1);
|
||||
};
|
||||
|
||||
this.threeCard = new CardNode();
|
||||
this.threeCard.setPosition(728, -220);
|
||||
this.addChild(this.threeCard);
|
||||
const threeBba = this.threeCard.addComponent(BaseButtonAction);
|
||||
threeBba.onMouseLeftDown = () => {
|
||||
this.onMouseLeftDown(2);
|
||||
};
|
||||
}
|
||||
|
||||
//* 倒计时
|
||||
initTiming() {
|
||||
// 倒计时
|
||||
const time = new TimingProgressBar();
|
||||
this.addChild(time);
|
||||
|
||||
time.tweenerStart(3, () => {
|
||||
//倒计时缓动完成
|
||||
//开始翻转动画,需要1秒完成动画
|
||||
this.flipsCard();
|
||||
|
||||
//* 2秒后关闭node
|
||||
setTimeout(() => {
|
||||
this.doneFunc();
|
||||
/// 这一帧结束之后调用
|
||||
director.once(Director.EVENT_END_FRAME, () => {
|
||||
// 销毁,销毁节点只能在当前帧结束后
|
||||
this.destroy();
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//* 翻转卡片
|
||||
flipsCard() {
|
||||
const cards = [this.oneCard, this.twoCard, this.threeCard];
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
const card = cards[i];
|
||||
card.Disable = true;
|
||||
card.flipsAnimation.animationStart(i, "玩家" + i);
|
||||
}
|
||||
}
|
||||
|
||||
onMouseLeftDown(tag: number) {
|
||||
const cards = [this.oneCard, this.twoCard, this.threeCard];
|
||||
cards.forEach((card) => {
|
||||
card.Disable = true;
|
||||
});
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "06193d25-5a05-4aaf-92a9-d5358c56a4ff",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-21 13:29:53
|
||||
* @LastEditTime: 2024-03-29 14:21:02
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import { _decorator, Component, Node } from "cc";
|
||||
import { BoardRoot } from "./BoardRoot";
|
||||
import { UIRoot } from "./UIRoot/UIRoot";
|
||||
import { GameRoleController } from "./UIRoot/GameRoleController";
|
||||
import { DialogRoot } from "./DialogRoot/DialogRoot";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* @description: 游戏根节点的单例 用于直接提供子节点
|
||||
*/
|
||||
export class GameRootSingleton {
|
||||
private static readonly _instance: GameRootSingleton =
|
||||
new GameRootSingleton();
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): GameRootSingleton {
|
||||
return GameRootSingleton._instance;
|
||||
}
|
||||
|
||||
boardRootNode: Node;
|
||||
UIRootNode: Node;
|
||||
DialogRootNode: Node;
|
||||
|
||||
boardRoot: BoardRoot;
|
||||
UIRoot: UIRoot;
|
||||
DialogRoot: DialogRoot;
|
||||
|
||||
/** 玩家角色控制脚本 */
|
||||
gameRoleController: GameRoleController;
|
||||
|
||||
}
|
||||
|
||||
@ccclass("GameRootController")
|
||||
/**
|
||||
* @description: 游戏根节点脚本
|
||||
*/
|
||||
export class GameRootController extends Component {
|
||||
@property(Node) boardRootNode: Node;
|
||||
@property(Node) UIRootNode: Node;
|
||||
@property(Node) DialogRootNode: Node;
|
||||
|
||||
start() {
|
||||
/// 给三个图层添加 root 根脚本
|
||||
const game = GameRootSingleton.getInstance();
|
||||
game.boardRootNode = this.boardRootNode;
|
||||
game.UIRootNode = this.UIRootNode;
|
||||
game.DialogRootNode = this.DialogRootNode;
|
||||
|
||||
/// 给三个图层添加 root 根脚本
|
||||
game.boardRoot = this.boardRootNode.getComponent(BoardRoot);
|
||||
game.UIRoot = this.UIRootNode.getComponent(UIRoot);
|
||||
game.DialogRoot = this.DialogRootNode.getComponent(DialogRoot);
|
||||
|
||||
/// 在 UI 节点 添加玩家角色控制脚本
|
||||
this.UIRootNode.addComponent(GameRoleController);
|
||||
|
||||
|
||||
// 添加游戏 匹配过程控制 脚本
|
||||
game.gameRoleController = this.addComponent(GameRoleController);
|
||||
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "949ead83-9b0e-4202-8007-c50ab2ceeeb5",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "d61e7a19-5a2c-45c6-b9c8-8efecdaafe18",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-09 17:02:06
|
||||
* @LastEditTime: 2024-03-27 16:11:51
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import { _decorator, Color, Label, Node, Size, Sprite, SpriteFrame, tween, UITransform, VerticalTextAlignment } from 'cc';
|
||||
import { BaseSprite } from '../../GlobalScript/CommonComponent/BaseSprite';
|
||||
import { NpkImage } from '../../Tool/NPKImage';
|
||||
import { BaseSpriteFrame } from '../../GlobalScript/CommonComponent/BaseSpriteFrame';
|
||||
import { GamerRoleType } from './GamerRoleType';
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
|
||||
|
||||
|
||||
/// 玩家Node封装
|
||||
@ccclass('GamerCardNode')
|
||||
export class GamerCardNode extends Node {
|
||||
|
||||
/// 玩家角色类型
|
||||
private _characterType : GamerRoleType;
|
||||
|
||||
/// 玩家名称
|
||||
private GamerNameLabel : Label;
|
||||
|
||||
/// 幻想点数
|
||||
private _count: number = 0;
|
||||
private countLabel: Label;
|
||||
|
||||
/// 玩家排序的精灵
|
||||
private serialNumberSprite: Sprite;
|
||||
private serialOneFrame: SpriteFrame;
|
||||
private serialTwoFrame: SpriteFrame;
|
||||
private serialThreeFrame: SpriteFrame;
|
||||
|
||||
private blue = new Color('00baff');
|
||||
|
||||
set charchterType(type:GamerRoleType){
|
||||
if(!this.getChildByName('GamerCharacterNode')){
|
||||
this._characterType = type;
|
||||
this.initCharacterNode();
|
||||
}
|
||||
}
|
||||
|
||||
/// 设置新的幻想点数
|
||||
set count(newCount: number){
|
||||
|
||||
let numberString = newCount.toLocaleString();
|
||||
|
||||
const obj = {n:this._count};
|
||||
|
||||
if (numberString != this.GamerNameLabel.string){
|
||||
tween(obj).to(1.0,{ n: newCount },{onUpdate:(target,ration)=>{
|
||||
this._count = obj.n;
|
||||
const count:number = parseInt(obj.n.toFixed(0));
|
||||
this.countLabel.string = count.toLocaleString();
|
||||
this.countLabel.color = this.getCountColor(obj.n);
|
||||
}},).start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 设置玩家名称
|
||||
set gamerName(newName: string){
|
||||
let name = newName;
|
||||
if (name.length > 6){
|
||||
name = newName.slice(0,3) + '...' + newName.slice(newName.length - 3);
|
||||
}
|
||||
this.GamerNameLabel.string = name;
|
||||
}
|
||||
|
||||
/// 玩家排序
|
||||
set serialNumber( serial: 1 | 2 | 3){
|
||||
switch (serial) {
|
||||
case 1:
|
||||
this.serialNumberSprite.spriteFrame = this.serialOneFrame;
|
||||
this.GamerNameLabel.color = Color.RED;
|
||||
break;
|
||||
case 2:
|
||||
this.serialNumberSprite.spriteFrame = this.serialTwoFrame;
|
||||
this.GamerNameLabel.color = this.blue;
|
||||
break;
|
||||
case 3:
|
||||
this.serialNumberSprite.spriteFrame = this.serialThreeFrame;
|
||||
this.GamerNameLabel.color = Color.GREEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private getCountColor(count:number):Color{
|
||||
if ( count < 50000){
|
||||
return Color.RED;
|
||||
}else if ( count < 200000){
|
||||
return Color.YELLOW;
|
||||
}else{
|
||||
return this.blue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constructor(gamerName:string){
|
||||
super();
|
||||
|
||||
this.initBackgroundNode();
|
||||
this.initPNode();
|
||||
this.initCountNode();
|
||||
this.initGamerNameNode();
|
||||
this.initSerialNumberNode();
|
||||
|
||||
this.gamerName = gamerName;
|
||||
|
||||
/// 提前加载精灵帧
|
||||
new BaseSpriteFrame(NpkImage.ingame, 1, _SpriteFrame => { this.serialOneFrame = _SpriteFrame });
|
||||
new BaseSpriteFrame(NpkImage.ingame, 2, _SpriteFrame => { this.serialTwoFrame = _SpriteFrame });
|
||||
new BaseSpriteFrame(NpkImage.ingame, 3, _SpriteFrame => { this.serialThreeFrame = _SpriteFrame });
|
||||
}
|
||||
|
||||
/// 背景
|
||||
initBackgroundNode(){
|
||||
/// 背景节点
|
||||
const backgroundNode = new Node('GamerBackgroundNode');
|
||||
this.addChild(backgroundNode);
|
||||
|
||||
/// 给背景节点添加 baseSprite 组件
|
||||
const backgroundComponent = backgroundNode.addComponent( BaseSprite );
|
||||
backgroundComponent.updateSpriteFrame(NpkImage.ingame,32);
|
||||
|
||||
}
|
||||
|
||||
/// 角色
|
||||
initCharacterNode(){
|
||||
const node = new Node('GamerCharacterNode');
|
||||
this.addChild(node);
|
||||
|
||||
/// 添加 baseSprite 组件
|
||||
const backgroundComponent = node.addComponent( BaseSprite );
|
||||
backgroundComponent.updateSpriteFrame(NpkImage.character_sd,this._characterType);
|
||||
}
|
||||
|
||||
/// P图标
|
||||
initPNode(){
|
||||
const node = new Node('GamerPNode');
|
||||
this.addChild(node);
|
||||
|
||||
node.setPosition(50,-9.5);
|
||||
|
||||
/// 添加 baseSprite 组件
|
||||
const backgroundComponent = node.addComponent( BaseSprite );
|
||||
backgroundComponent.updateSpriteFrame(NpkImage.ingame,53);
|
||||
|
||||
}
|
||||
|
||||
/// 幻想点数
|
||||
initCountNode(){
|
||||
const node = new Node('GamerCountNode');
|
||||
this.addChild(node);
|
||||
|
||||
node.setPosition(100,-18);
|
||||
const trf = node.addComponent(UITransform);
|
||||
trf.contentSize = new Size(60,20);
|
||||
|
||||
const label = node.addComponent(Label);
|
||||
label.fontSize = 14;
|
||||
label.string = '0';
|
||||
label.color = Color.RED;
|
||||
label.verticalAlign = VerticalTextAlignment.CENTER;
|
||||
this.countLabel = label;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 玩家名称
|
||||
initGamerNameNode(){
|
||||
const node = new Node('GamerNameNode');
|
||||
this.addChild(node);
|
||||
|
||||
node.setPosition(90,-40);
|
||||
const trf = node.addComponent(UITransform);
|
||||
trf.contentSize = new Size(100,20);
|
||||
|
||||
const label = node.addComponent(Label);
|
||||
label.string = '';
|
||||
label.fontSize = 12;
|
||||
label.color = Color.GRAY;
|
||||
label.verticalAlign = VerticalTextAlignment.CENTER;
|
||||
|
||||
this.GamerNameLabel = label;
|
||||
}
|
||||
|
||||
/// 玩家顺序
|
||||
initSerialNumberNode(){
|
||||
const node = new Node('GamerNameNode');
|
||||
this.addChild(node);
|
||||
|
||||
node.setPosition(160,-30);
|
||||
|
||||
this.serialNumberSprite = node.addComponent( Sprite );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "790760a1-d532-45f7-89e4-d81781d5466b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-27 15:58:07
|
||||
* @LastEditTime: 2024-03-29 14:40:52
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import {
|
||||
_decorator,
|
||||
Component,
|
||||
Node,
|
||||
Sprite,
|
||||
SpriteFrame,
|
||||
} from "cc";
|
||||
import { NpkImageTool } from "../../Tool/NPKImage";
|
||||
import { GamerRoleAni, GamerRoleType } from "./GamerRoleType";
|
||||
import { GameState } from "../../GlobalScript/GlobalGameState/GameState";
|
||||
const { ccclass, property } = _decorator;
|
||||
@ccclass("GamerRoleNode")
|
||||
|
||||
//* ─── 玩家在地图上的角色 Node ────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @description: 玩家在地图上的角色 节点
|
||||
*/
|
||||
export class GamerRoleNode extends Node {
|
||||
constructor(type: GamerRoleType) {
|
||||
super();
|
||||
|
||||
//角色类型 设置后自动播放动画
|
||||
this.addComponent(RoleAnimation).type = type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//* ─── 角色动画播放 Component ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export enum PlayAniState {
|
||||
//播放中
|
||||
playing,
|
||||
//暂停
|
||||
pause,
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 角色的动画
|
||||
*/
|
||||
export class RoleAnimation extends Component {
|
||||
/** 节点精灵 */
|
||||
private sprite: Sprite;
|
||||
/** 精灵帧总数 */
|
||||
private frameCount: number;
|
||||
/** 是否初始化完成 */
|
||||
private InitState: boolean;
|
||||
/** 精灵帧map缓存 */
|
||||
private frameMap: Map<number, SpriteFrame> = new Map<number, SpriteFrame>();
|
||||
|
||||
/** 每一帧需要显示的时间 千分之一秒 */
|
||||
private static frameShowTime: number = 60;
|
||||
|
||||
/** 当前帧显示了的时间 */
|
||||
private nowFrameTime: number = 0;
|
||||
|
||||
/** 当前帧 */
|
||||
private nowFrameIndex: number = 0;
|
||||
|
||||
/** 动画状态 */
|
||||
private playState: PlayAniState = PlayAniState.playing;
|
||||
|
||||
/** 角色类型 设置后自动播放动画 */
|
||||
set type(type: GamerRoleType) {
|
||||
|
||||
const node = new Node();
|
||||
this.node.addChild(node);
|
||||
|
||||
this.sprite = node.addComponent(Sprite);
|
||||
|
||||
//设置类型
|
||||
this.sprite.sizeMode = Sprite.SizeMode.RAW;
|
||||
//设置
|
||||
this.sprite.trim = false;
|
||||
|
||||
// 获取所有帧图片
|
||||
NpkImageTool.GetNpkImageAll(
|
||||
GamerRoleAni.getPath(type),
|
||||
(count, frameMap) => {
|
||||
this.frameCount = count;
|
||||
this.frameMap = frameMap;
|
||||
this.InitState = true;
|
||||
// 显示第一帧
|
||||
this.sprite.spriteFrame = this.frameMap.get(this.nowFrameIndex);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
start() {}
|
||||
|
||||
update(dt: number) {
|
||||
//如果游戏世界处于暂停的模式下 不再继续播放
|
||||
if (GameState.getInstance().IsPauseState()) return;
|
||||
//如果初始化未完成,不播放
|
||||
if (!this.InitState) return;
|
||||
//如果不在播放中
|
||||
if (this.playState != PlayAniState.playing) return;
|
||||
|
||||
//每帧增加过去的时间 取千分之一秒为单位
|
||||
this.nowFrameTime += Math.trunc(dt * 1000);
|
||||
|
||||
// 大于60毫秒换下一帧
|
||||
if (this.nowFrameTime < 60) return;
|
||||
|
||||
this.nowFrameTime -= 60;
|
||||
this.nowFrameTime++;
|
||||
|
||||
// 播放完成后 重新播放
|
||||
if (this.nowFrameIndex >= this.frameCount) this.nowFrameIndex = 0;
|
||||
|
||||
this.sprite.spriteFrame = this.frameMap.get(this.nowFrameIndex);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "7b231e75-2650-4560-a447-3e3de615fdae",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-27 16:10:31
|
||||
* @LastEditTime: 2024-03-29 10:49:55
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 玩家角色类型
|
||||
*/
|
||||
/// 官网总数 63
|
||||
|
||||
import { NpkImage, NpkImagePath } from "../../Tool/NPKImage";
|
||||
|
||||
//* ─── 玩家角色类型 ──────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @description: 玩家角色类型
|
||||
*
|
||||
*/
|
||||
export enum GamerRoleType {
|
||||
/** 散打 */
|
||||
SanDa,
|
||||
/** 柔道 */
|
||||
RouDao,
|
||||
/** 气功 */
|
||||
QiGong,
|
||||
/** 街霸 */
|
||||
JieBa,
|
||||
|
||||
/** 女漫游 */
|
||||
NvManYou,
|
||||
/** 女弹药 */
|
||||
NvDanYao,
|
||||
/** 女机械 */
|
||||
NvJiXie,
|
||||
/** 女枪炮 */
|
||||
NvQiangPao,
|
||||
|
||||
/** 冰洁 */
|
||||
BingJie,
|
||||
/** 元素爆破 */
|
||||
|
||||
YuanSuBaoPo,
|
||||
/** 剑魔 */
|
||||
JianMo,
|
||||
/** 剑宗 */
|
||||
|
||||
JianZong,
|
||||
/** 暗殿骑士 */
|
||||
AnDianQiShi,
|
||||
/** 流浪骑士 */
|
||||
|
||||
LiuLangQiShi,
|
||||
/** 光枪 */
|
||||
GuangQiang,
|
||||
/** 暗枪 */
|
||||
AnQiang,
|
||||
|
||||
/** 女街霸 */
|
||||
NvJieBa,
|
||||
/** 女散打 */
|
||||
NvSanDa,
|
||||
/** 女气功 */
|
||||
NvQiGong,
|
||||
/** 女柔道 */
|
||||
NvRouDao,
|
||||
|
||||
/** 弹药 */
|
||||
DanYao,
|
||||
/** 枪炮 */
|
||||
QiangPao,
|
||||
/** 机械 */
|
||||
JiXie,
|
||||
/** 漫游 */
|
||||
ManYou,
|
||||
|
||||
/** 战法 */
|
||||
ZanFa,
|
||||
/** 召唤 */
|
||||
ZhaoHuan,
|
||||
/** 魔道 */
|
||||
MoDao,
|
||||
/** 元素 */
|
||||
YuanSu,
|
||||
|
||||
/** 复仇 */
|
||||
FuChou,
|
||||
/** 篮拳 */
|
||||
LanQuan,
|
||||
/** 圣骑 */
|
||||
ShenQi,
|
||||
/** 驱魔 */
|
||||
QuMo,
|
||||
|
||||
/** 狂战 */
|
||||
KuangZhan,
|
||||
/** 鬼泣 */
|
||||
GuiQi,
|
||||
/** 阿修罗 */
|
||||
AXiuLuo,
|
||||
/** 剑魂 */
|
||||
JianHun,
|
||||
|
||||
/** 刺客 */
|
||||
Cike,
|
||||
/** 影武者 */
|
||||
YinWuZhe,
|
||||
/** 忍者 */
|
||||
RenZhe,
|
||||
/** 死灵 */
|
||||
SiLin,
|
||||
/** 普通鬼剑士 */
|
||||
GuiJianShi,
|
||||
}
|
||||
|
||||
//* ─── 角色立绘 路径 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @description: 角色立绘 路径
|
||||
*/
|
||||
export class GamerRoleCardDate {
|
||||
/** NPk路径 */
|
||||
npkPath: string;
|
||||
/** index */
|
||||
index: number;
|
||||
|
||||
constructor(index: number) {
|
||||
this.npkPath = NpkImage.character_sd;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 从角色类型获取立绘数据
|
||||
*/
|
||||
static getDate(type: GamerRoleType): GamerRoleCardDate {
|
||||
switch (type) {
|
||||
// 散打
|
||||
case GamerRoleType.SanDa:
|
||||
return new GamerRoleCardDate(29);
|
||||
// 柔道
|
||||
case GamerRoleType.RouDao:
|
||||
return new GamerRoleCardDate(31);
|
||||
// 气功
|
||||
case GamerRoleType.QiGong:
|
||||
return new GamerRoleCardDate(28);
|
||||
// 街霸
|
||||
case GamerRoleType.JieBa:
|
||||
return new GamerRoleCardDate(30);
|
||||
|
||||
// 女漫游
|
||||
case GamerRoleType.NvManYou:
|
||||
return new GamerRoleCardDate(20);
|
||||
// 女弹药
|
||||
case GamerRoleType.NvDanYao:
|
||||
return new GamerRoleCardDate(23);
|
||||
// 女机械
|
||||
case GamerRoleType.NvJiXie:
|
||||
return new GamerRoleCardDate(22);
|
||||
// 女枪炮
|
||||
case GamerRoleType.NvQiangPao:
|
||||
return new GamerRoleCardDate(21);
|
||||
|
||||
// 冰洁
|
||||
case GamerRoleType.BingJie:
|
||||
return new GamerRoleCardDate(33);
|
||||
// 元素爆破
|
||||
case GamerRoleType.YuanSuBaoPo:
|
||||
return new GamerRoleCardDate(32);
|
||||
|
||||
// 剑魔
|
||||
case GamerRoleType.JianMo:
|
||||
return new GamerRoleCardDate(41);
|
||||
// 剑宗
|
||||
case GamerRoleType.JianZong:
|
||||
return new GamerRoleCardDate(39);
|
||||
|
||||
// 暗殿骑士
|
||||
case GamerRoleType.AnDianQiShi:
|
||||
return new GamerRoleCardDate(40);
|
||||
// 流浪骑士
|
||||
case GamerRoleType.LiuLangQiShi:
|
||||
return new GamerRoleCardDate(42);
|
||||
|
||||
// 光枪
|
||||
case GamerRoleType.GuangQiang:
|
||||
return new GamerRoleCardDate(48);
|
||||
// 暗枪
|
||||
case GamerRoleType.AnQiang:
|
||||
return new GamerRoleCardDate(47);
|
||||
|
||||
// 女街霸
|
||||
case GamerRoleType.NvJieBa:
|
||||
return new GamerRoleCardDate(6);
|
||||
// 女散打
|
||||
case GamerRoleType.NvSanDa:
|
||||
return new GamerRoleCardDate(5);
|
||||
// 女气功
|
||||
case GamerRoleType.NvQiGong:
|
||||
return new GamerRoleCardDate(4);
|
||||
// 女柔道
|
||||
case GamerRoleType.NvRouDao:
|
||||
return new GamerRoleCardDate(7);
|
||||
|
||||
// 弹药
|
||||
case GamerRoleType.DanYao:
|
||||
return new GamerRoleCardDate(11);
|
||||
// 枪炮
|
||||
case GamerRoleType.QiangPao:
|
||||
return new GamerRoleCardDate(9);
|
||||
// 机械
|
||||
case GamerRoleType.JiXie:
|
||||
return new GamerRoleCardDate(10);
|
||||
// 漫游
|
||||
case GamerRoleType.ManYou:
|
||||
return new GamerRoleCardDate(8);
|
||||
|
||||
// 战法
|
||||
case GamerRoleType.ZanFa:
|
||||
return new GamerRoleCardDate(14);
|
||||
// 召唤
|
||||
case GamerRoleType.ZhaoHuan:
|
||||
return new GamerRoleCardDate(13);
|
||||
// 魔道
|
||||
case GamerRoleType.MoDao:
|
||||
return new GamerRoleCardDate(15);
|
||||
// 元素
|
||||
case GamerRoleType.YuanSu:
|
||||
return new GamerRoleCardDate(12);
|
||||
|
||||
// 复仇
|
||||
case GamerRoleType.FuChou:
|
||||
return new GamerRoleCardDate(19);
|
||||
// 篮拳
|
||||
case GamerRoleType.LanQuan:
|
||||
return new GamerRoleCardDate(16);
|
||||
// 圣骑
|
||||
case GamerRoleType.ShenQi:
|
||||
return new GamerRoleCardDate(17);
|
||||
// 驱魔
|
||||
case GamerRoleType.QuMo:
|
||||
return new GamerRoleCardDate(18);
|
||||
|
||||
// 狂战
|
||||
case GamerRoleType.KuangZhan:
|
||||
return new GamerRoleCardDate(2);
|
||||
// 鬼泣
|
||||
case GamerRoleType.GuiQi:
|
||||
return new GamerRoleCardDate(1);
|
||||
// 阿修罗
|
||||
case GamerRoleType.AXiuLuo:
|
||||
return new GamerRoleCardDate(3);
|
||||
// 剑魂
|
||||
case GamerRoleType.JianHun:
|
||||
return new GamerRoleCardDate(0);
|
||||
|
||||
// 刺客
|
||||
case GamerRoleType.Cike:
|
||||
return new GamerRoleCardDate(24);
|
||||
// 影武者
|
||||
case GamerRoleType.YinWuZhe:
|
||||
return new GamerRoleCardDate(27);
|
||||
// 忍者
|
||||
case GamerRoleType.RenZhe:
|
||||
return new GamerRoleCardDate(26);
|
||||
// 死灵
|
||||
case GamerRoleType.SiLin:
|
||||
return new GamerRoleCardDate(25);
|
||||
|
||||
// 普通鬼剑士
|
||||
case GamerRoleType.GuiJianShi:
|
||||
return new GamerRoleCardDate(62);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//* ─── 角色站立动画 路径 ───────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @description: 角色站立动画 路径
|
||||
*/
|
||||
export class GamerRoleAni {
|
||||
/**
|
||||
* @description: 从角色站立动画 路径
|
||||
*/
|
||||
static getPath(type: GamerRoleType): string {
|
||||
switch (type) {
|
||||
// 散打
|
||||
case GamerRoleType.SanDa:
|
||||
return NpkImagePath + "role_1_sanda.img";
|
||||
// 柔道
|
||||
case GamerRoleType.RouDao:
|
||||
return NpkImagePath + "role_2_roudao.img";
|
||||
// 气功
|
||||
case GamerRoleType.QiGong:
|
||||
return NpkImagePath + "role_3_qigong.img";
|
||||
// 街霸
|
||||
case GamerRoleType.JieBa:
|
||||
return NpkImagePath + "role_4_jieba.img";
|
||||
// 女漫游
|
||||
case GamerRoleType.NvManYou:
|
||||
return NpkImagePath + "role_5_nv_manyou.img";
|
||||
// 女弹药
|
||||
case GamerRoleType.NvDanYao:
|
||||
return NpkImagePath + "role_6_nv_danyao.img";
|
||||
// 女机械
|
||||
case GamerRoleType.NvJiXie:
|
||||
return NpkImagePath + "role_7_nv_jixie.img";
|
||||
// 女枪炮
|
||||
case GamerRoleType.NvQiangPao:
|
||||
return NpkImagePath + "role_8_nv_qiangpao.img";
|
||||
// 冰洁
|
||||
case GamerRoleType.BingJie:
|
||||
return NpkImagePath + "role_9_bingjie.img";
|
||||
// 元素爆破
|
||||
case GamerRoleType.YuanSuBaoPo:
|
||||
return NpkImagePath + "role_10_yuasubaopo.img";
|
||||
// 剑魔
|
||||
case GamerRoleType.JianMo:
|
||||
return NpkImagePath + "role_11_jianmo.img";
|
||||
// 剑宗
|
||||
case GamerRoleType.JianZong:
|
||||
return NpkImagePath + "role_12_jianzong.img";
|
||||
// 暗殿骑士
|
||||
case GamerRoleType.AnDianQiShi:
|
||||
return NpkImagePath + "role_13_andianqishi.img";
|
||||
// 流浪骑士
|
||||
case GamerRoleType.LiuLangQiShi:
|
||||
return NpkImagePath + "role_14_liulangjianshi.img";
|
||||
// 光枪
|
||||
case GamerRoleType.GuangQiang:
|
||||
return NpkImagePath + "role_15_guangqiang.img";
|
||||
// 暗枪
|
||||
case GamerRoleType.AnQiang:
|
||||
return NpkImagePath + "role_16_anqiang.img";
|
||||
// 女街霸
|
||||
case GamerRoleType.NvJieBa:
|
||||
return NpkImagePath + "role_17_nv_jieba.img";
|
||||
// 女散打
|
||||
case GamerRoleType.NvSanDa:
|
||||
return NpkImagePath + "role_18_nv_sanda.img";
|
||||
// 女气功
|
||||
case GamerRoleType.NvQiGong:
|
||||
return NpkImagePath + "role_19_nv_qigong.img";
|
||||
// 女柔道
|
||||
case GamerRoleType.NvRouDao:
|
||||
return NpkImagePath + "role_20_nv_roudao.img";
|
||||
// 弹药
|
||||
case GamerRoleType.DanYao:
|
||||
return NpkImagePath + "role_21_danyao.img";
|
||||
// 枪炮
|
||||
case GamerRoleType.QiangPao:
|
||||
return NpkImagePath + "role_22_qiangpao.img";
|
||||
// 机械
|
||||
case GamerRoleType.JiXie:
|
||||
return NpkImagePath + "role_23_jixie.img";
|
||||
// 漫游
|
||||
case GamerRoleType.ManYou:
|
||||
return NpkImagePath + "role_24_manyou.img";
|
||||
// 战法
|
||||
case GamerRoleType.ZanFa:
|
||||
return NpkImagePath + "role_25_zhanfa.img";
|
||||
// 召唤
|
||||
case GamerRoleType.ZhaoHuan:
|
||||
return NpkImagePath + "role_26_zhaohuan.img";
|
||||
// 魔道
|
||||
case GamerRoleType.MoDao:
|
||||
return NpkImagePath + "role_27_modao.img";
|
||||
// 元素
|
||||
case GamerRoleType.YuanSu:
|
||||
return NpkImagePath + "role_28_yuansu.img";
|
||||
// 复仇
|
||||
case GamerRoleType.FuChou:
|
||||
return NpkImagePath + "role_29_fuchou.img";
|
||||
// 篮拳
|
||||
case GamerRoleType.LanQuan:
|
||||
return NpkImagePath + "role_30_lanquan.img";
|
||||
// 圣骑
|
||||
case GamerRoleType.ShenQi:
|
||||
return NpkImagePath + "role_31_shenqi.img";
|
||||
// 驱魔
|
||||
case GamerRoleType.QuMo:
|
||||
return NpkImagePath + "role_32_qumo.img";
|
||||
// 狂战
|
||||
case GamerRoleType.KuangZhan:
|
||||
return NpkImagePath + "role_33_kuangzhan.img";
|
||||
// 鬼泣
|
||||
case GamerRoleType.GuiQi:
|
||||
return NpkImagePath + "role_34_guiqi.img";
|
||||
// 阿修罗
|
||||
case GamerRoleType.AXiuLuo:
|
||||
return NpkImagePath + "role_35_axiuluo.img";
|
||||
// 剑魂
|
||||
case GamerRoleType.JianHun:
|
||||
return NpkImagePath + "role_36_jianhun.img";
|
||||
// 刺客
|
||||
case GamerRoleType.Cike:
|
||||
return NpkImagePath + "role_37_ceke.img";
|
||||
// 影武者
|
||||
case GamerRoleType.YinWuZhe:
|
||||
return NpkImagePath + "role_38_yinwuzhe.img";
|
||||
// 忍者
|
||||
case GamerRoleType.RenZhe:
|
||||
return NpkImagePath + "role_39_renzhe.img";
|
||||
// 死灵
|
||||
case GamerRoleType.SiLin:
|
||||
return NpkImagePath + "role_40_silin.img";
|
||||
// 普通鬼剑士
|
||||
case GamerRoleType.GuiJianShi:
|
||||
return NpkImagePath + "role_41_guijian.img";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "150e386d-95e6-4ebc-af15-1ef927aa4788",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "1554040b-ede2-463f-bced-04c443740947",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
import {
|
||||
_decorator,
|
||||
Color,
|
||||
Component,
|
||||
EventMouse,
|
||||
Node,
|
||||
Sprite,
|
||||
UITransform,
|
||||
v2,
|
||||
v3,
|
||||
Vec3,
|
||||
} from "cc";
|
||||
import { NpkImage } from "../../Tool/NPKImage";
|
||||
import { MapTileDirection } from "./MapTileType";
|
||||
import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite";
|
||||
import { DiamondCheck, Point } from "./../Common/InDiamondCheck";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
enum buttonState {
|
||||
// 普通
|
||||
Normal,
|
||||
// 悬停
|
||||
Hover,
|
||||
// // 按下
|
||||
// Down,
|
||||
}
|
||||
|
||||
@ccclass("MapTileButtonComponent")
|
||||
export class MapTileButtonComponent extends Component {
|
||||
direction: MapTileDirection;
|
||||
|
||||
private position: Vec3;
|
||||
|
||||
/// 状态
|
||||
set state(newState: buttonState) {
|
||||
if (!this.SpriteObj) {
|
||||
this.SpriteObj = this.node.getComponent(Sprite);
|
||||
}
|
||||
switch (newState) {
|
||||
case buttonState.Normal:
|
||||
this.SpriteObj.color = Color.WHITE;
|
||||
break;
|
||||
case buttonState.Hover:
|
||||
this.SpriteObj.color = Color.YELLOW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//精灵对象
|
||||
private SpriteObj: Sprite;
|
||||
|
||||
start() {
|
||||
this.position = this.node.getPosition();
|
||||
|
||||
if (!this.node.getComponent(UITransform)) {
|
||||
this.node.addComponent(UITransform);
|
||||
}
|
||||
this.node.getComponent(UITransform).anchorPoint = v2(0, 0);
|
||||
|
||||
const bs = this.node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(NpkImage.board, this.direction);
|
||||
|
||||
// this.node.on(Node.EventType.MOUSE_ENTER, this.OnHover, this);
|
||||
this.node.on(Node.EventType.MOUSE_LEAVE, this.OffHover, this);
|
||||
this.node.on(Node.EventType.MOUSE_DOWN, this.onEvent, this);
|
||||
this.node.on(Node.EventType.MOUSE_UP, this.onEvent, this);
|
||||
this.node.on(Node.EventType.MOUSE_MOVE, this.onEvent, this);
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
|
||||
/// 事件的统一处理
|
||||
onEvent(event: EventMouse) {
|
||||
/// 判断是否在矩形范围内
|
||||
const inDiamond = this.getEventDiamond(event);
|
||||
if (inDiamond) {
|
||||
this.OnHover();
|
||||
|
||||
switch (event.type) {
|
||||
case Node.EventType.MOUSE_DOWN:
|
||||
this.OnDown(event);
|
||||
break;
|
||||
case Node.EventType.MOUSE_UP:
|
||||
this.OnUp(event);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 结束悬浮状态
|
||||
this.OffHover();
|
||||
// 事件穿透
|
||||
event.preventSwallow = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标悬浮状态
|
||||
OnHover() {
|
||||
this.state = buttonState.Hover;
|
||||
}
|
||||
|
||||
// 鼠标悬浮状态结束
|
||||
OffHover() {
|
||||
this.state = buttonState.Normal;
|
||||
this.node.setPosition(this.position);
|
||||
}
|
||||
/// 按下
|
||||
OnDown(event: EventMouse) {
|
||||
if (event.getButton() != EventMouse.BUTTON_LEFT) return;
|
||||
const np = this.node.position;
|
||||
this.node.setPosition(np.x, np.y - 1);
|
||||
}
|
||||
|
||||
OnUp(event: EventMouse) {
|
||||
//必须是鼠标左键
|
||||
if (event.getButton() != EventMouse.BUTTON_LEFT) return;
|
||||
const np = this.node.position;
|
||||
this.node.setPosition(this.position);
|
||||
}
|
||||
|
||||
// 判断事件是否在矩形内
|
||||
getEventDiamond(event: EventMouse): boolean {
|
||||
const point = event.getLocation();
|
||||
// 转换获取到 node 内的坐标
|
||||
const location = this.node
|
||||
.getComponent(UITransform)
|
||||
.convertToNodeSpaceAR(v3(point.x, point.y, 0));
|
||||
// 是否在图片的菱形范围内
|
||||
const inDiamond = DiamondCheck.isPointInDiamond(
|
||||
{ x: location.x, y: location.y },
|
||||
this.getDiamond()
|
||||
);
|
||||
|
||||
return inDiamond;
|
||||
}
|
||||
|
||||
// 判断坐标是否在矩形内部
|
||||
getDiamond(): [Point, Point, Point, Point] {
|
||||
let w = 58.5;
|
||||
let h = 37.5;
|
||||
let hc = 10;
|
||||
let wc = 17;
|
||||
|
||||
switch (this.direction) {
|
||||
case MapTileDirection.nook:
|
||||
w = 58.5;
|
||||
h = 37.5;
|
||||
return [
|
||||
{ x: w, y: 0 },
|
||||
{ x: w + w, y: -h },
|
||||
{ x: w, y: -h - h },
|
||||
{ x: 0, y: -h },
|
||||
];
|
||||
case MapTileDirection.horizontal:
|
||||
w = 42;
|
||||
h = 27;
|
||||
return [
|
||||
{ x: w + wc, y: 0 },
|
||||
{ x: w + w + wc, y: -h },
|
||||
{ x: w, y: -h - h - hc },
|
||||
{ x: 0, y: -h - hc },
|
||||
];
|
||||
case MapTileDirection.vertical:
|
||||
w = 42;
|
||||
h = 27;
|
||||
return [
|
||||
{ x: w, y: 0 },
|
||||
{ x: w + w + wc, y: -h - hc },
|
||||
{ x: w + wc, y: -h - h - hc },
|
||||
{ x: 0, y: -h },
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "bcd05978-d628-49d5-a5fc-c17782e7be27",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-16 16:34:19
|
||||
* @LastEditTime: 2024-03-28 21:09:58
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 地图地块的行为控制器
|
||||
*/
|
||||
import { _decorator, Component, } from "cc";
|
||||
import { MapTileData, MapTileType } from "./MapTileType";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass("MapTileController")
|
||||
export class MapTileController extends Component {
|
||||
|
||||
/// 地块数据
|
||||
private _tileData: MapTileData;
|
||||
get tileData(){ return this._tileData; };
|
||||
|
||||
/// 地块类型
|
||||
private _tileType: MapTileType;
|
||||
set tileType(newType: MapTileType){
|
||||
this._tileType = newType;
|
||||
this._tileData = MapTileData.getData(newType as MapTileType);
|
||||
};
|
||||
get tileType(){ return this._tileType; };
|
||||
|
||||
|
||||
/// 地块占领状态(是谁占领的,)
|
||||
private occupState: string;
|
||||
|
||||
/// 占领等级
|
||||
private occupyLevel: 0 | 1 | 2 | 3;
|
||||
|
||||
/// 决斗场等级
|
||||
private fightLevel: 2 | 4 | 8;
|
||||
|
||||
/// 进入选择地下城状态,海上列车选择,决斗场选择
|
||||
|
||||
start() {
|
||||
const location = this._tileData.location;
|
||||
this.node.setPosition(location.x,location.y);
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "81e11280-50a3-4363-b141-10d761ae7571",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
import { _decorator, Node } from "cc";
|
||||
import { MapTileDirection, MapTileType } from "./MapTileType";
|
||||
import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite";
|
||||
import { MapTileButtonComponent } from "./MapTileButtonComponent";
|
||||
import { MapTileController } from "./MapTileController";
|
||||
import { CloseButtonNode } from "../Common/CloseButtonNode";
|
||||
import { MapTitleAction } from "./MapTitleAction";
|
||||
import { LuckyType } from "../DialogRoot/LuckyCoinsNode";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
/// 地块
|
||||
@ccclass("MapTileNode")
|
||||
export class MapTileNode extends Node {
|
||||
/// -- Node
|
||||
|
||||
/// 背景节点
|
||||
private backgroundNode: Node;
|
||||
|
||||
/// 地块名称
|
||||
private nameNode: Node;
|
||||
|
||||
/// 决斗场选中的战斗边框
|
||||
private fightNode: Node;
|
||||
|
||||
/// 鼠标操作变化的边框
|
||||
private borderNode: Node;
|
||||
|
||||
/// 禁止选择
|
||||
private disableNode: Node;
|
||||
|
||||
/// 占领图标
|
||||
private occupyIconNode: Node;
|
||||
|
||||
/// 决斗场选中的图标 和倍数icon
|
||||
private fightIconNode: Node;
|
||||
|
||||
/// 控制器
|
||||
private controller: MapTileController;
|
||||
|
||||
constructor(type) {
|
||||
super();
|
||||
|
||||
this.controller = this.addComponent(MapTileController);
|
||||
this.controller.tileType = type;
|
||||
|
||||
this.initNode();
|
||||
|
||||
// todo 测试用按钮
|
||||
this.initButton();
|
||||
}
|
||||
|
||||
/// 测试使用按钮
|
||||
initButton() {
|
||||
const node = new CloseButtonNode(()=>{
|
||||
MapTitleAction.lucky( LuckyType.GoThree );
|
||||
})
|
||||
this.addChild(node);
|
||||
}
|
||||
|
||||
initNode() {
|
||||
//* 背景
|
||||
if (this.controller.tileData.backgroundIndex) {
|
||||
const node = new Node();
|
||||
this.addChild(node);
|
||||
|
||||
const bs = node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(
|
||||
this.controller.tileData.npkPath,
|
||||
this.controller.tileData.backgroundIndex
|
||||
);
|
||||
|
||||
this.backgroundNode = node;
|
||||
}
|
||||
|
||||
//* 名称
|
||||
const node = new Node();
|
||||
this.addChild(node);
|
||||
|
||||
const bs = node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(
|
||||
this.controller.tileData.npkPath,
|
||||
this.controller.tileType
|
||||
);
|
||||
|
||||
this.nameNode = node;
|
||||
|
||||
//* 红色边框
|
||||
// 决斗场选择后的红色边框,四角和命运硬币 没有红框
|
||||
if (
|
||||
this.controller.tileData.direction != MapTileDirection.nook &&
|
||||
this.controller.tileType !=
|
||||
(MapTileType.XiaoZhenMingYunYinBi || MapTileType.HaLinMingYunYinBi)
|
||||
) {
|
||||
const node = new Node();
|
||||
node.active = false;
|
||||
this.addChild(node);
|
||||
|
||||
// 横向地块27 竖向28
|
||||
const bs = node.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(
|
||||
this.controller.tileData.npkPath,
|
||||
this.controller.tileData.direction == MapTileDirection.horizontal
|
||||
? 27
|
||||
: 28
|
||||
);
|
||||
|
||||
this.fightNode = node;
|
||||
}
|
||||
|
||||
//* 鼠标选择边框
|
||||
const bordeNode = new Node();
|
||||
this.addChild(bordeNode);
|
||||
bordeNode.active = false;
|
||||
const bordeBC = bordeNode.addComponent(MapTileButtonComponent);
|
||||
bordeBC.direction = this.controller.tileData.direction;
|
||||
this.borderNode = bordeNode;
|
||||
|
||||
//* 禁止选择node
|
||||
const disableNode = new Node();
|
||||
this.addChild(disableNode);
|
||||
disableNode.active = false;
|
||||
const disableBS = disableNode.addComponent(BaseSprite);
|
||||
disableBS.updateSpriteFrame(
|
||||
this.controller.tileData.npkPath,
|
||||
this.controller.tileData.direction + 5
|
||||
);
|
||||
this.disableNode = disableNode;
|
||||
}
|
||||
|
||||
//* 显示海上列车选择
|
||||
shwTrainsSelect(show: boolean) {
|
||||
if (this.borderNode) {
|
||||
//* 许可选择
|
||||
if (this.controller.tileData.trainsSelectLicense) {
|
||||
this.borderNode.active = show;
|
||||
} else {
|
||||
this.disableNode.active = true;
|
||||
}
|
||||
} else {
|
||||
this.disableNode.active = false;
|
||||
this.borderNode.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "eac596d5-3e92-4bab-834e-c62b69dc232c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,419 @@
|
|||
import { Vec2, v2 } from "cc";
|
||||
import { NpkImage } from "../../Tool/NPKImage";
|
||||
|
||||
//* ─── 地块类型 ────────────────────────────────────────────────────────────────────
|
||||
|
||||
/** 地块类型 */
|
||||
export enum MapTileType {
|
||||
/** 赫顿玛尔 */
|
||||
HeDunMaEr = 0,
|
||||
/** 时间广场 */
|
||||
ShiJianGuangChang,
|
||||
/** 兽人峡谷 */
|
||||
ShouRenXiaGu,
|
||||
/** 超时空漩涡 */
|
||||
ChaoShiKongXuanWo,
|
||||
/** 恐怖的栖息地 */
|
||||
KongBuDeQiXiDi,
|
||||
/** 红色魔女之森 */
|
||||
HongSeMoNvZhiSen,
|
||||
|
||||
/** 月光酒馆 */
|
||||
YueGuangJiuGuan,
|
||||
/** 亡命杀阵 */
|
||||
WangMingShaZhen,
|
||||
/** 皇家娱乐 */
|
||||
HuangJaiYuLe,
|
||||
/** 黑暗都市 */
|
||||
HeiAnDuShi,
|
||||
/** 哈林的命运硬币(左边) */
|
||||
HaLinMingYunYinBi,
|
||||
/** 第九隔离区 */
|
||||
DiJiuGeLiQu,
|
||||
|
||||
/** 决斗场 */
|
||||
JueDouChang,
|
||||
/** 腐坏街道 */
|
||||
FuHuaiJieDao,
|
||||
/** 溢血的地下城 */
|
||||
YiXueDeDiXiaChen,
|
||||
/** 普雷·伊西斯 */
|
||||
PuLeiYiXiSi,
|
||||
/** 沉重的礼拜堂 */
|
||||
ChenZhongDeLiBaiTang,
|
||||
/** 螺旋王国 */
|
||||
LuoXuanWangGuo,
|
||||
|
||||
/** 海上列车 */
|
||||
HaiShangLieChe,
|
||||
/** 暗黑神殿 */
|
||||
AnHeiShenDian,
|
||||
/** 痛苦地下城 */
|
||||
TongKuDiXiaChen,
|
||||
/** 无底坑道 */
|
||||
WuDiKenDao,
|
||||
/** 切斯特小镇的命运硬币(右边) */
|
||||
XiaoZhenMingYunYinBi,
|
||||
/** 记忆之地 */
|
||||
JiYiZhiDi,
|
||||
}
|
||||
|
||||
//* ─── 所有地块类型数组 ────────────────────────────────────────────────────────────────
|
||||
|
||||
/** 所有地块类型数组 */
|
||||
export const MapTileTypes = [
|
||||
/** 赫顿玛尔 */
|
||||
MapTileType.HeDunMaEr,
|
||||
/** 时间广场 */
|
||||
MapTileType.ShiJianGuangChang,
|
||||
/** 兽人峡谷 */
|
||||
MapTileType.ShouRenXiaGu,
|
||||
/** 超时空漩涡 */
|
||||
MapTileType.ChaoShiKongXuanWo,
|
||||
/** 恐怖的栖息地 */
|
||||
MapTileType.KongBuDeQiXiDi,
|
||||
/** 红色魔女之森 */
|
||||
MapTileType.HongSeMoNvZhiSen,
|
||||
|
||||
/** 月光酒馆 */
|
||||
MapTileType.YueGuangJiuGuan,
|
||||
/** 亡命杀阵 */
|
||||
MapTileType.WangMingShaZhen,
|
||||
/** 皇家娱乐 */
|
||||
MapTileType.HuangJaiYuLe,
|
||||
/** 黑暗都市 */
|
||||
MapTileType.HeiAnDuShi,
|
||||
/** 哈林的命运硬币(左边) */
|
||||
MapTileType.HaLinMingYunYinBi,
|
||||
/** 第九隔离区 */
|
||||
MapTileType.DiJiuGeLiQu,
|
||||
|
||||
/** 决斗场 */
|
||||
MapTileType.JueDouChang,
|
||||
/** 腐坏街道 */
|
||||
MapTileType.FuHuaiJieDao,
|
||||
/** 溢血的地下城 */
|
||||
MapTileType.YiXueDeDiXiaChen,
|
||||
/** 普雷·伊西斯 */
|
||||
MapTileType.PuLeiYiXiSi,
|
||||
/** 沉重的礼拜堂 */
|
||||
MapTileType.ChenZhongDeLiBaiTang,
|
||||
/** 螺旋王国 */
|
||||
MapTileType.LuoXuanWangGuo,
|
||||
|
||||
/** 海上列车 */
|
||||
MapTileType.HaiShangLieChe,
|
||||
/** 暗黑神殿 */
|
||||
MapTileType.AnHeiShenDian,
|
||||
/** 痛苦地下城 */
|
||||
MapTileType.TongKuDiXiaChen,
|
||||
/** 无底坑道 */
|
||||
MapTileType.WuDiKenDao,
|
||||
/** 切斯特小镇的命运硬币(右边) */
|
||||
MapTileType.XiaoZhenMingYunYinBi,
|
||||
/** 记忆之地 */
|
||||
MapTileType.JiYiZhiDi,
|
||||
];
|
||||
|
||||
//* ─── 地块方向 ────────────────────────────────────────────────────────────────────
|
||||
|
||||
/** 地块方向 */
|
||||
export enum MapTileDirection {
|
||||
/** 横 */
|
||||
horizontal = 24,
|
||||
/** 竖 */
|
||||
vertical = 25,
|
||||
/** 角落 */
|
||||
nook = 26,
|
||||
}
|
||||
|
||||
//* ─── 地块的数据 ───────────────────────────────────────────────────────────────────
|
||||
|
||||
/** 地块的数据 */
|
||||
export class MapTileData {
|
||||
/** 坐标 */
|
||||
location: Vec2;
|
||||
/** npk路径 */
|
||||
npkPath: NpkImage;
|
||||
/** 地块背景index */
|
||||
backgroundIndex: number;
|
||||
/** 地块方向 */
|
||||
direction: MapTileDirection;
|
||||
/** 怪物相关数据 */
|
||||
|
||||
/** 列车选择许可 */
|
||||
trainsSelectLicense: boolean;
|
||||
/** 决斗场选择许可 */
|
||||
duelSelectLicense: boolean;
|
||||
/** 占领许可 */
|
||||
occupyLicense: boolean;
|
||||
|
||||
constructor({
|
||||
/** 坐标 */
|
||||
location,
|
||||
/** 背景index */
|
||||
backgroundIndex,
|
||||
/** 地块方向 */
|
||||
direction,
|
||||
/** 占领许可 */
|
||||
occupyLicense,
|
||||
/** 列车选择许可 */
|
||||
trainsSelectLicense,
|
||||
/** 决斗场选择许可 */
|
||||
duelSelectLicense,
|
||||
}: {
|
||||
location: Vec2;
|
||||
backgroundIndex?: number;
|
||||
direction: MapTileDirection;
|
||||
occupyLicense?: boolean;
|
||||
trainsSelectLicense?: boolean;
|
||||
duelSelectLicense?: boolean;
|
||||
}) {
|
||||
this.location = location;
|
||||
this.npkPath = NpkImage.board;
|
||||
this.backgroundIndex = backgroundIndex;
|
||||
this.direction = direction;
|
||||
|
||||
this.trainsSelectLicense = trainsSelectLicense ?? true;
|
||||
this.duelSelectLicense = duelSelectLicense ?? true;
|
||||
this.occupyLicense = occupyLicense ?? true;
|
||||
}
|
||||
|
||||
static getData(type: MapTileType): MapTileData {
|
||||
switch (type) {
|
||||
/// 赫顿玛尔
|
||||
case MapTileType.HeDunMaEr:
|
||||
return this.HeDunMaErData;
|
||||
/// 时间广场
|
||||
case MapTileType.ShiJianGuangChang:
|
||||
return this.ShiJianGuangChangData;
|
||||
/// 兽人峡谷
|
||||
case MapTileType.ShouRenXiaGu:
|
||||
return this.ShouRenXiaGuData;
|
||||
/// 超时空漩涡
|
||||
case MapTileType.ChaoShiKongXuanWo:
|
||||
return this.ChaoShiKongXuanWoData;
|
||||
/// 恐怖的栖息地
|
||||
case MapTileType.KongBuDeQiXiDi:
|
||||
return this.KongBuDeQiXiDiData;
|
||||
/// 红色魔女之森
|
||||
case MapTileType.HongSeMoNvZhiSen:
|
||||
return this.HongSeMoNvZhiSenData;
|
||||
/// 月光酒馆
|
||||
case MapTileType.YueGuangJiuGuan:
|
||||
return this.YueGuangJiuGuanData;
|
||||
/// 亡命杀镇子
|
||||
case MapTileType.WangMingShaZhen:
|
||||
return this.WangMingShaZhenData;
|
||||
/// 皇家娱乐
|
||||
case MapTileType.HuangJaiYuLe:
|
||||
return this.HuangJaiYuLeData;
|
||||
/// 黑暗都市
|
||||
case MapTileType.HeiAnDuShi:
|
||||
return this.HeiAnDuShiData;
|
||||
/// 哈林的命运硬币(左边)
|
||||
case MapTileType.HaLinMingYunYinBi:
|
||||
return this.HaLinMingYunYinBiData;
|
||||
/// 第九隔离区
|
||||
case MapTileType.DiJiuGeLiQu:
|
||||
return this.DiJiuGeLiQuData;
|
||||
/// 决斗场
|
||||
case MapTileType.JueDouChang:
|
||||
return this.JueDouChangData;
|
||||
/// 腐坏街道
|
||||
case MapTileType.FuHuaiJieDao:
|
||||
return this.FuHuaiJieDaoData;
|
||||
/// 溢血的地下城
|
||||
case MapTileType.YiXueDeDiXiaChen:
|
||||
return this.YiXueDeDiXiaChenData;
|
||||
/// 普雷·伊西斯
|
||||
case MapTileType.PuLeiYiXiSi:
|
||||
return this.PuLeiYiXiSiData;
|
||||
/// 沉重的礼拜堂
|
||||
case MapTileType.ChenZhongDeLiBaiTang:
|
||||
return this.ChenZhongDeLiBaiTangData;
|
||||
/// 螺旋王国
|
||||
case MapTileType.LuoXuanWangGuo:
|
||||
return this.LuoXuanWangGuoData;
|
||||
/// 海上列车
|
||||
case MapTileType.HaiShangLieChe:
|
||||
return this.HaiShangLieCheData;
|
||||
/// 暗黑神殿
|
||||
case MapTileType.AnHeiShenDian:
|
||||
return this.AnHeiShenDianData;
|
||||
/// 痛苦地下城
|
||||
case MapTileType.TongKuDiXiaChen:
|
||||
return this.TongKuDiXiaChenData;
|
||||
/// 无底坑道
|
||||
case MapTileType.WuDiKenDao:
|
||||
return this.WuDiKenDaoData;
|
||||
/// 切斯特小镇的命运硬币(右边)
|
||||
case MapTileType.XiaoZhenMingYunYinBi:
|
||||
return this.XiaoZhenMingYunYinBiData;
|
||||
/// 记忆之地
|
||||
case MapTileType.JiYiZhiDi:
|
||||
return this.JiYiZhiDiData;
|
||||
}
|
||||
}
|
||||
|
||||
/** 赫顿玛尔 */
|
||||
private static HeDunMaErData = new MapTileData({
|
||||
location: v2(475, -448),
|
||||
direction: MapTileDirection.nook,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
|
||||
/** 时间广场 (55,34) */
|
||||
private static ShiJianGuangChangData = new MapTileData({
|
||||
location: v2(420, -414),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 兽人峡谷 (52,34) */
|
||||
private static ShouRenXiaGuData = new MapTileData({
|
||||
location: v2(368, -380),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 超时空漩涡 (53,34) */
|
||||
private static ChaoShiKongXuanWoData = new MapTileData({
|
||||
location: v2(315, -346),
|
||||
backgroundIndex: 32,
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 恐怖的栖息地 (52,34) */
|
||||
private static KongBuDeQiXiDiData = new MapTileData({
|
||||
location: v2(262, -312),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 红色魔女之森 (52,34) */
|
||||
private static HongSeMoNvZhiSenData = new MapTileData({
|
||||
location: v2(209, -278),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
// 月光酒馆(69,44) */
|
||||
private static YueGuangJiuGuanData = new MapTileData({
|
||||
location: v2(140, -234),
|
||||
direction: MapTileDirection.nook,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
|
||||
/** 亡命杀镇 (53,34) */
|
||||
private static WangMingShaZhenData = new MapTileData({
|
||||
location: v2(209, -198),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
/** 皇家娱乐(53,34) */
|
||||
private static HuangJaiYuLeData = new MapTileData({
|
||||
location: v2(262, -164),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
/** 黑暗都市 */
|
||||
private static HeiAnDuShiData = new MapTileData({
|
||||
location: v2(315, -130),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
/** 哈林的命运硬币(左边) */
|
||||
private static HaLinMingYunYinBiData = new MapTileData({
|
||||
location: v2(368, -96),
|
||||
backgroundIndex: 34,
|
||||
direction: MapTileDirection.vertical,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
/** 第九隔离区 */
|
||||
private static DiJiuGeLiQuData = new MapTileData({
|
||||
location: v2(421, -62),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
// 决斗场(54,44) */
|
||||
private static JueDouChangData = new MapTileData({
|
||||
location: v2(475, -18),
|
||||
direction: MapTileDirection.nook,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
|
||||
/** 腐坏街道(53,34) */
|
||||
private static FuHuaiJieDaoData = new MapTileData({
|
||||
location: v2(544, -62),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 溢血的地下城(53,34) */
|
||||
private static YiXueDeDiXiaChenData = new MapTileData({
|
||||
location: v2(597, -96),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 普雷·伊西斯 */
|
||||
private static PuLeiYiXiSiData = new MapTileData({
|
||||
location: v2(650, -130),
|
||||
backgroundIndex: 33,
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 沉重的礼拜堂 */
|
||||
private static ChenZhongDeLiBaiTangData = new MapTileData({
|
||||
location: v2(703, -164),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
/** 螺旋王国 */
|
||||
private static LuoXuanWangGuoData = new MapTileData({
|
||||
location: v2(756, -198),
|
||||
direction: MapTileDirection.horizontal,
|
||||
});
|
||||
|
||||
// 海上列车(69,44) */
|
||||
private static HaiShangLieCheData = new MapTileData({
|
||||
location: v2(808, -234),
|
||||
direction: MapTileDirection.nook,
|
||||
trainsSelectLicense: false,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
|
||||
/** 暗黑神殿 */
|
||||
private static AnHeiShenDianData = new MapTileData({
|
||||
location: v2(756, -278),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
/** 痛苦地下城 */
|
||||
private static TongKuDiXiaChenData = new MapTileData({
|
||||
location: v2(703, -312),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
/** 无底坑道 */
|
||||
private static WuDiKenDaoData = new MapTileData({
|
||||
location: v2(650, -346),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
/** 切斯特小镇的命运硬币(右边) */
|
||||
private static XiaoZhenMingYunYinBiData = new MapTileData({
|
||||
location: v2(597, -380),
|
||||
backgroundIndex: 34,
|
||||
direction: MapTileDirection.vertical,
|
||||
duelSelectLicense: false,
|
||||
occupyLicense: false,
|
||||
});
|
||||
|
||||
/** 记忆之地 */
|
||||
private static JiYiZhiDiData = new MapTileData({
|
||||
location: v2(544, -414),
|
||||
direction: MapTileDirection.vertical,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "22719a4e-0012-43b0-8759-5d985734b3f1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-26 11:36:36
|
||||
* @LastEditTime: 2024-03-29 14:03:36
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
import { LuckyCoinsNode, LuckyType } from "../DialogRoot/LuckyCoinsNode";
|
||||
import { GameRootSingleton } from "../GameRootController";
|
||||
|
||||
/**
|
||||
* @description: 地图事件
|
||||
*/
|
||||
export class MapTitleAction {
|
||||
// ─── 特殊事件 ────────────────────────────────────────────────────────────
|
||||
//* 月光酒馆
|
||||
//* 决斗场
|
||||
//* 海上列车
|
||||
//* 幸运硬币
|
||||
/**
|
||||
* @description: 幸运硬币事件
|
||||
*/
|
||||
static lucky(type: LuckyType) {
|
||||
// 将幸运硬币动画节点添加到 Dialog 层
|
||||
const node = new LuckyCoinsNode(type, () => {
|
||||
LuckyAction.Action(type);
|
||||
});
|
||||
GameRootSingleton.getInstance().DialogRootNode.addChild(node);
|
||||
}
|
||||
// ─── 怪物事件 ────────────────────────────────────────────────────────────────────
|
||||
/**
|
||||
* @description: 怪物事件
|
||||
*/
|
||||
static monsterAction() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 幸运硬币事件
|
||||
*/
|
||||
export class LuckyAction {
|
||||
static Action(type: LuckyType) {
|
||||
const lucky = new LuckyAction();
|
||||
switch (type) {
|
||||
case LuckyType.GoThree:
|
||||
lucky.GoThreeAction();
|
||||
break;
|
||||
case LuckyType.YeGuangJiuGuan:
|
||||
lucky.YeGuangJiuGuanAction();
|
||||
break;
|
||||
case LuckyType.JueDouChang:
|
||||
lucky.JueDouChangAction();
|
||||
break;
|
||||
case LuckyType.HaiShangLieChe:
|
||||
lucky.HaiShangLieCheAction();
|
||||
break;
|
||||
case LuckyType.Double:
|
||||
lucky.DoubleAction();
|
||||
break;
|
||||
case LuckyType.Halve:
|
||||
lucky.HalveAction();
|
||||
break;
|
||||
case LuckyType.HorseCombat:
|
||||
lucky.HorseCombatAction();
|
||||
break;
|
||||
case LuckyType.Servicing:
|
||||
lucky.ServicingAction();
|
||||
break;
|
||||
case LuckyType.Charge:
|
||||
lucky.ChargeAction();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 前进三格
|
||||
GoThreeAction() {}
|
||||
// 移动到月光酒馆
|
||||
YeGuangJiuGuanAction() {}
|
||||
// 移动到决斗场
|
||||
JueDouChangAction() {}
|
||||
// 移动到海上列车
|
||||
HaiShangLieCheAction() {}
|
||||
// 我要双倍,点数x2
|
||||
DoubleAction() {}
|
||||
// 这是我的钱,点数减半
|
||||
HalveAction() {}
|
||||
// 骑士马战 ,点数+2w
|
||||
HorseCombatAction() {}
|
||||
// 装备修理, 点数-2w
|
||||
ServicingAction() {}
|
||||
// 收取费用,夺取其他人 2w 点数
|
||||
ChargeAction() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "38b0fe6c-2083-4510-92d6-8f50384fac2c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-27 15:20:29
|
||||
* @LastEditTime: 2024-03-28 21:15:43
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import { MapTileType, MapTileTypes } from "./MapTileType";
|
||||
import { MapTitleModel } from "./MapTitleModel";
|
||||
|
||||
/**
|
||||
* @description: 地图数据的单例
|
||||
*/
|
||||
export class MapTitleDatelSingleton {
|
||||
private static readonly _instance: MapTitleDatelSingleton =
|
||||
new MapTitleDatelSingleton();
|
||||
|
||||
//* 地块nodeMap
|
||||
mapModMap: Map<MapTileType, MapTitleModel> = new Map<
|
||||
MapTileType,
|
||||
MapTitleModel
|
||||
>();
|
||||
|
||||
private constructor() {
|
||||
|
||||
MapTileTypes.forEach((type) => {
|
||||
const mod = new MapTitleModel(type);
|
||||
this.mapModMap.set(type, mod);
|
||||
});
|
||||
}
|
||||
|
||||
public static getInstance(): MapTitleDatelSingleton {
|
||||
return MapTitleDatelSingleton._instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "de311b7f-a77a-4109-aefe-81e8f4d5740f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-26 11:12:32
|
||||
* @LastEditTime: 2024-03-27 15:16:42
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import { _decorator } from "cc";
|
||||
|
||||
import { MapTileType } from "./MapTileType";
|
||||
|
||||
/**
|
||||
* @description: 地图数据模型
|
||||
*/
|
||||
export class MapTitleModel {
|
||||
//* 地块类型
|
||||
type: MapTileType;
|
||||
|
||||
//* 地块占领状态(是谁占领的,)
|
||||
occupState: string;
|
||||
|
||||
//* 占领等级
|
||||
occupyLevel: 0 | 1 | 2 | 3;
|
||||
|
||||
//* 决斗场等级
|
||||
fightLevel: 0 | 2 | 4 | 8;
|
||||
|
||||
constructor(type: MapTileType) {
|
||||
this.type = type;
|
||||
this.occupState = "";
|
||||
this.occupyLevel = 0;
|
||||
this.fightLevel = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5597e322-7749-48fe-98d4-bb4294ab1a10",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "026e885d-7022-43db-bdd8-191d81662a0c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
import { _decorator, BlockInputEvents, Button, Color, Director, director, EventMouse, Label, Node, UITransform, v2 } from 'cc';
|
||||
import { BaseSprite } from '../../GlobalScript/CommonComponent/BaseSprite';
|
||||
import { NpkImage } from '../../Tool/NPKImage';
|
||||
import { BaseButton } from '../../GlobalScript/CommonComponent/BaseButton';
|
||||
import { AnimationNode } from '../../GlobalScript/Animation/AnimationNode';
|
||||
import {CloseButtonNode } from '../Common/CloseButtonNode';
|
||||
import { GameRootSingleton } from '../GameRootController';
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
/// 开始游戏按钮界面
|
||||
@ccclass('StartGameUINode')
|
||||
export class StartGameUINode extends Node {
|
||||
|
||||
/// 玩法介绍
|
||||
private pressenNode: Node;
|
||||
|
||||
constructor(){
|
||||
super();
|
||||
|
||||
this.addComponent(UITransform).setContentSize(1067,600);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
/// 初始化子节点
|
||||
init(){
|
||||
|
||||
this.initBackground();
|
||||
this.initTitle();
|
||||
this.initStartButton();
|
||||
this.initLabel();
|
||||
this.initPressenButton();
|
||||
this.initPressen();
|
||||
}
|
||||
|
||||
/// 背景
|
||||
initBackground(){
|
||||
/// 背景节点
|
||||
const backgroundNode = new Node('StartBackgroundNode');
|
||||
this.addChild(backgroundNode);
|
||||
|
||||
/// 给背景节点添加 baseSprite 组件
|
||||
const backgroundComponent = backgroundNode.addComponent( BaseSprite );
|
||||
backgroundComponent.updateSpriteFrame(NpkImage.main,24);
|
||||
}
|
||||
|
||||
/// 标题动画
|
||||
initTitle(){
|
||||
let titleNode = new AnimationNode('ani/title_loop.ani');
|
||||
titleNode.setPosition(544.5,-305);
|
||||
this.addChild(titleNode);
|
||||
}
|
||||
|
||||
/// 开始游戏
|
||||
initStartButton(){
|
||||
/// 按钮节点
|
||||
const startButtonNode = new Node('StartButton');
|
||||
startButtonNode.setPosition(441.5,-450);
|
||||
|
||||
/// 给节点添加 button 组件
|
||||
const buttonComponent = startButtonNode.addComponent( BaseButton );
|
||||
buttonComponent.init(NpkImage.main,1);
|
||||
|
||||
startButtonNode.addComponent( Button)
|
||||
startButtonNode.on(Button.EventType.CLICK,this.startOnTouchEnd,this);
|
||||
|
||||
this.addChild(startButtonNode);
|
||||
}
|
||||
|
||||
/// 入场次数
|
||||
initLabel(){
|
||||
const labelNode = new Node('Label');
|
||||
labelNode.setPosition(550,-421);
|
||||
|
||||
const labelComponent = labelNode.addComponent( Label );
|
||||
labelComponent.string = '∞';
|
||||
labelComponent.color = new Color('24a5cd');
|
||||
labelComponent.fontSize = 18;
|
||||
|
||||
this.addChild(labelNode);
|
||||
}
|
||||
|
||||
/// 玩法介绍按钮
|
||||
initPressenButton(){
|
||||
/// 按钮节点
|
||||
const pressenButtonNode = new Node('PressenButton');
|
||||
pressenButtonNode.setPosition(1020,-10);
|
||||
|
||||
/// 给节点添加 button 组件
|
||||
const buttonComponent = pressenButtonNode.addComponent( BaseButton );
|
||||
buttonComponent.init(NpkImage.main,9);
|
||||
|
||||
pressenButtonNode.on(Node.EventType.MOUSE_UP,this.pressenOnTouchEnd,this);
|
||||
|
||||
this.addChild(pressenButtonNode);
|
||||
}
|
||||
|
||||
/// 玩法介绍
|
||||
initPressen(){
|
||||
/// 节点
|
||||
this.pressenNode = new Node('Pressen');
|
||||
this.pressenNode.active = false;
|
||||
this.addChild(this.pressenNode);
|
||||
|
||||
this.pressenNode.setPosition(0,0);
|
||||
this.pressenNode.addComponent( UITransform).setContentSize(1067,600);
|
||||
this.pressenNode.getComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
|
||||
/// 拦截下层的点击事件
|
||||
this.pressenNode.addComponent( BlockInputEvents );
|
||||
|
||||
/// 给节点添加 img
|
||||
const imgNode = new Node('PressenImage');
|
||||
imgNode.setPosition(134,-21.5);
|
||||
const imgComponent = imgNode.addComponent( BaseSprite );
|
||||
imgComponent.updateSpriteFrame(NpkImage.main,25);
|
||||
this.pressenNode.addChild(imgNode);
|
||||
|
||||
/// 关闭按钮
|
||||
const closeNode = new CloseButtonNode(this.closeOnTouchEnd.bind(this));
|
||||
closeNode.setPosition(767,-10);
|
||||
imgNode.addChild(closeNode);
|
||||
|
||||
}
|
||||
|
||||
/// 打开玩法介绍
|
||||
pressenOnTouchEnd(event:EventMouse){
|
||||
if ( event.getButton() === EventMouse.BUTTON_LEFT ){
|
||||
this.pressenNode.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
closeOnTouchEnd(event:EventMouse){
|
||||
this.pressenNode.active = false;
|
||||
}
|
||||
|
||||
/// 开始游戏
|
||||
startOnTouchEnd(event:Event){
|
||||
const uiroot = GameRootSingleton.getInstance().UIRoot;
|
||||
uiroot.initGameUI();
|
||||
|
||||
/// 一帧结束之后销毁
|
||||
director.once(Director.EVENT_END_FRAME,()=>{
|
||||
// 销毁
|
||||
this.destroy();
|
||||
});
|
||||
|
||||
console.log('开始游戏');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "37227f6a-00a4-4840-a07e-025b6be2f27c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "7385a06a-b90d-4a7e-ab36-bf702f6f220e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-13 12:19:50
|
||||
* @LastEditTime: 2024-03-29 13:01:41
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-13 12:19:50
|
||||
* @LastEditTime: 2024-03-25 14:19:53
|
||||
* @LastEditors: WoNiu
|
||||
* @Description:
|
||||
*/
|
||||
import {
|
||||
_decorator,
|
||||
Component,
|
||||
EventMouse,
|
||||
Node,
|
||||
Sprite,
|
||||
SpriteFrame,
|
||||
Texture2D,
|
||||
UITransform,
|
||||
v2,
|
||||
} from "cc";
|
||||
import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite";
|
||||
import { NpkImage, NpkImageTool } from "../../Tool/NPKImage";
|
||||
import {
|
||||
BaseButton,
|
||||
BaseButtonState,
|
||||
} from "../../GlobalScript/CommonComponent/BaseButton";
|
||||
import { BaseButtonAction } from "../../GlobalScript/CommonComponent/BaseButtonAction";
|
||||
import { ImagePack } from "../../GlobalScript/ImagePack/ImagePack";
|
||||
import { GameState } from "../../GlobalScript/GlobalGameState/GameState";
|
||||
import { ImgInfo } from "../../GlobalScript/GlobalInterface/GlobalInterface";
|
||||
import { GamerRoleAni, GamerRoleType } from "../Gamer/GamerRoleType";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass("DiceButtonNode")
|
||||
/**
|
||||
* @description: 投骰子按钮的整个节点
|
||||
*/
|
||||
export class DiceButtonNode extends Node {
|
||||
winButtonComponent: BaseButton;
|
||||
diceButtonComponent: BaseButton;
|
||||
|
||||
winButtonBlock: Function;
|
||||
diceDownBlock: Function;
|
||||
diceUpBlock: Function;
|
||||
|
||||
gaugeAnimation: GaugeAnimation;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.initBackgroundNode();
|
||||
this.initOtherWinButtonNode();
|
||||
this.initdiceButtonNode();
|
||||
this.initdiceDiceAniNode();
|
||||
}
|
||||
|
||||
// 背景节点
|
||||
private initBackgroundNode(){
|
||||
const backgroundNode = new Node();
|
||||
const bs = backgroundNode.addComponent(BaseSprite);
|
||||
bs.updateSpriteFrame(NpkImage.ingame, 7);
|
||||
this.addChild(backgroundNode);
|
||||
}
|
||||
|
||||
// 其他获胜条件按钮节点
|
||||
private initOtherWinButtonNode() {
|
||||
/// 其他获胜条件
|
||||
const winButtonNode = new Node();
|
||||
this.addChild(winButtonNode);
|
||||
winButtonNode.setPosition(20.5, -123);
|
||||
|
||||
const winBa = winButtonNode.addComponent(BaseButtonAction);
|
||||
winBa.onMouseUp = this.winOnMouseUp.bind(this);
|
||||
|
||||
this.winButtonComponent = winButtonNode.addComponent(BaseButton);
|
||||
this.winButtonComponent.init(NpkImage.ingame, 60);
|
||||
}
|
||||
|
||||
// 骰子按钮节点
|
||||
private initdiceButtonNode() {
|
||||
/// dice 按钮
|
||||
const diceButtonNode = new Node('diceButton');
|
||||
this.addChild(diceButtonNode);
|
||||
diceButtonNode.setPosition(89, -57);
|
||||
|
||||
const diceBc = diceButtonNode.addComponent(BaseButtonAction);
|
||||
diceBc.onMouseLeftDown = this.diceOnMouseDown.bind(this);
|
||||
diceBc.onMouseLeftUp = this.diceOnMouseUp.bind(this);
|
||||
|
||||
this.diceButtonComponent = diceButtonNode.addComponent(BaseButton);
|
||||
this.diceButtonComponent.init(NpkImage.ingame, 8);
|
||||
this.diceButtonComponent.ButtonState = BaseButtonState.Disable;
|
||||
}
|
||||
|
||||
// 播放动画节点
|
||||
private initdiceDiceAniNode() {
|
||||
const node = new Node();
|
||||
this.addChild(node);
|
||||
node.setPosition(45, -15);
|
||||
|
||||
//设置节点锚点为左上角
|
||||
node.addComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
this.gaugeAnimation = node.addComponent(GaugeAnimation);
|
||||
}
|
||||
|
||||
/// 其他获胜条件
|
||||
private winOnMouseUp(event: EventMouse) {
|
||||
if (this.winButtonComponent.ButtonState == BaseButtonState.Disable) return;
|
||||
if (this.winButtonBlock) this.winButtonBlock();
|
||||
}
|
||||
|
||||
/// 投骰子
|
||||
private diceOnMouseDown(event: EventMouse) {
|
||||
console.log('diceOnMouseDown');
|
||||
if (this.diceButtonComponent.ButtonState == BaseButtonState.Disable)
|
||||
return;
|
||||
if (this.diceDownBlock) this.diceDownBlock();
|
||||
this.gaugeAnimation.updatePlayState(PlayAniState.playing);
|
||||
}
|
||||
private diceOnMouseUp(event: EventMouse) {
|
||||
console.log('diceOnMouseUp');
|
||||
if (this.diceButtonComponent.ButtonState == BaseButtonState.Disable)
|
||||
return;
|
||||
if (this.diceUpBlock) this.diceUpBlock();
|
||||
this.gaugeAnimation.updatePlayState(PlayAniState.pause);
|
||||
}
|
||||
}
|
||||
|
||||
//* ─── 动画播放 ────────────────────────────────────────────────────────────────────
|
||||
|
||||
export enum PlayAniState {
|
||||
//未播放
|
||||
unplayed,
|
||||
//播放中
|
||||
playing,
|
||||
//倒放
|
||||
reversed,
|
||||
//暂停
|
||||
pause,
|
||||
//播放完成
|
||||
done,
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 骰子按钮动画
|
||||
*/
|
||||
export class GaugeAnimation extends Component {
|
||||
// 所有精灵帧缓存
|
||||
private frameMap: Map<number, SpriteFrame> = new Map<number, SpriteFrame>();
|
||||
|
||||
// 精灵帧的数量
|
||||
private frameCount: number = 100;
|
||||
|
||||
// 精灵帧初始化状态
|
||||
private InitState: boolean = false;
|
||||
|
||||
// 总的播放时间
|
||||
private aniTime: number = 1;
|
||||
|
||||
// 当前帧显示时间
|
||||
private nowFrameTime: number = 0;
|
||||
|
||||
// 每一帧需要显示的时间
|
||||
private frameShowTime: number = 0;
|
||||
|
||||
// 当前帧
|
||||
private nowFrameIndex: number = -1;
|
||||
|
||||
//* 动画状态
|
||||
private playState: PlayAniState = PlayAniState.unplayed;
|
||||
|
||||
// 节点的精灵
|
||||
private sprite: Sprite;
|
||||
|
||||
onLoad() {
|
||||
if (!this.node.getComponent(Sprite)) {
|
||||
this.sprite = this.node.addComponent(Sprite);
|
||||
} else {
|
||||
this.sprite = this.node.getComponent(Sprite);
|
||||
}
|
||||
|
||||
//设置类型
|
||||
this.sprite.sizeMode = Sprite.SizeMode.RAW;
|
||||
//设置
|
||||
this.sprite.trim = false;
|
||||
|
||||
NpkImageTool.GetNpkImageAll(NpkImage.gauge, (count,frameMap)=>{
|
||||
this.frameMap = frameMap;
|
||||
this.frameCount = count;
|
||||
this.InitState = true;
|
||||
});
|
||||
}
|
||||
|
||||
start() {}
|
||||
|
||||
/**
|
||||
* @description: 刷新动画状态
|
||||
* @param {PlayAniState} palyState: 动画状态
|
||||
* @param {number} aniTime:播放动画时需要传入 动画的播放时间
|
||||
*/
|
||||
updatePlayState(palyState: PlayAniState, aniTime?: number) {
|
||||
this.playState = palyState;
|
||||
|
||||
// 数据的初始化
|
||||
if (this.playState == PlayAniState.unplayed) {
|
||||
this.sprite.spriteFrame = null;
|
||||
this.nowFrameIndex = -1;
|
||||
} else if (
|
||||
this.playState == (PlayAniState.playing || PlayAniState.reversed)
|
||||
) {
|
||||
this.aniTime = aniTime ?? this.aniTime;
|
||||
// 单帧显示时间
|
||||
this.frameShowTime = this.aniTime * 1000 / this.frameCount;
|
||||
// this.frameShowTime = this.frameShowTime / this.frameCount;
|
||||
}
|
||||
|
||||
// 精灵帧的初始化
|
||||
if (this.playState == PlayAniState.playing) {
|
||||
this.sprite.spriteFrame = this.frameMap.get(0);
|
||||
} else if (this.playState == PlayAniState.reversed) {
|
||||
this.sprite.spriteFrame = this.frameMap.get(this.frameCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
|
||||
//如果游戏世界处于暂停的模式下 不再继续播放
|
||||
if (GameState.getInstance().IsPauseState()) return;
|
||||
//如果初始化未完成,不播放
|
||||
if (!this.InitState) return;
|
||||
//如果不在播放中
|
||||
if (this.playState != PlayAniState.playing && this.playState != PlayAniState.reversed)
|
||||
return;
|
||||
|
||||
//每帧增加过去的时间 取千分之一秒为单位
|
||||
this.nowFrameTime += Math.trunc(dt * 1000);
|
||||
|
||||
// 计算当前加减帧数
|
||||
const index = Math.trunc(this.nowFrameTime / this.frameShowTime);
|
||||
// 当前帧时间不足 一帧显示就跳过
|
||||
if (index < 1) return;
|
||||
|
||||
// 将多余的时间 重新赋值回去
|
||||
this.nowFrameTime = this.nowFrameTime % this.frameShowTime;
|
||||
|
||||
if (this.playState == PlayAniState.playing) {
|
||||
this.nowFrameIndex += index
|
||||
|
||||
this.sprite.spriteFrame = this.frameMap.get(this.nowFrameIndex);
|
||||
|
||||
// 播放到最后一帧 修改播放状态 为倒放
|
||||
if (this.nowFrameIndex >= this.frameCount - 1) {
|
||||
this.playState = PlayAniState.reversed;
|
||||
}
|
||||
} else if (this.playState == PlayAniState.reversed) {
|
||||
this.nowFrameIndex -= index;
|
||||
|
||||
this.sprite.spriteFrame = this.frameMap.get(this.nowFrameIndex);
|
||||
|
||||
// 播放到第一帧 修改播放状态 为倒放
|
||||
if (this.nowFrameIndex <= 0) {
|
||||
this.playState = PlayAniState.playing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9fa9f4d2-1eba-49a5-b9f6-3ec51e1fa959",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-29 13:20:16
|
||||
* @LastEditTime: 2024-03-29 14:16:51
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 游戏匹配过程控制
|
||||
*/
|
||||
import { _decorator, Component, Director, director, Node } from "cc";
|
||||
import { UIRoot } from "./UIRoot";
|
||||
import { GameRootSingleton } from "./../GameRootController";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("GameMatchingProcessControl")
|
||||
/**
|
||||
* @description: 游戏匹配过程控制
|
||||
*/
|
||||
export class GameMatchingProcessControl extends Component {
|
||||
/** UIRoot 节点的 UI节点 */
|
||||
uiRoot: UIRoot;
|
||||
|
||||
start() {
|
||||
this.uiRoot = GameRootSingleton.getInstance().UIRoot;
|
||||
|
||||
this.countDown();
|
||||
}
|
||||
|
||||
//todo 自动跳过,接入网络后修改
|
||||
/** 匹配加载动画控制 */
|
||||
countDown() {
|
||||
|
||||
// 1秒后 结束加载
|
||||
setTimeout(() => {
|
||||
/// 这一帧结束之后销毁
|
||||
director.once(Director.EVENT_END_FRAME, () => {
|
||||
// 销毁
|
||||
this.uiRoot.awaitGamerNode.destroy();
|
||||
|
||||
// todo 开发时跳过倒计时动画
|
||||
/// 初始化开始倒计时动画
|
||||
// this.initCountDownFontAni(5);
|
||||
});
|
||||
|
||||
// todo 开发时跳过倒计时动画
|
||||
this.uiRoot.countDownAniDone();
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "79e2c1f6-7206-4356-82a5-09f3d1039dff",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* @Author: WoNiu
|
||||
* @Date: 2024-03-29 14:04:56
|
||||
* @LastEditTime: 2024-03-29 14:14:48
|
||||
* @LastEditors: WoNiu
|
||||
* @Description: 玩家角色控制
|
||||
*/
|
||||
import { _decorator, Component, Node } from "cc";
|
||||
import { GamerRoleNode } from "../Gamer/GamerRoleNode";
|
||||
import { GamerRoleType } from "../Gamer/GamerRoleType";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("GameRoleController")
|
||||
/**
|
||||
* @description: 玩家角色控制
|
||||
*/
|
||||
export class GameRoleController extends Component {
|
||||
/** 玩家 1 角色 */
|
||||
oneRole: GamerRoleNode;
|
||||
/** 玩家 2 角色 */
|
||||
twoRole: GamerRoleNode;
|
||||
/** 玩家 3 角色 */
|
||||
threeRole: GamerRoleNode;
|
||||
|
||||
/**
|
||||
* @description: 初始化角色
|
||||
* @param oneRoleType : 玩家 1
|
||||
* @param twoRoleType : 玩家 2
|
||||
* @param threeRoleType : 玩家 3
|
||||
*/
|
||||
initRole(
|
||||
oneRoleType: GamerRoleType,
|
||||
twoRoleType: GamerRoleType,
|
||||
threeRoleType: GamerRoleType
|
||||
) {
|
||||
this.oneRole = new GamerRoleNode(oneRoleType);
|
||||
this.twoRole = new GamerRoleNode(twoRoleType);
|
||||
this.threeRole = new GamerRoleNode(threeRoleType);
|
||||
|
||||
this.node.addChild(this.oneRole);
|
||||
this.node.addChild(this.twoRole);
|
||||
this.node.addChild(this.threeRole);
|
||||
}
|
||||
|
||||
start() {}
|
||||
|
||||
update(deltaTime: number) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "80141aea-c2a5-4eab-8430-59484a333bf1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { _decorator, BlockInputEvents, Component, Node, Size, UITransform, v2 } from 'cc';
|
||||
import { BaseSprite } from '../../GlobalScript/CommonComponent/BaseSprite';
|
||||
import { NpkImage } from '../../Tool/NPKImage';
|
||||
import { CloseButtonNode } from '../Common/CloseButtonNode';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
export enum otherWinType{
|
||||
/// 长跑达人
|
||||
longRun = 0,
|
||||
/// 地轨中心的王
|
||||
groundKing = 1,
|
||||
/// 哈林的王
|
||||
halinKing = 2,
|
||||
/// 魔界大战的王
|
||||
hellWarKing = 3,
|
||||
/// 切斯特小镇的王
|
||||
townsKing = 4,
|
||||
/// 区域独占
|
||||
districtExclusive = 5
|
||||
|
||||
}
|
||||
|
||||
/// 其他获胜条件
|
||||
@ccclass('OtherWinNode')
|
||||
export class OtherWinNode extends Node {
|
||||
|
||||
constructor(type:otherWinType){
|
||||
super();
|
||||
|
||||
this.setPosition(0,0);
|
||||
this.addComponent( UITransform).setContentSize(new Size(1067,600));
|
||||
this.getComponent(UITransform).anchorPoint = v2(0, 1);
|
||||
this.addComponent( BlockInputEvents );
|
||||
|
||||
/// 获胜条件图片
|
||||
const winImgNode = new Node();
|
||||
this.addChild(winImgNode);
|
||||
|
||||
this.setPosition(366,-176.5);
|
||||
|
||||
const winBs = winImgNode.addComponent( BaseSprite );
|
||||
winBs.updateSpriteFrame(NpkImage.conditionsofvictory,type);
|
||||
|
||||
|
||||
/// 关闭按钮
|
||||
const closeNode = new CloseButtonNode(()=>{
|
||||
this.active = false;
|
||||
});
|
||||
winImgNode.addChild(closeNode);
|
||||
|
||||
closeNode.setPosition(310,-15);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b5b4e31e-b152-4a72-968b-3aa98a6aaa77",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue