Files
GoldEgg/assets/app-bundle/app-view/page/main/native/PageMain.ts
2026-05-19 11:45:08 +08:00

301 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<Node>[] = [];
/** 此轮是否点击过鸡蛋 */
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<PageMain>({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<PageTips>({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<PageRewardhistory>({name: 'PageRewardhistory'})
}
}