diff --git a/assets/Script/DialogNode/SelectNumberNode.ts b/assets/Script/DialogNode/SelectNumberNode.ts index 9a742e7..1a59716 100644 --- a/assets/Script/DialogNode/SelectNumberNode.ts +++ b/assets/Script/DialogNode/SelectNumberNode.ts @@ -1,7 +1,7 @@ /* * @Author: WoNiu * @Date: 2024-03-21 13:28:47 - * @LastEditTime: 2024-03-24 16:49:37 + * @LastEditTime: 2024-03-25 19:44:01 * @LastEditors: WoNiu * @Description: */ @@ -12,10 +12,7 @@ * @LastEditors: WoNiu * @Description: 顺序选择卡片节点 */ -import { - _decorator, - Node, -} from "cc"; +import { _decorator, Director, director, Node } from "cc"; import { BaseSprite } from "../../GlobalScript/CommonComponent/BaseSprite"; import { NpkImage } from "../../Tool/NPKImage"; import { BaseButtonAction } from "../../GlobalScript/CommonComponent/BaseButtonAction"; @@ -29,6 +26,7 @@ export class SelectNumberNode extends Node { oneCard: CardNode; twoCard: CardNode; threeCard: CardNode; + doneFunc: Function; constructor() { super(); @@ -52,51 +50,67 @@ export class SelectNumberNode extends Node { this.oneCard.setPosition(339, -220); this.addChild(this.oneCard); const Onebba = this.oneCard.addComponent(BaseButtonAction); - Onebba.onMouseLeftDown = ()=>{ this.onMouseLeftDown(0) }; + 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) }; + 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) }; - + threeBba.onMouseLeftDown = () => { + this.onMouseLeftDown(2); + }; } - initTiming(){ + //* 倒计时 + initTiming() { + // 倒计时 const time = new TimingProgressBar(); this.addChild(time); - time.tweenerStart(3,()=>{ - console.log('缓动完成'); + + 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]; + 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); + card.flipsAnimation.animationStart(i, "玩家" + i); } - } - onMouseLeftDown(tag:number){ - const cards = [this.oneCard,this.twoCard,this.threeCard]; - cards.forEach((card)=>{ + onMouseLeftDown(tag: number) { + const cards = [this.oneCard, this.twoCard, this.threeCard]; + cards.forEach((card) => { card.Disable = true; }); - - }; + } update(deltaTime: number) {} } - - diff --git a/assets/Script/DialogRoot.ts b/assets/Script/DialogRoot.ts index 2aa3102..a6e5af2 100644 --- a/assets/Script/DialogRoot.ts +++ b/assets/Script/DialogRoot.ts @@ -1,8 +1,18 @@ +/* + * @Author: WoNiu + * @Date: 2024-03-19 17:44:59 + * @LastEditTime: 2024-03-25 14:58:55 + * @LastEditors: WoNiu + * @Description: + */ import { _decorator, Component, Director, director, Node } from 'cc'; import { SelectNumberNode } from './DialogNode/SelectNumberNode'; const { ccclass, property } = _decorator; @ccclass('DialogRoot') +/** + * @description: 弹窗 + */ export class DialogRoot extends Component { start() { @@ -14,10 +24,11 @@ export class DialogRoot extends Component { //* 初始化并显示顺序选择node - initSelectNumberNode(){ + initSelectNumberNode(): SelectNumberNode{ const selectNode = new SelectNumberNode(); selectNode.name = 'SelectNumberNode'; this.node.addChild(selectNode); + return selectNode; } //* 销毁顺序选择node diff --git a/assets/Script/GameRootController.ts b/assets/Script/GameRootController.ts index 6ed3c17..32b7340 100644 --- a/assets/Script/GameRootController.ts +++ b/assets/Script/GameRootController.ts @@ -1,3 +1,10 @@ +/* + * @Author: WoNiu + * @Date: 2024-03-21 13:29:53 + * @LastEditTime: 2024-03-25 01:18:18 + * @LastEditors: WoNiu + * @Description: + */ import { _decorator,Component, Node } from 'cc'; import { BoardRoot } from './BoardRoot'; import { UIRoot } from './UIRoot'; @@ -5,6 +12,9 @@ import { DialogRoot } from './DialogRoot'; const { ccclass, property } = _decorator; +/** + * @description: 游戏根节点的单例 用于直接提供子节点 + */ export class GameRootSingleton { private static readonly _instance: GameRootSingleton = new GameRootSingleton(); @@ -26,6 +36,9 @@ export class GameRootSingleton { @ccclass('GameRootController') +/** + * @description: 游戏根节点脚本 + */ export class GameRootController extends Component { @property(Node) boardRootNode:Node; diff --git a/assets/Script/UINode/DiceButtonNode.ts b/assets/Script/UINode/DiceButtonNode.ts index c7cf81e..c90ba3d 100644 --- a/assets/Script/UINode/DiceButtonNode.ts +++ b/assets/Script/UINode/DiceButtonNode.ts @@ -1,78 +1,302 @@ /* * @Author: WoNiu * @Date: 2024-03-13 12:19:50 - * @LastEditTime: 2024-03-22 22:49:20 + * @LastEditTime: 2024-03-25 19:49:13 * @LastEditors: WoNiu * @Description: */ -import { _decorator, EventMouse, Node } from 'cc'; -import { BaseSprite } from '../../GlobalScript/CommonComponent/BaseSprite'; -import { NpkImage } from '../../Tool/NPKImage'; -import { BaseButton, BaseButtonState } from '../../GlobalScript/CommonComponent/BaseButton'; -import { BaseButtonAction } from '../../GlobalScript/CommonComponent/BaseButtonAction'; +/* + * @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 } 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"; const { ccclass } = _decorator; - -/// 投骰子按钮的整个节点 -@ccclass('DiceButtonNode') +@ccclass("DiceButtonNode") +/** + * @description: 投骰子按钮的整个节点 + */ export class DiceButtonNode extends Node { + winButtonComponent: BaseButton; + diceButtonComponent: BaseButton; - winButtonComponent: BaseButton; - spaceButtonComponent: BaseButton; + winButtonBlock: Function; + diceDownBlock: Function; + diceUpBlock: Function; - winButtonBlock: Function; - spaceDownBlock: Function; - spaceUpBlock: Function; + gaugeAnimation: GaugeAnimation; - constructor(){ - super(); + constructor() { + super(); - const backgroundNode = new Node(); - const bs = backgroundNode.addComponent( BaseSprite ); - bs.updateSpriteFrame(NpkImage.ingame,7); - this.addChild(backgroundNode); + this.initBackgroundNode(); + this.initOtherWinButtonNode(); + this.initdiceButtonNode(); + this.initdiceDiceAniNode(); + } - /// 其他获胜条件 - 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) - - - /// space - const spaceButtonNode = new Node(); - this.addChild(spaceButtonNode); - spaceButtonNode.setPosition(89,-57); - - const spaceBc = spaceButtonNode.addComponent( BaseButtonAction); - spaceBc.onMouseLeftDown = this.spaceOnMouseDown.bind(this); - spaceBc.onMouseLeftUp = this.spaceOnMouseUp.bind(this); - - this.spaceButtonComponent = spaceButtonNode.addComponent( BaseButton ); - this.spaceButtonComponent.init(NpkImage.ingame,8); - this.spaceButtonComponent.ButtonState = BaseButtonState.Disable; - - } + // 背景节点 + private initBackgroundNode(){ + const backgroundNode = new Node(); + const bs = backgroundNode.addComponent(BaseSprite); + bs.updateSpriteFrame(NpkImage.ingame, 7); + this.addChild(backgroundNode); + } + // 其他获胜条件按钮节点 + private initOtherWinButtonNode() { /// 其他获胜条件 - private winOnMouseUp(event:EventMouse){ - if (this.winButtonComponent.ButtonState == BaseButtonState.Disable ) return; - if (this.winButtonBlock) this.winButtonBlock(); - } + const winButtonNode = new Node(); + this.addChild(winButtonNode); + winButtonNode.setPosition(20.5, -123); - /// 投骰子 - private spaceOnMouseDown(event:EventMouse){ - if (this.spaceButtonComponent.ButtonState == BaseButtonState.Disable ) return; - if (this.spaceDownBlock) this.spaceDownBlock(); - } - private spaceOnMouseUp(event: EventMouse){ - if (this.spaceButtonComponent.ButtonState == BaseButtonState.Disable ) return; - if (this.spaceUpBlock) this.spaceUpBlock(); - } + 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 = new Map(); + + // 精灵帧的数量 + 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; + + ImagePack.getInstance().ReadNpkTable( + "sprite/" + NpkImage.gauge.toLocaleLowerCase(), + (ImgObj) => { + const Pngs = ImgObj.Png_List; + // 总数量 + this.frameCount = ImgObj.Png_Count; + + for (let i = 0; i < Pngs.length; i++) { + const png = Pngs[i]; + this.initSpriteFrame(i,png); + } + + this.InitState = true; + + } + ); + } + + /// 根据拿到的数据 初始化精灵帧 + initSpriteFrame(index:number,Png: ImgInfo) { + const 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.frameMap.set(index, spriteFrame); + } + + 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; + + // this.SetAniFrameByTime(); + //如果不在播放中 + 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; + } + } + } } diff --git a/assets/Script/UIRoot.ts b/assets/Script/UIRoot.ts index c5851ba..840603a 100644 --- a/assets/Script/UIRoot.ts +++ b/assets/Script/UIRoot.ts @@ -16,6 +16,7 @@ import { OtherWinNode, otherWinType } from "./UINode/OtherWinNode"; import { BoardRoot } from "./BoardRoot"; import { StartGameUINode } from "./StartGameNode/StartGameUINode"; import { GameRootSingleton } from "./GameRootController"; +import { SelectNumberNode } from "./DialogNode/SelectNumberNode"; const { ccclass } = _decorator; @ccclass("UIRoot") @@ -65,8 +66,6 @@ export class UIRoot extends Component { this.gamerThree = new GamerNode(""); this.node.addChild(this.gamerThree); - - this.initDiceButton(); } //* 初始化等待玩家加载UI @@ -85,7 +84,7 @@ export class UIRoot extends Component { this.awaitGamerNode = node; - + //todo 自动跳过,接入网络后修改 // 1秒后 结束加载 setTimeout(() => { @@ -120,7 +119,7 @@ export class UIRoot extends Component { this.node.addChild(ani); } - //* 初始化投骰子按钮 + //* 初始化骰子节点 initDiceButton() { this.diceButton = new DiceButtonNode(); this.diceButton.setPosition(849, -453); @@ -156,8 +155,14 @@ export class UIRoot extends Component { //* 显示顺序选择node this.otherWinNode.active = false; - - GameRootSingleton.getInstance().DialogRoot.initSelectNumberNode(); + + const select = GameRootSingleton.getInstance().DialogRoot.initSelectNumberNode(); + + select.doneFunc = ()=>{ + // todo 开发阶段在选择顺序结束后,恢复骰子按钮状态 + this.diceButton.diceButtonComponent.ButtonState = BaseButtonState.Normal; + }; + }, 1000); } diff --git a/assets/Script/common/TimingProgressBar.ts b/assets/Script/common/TimingProgressBar.ts index 49c756f..ac9a59b 100644 --- a/assets/Script/common/TimingProgressBar.ts +++ b/assets/Script/common/TimingProgressBar.ts @@ -1,7 +1,7 @@ /* * @Author: WoNiu * @Date: 2024-03-21 13:44:57 - * @LastEditTime: 2024-03-24 17:53:53 + * @LastEditTime: 2024-03-25 19:42:52 * @LastEditors: WoNiu * @Description: */ @@ -53,7 +53,12 @@ export class TimingProgressBar extends Node { this.initProgressBar(); } - //* 开始缓动 + //* 倒计时缓动开始 + /** + * @description: + * @param {number} time: 时间 + * @param {Function} back: 缓动完成回调 + */ tweenerStart(time:number,back:Function){ this.timingComponent.tweenerStart(time,back); } diff --git a/assets/scene/main.scene b/assets/scene/main.scene index e92fbf1..217534c 100644 --- a/assets/scene/main.scene +++ b/assets/scene/main.scene @@ -175,7 +175,7 @@ "_priority": 0, "_fov": 45, "_fovAxis": 0, - "_orthoHeight": 444.3474801061008, + "_orthoHeight": 461.4054054054054, "_near": 0, "_far": 1000, "_color": {