From 681b1efb8680696d938afbf256cbd4d07f4d3c44 Mon Sep 17 00:00:00 2001 From: "COMPUTER\\EDY" <249929363@qq.com> Date: Fri, 14 Nov 2025 17:56:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=8C=E6=95=B4=E7=89=88?= =?UTF-8?q?=20=20=E5=85=A5=E8=81=8C=E6=8E=92=E8=A1=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Scene/HomeScene.fire | 6 +- assets/Script/JiaZai.ts | 52 ++++++++- assets/Script/Sdk/MiniGameSdk.ts | 83 ++++++++++++-- assets/Script/module/Pay/Utils.ts | 2 +- assets/Script/module/Position.meta | 13 +++ assets/career/prefab/rankGame.prefab | 4 +- assets/career/script/CareerList.ts | 165 ++++++++++++++++++++++++++- settings/project.json | 2 +- 8 files changed, 306 insertions(+), 21 deletions(-) create mode 100644 assets/Script/module/Position.meta diff --git a/assets/Scene/HomeScene.fire b/assets/Scene/HomeScene.fire index 5409d35..5734836 100644 --- a/assets/Scene/HomeScene.fire +++ b/assets/Scene/HomeScene.fire @@ -10907,7 +10907,7 @@ "ctor": "Float64Array", "array": [ 407.585, - -622.208, + -820, 0, 0, 0, @@ -11269,7 +11269,7 @@ "ctor": "Float64Array", "array": [ 407.585, - -819.71, + -622.208, 0, 0, 0, @@ -11450,7 +11450,7 @@ "ctor": "Float64Array", "array": [ 407.585, - -819.71, + -622.208, 0, 0, 0, diff --git a/assets/Script/JiaZai.ts b/assets/Script/JiaZai.ts index 0441963..d4f01d1 100644 --- a/assets/Script/JiaZai.ts +++ b/assets/Script/JiaZai.ts @@ -5,6 +5,7 @@ // Learn life-cycle callbacks: // - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html + import GameManager from "./GameManager"; import MapConroler from "./Map"; import NumberToImage from "./NumberToImage"; @@ -2474,7 +2475,7 @@ export default class JiaZai extends cc.Component { .start() }) } - console.log("rankData", rankData); + // console.log("rankData", rankData); }); } @@ -2500,20 +2501,63 @@ export default class JiaZai extends cc.Component { } openPosition() { - if (cc.fx.GameConfig.GM_INFO.address == "") { + let scrollVIew = this.RankNode.getChildByName("ScrollView"); + let top = this.node.getChildByName("Load").getChildByName("Top"); + // 获取CareerList组件实例 + let careerList = scrollVIew.getComponent("CareerList"); + let address = cc.fx.StorageMessage.getStorage("address"); + if (address == "" || address == null || address == undefined) { console.log("没有地址"); MiniGameSdk.API.getWechatCityInfo((success, data, error) => { + console.log("解析地址:", success, data, error); if (success) { console.log('详细城市信息:', data); - // 包含省份、城市、区县等详细信息 - const { province, city, district } = data; + console.log("给用户移动到他所在的区域"); + + top.getChildByName("posBtn").active = false; + top.getChildByName("topBtn").active = true; + //缓存地址 + // cc.fx.StorageMessage.setStorage("address", cc.fx.GameConfig.GM_INFO.address); + // 在需要的地方调用 + // 滚动到其他城市(自定义位置和动画时间) + if (cc.fx.GameConfig.GM_INFO.address == "") { + cc.fx.GameConfig.GM_INFO.address = "其他"; + } + careerList.scrollToCity(cc.fx.GameConfig.GM_INFO.address, 1.0, 0.5); // 1秒动画,屏幕30%位置 + } + else { + // cc.fx.StorageMessage.setStorage("address", cc.fx.GameConfig.GM_INFO.address); + cc.fx.GameConfig.GM_INFO.address = "其他"; + careerList.scrollToCity(cc.fx.GameConfig.GM_INFO.address, 1.0, 0.5); // 1秒动画,屏幕30%位置 + top.getChildByName("posBtn").active = false; + top.getChildByName("topBtn").active = true; } }, true); // 第二个参数设为true启用逆解析 } + else { + if (cc.fx.GameConfig.GM_INFO.address == "") { + cc.fx.GameConfig.GM_INFO.address = "其他"; + } + careerList.scrollToCity(cc.fx.GameConfig.GM_INFO.address, 1.0, 0.5); // 1秒动画,屏幕30%位置 + top.getChildByName("posBtn").active = false; + top.getChildByName("topBtn").active = true; + } } backTop() { + console.log("给用户移动到列表顶部"); + let top = this.node.getChildByName("Load").getChildByName("Top"); + top.getChildByName("posBtn").active = true; + top.getChildByName("topBtn").active = false; + let scrollVIew = this.RankNode.getChildByName("ScrollView"); + // 获取CareerList组件实例 + let careerList = scrollVIew.getComponent("CareerList"); + const scrollPosition = careerList.getScrollPosition(); + console.log('当前滚动位置:', scrollPosition); // 0表示顶部,1表示底部 + let time = 1 * scrollPosition; + // 2. 指定动画时间回到顶部 + careerList.backTop(time); // 0.5秒动画 } update(dt) { diff --git a/assets/Script/Sdk/MiniGameSdk.ts b/assets/Script/Sdk/MiniGameSdk.ts index bf738fd..9397894 100644 --- a/assets/Script/Sdk/MiniGameSdk.ts +++ b/assets/Script/Sdk/MiniGameSdk.ts @@ -1,4 +1,5 @@ import Utils from "../module/Pay/Utils"; +// import { getProvinceName } from "../module/Position/ProvinceLocator"; /** * 小游戏平台SDK工具封装,目前只支持微信和抖音平台 @@ -1941,7 +1942,12 @@ export namespace MiniGameSdk { API._getCityInfo(callback, useReverseGeocoding); } else { callback(false, null, '用户拒绝授权位置权限'); + API._setCityInfo(null, useReverseGeocoding); } + }, + fail: (err) => { + console.log('打开设置失败:', err); + API._setCityInfo(callback, useReverseGeocoding); } }); } @@ -1971,10 +1977,55 @@ export namespace MiniGameSdk { success: (res) => { console.log('获取位置成功:', res); + if (useReverseGeocoding) { + // 使用逆解析获取详细地址信息 + API._reverseGeocoding(res.latitude, res.longitude, callback); + } else { + // 直接返回基本位置信息,包含经纬度 + const cityInfo = { + latitude: res.latitude, // 纬度 + longitude: res.longitude, // 经度 + province: '', // 省份(需要通过逆解析获取) + city: '', // 城市(需要通过逆解析获取) + district: '', // 区县(需要通过逆解析获取) + address: '' // 详细地址(需要通过逆解析获取) + }; + callback(true, cityInfo); + } }, fail: (err) => { console.log('获取位置失败:', err); - callback(false, null, err.errMsg || '获取位置失败'); + API._setCityInfo(callback, useReverseGeocoding); + // 处理错误码102:位置服务不可用 + if (err.errCode === 102) { + // 错误码102的常见原因和解决方案: + // 1. 设备定位服务未开启 + // 2. 网络问题导致定位失败 + // 3. 权限问题 + + // 提供更友好的错误信息 + let errorMsg = '位置服务不可用'; + if (err.errMsg.includes('auth deny')) { + errorMsg = '位置权限被拒绝,请检查系统设置'; + } else if (err.errMsg.includes('network')) { + errorMsg = '网络连接失败,请检查网络设置'; + } else { + errorMsg = '定位服务不可用,请检查设备定位功能是否开启'; + } + + // 提供用户友好的提示 + //@ts-ignore + wx.showModal({ + title: '定位失败', + content: errorMsg, + showCancel: false, + confirmText: '知道了' + }); + + callback(false, null, errorMsg); + } else { + callback(false, null, err.errMsg || '获取位置失败'); + } } }); } @@ -1989,13 +2040,29 @@ export namespace MiniGameSdk { * 逆解析经纬度获取详细地址信息 */ private static _reverseGeocoding(latitude: number, longitude: number, callback: (success: boolean, data?: any, error?: any) => void) { + //@ts-ignore + // if (typeof wx !== "undefined" && wx.getLocation) { + + // const lat = latitude; + // const lng = longitude; + + // const province = getProvinceName(lat, lng); + // console.log("玩家省份:", province); + + // // TODO: 这里写你的逻辑:埋点、排行榜、活动分组等 + + + // } else { + // // 非微信环境(比如 Cocos 预览),用个测试坐标 + // const province = getProvinceName(39.9, 116.4); + // console.log("测试坐标所在省份:", province); + // } + + + const key = '6PPBZ-VBEHW-XE3RU-3XNC5-TQH6H-KLBTF'; // 需要替换为实际的key + const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}&get_poi=0`; // 注意:微信小游戏本身不提供逆解析API,需要调用第三方服务或自己的服务器 // 这里提供一个示例,实际使用时需要替换为你的服务器接口 - - // 示例:使用腾讯地图逆解析API(需要申请key) - const key = 'YOUR_TENCENT_MAP_KEY'; // 需要替换为实际的key - const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}&get_poi=0`; - //@ts-ignore wx.request({ url: url, @@ -2016,12 +2083,12 @@ export namespace MiniGameSdk { callback(true, cityInfo); } else { console.log('逆解析失败:', res.data); - callback(false, null, '逆解析失败'); + callback(true, null, '逆解析失败'); } }, fail: (err) => { console.log('逆解析请求失败:', err); - callback(false, null, '逆解析请求失败'); + callback(true, null, '逆解析请求失败'); } }); } diff --git a/assets/Script/module/Pay/Utils.ts b/assets/Script/module/Pay/Utils.ts index 69232a6..9c104e7 100644 --- a/assets/Script/module/Pay/Utils.ts +++ b/assets/Script/module/Pay/Utils.ts @@ -1354,7 +1354,7 @@ export default class Utils { let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', - address: data, + address: "其他", } Utils.POST("address", setData, res => { if (res.code === 1) { diff --git a/assets/Script/module/Position.meta b/assets/Script/module/Position.meta new file mode 100644 index 0000000..0ab5621 --- /dev/null +++ b/assets/Script/module/Position.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.3", + "uuid": "c2058a49-28b1-42a2-bf5e-c4700a366cac", + "importer": "folder", + "isBundle": false, + "bundleName": "", + "priority": 1, + "compressionType": {}, + "optimizeHotUpdate": {}, + "inlineSpriteFrames": {}, + "isRemoteBundle": {}, + "subMetas": {} +} \ No newline at end of file diff --git a/assets/career/prefab/rankGame.prefab b/assets/career/prefab/rankGame.prefab index 2f45679..b68a106 100644 --- a/assets/career/prefab/rankGame.prefab +++ b/assets/career/prefab/rankGame.prefab @@ -279,7 +279,7 @@ "__id__": 7 } ], - "_active": true, + "_active": false, "_components": [ { "__id__": 10 @@ -13926,7 +13926,7 @@ }, "_enabled": true, "phone": null, - "_id": "" + "_id": "45r+ulHaFN/7dD+23ACtCZ" }, { "__type__": "cc.PrefabInfo", diff --git a/assets/career/script/CareerList.ts b/assets/career/script/CareerList.ts index 959ac52..de90145 100644 --- a/assets/career/script/CareerList.ts +++ b/assets/career/script/CareerList.ts @@ -181,8 +181,8 @@ export default class CareerList extends cc.Component { this.content.width = this.content.parent.width; // 计算高度时考虑firstRender的高度和间距 this.content.height = firstRenderHeight + (firstRenderHeight > 0 ? this.spaceY : 0) + - dataLen * this.itemHeight + (dataLen - 3) * this.spaceY + this.padding_top + this.padding_buttom; - this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) + 2; //计算创建的item实例数量,比当前scrollView容器能放下的item数量再加上2个 + dataLen * this.itemHeight + (dataLen - 3) * this.spaceY + this.padding_top + this.padding_buttom + 500; + this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) + 4; //计算创建的item实例数量,比当前scrollView容器能放下的item数量再加上2个 this.halfScrollView = this.scrollView.node.height / 2 + this.itemHeight / 2 + this.spaceY; //计算bufferZone,item的显示范围 this.updateFun = this.updateV; } @@ -503,6 +503,167 @@ export default class CareerList extends cc.Component { //清理列表数据 this.itemDataList.length = 0; } + + /** + * 将滑动列表滑动回到最顶端 + * @param duration 动画持续时间,单位秒,默认0.3秒 + * @param easing 缓动函数,默认使用平滑缓动 + */ + public backTop(duration: number = 0.3, easing?: string) { + if (!this.scrollView || !this.content) { + console.warn('ScrollView或Content未初始化'); + return; + } + + // 计算回到顶部的位置 + let targetPosition: cc.Vec2; + + if (this.type == ListType.Vertical) { + // 垂直列表:将content的y坐标设置为0(最顶端) + targetPosition = new cc.Vec2(this.content.x, 0); + } else if (this.type == ListType.Horizontal) { + // 水平列表:将content的x坐标设置为0(最左端) + targetPosition = new cc.Vec2(0, this.content.y); + } else { + console.warn('不支持Grid类型的回到顶部操作'); + return; + } + + // 使用scrollTo方法平滑滚动到顶部 + this.scrollView.scrollToOffset(targetPosition, duration, false); + + console.log('回到顶部操作执行完成'); + } + + /** + * 获取当前滚动位置 + * @returns 返回当前滚动位置的百分比(0-1) + */ + public getScrollPosition(): number { + if (!this.scrollView || !this.content) { + return 0; + } + + if (this.type == ListType.Vertical) { + const maxScrollY = Math.max(0, this.content.height - this.scrollView.node.height); + if (maxScrollY <= 0) return 0; + return Math.abs(this.content.y) / maxScrollY; + } else if (this.type == ListType.Horizontal) { + const maxScrollX = Math.max(0, this.content.width - this.scrollView.node.width); + if (maxScrollX <= 0) return 0; + return Math.abs(this.content.x) / maxScrollX; + } + + return 0; + } + + /** + * 查找并滚动到指定城市名的子节点 + * @param cityName 要查找的城市名,如"北京" + * @param duration 动画持续时间,单位秒,默认0.5秒 + * @param position 目标位置,0表示屏幕顶部,0.5表示屏幕中间,1表示屏幕底部,默认0.5(屏幕中间) + */ + public scrollToCity(cityName: string, duration: number = 0.5, position: number = 0.5): boolean { + if (!this.scrollView || !this.content) { + console.warn('ScrollView或Content未初始化'); + return false; + } + + if (this.type !== ListType.Vertical) { + console.warn('目前只支持垂直列表的滚动到城市功能'); + return false; + } + + // 循环遍历itemDataList查找目标城市 + let targetIndex = -1; + for (let i = 0; i < this.itemDataList.length; i++) { + if (this.itemDataList[i] && this.itemDataList[i].name === cityName) { + targetIndex = i; + break; + } + } + + if (targetIndex === -1) { + console.warn(`未找到城市名为"${cityName}"的列表项`); + return false; + } + + console.log(`找到城市"${cityName}",索引位置:${targetIndex}`); + + // 计算目标城市在列表中的位置 + const itemHeight = this.itemHeight; + const spaceY = this.spaceY; + const paddingTop = this.padding_top; + + // 计算firstRender的高度偏移 + let firstRenderHeight = this.firstRender ? this.firstRender.height : 0; + let firstRenderOffsetY = firstRenderHeight > 0 ? firstRenderHeight + this.spaceY : 0; + + // 计算目标城市在content中的Y坐标(相对于content顶部) + let targetYInContent = -itemHeight * (0.5 + targetIndex) - spaceY * targetIndex - paddingTop - firstRenderOffsetY; + + // 计算目标城市在屏幕中的期望位置 + const scrollViewHeight = this.scrollView.node.height; + const contentHeight = this.content.height; + + // 计算目标城市在屏幕中的期望Y坐标(相对于scrollView顶部) + let targetYInView = -targetYInContent - (scrollViewHeight * position); + + // 限制滚动范围 + const maxScrollY = Math.max(0, contentHeight - scrollViewHeight); + targetYInView = Math.max(0, Math.min(maxScrollY, targetYInView)); + + // 获取当前滚动偏移量 + const currentOffset = this.scrollView.getScrollOffset(); + + // 计算相对偏移量(从当前位置到目标位置的差值) + const relativeOffsetY = targetYInView - currentOffset.y; + + // 计算目标偏移量(当前位置 + 相对偏移量) + const targetOffset = new cc.Vec2(0, currentOffset.y + relativeOffsetY); + + // 根据滚动距离动态调整动画时间(距离越大,时间越长) + const distance = Math.abs(relativeOffsetY); + const baseDuration = 0.2; // 基础动画时间 + const maxDuration = 1; // 最大动画时间 + const adjustedDuration = Math.min(maxDuration, baseDuration + (distance / 1000) * 0.5); + + console.log(`当前偏移量: ${currentOffset.y}, 目标偏移量: ${targetOffset.y}, 相对偏移量: ${relativeOffsetY}, 距离: ${distance}`); + + // 执行滚动 + this.scrollView.scrollToOffset(targetOffset, adjustedDuration, false); + + console.log(`滚动到城市"${cityName}",目标位置:${position},动画时间:${adjustedDuration}秒`); + return true; + } + + + + + /** + * 查找并滚动到北京的子节点(屏幕中间) + * @param duration 动画持续时间,单位秒,默认0.5秒 + */ + public scrollToBeijing(duration: number = 0.5): boolean { + return this.scrollToCity("北京", duration, 0.5); + } + + /** + * 查找并滚动到北京的子节点(屏幕顶部) + * @param duration 动画持续时间,单位秒,默认0.5秒 + */ + public scrollToBeijingTop(duration: number = 0.5): boolean { + return this.scrollToCity("北京", duration, 0); + } + + /** + * 查找并滚动到北京的子节点(屏幕底部) + * @param duration 动画持续时间,单位秒,默认0.5秒 + */ + public scrollToBeijingBottom(duration: number = 0.5): boolean { + return this.scrollToCity("北京", duration, 1); + } + } diff --git a/settings/project.json b/settings/project.json index 08cf880..37cf268 100644 --- a/settings/project.json +++ b/settings/project.json @@ -1,5 +1,5 @@ { - "last-module-event-record-time": 1762504664109, + "last-module-event-record-time": 1763110351954, "group-list": [ "default", "Map"