推荐流直玩,关闭效果
This commit is contained in:
parent
fcc2369e89
commit
498ab8d3bf
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"ver": "1.3.2",
|
||||
"uuid": "4eaf518b-35ec-4262-928d-4d497c3f2830",
|
||||
"uuid": "6eabf805-275a-4c3f-84de-eed951841e3e",
|
||||
"importer": "scene",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -50,6 +50,7 @@ export default class JiaZai extends cc.Component {
|
|||
private static cachedPassCheckPrefab: cc.Prefab | null = null;
|
||||
private passCheckNode: cc.Node | null = null;
|
||||
|
||||
private isGetSidebar: boolean = false;
|
||||
|
||||
|
||||
@property(cc.EditBox)
|
||||
|
|
@ -658,6 +659,8 @@ export default class JiaZai extends cc.Component {
|
|||
// console.log("HomeScene广告预加载初始化失败");
|
||||
// }
|
||||
// });
|
||||
// 上报游戏加载完成时机(推荐流直玩需要)
|
||||
cc.fx.GameTool.reportLoadComplete();
|
||||
}
|
||||
|
||||
// 适配pad
|
||||
|
|
@ -2232,25 +2235,29 @@ export default class JiaZai extends cc.Component {
|
|||
// 可以在这里处理关卡信息和 UID
|
||||
}
|
||||
} else if (cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
// 处理分享链接参数
|
||||
//@ts-ignore
|
||||
const launchOptions = tt.getLaunchOptionsSync();
|
||||
const query = launchOptions.query;
|
||||
if (query.level && query.uid) {
|
||||
const level = parseInt(query.level, 10);
|
||||
const uid = query.uid;
|
||||
cc.fx.GameConfig.GM_INFO.otherUid = uid;
|
||||
cc.fx.GameConfig.GM_INFO.otherLevel = level;
|
||||
// 可以在这里处理关卡信息和 UID
|
||||
let eventData = {
|
||||
identity: "helper", //发起者为helped 帮助者为helper
|
||||
helpedId: cc.fx.GameConfig.GM_INFO.otherUid, //被帮助者UID
|
||||
level: level //被帮助关卡等级
|
||||
const uid = query.uid.toString();
|
||||
if (uid != cc.fx.GameConfig.GM_INFO.uid) {
|
||||
cc.fx.GameConfig.GM_INFO.otherUid = uid;
|
||||
cc.fx.GameConfig.GM_INFO.otherLevel = level;
|
||||
let eventData = {
|
||||
identity: "helper", //发起者为helped 帮助者为helper
|
||||
helpedId: cc.fx.GameConfig.GM_INFO.otherUid, //被帮助者UID
|
||||
level: level //被帮助关卡等级
|
||||
}
|
||||
cc.fx.GameTool.shushu_Track("stage_help", eventData); //帮助通关
|
||||
this.openShare();
|
||||
}
|
||||
cc.fx.GameTool.shushu_Track("stage_help", eventData); //帮助通关
|
||||
this.openShare();
|
||||
} else {
|
||||
cc.fx.GameConfig.GM_INFO.otherLevel = 0;
|
||||
cc.fx.GameConfig.GM_INFO.otherUid = "";
|
||||
else {
|
||||
cc.fx.GameConfig.GM_INFO.otherLevel = 0;
|
||||
cc.fx.GameConfig.GM_INFO.otherUid = "";
|
||||
}
|
||||
// 可以在这里处理关卡信息和 UID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3590,11 +3597,13 @@ export default class JiaZai extends cc.Component {
|
|||
|
||||
this.node.getChildByName("ToSidebar").getChildByName("sidebarBtn_1").active = false;
|
||||
this.node.getChildByName("ToSidebar").getChildByName("sidebarBtn_2").active = false;
|
||||
if (isGet) {
|
||||
if (isGet || this.isGetSidebar) {
|
||||
this.node.getChildByName("ToSidebar").getChildByName("sidebarBtn_2").active = true;
|
||||
this.node.getChildByName("ToSidebar").getChildByName("close_btn").active = false;
|
||||
this.node.getChildByName("ToSidebar").getChildByName("close_btn").active = true;
|
||||
this.isGetSidebar = true;
|
||||
} else {
|
||||
this.node.getChildByName("ToSidebar").getChildByName("sidebarBtn_1").active = true;
|
||||
this.isGetSidebar = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3675,6 +3684,8 @@ export default class JiaZai extends cc.Component {
|
|||
// }
|
||||
if (lastRewardDate == 1) {
|
||||
MiniGameSdk.API.showToast('已领取过侧边栏奖励');
|
||||
// 加一个把界面隐藏
|
||||
this.onSidebarClose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3705,7 +3716,10 @@ export default class JiaZai extends cc.Component {
|
|||
// 显示奖励提示
|
||||
MiniGameSdk.API.showToast(`侧边栏奖励!获得${rewardHammer}个锤子`, 3);
|
||||
console.log(`获得侧边栏奖励: ${rewardHammer}个锤子`);
|
||||
|
||||
// 存储领取状态
|
||||
cc.fx.StorageMessage.setStorage('sidebar_reward_date', 1);
|
||||
|
||||
this.initDouyinSidebar();
|
||||
this.onSidebarClose();
|
||||
|
||||
|
|
@ -3731,6 +3745,14 @@ export default class JiaZai extends cc.Component {
|
|||
MiniGameSdk.BytedanceSidebar.listenFromSidebar((fromSidebar: boolean) => {
|
||||
if (fromSidebar) {
|
||||
console.log('用户从侧边栏启动游戏');
|
||||
|
||||
// 检查玩家是否已经领取过奖励
|
||||
const lastRewardDate = cc.fx.StorageMessage.getStorage('sidebar_reward_date');
|
||||
if (lastRewardDate == 1) {
|
||||
console.log('玩家已经领取过侧边栏奖励,不再显示领取界面');
|
||||
return;
|
||||
}
|
||||
|
||||
// this.handleSidebarReward();
|
||||
this.toSidebarShow(true);
|
||||
|
||||
|
|
@ -3804,6 +3826,32 @@ export default class JiaZai extends cc.Component {
|
|||
sidebarBtn.active = false;
|
||||
}
|
||||
dy_kefu.active = true;
|
||||
// 检测推荐流直玩场景
|
||||
const recommendFeedResult = cc.fx.GameTool.checkRecommendFeedLaunch();
|
||||
|
||||
console.log("推荐流直玩场景检测结果", recommendFeedResult);
|
||||
if (recommendFeedResult && recommendFeedResult.isRecommendFeedLaunch) {
|
||||
// 检查 tt.getRecommendFeedInfo 是否存在
|
||||
//@ts-ignore
|
||||
if (tt && tt.getRecommendFeedInfo) {
|
||||
//@ts-ignore
|
||||
tt.getRecommendFeedInfo({
|
||||
success: (res) => {
|
||||
console.log("推荐流信息:", res);
|
||||
// 处理推荐流信息
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error("获取推荐流信息失败:", err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log("tt.getRecommendFeedInfo 方法不可用,跳过获取推荐流信息");
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化推荐流直玩监听器
|
||||
cc.fx.GameTool.initFeedGameListeners();
|
||||
|
||||
} else {
|
||||
sidebarBtn.active = false;
|
||||
dy_kefu.active = false;
|
||||
|
|
|
|||
|
|
@ -2063,14 +2063,16 @@ export namespace MiniGameSdk {
|
|||
// 构建分享参数
|
||||
const shareParams = {
|
||||
title: '如果你突然打了个喷嚏,那一定是我在等你帮忙过关!', // 分享标题
|
||||
path: `/pages/index/index?level=${level}&uid=${uid}`, // 分享路径,带上关卡信息和 UID
|
||||
imageUrl: img // 分享图片链接
|
||||
};
|
||||
|
||||
// 调用微信分享 API
|
||||
if (cc.sys.platform === cc.sys.WECHAT_GAME) {
|
||||
//@ts-ignore
|
||||
wx.shareAppMessage(shareParams);
|
||||
wx.shareAppMessage({
|
||||
...shareParams,
|
||||
path: `/pages/index/index?level=${level}&uid=${uid}`, // 分享路径,带上关卡信息和 UID
|
||||
});
|
||||
let eventData = {
|
||||
identity: "helped", //发起者为helped 帮助者为helper
|
||||
helpedId: cc.fx.GameConfig.GM_INFO.uid, //被帮助者uid
|
||||
|
|
@ -2082,6 +2084,7 @@ export namespace MiniGameSdk {
|
|||
// @ts-ignore
|
||||
tt.shareAppMessage({
|
||||
...shareParams,
|
||||
query: `level=${level}&uid=${uid}`, // 抖音使用 query 字段传递参数
|
||||
success: (res) => {
|
||||
console.log('抖音分享成功mini', res);
|
||||
let eventData = {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default class Utils {
|
|||
wx.login({
|
||||
success(res) {
|
||||
console.log("微信login成功");
|
||||
let restart = 0;
|
||||
//console.log(res.code);
|
||||
if (res.code) {
|
||||
// 标志位,用于记录 callBack 是否已经被调用
|
||||
|
|
|
|||
|
|
@ -1432,6 +1432,9 @@ var GameTool = {
|
|||
let isWeChat = typeof wx !== 'undefined' && wx !== null && cc.sys.platform === cc.sys.WECHAT_GAME;
|
||||
console.log("获取小游戏版号", isBytedance, isWeChat);
|
||||
if (isBytedance) {
|
||||
//@ts-ignore
|
||||
const systemInfo = tt.getSystemInfoSync();
|
||||
console.log('系统信息:', systemInfo);
|
||||
//@ts-ignore
|
||||
const envInfo = tt.getEnvInfoSync();
|
||||
const { envType, mpVersion } = envInfo.microapp;
|
||||
|
|
@ -2404,5 +2407,143 @@ var GameTool = {
|
|||
cc.director.loadScene("GameScene");
|
||||
},
|
||||
|
||||
// 检测推荐流直玩场景
|
||||
checkRecommendFeedLaunch() {
|
||||
if (cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
//@ts-ignore
|
||||
const launchOptions = tt.getLaunchOptionsSync();
|
||||
const scene = launchOptions.scene;
|
||||
const query = launchOptions.query;
|
||||
|
||||
// 检测是否为推荐流直玩场景(scene后四位是3041)
|
||||
const isRecommendFeedLaunch = scene && typeof scene === 'string' && scene.slice(-4) === '3041';
|
||||
|
||||
if (isRecommendFeedLaunch) {
|
||||
// 处理推荐流直玩参数
|
||||
let feedGameScene, feedGameExtra, feedGameContentId, feedGameChannel;
|
||||
|
||||
// 尝试解析 query 参数
|
||||
if (query) {
|
||||
const queryKeys = Object.keys(query);
|
||||
if (queryKeys.length > 0) {
|
||||
for (const key of queryKeys) {
|
||||
if (key.includes('feed_game_scene')) {
|
||||
feedGameScene = query[key];
|
||||
} else if (key.includes('feed_game_extra')) {
|
||||
feedGameExtra = query[key];
|
||||
} else if (key.includes('feed_game_content_id')) {
|
||||
feedGameContentId = query[key];
|
||||
} else if (key.includes('feed_game_channel')) {
|
||||
feedGameChannel = query[key];
|
||||
}
|
||||
}
|
||||
|
||||
if (!feedGameScene) {
|
||||
for (const key of queryKeys) {
|
||||
const value = query[key];
|
||||
if (typeof value === 'string' && value.includes('feed_game_scene')) {
|
||||
try {
|
||||
const decoded = decodeURIComponent(value);
|
||||
const parsed = JSON.parse(decoded);
|
||||
if (parsed.query) {
|
||||
feedGameScene = parsed.query.feed_game_scene;
|
||||
feedGameExtra = parsed.query.feed_game_extra;
|
||||
feedGameContentId = parsed.query.feed_game_content_id;
|
||||
feedGameChannel = parsed.query.feed_game_channel;
|
||||
}
|
||||
} catch (e) {
|
||||
// 解析失败
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isRecommendFeedLaunch: true,
|
||||
scene: scene,
|
||||
query: query,
|
||||
feedGameScene: feedGameScene,
|
||||
feedGameExtra: feedGameExtra,
|
||||
feedGameContentId: feedGameContentId,
|
||||
feedGameChannel: feedGameChannel
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
isRecommendFeedLaunch: false
|
||||
};
|
||||
},
|
||||
|
||||
// 上报游戏加载完成时机(推荐流直玩需要)
|
||||
reportLoadComplete() {
|
||||
if (cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
//@ts-ignore
|
||||
if (tt && tt.reportScene) {
|
||||
//@ts-ignore
|
||||
tt.reportScene({
|
||||
sceneId: 7001,
|
||||
success: function (res) {
|
||||
// 上报成功
|
||||
},
|
||||
fail: function (res) {
|
||||
// 上报失败
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化推荐流直玩监听器
|
||||
initFeedGameListeners() {
|
||||
if (cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
//@ts-ignore
|
||||
const launchOptions = tt.getLaunchOptionsSync();
|
||||
const scene = launchOptions.scene;
|
||||
|
||||
// 检测是否为推荐流直玩场景(scene后四位是3041)
|
||||
const isRecommendFeedLaunch = scene && typeof scene === 'string' && scene.slice(-4) === '3041';
|
||||
|
||||
if (isRecommendFeedLaunch) {
|
||||
// 上报预启动数据
|
||||
this.reportFeedGameData('preboot');
|
||||
|
||||
let firstEnter = true;
|
||||
|
||||
// 启动监听
|
||||
//@ts-ignore
|
||||
if (tt && tt.feedGame && tt.feedGame.onFeedStatusChange) {
|
||||
//@ts-ignore
|
||||
tt.feedGame.onFeedStatusChange(({ type }) => {
|
||||
// 用户首次从预览流进入游戏
|
||||
if (firstEnter && type === 'feedEnter') {
|
||||
firstEnter = false;
|
||||
// 上报用户活跃数据
|
||||
this.reportFeedGameData('Activity');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 上报推荐流直玩相关数据
|
||||
reportFeedGameData(type: string) {
|
||||
if (cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
|
||||
//@ts-ignore
|
||||
if (tt && tt.feedGame && tt.feedGame.reportData) {
|
||||
//@ts-ignore
|
||||
tt.feedGame.reportData(type, {
|
||||
success: function (res) {
|
||||
// 上报成功
|
||||
},
|
||||
fail: function (res) {
|
||||
// 上报失败
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
export { GameTool };
|
||||
366
assets/Script/module/Tool/GenieEffect.ts
Normal file
366
assets/Script/module/Tool/GenieEffect.ts
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/**
|
||||
* Genie Effect 动画工具
|
||||
* 使用 RenderTexture 捕获整个节点,然后应用 Mac 风格最小化效果
|
||||
* Cocos Creator 2.4.15
|
||||
*/
|
||||
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export default class GenieEffect extends cc.Component {
|
||||
|
||||
@property(cc.Material)
|
||||
genieMaterial: cc.Material = null;
|
||||
|
||||
@property
|
||||
duration: number = 0.4;
|
||||
|
||||
@property
|
||||
bendStrength: number = 0.5;
|
||||
|
||||
private _renderTexture: cc.RenderTexture = null;
|
||||
private _captureSprite: cc.Sprite = null;
|
||||
private _isPlaying: boolean = false;
|
||||
|
||||
onLoad() {
|
||||
// 材质可以通过编辑器设置或动态传入
|
||||
}
|
||||
|
||||
/**
|
||||
* 捕获整个节点为 RenderTexture
|
||||
*/
|
||||
captureNode(): cc.SpriteFrame {
|
||||
const node = this.node;
|
||||
const size = node.getContentSize();
|
||||
|
||||
// 创建 RenderTexture
|
||||
const renderTexture = new cc.RenderTexture();
|
||||
renderTexture.initWithSize(size.width, size.height);
|
||||
|
||||
// 创建相机
|
||||
const cameraNode = new cc.Node('CaptureCamera');
|
||||
cameraNode.parent = node;
|
||||
const camera = cameraNode.addComponent(cc.Camera);
|
||||
|
||||
// 设置相机
|
||||
camera.targetTexture = renderTexture;
|
||||
camera.clearFlags = cc.Camera.ClearFlags.COLOR | cc.Camera.ClearFlags.DEPTH;
|
||||
camera.backgroundColor = cc.color(0, 0, 0, 0);
|
||||
camera.zoomRatio = 1;
|
||||
camera.cullingMask = 0xffffffff;
|
||||
|
||||
// 渲染一帧
|
||||
camera.render();
|
||||
|
||||
// 销毁相机节点
|
||||
cameraNode.destroy();
|
||||
|
||||
// 创建 SpriteFrame
|
||||
const spriteFrame = new cc.SpriteFrame(renderTexture);
|
||||
|
||||
this._renderTexture = renderTexture;
|
||||
|
||||
return spriteFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建捕获用的 Sprite 节点
|
||||
*/
|
||||
createCaptureSprite(): cc.Node {
|
||||
// 捕获节点画面
|
||||
const spriteFrame = this.captureNode();
|
||||
|
||||
// 创建 Sprite 节点
|
||||
const spriteNode = new cc.Node('GenieCaptureSprite');
|
||||
spriteNode.parent = this.node.parent;
|
||||
spriteNode.setContentSize(this.node.getContentSize());
|
||||
spriteNode.position = this.node.position;
|
||||
spriteNode.anchorX = this.node.anchorX;
|
||||
spriteNode.anchorY = this.node.anchorY;
|
||||
|
||||
// 添加 Sprite 组件
|
||||
const sprite = spriteNode.addComponent(cc.Sprite);
|
||||
sprite.spriteFrame = spriteFrame;
|
||||
|
||||
// 隐藏原节点
|
||||
this.node.active = false;
|
||||
|
||||
this._captureSprite = sprite;
|
||||
|
||||
return spriteNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放关闭动画(吸入到目标点)
|
||||
* @param targetNode 目标节点(吸入位置)
|
||||
* @param callback 动画完成回调
|
||||
*/
|
||||
playClose(targetNode: cc.Node, callback?: Function) {
|
||||
if (this._isPlaying) {
|
||||
console.warn('GenieEffect: 动画正在播放中');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.genieMaterial) {
|
||||
console.warn('GenieEffect: 材质未加载,使用默认动画');
|
||||
this.playDefaultClose(targetNode, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建捕获的 Sprite 节点
|
||||
const captureNode = this.createCaptureSprite();
|
||||
if (!captureNode) {
|
||||
console.warn('GenieEffect: 无法创建捕获节点');
|
||||
this.playDefaultClose(targetNode, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
this._isPlaying = true;
|
||||
|
||||
// 获取 Sprite 组件
|
||||
const sprite = captureNode.getComponent(cc.Sprite);
|
||||
|
||||
// 获取起始位置和目标位置(世界坐标)
|
||||
const startWorldPos = this.node.convertToWorldSpaceAR(cc.v2(0, 0));
|
||||
const targetWorldPos = targetNode.convertToWorldSpaceAR(cc.v2(0, 0));
|
||||
|
||||
// 设置材质参数
|
||||
const material = this.genieMaterial;
|
||||
material.setProperty('u_targetPos', [targetWorldPos.x, targetWorldPos.y]);
|
||||
material.setProperty('u_progress', 0);
|
||||
material.setProperty('u_bendStrength', this.bendStrength);
|
||||
material.setProperty('u_shrinkWidth', 0.2);
|
||||
|
||||
// 应用材质
|
||||
sprite.setMaterial(0, material);
|
||||
|
||||
// 播放动画 - 同时移动节点和更新 Shader
|
||||
const animData = { progress: 0 };
|
||||
const startPos = captureNode.position;
|
||||
const targetPos = captureNode.parent.convertToNodeSpaceAR(targetWorldPos);
|
||||
|
||||
cc.tween(animData)
|
||||
.to(this.duration, { progress: 1 }, {
|
||||
easing: 'quadInOut',
|
||||
onUpdate: (target, ratio) => {
|
||||
if (material && sprite) {
|
||||
material.setProperty('u_progress', animData.progress);
|
||||
}
|
||||
// 同时移动捕获节点向目标点靠近
|
||||
if (captureNode) {
|
||||
const t = animData.progress;
|
||||
// 使用缓动函数让移动更自然
|
||||
const easeT = t * t * (3 - 2 * t); // smoothstep
|
||||
captureNode.x = startPos.x + (targetPos.x - startPos.x) * easeT;
|
||||
captureNode.y = startPos.y + (targetPos.y - startPos.y) * easeT;
|
||||
}
|
||||
}
|
||||
})
|
||||
.call(() => {
|
||||
this._isPlaying = false;
|
||||
// 销毁捕获节点
|
||||
if (captureNode) {
|
||||
captureNode.destroy();
|
||||
}
|
||||
if (callback) callback();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放打开动画(从目标点展开)
|
||||
* @param fromNode 起始节点(展开位置)
|
||||
* @param callback 动画完成回调
|
||||
*/
|
||||
playOpen(fromNode: cc.Node, callback?: Function) {
|
||||
if (this._isPlaying) {
|
||||
console.warn('GenieEffect: 动画正在播放中');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.genieMaterial) {
|
||||
console.warn('GenieEffect: 材质未加载,使用默认动画');
|
||||
this.playDefaultOpen(fromNode, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建捕获的 Sprite 节点
|
||||
const captureNode = this.createCaptureSprite();
|
||||
if (!captureNode) {
|
||||
console.warn('GenieEffect: 无法创建捕获节点');
|
||||
this.playDefaultOpen(fromNode, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
this._isPlaying = true;
|
||||
|
||||
// 获取 Sprite 组件
|
||||
const sprite = captureNode.getComponent(cc.Sprite);
|
||||
|
||||
// 计算起始位置(世界坐标)
|
||||
const fromWorldPos = fromNode.convertToWorldSpaceAR(cc.v2(0, 0));
|
||||
|
||||
// 设置材质参数(从完全吸入状态开始)
|
||||
const material = this.genieMaterial;
|
||||
material.setProperty('u_targetPos', [fromWorldPos.x, fromWorldPos.y]);
|
||||
material.setProperty('u_progress', 1);
|
||||
material.setProperty('u_bendStrength', this.bendStrength);
|
||||
material.setProperty('u_shrinkWidth', 0.2);
|
||||
|
||||
// 应用材质
|
||||
sprite.setMaterial(0, material);
|
||||
|
||||
// 播放动画(progress 从 1 到 0)
|
||||
const animData = { progress: 1 };
|
||||
|
||||
cc.tween(animData)
|
||||
.to(this.duration, { progress: 0 }, {
|
||||
easing: 'quadOut',
|
||||
onUpdate: (target, ratio) => {
|
||||
if (material && sprite) {
|
||||
material.setProperty('u_progress', animData.progress);
|
||||
}
|
||||
}
|
||||
})
|
||||
.call(() => {
|
||||
this._isPlaying = false;
|
||||
// 显示原节点
|
||||
this.node.active = true;
|
||||
// 销毁捕获节点
|
||||
if (captureNode) {
|
||||
captureNode.destroy();
|
||||
}
|
||||
if (callback) callback();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认关闭动画(当 Shader 不可用时使用)
|
||||
*/
|
||||
private playDefaultClose(targetNode: cc.Node, callback?: Function) {
|
||||
const startPos = this.node.position; const targetWorldPos = targetNode.convertToWorldSpaceAR(cc.v2(0, 0));
|
||||
const targetLocalPos = this.node.parent.convertToNodeSpaceAR(targetWorldPos);
|
||||
|
||||
cc.tween(this.node)
|
||||
.to(this.duration * 0.5, {
|
||||
position: cc.v3(
|
||||
startPos.x + (targetLocalPos.x - startPos.x) * 0.5,
|
||||
startPos.y + (targetLocalPos.y - startPos.y) * 0.5,
|
||||
0
|
||||
),
|
||||
scale: 0.6
|
||||
}, { easing: 'quadIn' })
|
||||
.to(this.duration * 0.5, {
|
||||
position: cc.v3(targetLocalPos.x, targetLocalPos.y, 0),
|
||||
scale: 0.01,
|
||||
opacity: 0
|
||||
}, { easing: 'expoIn' })
|
||||
.call(() => {
|
||||
if (callback) callback();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认打开动画(当 Shader 不可用时使用)
|
||||
*/
|
||||
private playDefaultOpen(fromNode: cc.Node, callback?: Function) {
|
||||
const fromWorldPos = fromNode.convertToWorldSpaceAR(cc.v2(0, 0));
|
||||
const fromLocalPos = this.node.parent.convertToNodeSpaceAR(fromWorldPos);
|
||||
const endPos = this.node.position;
|
||||
|
||||
this.node.scale = 0.01;
|
||||
this.node.opacity = 0;
|
||||
this.node.position = cc.v3(fromLocalPos.x, fromLocalPos.y, 0);
|
||||
|
||||
cc.tween(this.node)
|
||||
.to(this.duration * 0.5, {
|
||||
position: cc.v3(
|
||||
fromLocalPos.x + (endPos.x - fromLocalPos.x) * 0.5,
|
||||
fromLocalPos.y + (endPos.y - fromLocalPos.y) * 0.5,
|
||||
0
|
||||
),
|
||||
scale: 0.6,
|
||||
opacity: 128
|
||||
}, { easing: 'quadOut' })
|
||||
.to(this.duration * 0.5, {
|
||||
position: endPos,
|
||||
scale: 1,
|
||||
opacity: 255
|
||||
}, { easing: 'expoOut' })
|
||||
.call(() => {
|
||||
if (callback) callback();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态工具函数 - 方便外部调用
|
||||
*/
|
||||
export namespace GenieEffectUtil {
|
||||
/**
|
||||
* 播放关闭动画(静态方法)
|
||||
* @param node 目标节点(动画作用的节点)
|
||||
* @param targetNode 吸入目标节点
|
||||
* @param callback 完成回调
|
||||
* @param material 材质(可选)
|
||||
* @param duration 动画时长
|
||||
*/
|
||||
export function playClose(
|
||||
node: cc.Node,
|
||||
targetNode: cc.Node,
|
||||
callback?: Function,
|
||||
material?: cc.Material,
|
||||
duration: number = 0.4
|
||||
) {
|
||||
const genieEffect = node.getComponent(GenieEffect);
|
||||
if (genieEffect) {
|
||||
genieEffect.playClose(targetNode, callback);
|
||||
} else {
|
||||
// 动态添加组件并播放
|
||||
const effect = node.addComponent(GenieEffect);
|
||||
effect.duration = duration;
|
||||
if (material) {
|
||||
effect.genieMaterial = material;
|
||||
}
|
||||
|
||||
// 延迟一帧等待组件初始化
|
||||
cc.director.once(cc.Director.EVENT_AFTER_UPDATE, () => {
|
||||
effect.playClose(targetNode, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放打开动画(静态方法)
|
||||
* @param node 目标节点(动画作用的节点)
|
||||
* @param fromNode 展开起始节点
|
||||
* @param callback 完成回调
|
||||
* @param material 材质(可选)
|
||||
* @param duration 动画时长
|
||||
*/
|
||||
export function playOpen(
|
||||
node: cc.Node,
|
||||
fromNode: cc.Node,
|
||||
callback?: Function,
|
||||
material?: cc.Material,
|
||||
duration: number = 0.4
|
||||
) {
|
||||
const genieEffect = node.getComponent(GenieEffect);
|
||||
if (genieEffect) {
|
||||
genieEffect.playOpen(fromNode, callback);
|
||||
} else {
|
||||
const effect = node.addComponent(GenieEffect);
|
||||
effect.duration = duration;
|
||||
if (material) {
|
||||
effect.genieMaterial = material;
|
||||
}
|
||||
|
||||
cc.director.once(cc.Director.EVENT_AFTER_UPDATE, () => {
|
||||
effect.playOpen(fromNode, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
10
assets/Script/module/Tool/GenieEffect.ts.meta
Normal file
10
assets/Script/module/Tool/GenieEffect.ts.meta
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "72fc5a36-281e-44b0-be0a-419bb0276437",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import JiaZai from "./JiaZai";
|
||||
import Utils from "./module/Pay/Utils";
|
||||
import GenieEffect, { GenieEffectUtil } from "./module/Tool/GenieEffect";
|
||||
import NumberToImage from "./NumberToImage";
|
||||
import SceneManager from "./SceneManager";
|
||||
import { MiniGameSdk } from "./Sdk/MiniGameSdk";
|
||||
|
|
@ -32,6 +33,9 @@ export default class NewClass extends cc.Component {
|
|||
public juwai = false;
|
||||
btn_Touch: boolean = false;
|
||||
|
||||
@property(cc.Material)
|
||||
genieMaterial: cc.Material = null;
|
||||
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
private onShowListener: () => void;
|
||||
private iosPrice: number = 0;
|
||||
|
|
@ -283,11 +287,47 @@ export default class NewClass extends cc.Component {
|
|||
jiazaiComp.onGames();
|
||||
|
||||
}
|
||||
if (this.node) {
|
||||
|
||||
// if (this.node) {
|
||||
// this.node.active = false;
|
||||
// }
|
||||
|
||||
const topNode = jiazaiNode.getChildByName("Load").getChildByName("Top");
|
||||
if (!topNode) {
|
||||
console.warn("找不到 Top 节点,直接销毁通行证界面");
|
||||
this.destroyMonthlyCard();
|
||||
return;
|
||||
}
|
||||
const yicon = topNode.getChildByName("yicon");
|
||||
console.log("退出月卡:", yicon);
|
||||
|
||||
if (yicon && this.node && cc.isValid(this.node)) {
|
||||
// 隐藏第一个子节点(可能包含按钮)
|
||||
// this.node.children[0].active = false;
|
||||
|
||||
// 禁止所有按钮操作 - 禁用整个节点的交互
|
||||
// this.setButtonsEnabled(false);
|
||||
|
||||
// 使用 GenieEffectUtil 播放关闭动画
|
||||
// 参数:动画节点, 目标节点, 回调, 材质(可选)
|
||||
GenieEffectUtil.playClose(this.node, yicon, () => {
|
||||
// 动画完成后执行销毁逻辑
|
||||
this.destroyMonthlyCard();
|
||||
}, this.genieMaterial);
|
||||
} else {
|
||||
// 如果找不到 yicon,直接销毁
|
||||
this.destroyMonthlyCard();
|
||||
}
|
||||
|
||||
}
|
||||
destroyMonthlyCard() {
|
||||
if (this.node && cc.isValid(this.node)) {
|
||||
// 恢复节点原始状态
|
||||
this.node.scale = 1;
|
||||
this.node.opacity = 255;
|
||||
this.node.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
buyProduct(event, customData) {
|
||||
if (!this.btn_Touch) {
|
||||
return;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "cfe3e40a-7813-4913-93b2-b9f4066f8296",
|
||||
"uuid": "f3f0dece-8b63-488c-92b9-3a0a93554ed0",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"isPlugin": true,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
|
|
|
|||
13
assets/effect/genie.meta
Normal file
13
assets/effect/genie.meta
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "82766fb6-9f6e-4af6-8908-2f2b1f828580",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
||||
93
assets/effect/genie/genie.effect
Normal file
93
assets/effect/genie/genie.effect
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
CCEffect %{
|
||||
techniques:
|
||||
- name: opaque
|
||||
passes:
|
||||
- vert: genie-vs:vs # 程序 genie-vs,入口 vs
|
||||
frag: genie-fs:fs # 程序 genie-fs,入口 fs
|
||||
blendState:
|
||||
targets:
|
||||
- blend: true
|
||||
blendSrc: src_alpha
|
||||
blendDst: one_minus_src_alpha
|
||||
rasterizerState:
|
||||
cullMode: none
|
||||
properties:
|
||||
u_targetPos: { value: [0, -300] }
|
||||
u_progress: { value: 0.0, editor: { slide: true, range: [0, 1], step: 0.01 } }
|
||||
u_bendStrength: { value: 1.0, editor: { slide: true, range: [0, 3], step: 0.1 } }
|
||||
u_shrinkWidth: { value: 0.2, editor: { slide: true, range: [0, 1], step: 0.01 } }
|
||||
}%
|
||||
|
||||
CCProgram genie-vs %{
|
||||
precision highp float;
|
||||
#include <cc-global>
|
||||
#include <cc-local>
|
||||
|
||||
in vec3 a_position;
|
||||
in vec2 a_uv0;
|
||||
in vec4 a_color;
|
||||
|
||||
uniform MyConstants {
|
||||
vec2 u_targetPos;
|
||||
float u_progress;
|
||||
float u_bendStrength;
|
||||
float u_shrinkWidth;
|
||||
};
|
||||
|
||||
out vec2 v_uv;
|
||||
out vec4 v_color;
|
||||
|
||||
vec2 quadBezier(vec2 p0, vec2 p1, vec2 p2, float t) {
|
||||
float u = 1.0 - t;
|
||||
return u * u * p0 + 2.0 * u * t * p1 + t * t * p2;
|
||||
}
|
||||
|
||||
vec4 vs() {
|
||||
vec2 pos = a_position.xy;
|
||||
v_uv = a_uv0;
|
||||
v_color = a_color;
|
||||
|
||||
float p = clamp(u_progress, 0.0, 1.0);
|
||||
float uvY = a_uv0.y;
|
||||
float uvX = a_uv0.x;
|
||||
|
||||
vec2 topTarget = mix(pos, u_targetPos, p * 0.6);
|
||||
vec2 bottomTarget = u_targetPos;
|
||||
float bendDown = -80.0 * u_bendStrength * (1.0 - p);
|
||||
vec2 bottomControl = mix(pos, u_targetPos, 0.5) + vec2(0.0, bendDown);
|
||||
vec2 rowPos = quadBezier(topTarget, bottomControl, bottomTarget, uvY * p);
|
||||
|
||||
float widthScale = 1.0 - (1.0 - u_shrinkWidth) * p * uvY;
|
||||
vec2 center = mix(topTarget, bottomTarget, uvY);
|
||||
rowPos.x = center.x + (rowPos.x - center.x) * widthScale;
|
||||
|
||||
float bulge = -sin(uvY * 3.14159) * 30.0 * u_bendStrength * (1.0 - p);
|
||||
rowPos.y += bulge * sin((uvX - 0.5) * 3.14159);
|
||||
|
||||
// 增强吸进效果
|
||||
float depth = 1.0 - p * 0.8 * uvY;
|
||||
rowPos = mix(rowPos, u_targetPos, (1.0 - depth) * uvY * 1.0);
|
||||
|
||||
// 最终阶段快速收缩到目标点
|
||||
if (p > 0.8) {
|
||||
float finalT = (p - 0.8) / 0.2;
|
||||
rowPos = mix(rowPos, u_targetPos, finalT * 0.8);
|
||||
}
|
||||
|
||||
return cc_matViewProj * vec4(rowPos, 0.0, 1.0);
|
||||
}
|
||||
}%
|
||||
|
||||
CCProgram genie-fs %{
|
||||
precision highp float;
|
||||
#include <texture>
|
||||
|
||||
in vec2 v_uv;
|
||||
in vec4 v_color;
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
vec4 fs() {
|
||||
return texture(texture, v_uv) * v_color;
|
||||
}
|
||||
}%
|
||||
18
assets/effect/genie/genie.effect.meta
Normal file
18
assets/effect/genie/genie.effect.meta
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"ver": "1.0.27",
|
||||
"uuid": "3ce2780e-89e8-4262-ba0f-80fdfd58a026",
|
||||
"importer": "effect",
|
||||
"compiledShaders": [
|
||||
{
|
||||
"glsl1": {
|
||||
"vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nattribute vec3 a_position;\nattribute vec2 a_uv0;\nattribute vec4 a_color;\nuniform vec2 u_targetPos;\nuniform float u_progress;\nuniform float u_bendStrength;\nuniform float u_shrinkWidth;\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvec2 quadBezier(vec2 p0, vec2 p1, vec2 p2, float t) {\n float u = 1.0 - t;\n return u * u * p0 + 2.0 * u * t * p1 + t * t * p2;\n}\nvec4 vs() {\n vec2 pos = a_position.xy;\n v_uv = a_uv0;\n v_color = a_color;\n float p = clamp(u_progress, 0.0, 1.0);\n float uvY = a_uv0.y;\n float uvX = a_uv0.x;\n vec2 topTarget = mix(pos, u_targetPos, p * 0.6);\n vec2 bottomTarget = u_targetPos;\n float bendDown = -80.0 * u_bendStrength * (1.0 - p);\n vec2 bottomControl = mix(pos, u_targetPos, 0.5) + vec2(0.0, bendDown);\n vec2 rowPos = quadBezier(topTarget, bottomControl, bottomTarget, uvY * p);\n float widthScale = 1.0 - (1.0 - u_shrinkWidth) * p * uvY;\n vec2 center = mix(topTarget, bottomTarget, uvY);\n rowPos.x = center.x + (rowPos.x - center.x) * widthScale;\n float bulge = -sin(uvY * 3.14159) * 30.0 * u_bendStrength * (1.0 - p);\n rowPos.y += bulge * sin((uvX - 0.5) * 3.14159);\n float depth = 1.0 - p * 0.8 * uvY;\n rowPos = mix(rowPos, u_targetPos, (1.0 - depth) * uvY * 1.0);\n if (p > 0.8) {\n float finalT = (p - 0.8) / 0.2;\n rowPos = mix(rowPos, u_targetPos, finalT * 0.8);\n }\n return cc_matViewProj * vec4(rowPos, 0.0, 1.0);\n}\nvoid main() { gl_Position = vs(); }",
|
||||
"frag": "\nprecision highp float;\nvarying vec2 v_uv;\nvarying vec4 v_color;\nuniform sampler2D texture;\nvec4 fs() {\n return texture2D(texture, v_uv) * v_color;\n}\nvoid main() { gl_FragColor = fs(); }"
|
||||
},
|
||||
"glsl3": {
|
||||
"vert": "\nprecision highp float;\nuniform CCGlobal {\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n vec4 cc_time;\n mediump vec4 cc_screenSize;\n mediump vec4 cc_screenScale;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\nin vec3 a_position;\nin vec2 a_uv0;\nin vec4 a_color;\nuniform MyConstants {\n vec2 u_targetPos;\n float u_progress;\n float u_bendStrength;\n float u_shrinkWidth;\n};\nout vec2 v_uv;\nout vec4 v_color;\nvec2 quadBezier(vec2 p0, vec2 p1, vec2 p2, float t) {\n float u = 1.0 - t;\n return u * u * p0 + 2.0 * u * t * p1 + t * t * p2;\n}\nvec4 vs() {\n vec2 pos = a_position.xy;\n v_uv = a_uv0;\n v_color = a_color;\n float p = clamp(u_progress, 0.0, 1.0);\n float uvY = a_uv0.y;\n float uvX = a_uv0.x;\n vec2 topTarget = mix(pos, u_targetPos, p * 0.6);\n vec2 bottomTarget = u_targetPos;\n float bendDown = -80.0 * u_bendStrength * (1.0 - p);\n vec2 bottomControl = mix(pos, u_targetPos, 0.5) + vec2(0.0, bendDown);\n vec2 rowPos = quadBezier(topTarget, bottomControl, bottomTarget, uvY * p);\n float widthScale = 1.0 - (1.0 - u_shrinkWidth) * p * uvY;\n vec2 center = mix(topTarget, bottomTarget, uvY);\n rowPos.x = center.x + (rowPos.x - center.x) * widthScale;\n float bulge = -sin(uvY * 3.14159) * 30.0 * u_bendStrength * (1.0 - p);\n rowPos.y += bulge * sin((uvX - 0.5) * 3.14159);\n float depth = 1.0 - p * 0.8 * uvY;\n rowPos = mix(rowPos, u_targetPos, (1.0 - depth) * uvY * 1.0);\n if (p > 0.8) {\n float finalT = (p - 0.8) / 0.2;\n rowPos = mix(rowPos, u_targetPos, finalT * 0.8);\n }\n return cc_matViewProj * vec4(rowPos, 0.0, 1.0);\n}\nvoid main() { gl_Position = vs(); }",
|
||||
"frag": "\nprecision highp float;\nin vec2 v_uv;\nin vec4 v_color;\nuniform sampler2D texture;\nvec4 fs() {\n return texture(texture, v_uv) * v_color;\n}\nout vec4 cc_FragColor;\nvoid main() { cc_FragColor = fs(); }"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
||||
15
assets/effect/genie/genie.mtl
Normal file
15
assets/effect/genie/genie.mtl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"__type__": "cc.Material",
|
||||
"_name": "genie",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_effectAsset": {
|
||||
"__uuid__": "3ce2780e-89e8-4262-ba0f-80fdfd58a026"
|
||||
},
|
||||
"_techniqueIndex": 0,
|
||||
"_techniqueData": {
|
||||
"0": {
|
||||
"defines": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
assets/effect/genie/genie.mtl.meta
Normal file
7
assets/effect/genie/genie.mtl.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "d53fa0ca-8b03-4458-8359-c0b3d5fd3821",
|
||||
"importer": "material",
|
||||
"dataAsSubAsset": null,
|
||||
"subMetas": {}
|
||||
}
|
||||
|
|
@ -3480,6 +3480,9 @@
|
|||
"monthCardBtn2": {
|
||||
"__id__": 34
|
||||
},
|
||||
"genieMaterial": {
|
||||
"__uuid__": "d53fa0ca-8b03-4458-8359-c0b3d5fd3821"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8753,6 +8753,9 @@
|
|||
"__uuid__": "f0fbe7be-4949-478f-a6f5-06e86e7ffbdc"
|
||||
},
|
||||
"btnActivate1": null,
|
||||
"genieMaterial": {
|
||||
"__uuid__": "d53fa0ca-8b03-4458-8359-c0b3d5fd3821"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import JiaZai from "../../Script/JiaZai";
|
|||
import Utils from "../../Script/module/Pay/Utils";
|
||||
import NumberToImage from "../../Script/NumberToImage";
|
||||
import { MiniGameSdk } from "../../Script/Sdk/MiniGameSdk";
|
||||
import { GenieEffectUtil } from "../../Script/module/Tool/GenieEffect";
|
||||
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
|
|
@ -39,8 +40,8 @@ export default class passCheck extends cc.Component {
|
|||
@property(cc.Prefab)
|
||||
buyActivate: cc.Prefab = null;
|
||||
|
||||
@property(cc.Button)
|
||||
btnActivate1: cc.Button = null;
|
||||
@property(cc.Material)
|
||||
genieMaterial: cc.Material = null;
|
||||
|
||||
private timeNumber: number = 0;
|
||||
private progressNum1: number = 0;
|
||||
|
|
@ -111,9 +112,9 @@ export default class passCheck extends cc.Component {
|
|||
if (cc.fx.GameConfig.GM_INFO.getItemType == 2) {
|
||||
this.oldPassCheckInfo = passCheckInfo[1];
|
||||
passCheck = passCheckInfo[2];
|
||||
if (this.activateBtn && this.activateBtn.node) {
|
||||
this.activateBtn.node.active = !passCheck.activate;
|
||||
}
|
||||
if (this.activateBtn && this.activateBtn.node) {
|
||||
this.activateBtn.node.active = !passCheck.activate;
|
||||
}
|
||||
} else {
|
||||
this.oldPassCheckInfo = passCheckInfo[2];
|
||||
passCheck = passCheckInfo[1];
|
||||
|
|
@ -396,12 +397,10 @@ export default class passCheck extends cc.Component {
|
|||
try {
|
||||
// 先移除事件监听器
|
||||
if (cc.sys.platform === cc.sys.WECHAT_GAME && this.onShowListener) {
|
||||
console.log("shop移除onshow");
|
||||
//@ts-ignore
|
||||
wx.offShow(this.onShowListener);
|
||||
this.onShowListener = null;
|
||||
} else if (cc.sys.platform === cc.sys.BYTEDANCE_GAME && this.onShowListener) {
|
||||
console.log("shop移除onshow");
|
||||
//@ts-ignore
|
||||
tt.offShow(this.onShowListener);
|
||||
this.onShowListener = null;
|
||||
|
|
@ -426,14 +425,73 @@ export default class passCheck extends cc.Component {
|
|||
this.countdownTimer = null;
|
||||
}
|
||||
|
||||
// 执行完整的销毁逻辑
|
||||
this.destroyPassCheck();
|
||||
// 执行关闭动画
|
||||
this.playCloseAnimation();
|
||||
} catch (error) {
|
||||
console.error("关闭通行证界面时发生错误:", error);
|
||||
// 即使出错也要确保清理引用
|
||||
this.cleanupAndDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放关闭动画,缩放到 HomeScene 的 passBtn 位置
|
||||
*/
|
||||
private playCloseAnimation() {
|
||||
|
||||
// 找到 HomeScene 中的 passBtn
|
||||
const jiazaiNode = cc.find("Canvas");
|
||||
|
||||
if (!jiazaiNode) {
|
||||
console.warn("找不到 Canvas 节点,直接销毁通行证界面");
|
||||
this.destroyPassCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
const topNode = jiazaiNode.getChildByName("Load").getChildByName("Top");
|
||||
if (!topNode) {
|
||||
console.warn("找不到 Top 节点,直接销毁通行证界面");
|
||||
this.destroyPassCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
const passBtn = topNode.getChildByName("passBtn");
|
||||
console.log("退出通行证:", passBtn);
|
||||
|
||||
if (passBtn && this.node && cc.isValid(this.node)) {
|
||||
// 隐藏第一个子节点(可能包含按钮)
|
||||
this.node.children[0].active = false;
|
||||
|
||||
// 禁止所有按钮操作 - 禁用整个节点的交互
|
||||
this.setButtonsEnabled(false);
|
||||
|
||||
// 使用 GenieEffectUtil 播放关闭动画
|
||||
GenieEffectUtil.playClose(this.node, passBtn, () => {
|
||||
// 动画完成后执行销毁逻辑
|
||||
this.destroyPassCheck();
|
||||
}, this.genieMaterial);
|
||||
} else {
|
||||
// 如果找不到 passBtn,直接销毁
|
||||
this.destroyPassCheck();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置所有按钮的启用/禁用状态
|
||||
* @param enabled true-启用按钮,false-禁用按钮
|
||||
*/
|
||||
private setButtonsEnabled(enabled: boolean) {
|
||||
if (!this.node || !cc.isValid(this.node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历所有子节点,禁用/启用按钮
|
||||
const buttons = this.node.getComponentsInChildren(cc.Button);
|
||||
for (const button of buttons) {
|
||||
button.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
private destroyPassCheck() {
|
||||
try {
|
||||
// 先隐藏节点
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
"title": "ColorBlock",
|
||||
"packageName": "org.cocos2d.demo",
|
||||
"startScene": "ea96c58a-b731-4349-bcfc-c446571823ad",
|
||||
"excludeScenes": [],
|
||||
"excludeScenes": [
|
||||
"0cb0fc28-9f05-4aff-878a-2414734c687c",
|
||||
"0a811625-58f1-4abc-8ab1-2015263ba8e3"
|
||||
],
|
||||
"orientation": {
|
||||
"landscapeRight": true,
|
||||
"landscapeLeft": true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user