import { _decorator, Button, Node, Tween, tween, Vec3, Animation, Sprite, Asset, ImageAsset, SpriteFrame, Texture2D, UITransform, Label } from 'cc'; import BaseView from '../../../../../../extensions/app/assets/base/BaseView'; import { PageTips } from '../../tips/native/PageTips'; import { app } from 'db://assets/app/app'; import { Tools } from 'db://assets/res-native/tools/Tools'; import { PageRewardhistory } from '../../rewardhistory/native/PageRewardhistory'; import { USERDATA } from 'db://assets/res-native/data/UserData'; const { ccclass, property } = _decorator; @ccclass('PageMain') export class PageMain extends BaseView { /** 标题 */ @property(Node) title: Node = null!; /** 鸡蛋 */ @property(Node) egg_item: Node = null!; /** 鸡蛋背景 */ @property(Node) egg_bg: Node = null!; /** 奖励 */ @property(Node) reward_bg: Node = null!; /** 奖励 */ @property(Node) noreward_bg: Node = null!; /** 音乐按钮 */ @property(Node) btn_music: Node = null!; /** 锤子 */ @property(Node) hammer: Node = null!; /** 剩余次数 */ @property(Label) lab_remain: Label = null!; /** 奖励文字 */ @property(Label) lab_rw: Label = null!; /** 奖励icon */ @property(Sprite) icon_rw: Sprite = null!; /** 奖励icon */ @property(Sprite) game_logo: Sprite = null!; /** 奖励icon */ @property(Sprite) game_logo_bg: Sprite = null!; /** 默认鸡蛋数量 */ private _eggs_num: number = 3; /** 鸡蛋节点管理 */ private _egg_mgr : Node[] = null!; /** 鸡蛋动画管理 */ private _egg_anim_mgr : Tween[] = []; /** 此轮是否点击过鸡蛋 */ private _clickEgg: boolean = false; // 初始化的相关逻辑写在这 onLoad() {} // 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对) onShow(params: any) { this.titleAnimation(); this.creatEggs(); this.lab_remain.string = "Cracks Used : " + USERDATA.point.toString(); // 加载配置的logo if (USERDATA.logo && this.game_logo) { Tools.remoteLoadSprite(USERDATA.logo, this.game_logo) } if (USERDATA.logo_back && this.game_logo_bg) { Tools.remoteLoadSprite(USERDATA.logo_back, this.game_logo_bg) } } /** 生成鸡蛋 */ creatEggs(){ this._clickEgg = false // 清理已有鸡蛋 for (let i = 0; i < this._egg_mgr?.length; i++) { this._egg_mgr[i].destroy(); } this._egg_mgr = []; // 根据鸡蛋数量进行设定初始角度 const oneThirdCircle = 2 * Math.PI / this._eggs_num; // for (let i = 0; i < this._eggs_num; i++) { this._egg_mgr[i] = Tools.AddChild(this.egg_bg, this.egg_item); Tools.GetChildComp(this._egg_mgr[i], "egg", Button).clickEvents[0].customEventData = i.toString(); this.eggsEllipseMotionPrecise(this._egg_mgr[i] , i * oneThirdCircle, i); } } /** 标题动画 */ titleAnimation() { const scaleDown = tween().to(0.6, { scale: new Vec3(0.96, 0.96, 1) }); const scaleUp = tween().to(0.6, { scale: new Vec3(1, 1, 1) }); tween(this.title) .sequence(scaleDown, scaleUp) // 使用sequence串联动画 .repeatForever() .start(); } /** 更精确的鸡蛋椭圆运动动画 - 修复停顿问题 */ eggsEllipseMotionPrecise(egg: Node, startAngle: number = 0, index: number) { // 椭圆参数 const centerX = 0; const centerY = 350; const a = 250; // 长半轴 const b = 60; // 短半轴 const duration = 5; // 一圈的时间 // 首先设置初始位置 const initialX = centerX + a * Math.cos(startAngle); const initialY = centerY + b * Math.sin(startAngle); egg.setPosition(new Vec3(initialX, initialY, 0)); // 创建多个关键帧实现更平滑的椭圆运动 const steps = 20; const actions = []; // 从指定起始角度开始创建动画序列 for (let i = 0; i < steps; i++) { // 改变角度计算方式,使用负角度或调整角度递增方向 const nextAngle = startAngle - (2 * Math.PI * (i + 1)) / steps; // 从起始角度开始 const nextX = centerX + a * Math.cos(nextAngle); const nextY = centerY + b * Math.sin(nextAngle); actions.push( tween().to( duration/steps, { position: new Vec3(nextX, nextY, 0) }, { easing: 'linear' } ) ); } this._egg_anim_mgr[index] = tween(egg) .sequence(...actions) .repeatForever() .start(); egg.active = true; } // 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide) onHide(result: undefined) { // app.manager.ui.show({name: 'PageMain', onHide:(result) => { 接收到return的数据,并且有类型提示 }}) return result; } protected update(dt: number): void { // 比较三个鸡蛋的y位置并设置它们的前后顺序 if (this._egg_mgr.length > 0){ this.updateEggSorting(); } } /** * 根据Y轴位置更新鸡蛋的层级顺序 * Y值越大(越靠下)的鸡蛋应该显示在前后 */ private updateEggSorting() { // 创建包含鸡蛋和Y位置的数组 const eggs = []; for (let i = 0; i < this._egg_mgr.length; i++) { eggs[i] = { node: this._egg_mgr[i], y: this._egg_mgr[i].position.y }; } // 按照Y值从大到小排序(Y值大的在后面) eggs.sort((a, b) => b.y - a.y); // 设置层级顺序,Y值大的显示在后面 for (let i = 0; i < eggs.length; i++) { eggs[i].node.setSiblingIndex(i); } } /** 点击鸡蛋 */ onClickEgg(event:any, eggIndex: string) { if (this._clickEgg) return; if (USERDATA.point <= 0) { app.manager.ui.showToast(Tools.GetLocalized("no crack")); return; } this._clickEgg = true; // 停止所有鸡蛋的动画 for (let i = 0; i < this._egg_anim_mgr.length; i++) { this._egg_anim_mgr[i].stop(); } const index = parseInt(eggIndex); // 在这里添加点击鸡蛋后的逻辑处理 let egg = this._egg_mgr[index] // 创建锤子 let worldPos =event.touch.getUILocation(); worldPos = new Vec3(worldPos.x, worldPos.y, 0); let localPos = this._egg_mgr[parseInt(eggIndex)].getComponent(UITransform).convertToNodeSpaceAR(worldPos); let hammer = Tools.AddChild(egg, this.hammer) hammer.setPosition(new Vec3(localPos.x + 80, localPos.y, 0)) hammer.active = true hammer.getComponent(Animation).play() app.manager.sound.playEffect({name: 'effect/hit'}); // 鸡蛋摇晃动画 this.scheduleOnce(() => { hammer.destroy() tween(egg) .sequence( tween().by(0.05, {position: new Vec3(20, 0, 0)}), // 向右 tween().by(0.1, {position: new Vec3(-40, 0, 0)}), // 向左 tween().by(0.05, {position: new Vec3(20, 0, 0)}) // 回到中心 ) .repeat(3) .start() }, 0.6); // 破蛋动画 this.scheduleOnce(() => { Tools.ActChild(egg, 'egg', false) Tools.ActChild(egg, 'egg_break', true) }, 1.3); // 破蛋动画 this.scheduleOnce(() => { egg.getChildByPath('egg_break').getComponent(Animation).play() app.manager.sound.playEffect({name: 'effect/broken'}); }, 1.5); this.scheduleOnce(() => { Tools.ActChild(egg, 'light', true) }, 1.6); this.icon_rw.spriteFrame = null; Tools.httpReq("lottery", {}, (res:any)=>{ USERDATA.point-- this.lab_remain.string = "Cracks Used : " + USERDATA.point.toString(); let n = null for (let i = 0; i < USERDATA.prize_list.length; i++) { const element = USERDATA.prize_list[i]; if (res.prize_id == element.id){ n = i break } } if (n == null){ app.manager.ui.showToast(Tools.GetLocalized("fail")) return } this.lab_rw.string = Tools.StringLFormat(res.message) Tools.remoteLoadSprite(USERDATA.prize_list[n].pic, this.icon_rw) // 展示奖励 this.scheduleOnce(() => { app.manager.sound.playEffect({name: 'effect/win'}); this.reward_bg.active = res.prize_type != 3 this.noreward_bg.active = res.prize_type == 3 }, 2.5); }) } /** 点击奖励确定 */ onClickRewardSure(){ this.reward_bg.active = false this.noreward_bg.active = false this.creatEggs(); } /** 点击提示 */ onClickTips(){ app.manager.ui.show({name: 'PageTips'}) } /** 点击音乐 */ oncClickMusic(){ let music = app.manager.sound.isMusicPlaying music ? app.manager.sound.stopMusic() : app.manager.sound.playDefaultMusic() this.loadRes(music ? "main_btn_sounds_off" : "main_btn_sounds_on", Asset, (res: ImageAsset)=>{ let sp = new SpriteFrame() let tex = new Texture2D(); tex.image = res; sp.texture = tex this.btn_music.getComponent(Sprite).spriteFrame = sp }); } /** 点击历史 */ onClickRwHis(){ app.manager.ui.show({name: 'PageRewardhistory'}) } }