303 lines
9.2 KiB
TypeScript
303 lines
9.2 KiB
TypeScript
import { _decorator, Node, tween, Vec3, Sprite, Asset, ImageAsset, SpriteFrame, Texture2D, Label, EventTouch, UITransform } from 'cc';
|
||
import BaseView from '../../../../../../extensions/app/assets/base/BaseView';
|
||
import { PageTips } from '../../tips/native/PageTips';
|
||
import { app } from 'db://assets/app/app';
|
||
import { PageRewardhistory } from '../../rewardhistory/native/PageRewardhistory';
|
||
import { Tools } from 'db://assets/res-native/tools/Tools';
|
||
import { USERDATA } from 'db://assets/res-native/data/UserData';
|
||
const { ccclass, property } = _decorator;
|
||
@ccclass('PageMain')
|
||
export class PageMain extends BaseView {
|
||
/** 音乐按钮 */
|
||
@property(Node)
|
||
btn_music: Node = null!;
|
||
/** 奖励文字 */
|
||
@property(Label)
|
||
lab_rw: Label = null!;
|
||
/** 奖励 */
|
||
@property(Node)
|
||
reward_bg: Node = null!;
|
||
/** 奖励 */
|
||
@property(Node)
|
||
noreward_bg: Node = null!;
|
||
/** 宝箱item */
|
||
@property(Node)
|
||
box_item: Node = null!;
|
||
/** 宝箱列表 */
|
||
@property(Node)
|
||
list_box: Node = null!;
|
||
/** 奖励icon */
|
||
@property(Sprite)
|
||
icon_rw: Sprite = null!;
|
||
/** 剩余次数 */
|
||
@property(Label)
|
||
lab_remain: Label = null!;
|
||
/** 钻石 */
|
||
@property(Node)
|
||
diomand: Node[] = [];
|
||
/** 钻石 */
|
||
@property(Node)
|
||
logo: Node = null!;
|
||
/** 奖励icon */
|
||
@property(Sprite)
|
||
game_logo: Sprite = null!;
|
||
/** 奖励icon */
|
||
@property(Sprite)
|
||
game_logo_bg: Sprite = null!;
|
||
|
||
/** 宝箱位置 */
|
||
private _position: { [key: number]: Vec3 } = {
|
||
0: new Vec3(-310, 320, 0),
|
||
1: new Vec3(0, 320, 0),
|
||
2: new Vec3(310, 320, 0),
|
||
3: new Vec3(310, 0, 0),
|
||
4: new Vec3(310, -320, 0),
|
||
5: new Vec3(0, -320, 0),
|
||
6: new Vec3(-310, -320, 0),
|
||
7: new Vec3(-310, 0, 0),
|
||
};
|
||
|
||
/** 是否可以开始游戏 */
|
||
private _canStart = true;
|
||
/** 宝箱管理 */
|
||
private _boxMgr : Node[] = []
|
||
|
||
/** 是否正在播放动画 */
|
||
private _isSpinning: boolean = false;
|
||
|
||
|
||
// 初始化的相关逻辑写在这
|
||
onLoad() {}
|
||
|
||
// 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对)
|
||
onShow(params: any) {
|
||
this.lab_remain.string = "CHANCE:" + USERDATA.point.toString()
|
||
this.initRw()
|
||
this.startAnimation()
|
||
|
||
// 加载配置的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)
|
||
}
|
||
}
|
||
|
||
// 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide)
|
||
onHide(result: undefined) {
|
||
// app.manager.ui.show<PageMain>({name: 'PageMain', onHide:(result) => { 接收到return的数据,并且有类型提示 }})
|
||
return result;
|
||
}
|
||
|
||
startAnimation(){
|
||
// 钻石上下移动动画
|
||
this.diomand.forEach((diamond, index) => {
|
||
if (diamond) {
|
||
tween(diamond)
|
||
.repeatForever(
|
||
tween()
|
||
.by(0.5, { position: new Vec3(0, 10, 0) })
|
||
.by(0.5, { position: new Vec3(0, -10, 0) })
|
||
)
|
||
.start();
|
||
}
|
||
});
|
||
|
||
// Logo放大缩小动画
|
||
if (this.logo) {
|
||
tween(this.logo)
|
||
.repeatForever(
|
||
tween()
|
||
.to(0.8, { scale: new Vec3(1.1, 1.1, 1) })
|
||
.to(0.8, { scale: new Vec3(1, 1, 1) })
|
||
)
|
||
.start();
|
||
}
|
||
}
|
||
|
||
initRw(){
|
||
this._boxMgr = []
|
||
for (let i = 0; i < 8; i++) {
|
||
this._boxMgr[i] = Tools.AddChild(this.list_box, this.box_item, "item_" + i)
|
||
let item = this._boxMgr[i]
|
||
item.setPosition(this._position[i])
|
||
item.active = true
|
||
if (USERDATA.prize_list[i]){
|
||
Tools.remoteLoadSprite(USERDATA.prize_list[i].pic, Tools.GetChildComp(item, "icon", Sprite))
|
||
Tools.SetChildText(item, "lab", USERDATA.prize_list[i].name)
|
||
}
|
||
}
|
||
this._canStart = true
|
||
}
|
||
|
||
|
||
/** 点击奖励确定 */
|
||
onClickRewardSure(){
|
||
this.reward_bg.active = false
|
||
this.noreward_bg.active = false
|
||
this._canStart = true
|
||
}
|
||
|
||
/** 点击提示 */
|
||
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.loadSprite(music ? "main_btn_sounds_off" : "main_btn_sounds_on", this.btn_music)
|
||
}
|
||
|
||
/** 点击历史 */
|
||
onClickRwHis(){
|
||
app.manager.ui.show<PageRewardhistory>({name: 'PageRewardhistory'})
|
||
}
|
||
|
||
/** 点击开始 */
|
||
onStartGame() {
|
||
if (!this._canStart) return;
|
||
if (USERDATA.point <= 0) {
|
||
app.manager.ui.showToast(Tools.GetLocalized("no chance"));
|
||
return;
|
||
}
|
||
|
||
this._canStart = false;
|
||
|
||
Tools.httpReq("lottery", {}, (res:any)=>{
|
||
let n = this.checkRwId(res.prize_id)
|
||
if (n == null){
|
||
app.manager.ui.showToast(Tools.GetLocalized("fail"))
|
||
return
|
||
}
|
||
|
||
USERDATA.point--
|
||
this.lab_remain.string = "CHANCE:" + USERDATA.point.toString()
|
||
this.lab_rw.string = Tools.StringLFormat(res.message)
|
||
Tools.remoteLoadSprite(USERDATA.prize_list[n].pic, this.icon_rw)
|
||
|
||
// 开始转格子动画
|
||
this.startSpinAnimation(n, res.prize_type);
|
||
},()=>{
|
||
this._canStart = true;
|
||
})
|
||
}
|
||
|
||
checkRwId(prize_id: number){
|
||
let n = null
|
||
for (let i = 0; i < USERDATA.prize_list.length; i++) {
|
||
const element = USERDATA.prize_list[i];
|
||
if (prize_id == element.id){
|
||
n = i
|
||
break
|
||
}
|
||
}
|
||
return n
|
||
}
|
||
|
||
loadSprite(pic: string, node: Node){
|
||
this.loadRes(pic, Asset, (res: ImageAsset)=>{
|
||
let sp = new SpriteFrame()
|
||
let tex = new Texture2D();
|
||
tex.image = res;
|
||
sp.texture = tex
|
||
node.getComponent(Sprite).spriteFrame = sp
|
||
});
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 开始转格子动画
|
||
* @param targetIndex 目标格子索引
|
||
*/
|
||
private startSpinAnimation(targetIndex: number, prize_type:number) {
|
||
if (this._isSpinning) return;
|
||
|
||
this._isSpinning = true;
|
||
|
||
// 先清除所有高亮
|
||
this.clearAllHighlights();
|
||
|
||
// 开始动画 - 至少转3圈再停到目标位置
|
||
const totalSpins = 3;
|
||
const totalSteps = totalSpins * 8 + targetIndex;
|
||
|
||
this.spinStep(0, totalSteps, targetIndex, prize_type);
|
||
}
|
||
|
||
|
||
/**
|
||
* 执行旋转步骤
|
||
* @param currentStep 当前步数
|
||
* @param totalSteps 总步数
|
||
* @param targetIndex 目标索引
|
||
* @param prize_type 奖品类型
|
||
*/
|
||
private spinStep(currentStep: number, totalSteps: number, targetIndex: number, prize_type:number) {
|
||
if (currentStep >= totalSteps) {
|
||
// 动画结束 - 确保目标格子高亮
|
||
this.clearAllHighlights();
|
||
this.highlightBox(targetIndex);
|
||
|
||
this._isSpinning = false;
|
||
|
||
// 延迟显示奖励面板
|
||
this.scheduleOnce(() => {
|
||
this.reward_bg.active = prize_type != 3;
|
||
this.noreward_bg.active = prize_type == 3;
|
||
app.manager.sound.playEffect({name: 'effect/win'});
|
||
}, 0.5);
|
||
|
||
return;
|
||
}
|
||
|
||
// 计算当前应该高亮的格子索引
|
||
const currentIndex = currentStep % 8;
|
||
|
||
// 清除之前高亮并设置新的高亮
|
||
this.clearAllHighlights();
|
||
this.highlightBox(currentIndex);
|
||
|
||
// 根据进度调整速度(越接近终点越慢)
|
||
let delay = 100; // 默认速度
|
||
const remainingSteps = totalSteps - currentStep;
|
||
|
||
if (remainingSteps < 8) {
|
||
delay = 200 + (8 - remainingSteps) * 50; // 最后几帧逐渐变慢
|
||
}
|
||
|
||
// 继续下一步动画
|
||
this.scheduleOnce(() => {
|
||
app.manager.sound.playEffect({name: 'effect/jump'});
|
||
|
||
this.spinStep(currentStep + 1, totalSteps, targetIndex, prize_type);
|
||
}, delay / 1000); // scheduleOnce 使用秒为单位
|
||
}
|
||
|
||
/**
|
||
* 高亮指定格子
|
||
* @param index 格子索引
|
||
*/
|
||
private highlightBox(index: number) {
|
||
if (index < 0 || index >= this._boxMgr.length) return;
|
||
|
||
const boxNode = this._boxMgr[index];
|
||
if (boxNode) {
|
||
Tools.ActChild(boxNode, "select", true);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清除所有格子的高亮状态
|
||
*/
|
||
private clearAllHighlights() {
|
||
for (let i = 0; i < this._boxMgr.length; i++) {
|
||
const boxNode = this._boxMgr[i];
|
||
Tools.ActChild(boxNode, "select", false);
|
||
}
|
||
}
|
||
} |