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

284 lines
9.9 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, Node, tween, Vec3, Sprite, Asset, ImageAsset, SpriteFrame, Texture2D, Label, Graphics, EventTouch, Vec2, UITransform, Color, Mask, UIOpacity, resources } 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 { USERDATA } from 'db://assets/res-native/data/UserData';
import { Tools } from 'db://assets/res-native/tools/Tools';
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!;
/** 游戏提示 */
@property(Node)
game_tips: Node = null!;
/** 触摸节点 */
@property(Node)
touch: Node = null!;
/** 刮刮乐涂层 */
@property(Node)
scratchLayer: Node = null!;
/**奖励icon */
@property(Node)
rw_icon: Node = null!;
/** 奖励icon */
@property(Sprite)
icon_rw: Sprite = null!;
/** 剩余次数 */
@property(Label)
lab_remain: Label = null!;
/** 开始按钮 */
@property(Node)
btn_start: Node = null!;
/** 奖励icon */
@property(Sprite)
game_logo: Sprite = null!;
/** 奖励icon */
@property(Sprite)
game_logo_bg: Sprite = null!;
/** 涂层遮罩 */
private _graphics : Graphics = null!;
/** 每次刮开的宽度半径 */
private _scratchRadioX = 20;
/** 每次刮开的长度半径 */
private _scratchRadioY = 20;
/** 遮罩点 */
private _hidePoint : any[] = []
/** 遮罩点数量 */
private _hidePointNum = 0
/** 是否可以刮 */
private _canScratching = false
/** 是否在播放擦除音效 */
private _wipeEff = false;
/** 是否获得奖励 */
private _rw_type : number = null;
// 初始化的相关逻辑写在这
onLoad() {}
// 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对)
onShow(params: any) {
this._graphics = this.scratchLayer.getComponent(Graphics);
this.lab_remain.string = "REMAINING CHANCE : " + USERDATA.point.toString();
this.GameReset(false)
// 监听触摸事件
this.touch.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.touch.on(Node.EventType.TOUCH_MOVE, this.onTouch, this);
this.touch.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
// 加载配置的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的数据并且有类型提示 }})
// 监听触摸事件
this.touch.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.touch.off(Node.EventType.TOUCH_MOVE, this.onTouch, this);
this.touch.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
return result;
}
/** 点击奖励确定 */
onClickRewardSure(){
this.reward_bg.active = false
this.noreward_bg.active = false
}
/** 点击提示 */
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'})
}
/** 计算遮罩点 */
initMaskPoint(){
let rows = Math.floor((this.rw_icon.getComponent(UITransform).height + 20) / (this._scratchRadioY * 2))
let cols = Math.floor((this.rw_icon.getComponent(UITransform).width + 50) / (this._scratchRadioX * 2))
rows = Math.ceil(rows / 2)
cols = Math.ceil(cols / 2)
this._hidePoint = []
for (let i = -rows; i <= rows; i++) {
for (let j = -cols; j <= cols; j++) {
this._hidePoint.push({x: j, y: i})
}
}
this._hidePointNum = this._hidePoint.length
}
/** 隐藏游戏提示 */
hideGameTips(){
this.game_tips.active = false
}
onTouch(event: EventTouch) {
this.scratchAtPosition(event.getUILocation());
}
onTouchStart(event: EventTouch) {
if (this._canScratching){
this._wipeEff = true;
app.manager.sound.playEffect({name : "effect/wipe", loop: true})
this.onTouch(event);
}else{
app.manager.ui.showToast(Tools.GetLocalized("Please click start or retry first"));
}
}
onTouchEnd(event: EventTouch) {
if (this._wipeEff) {
app.manager.sound.stopAllEffects();
this._wipeEff = false;
}
this.onTouch(event);
}
// 在指定位置创建擦除效果
scratchAtPosition(worldPos: Vec2) {
if (!this._canScratching) { return; }
const localPos = this.scratchLayer.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(worldPos.x, worldPos.y, 0));
this._graphics.fillRect(localPos.x, localPos.y, this._scratchRadioX * 2, this._scratchRadioY * 2)
this.checkScratchCompletion(localPos);
}
// 检查是否完成刮刮乐
checkScratchCompletion(localPos: Vec3) {
if (this._canScratching){
let x = Math.floor(localPos.x / (this._scratchRadioX * 2))
let y = Math.floor(localPos.y / (this._scratchRadioY * 2))
for (let i = 0; i < this._hidePoint.length; i++) {
if (this._hidePoint[i].x == x && this._hidePoint[i].y == y) {
this._hidePoint.splice(i, 1)
break
}
}
if (this._hidePoint.length / this._hidePointNum < 0.3){
this._canScratching = false;
this.scheduleOnce(()=>{
if (this._wipeEff) {
app.manager.sound.stopAllEffects();
this._wipeEff = false;
}
app.manager.sound.playEffect({name : "effect/win"})
}, 0.3)
const opacity = this.scratchLayer.getComponent(UIOpacity);
tween(opacity)
.to(0.3, { opacity: 0 })
.call(() => {
if (this._rw_type != null) {
this.reward_bg.active = this._rw_type != 3
this.noreward_bg.active = this._rw_type == 3
}
this._rw_type = null
})
.start();
}
}
}
/** 重置刮刮乐 */
GameReset(need_req = true){
if (this._canScratching){
app.manager.ui.showToast("Game is in progress")
return
}
if (USERDATA.point <= 0 && need_req) {
app.manager.ui.showToast(Tools.GetLocalized("no chance"));
return;
}
this._graphics.clear()
this.initMaskPoint()
this.rw_icon.getComponent(Sprite).spriteFrame = null
this.icon_rw.spriteFrame = null
this.scratchLayer.getComponent(UIOpacity).opacity = 255
if (need_req){
this._canScratching = true
Tools.httpReq("lottery", {}, (res:any)=>{
this.loadRes("main_btn_retry", Asset, (res: ImageAsset)=>{
let sp = new SpriteFrame()
let tex = new Texture2D();
tex.image = res;
sp.texture = tex
this.btn_start.getComponent(Sprite).spriteFrame = sp
}),()=>{
this._canScratching = false
return
};
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._rw_type = res.prize_type
USERDATA.point--
this.lab_remain.string = "REMAINING CHANCE : " + USERDATA.point.toString()
Tools.remoteLoadSprite(USERDATA.prize_list[n].pic, this.icon_rw)
Tools.SetChildText(this.rw_icon, "lab", USERDATA.prize_list[n].name)
Tools.remoteLoadSprite(USERDATA.prize_list[n].pic, this.rw_icon.getComponent(Sprite))
this.lab_rw.string = Tools.StringLFormat(res.message)
})
}
}
}