jxg/jinxiangguo-home-master/pages/game/game.vue

661 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<map id="map" ref="map" :longitude="longitude" :latitude="latitude" :scale="mapScale" style="width: 100vw;"
:style="{ height: app.globalData.sysInfo.windowHeight + 'px' }" :circles="circles" :markers="markers"
@markertap="markerclick" :enable-scroll="!popupOpenState" subkey="AM4BZ-UGEKQ-F355S-2PJVY-46UEO-ZXBDD" layer-style="1">
</map>
<!-- 顶部阴影 -->
<view class="bck-top">
<image style="width: 100%;" src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/bck-top.png" mode="widthFix"></image>
</view>
<!-- 底部阴影 -->
<view class="bck-bottom">
<image style="width: 100%;" src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/bck-bottom.png" mode="widthFix"></image>
</view>
<!-- 当前定位城市 -->
<view class="city-position">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/city-position.png" mode="widthFix"></image>
<text style="margin-left: 5px;">{{positionCity}}</text>
</view>
<!-- 右侧菜单 -->
<view class="tabbar-right">
<view @click="openPopupSetSystem">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/set.png" mode="widthFix"></image>
</view>
<view @click="openPopupSignin">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/signin.png" mode="widthFix"></image>
</view>
<view @click="scanQRCode">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/scan.png" mode="widthFix"></image>
</view>
<view @click="switchPageCoinType">
<image :src="'https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/' + (curPageCoinType > 1 ? 'gold.png' : 'copper.png')" mode="widthFix"></image>
</view>
</view>
<!-- 底部菜单 -->
<view class="tabbar-bottom">
<view class="group" style="justify-content: flex-end;">
<view class="item" @click="openPopupTask">
<image class="logo" src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/index/logo.png" mode="heightFix"></image>
<image style="width: 25px;" src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/tabbar-icon1.png" mode="widthFix"></image>
</view>
</view>
<view class="group" style="justify-content: center;">
<view @click="myPosition" class="item">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/tabbar-icon2.png" mode="widthFix"></image>
</view>
</view>
<view class="group" style="justify-content: flex-start;">
<view @click="goMy" class="item">
<image src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/tabbar-icon3.png" mode="widthFix"></image>
</view>
</view>
</view>
<!-- 弹窗设置 -->
<popup-setsystem ref="pSetsystem" @close="publicClose"></popup-setsystem>
<block v-if="JSON.stringify(app.globalData.userinfo) !== '{}'">
<!-- 弹窗:悬赏、赏金任务 -->
<popup-task ref="pTask" @close="publicClose"></popup-task>
<!-- 弹窗:签到 -->
<popup-signin ref="pSign" @close="publicClose"></popup-signin>
<!-- 弹窗:踪迹 -->
<popup-trace ref="pTrace" @close="traceClose"></popup-trace>
<!-- 弹窗:找到宝藏 -->
<popup-findcoin ref="pFindcoin" @close="publicClose" :coinId="findCoinInfo.id" :coinType="findCoinInfo.type" :coinName="findCoinInfo.name" :coinAddress="findCoinInfo.address"></popup-findcoin>
<!-- 弹窗:查看视频 -->
<popup-findvideo ref="pFindvideo" @close="publicClose"></popup-findvideo>
</block>
</view>
</template>
<script setup>
const app = getApp()
import {
ref,
computed,
getCurrentInstance
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
import {
jsonp
} from 'vue-jsonp'
const { proxy } = getCurrentInstance() // 全局对象
// ref组件
const pTask = ref() // 赏金、悬赏任务弹窗
const pSign = ref() // 签到弹窗
const pSetsystem = ref() // 设置弹窗
const pTrace = ref() // 踪迹弹窗
const pFindcoin = ref() // 找到宝藏弹窗
const pFindvideo = ref() // 查看视频弹窗
const mapContext = ref()
const popupOpenState = ref(false)
const userInfo = ref(app.globalData.userinfo)
// 找到宝藏
const findCoinInfo = ref({}) // 硬币信息
// 当前地图类型1金币2银币与铜币
const curPageCoinType = ref(2)
// 关于地图贴片
const curClickMarkerId = ref(0)
const positionCity = ref('正在定位')
const longitude = ref(121.472644) // 我的定位 经度
const latitude = ref(31.231706) // 我的定位 纬度
const myPositionMarker = ref({}) // 我的位置 marker标记
const mapScale = ref(13)
const isShanghai = ref(false) // 是否在上海
const markers = ref([])
var coinMapList = [] // 银币与铜币列表
var coinGoldMapList = [] // 金币列表
var circlesTmp = [] // circle根据scale级别会隐藏
const circles = ref([])
onLoad(async (options) => {
// #ifdef H5
if (!app.globalData.token) {
uni.redirectTo({
url: '/pages/index/index'
})
return
}
if (proxy.$wx && app.isWechat()) {
app.wxinit()
}
// #endif
// #ifdef MP-WEIXIN
await app.globalData.loginPromise // 等待登录完毕
if (app.globalData.token && (('scene' in options) || app.globalData.helpCode)) {
if (!app.globalData.helpCode) app.globalData.helpCode = options.scene
app.doHelp() // 直接助力
} else if ('scene' in options) {
app.globalData.helpCode = options.scene
}
// #endif
mapContext.value = uni.createMapContext('map', this)
uni.getLocation({
type: 'gcj02',
altitude: true,
isHighAccuracy: true,
success(res) {
if (app.globalData.token) {
loadData()
}
myPositionMarker.value = {longitude: res.longitude, latitude: res.latitude}
positionCity.value = '上海市'
},
fail(err) {
console.error(err)
if (app.globalData.token) {
loadData()
}
}
})
})
/**
* 加载所有硬币信息
*/
const loadData = (hideLoading = false) => {
// 请求硬币列表
let data = {}
if (curPageCoinType.value === 1) {
coinGoldMapList = []
data.type = curPageCoinType.value
} else {
coinMapList = []
}
uni.request({
url: app.globalData.requestUrl + '/api/coin/list',
header: {
'Authorization': 'Bearer ' + app.globalData.token
},
data: data,
success: (res) => {
if (res.data.code === 200) {
console.log(res.data.data)
// 对硬币进行分类
if (curPageCoinType.value === 1) {
coinGoldMapList = res.data.data
} else {
coinMapList = res.data.data
}
positionCity.value = '上海市'
calcMapMarkers() // 去计算markers该怎么放
} else {
uni.showToast({
title: res.data.msg,
icon: 'none'
})
}
},
complete() {
if (hideLoading) uni.hideLoading()
}
})
}
/**
* 摆放地图markers
*/
const calcMapMarkers = () => {
if (!app.globalData.isReloadMarkers) return
const CIRCLE_RADIUS = 1000 // 圆环暂定半径
let list = coinMapList
if (curPageCoinType.value === 1) {
list = coinGoldMapList // 当前是金币视角
}
let tmpMarkers = [],
tmpCircles = []
for (let i = 0; i < list.length; i++) {
let coin = list[i]
if (curPageCoinType.value === 1 && coin.is_unlock === 1) continue // 金币需要忽略已解锁的
if (coin.latitude < -90 || coin.latitude > 90) continue // 容错:经纬度填反
let icon = ''
switch (coin.type) {
case 1:
icon = 'gold-marker.png'
break
case 2:
icon = coin.is_unlock === 1 ? 'unlock-icon-red.png' : 'silver.png';
break
case 3:
icon = coin.is_unlock === 1 ? 'unlock-icon-yellow.png' : 'copper.png';
break
}
const {newLongitude, newLatitude, circleRadius} = azimuthOffset(coin)
let data = {
id: coin.id,
longitude: newLongitude,
latitude: newLatitude,
anchor: {x: .5, y: .5},
iconPath: 'https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/' + icon,
width: coin.type === 1 ? 41 : 37,
height: coin.type === 1 ? 37 : 35,
};
if (curPageCoinType.value !== 1 && coin.is_unlock === 1) {
data.width = 20;
data.height = 28;
}
tmpMarkers.push(data);
if (circleRadius === 0 || coin.is_unlock === 1) continue;
tmpCircles.push({
id: coin.id,
longitude: newLongitude,
latitude: newLatitude,
fillColor: '#FFFFFFA3',
color: '#B1CCCB',
strokeWidth: 2,
radius: circleRadius
})
}
tmpMarkers.unshift({
id: 999999999,
longitude: myPositionMarker.value.longitude,
latitude: myPositionMarker.value.latitude,
iconPath: "https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/game/myposition.png",
width: 49,
height: 68
}) // 我的位置
console.log(tmpMarkers)
markers.value = tmpMarkers
app.globalData.isReloadMarkers = false
circles.value = tmpCircles
}
const _d = new Date();
const _timestamp = new Date((_d.getFullYear() + '/' + (_d.getMonth()+1) + '/' + _d.getDate())).getTime(); // 今日时间戳
const _time = _d.getHours(); // 现在几点
// console.log('当前_time', _time, '当前_timestamp', _timestamp);
/**
* 偏移经纬度隐藏真实位置
* @param coin 硬币信息
* @returns {newLongitude, newLatitude, circleRadius} 新经度,新纬度,圆环半径
*/
const azimuthOffset = (coin) => {
const originLongitude = parseFloat(coin.longitude); // 原经度
const originLatitude = parseFloat(coin.latitude); // 原纬度
const clueCount = coin.clue_count; // 总线索数
const userClueCount = coin.user_clue_count; // 用户已解锁线索数
const type = coin.type; // 1金币2、3银币铜币
const createdAt = coin.created_at; // 根据硬币创建时间缩小圆环
if (type === 1 || clueCount === userClueCount) {
return {
newLongitude: originLongitude,
newLatitude: originLatitude,
circleRadius: 0
}
} // 线索只要相等说明完成了或者两者都为0从未设置过线索或者金币统一不设圆环不偏移
const EARTH_RADIUS = 6371393
let rightDist = 650 // 米,向右移动(变经度)
let topDist = -400 // 米,向上移动(变纬度)
let circleRadius = 1000; // 圆环半径:银币
if (type === 3) {
circleRadius = 800; // 圆环半径铜币初始化800米
}
// 先根据硬币的创建时间缩小圆环半径
// 缩小规则硬币创建的第3天开始第3-6天每天缩小20%第7天缩小10%每日8点后会算做一天
// 获取现在的日期与时间
let date = new Date(createdAt);
let formatDate = (date.getFullYear() + '/' + (date.getMonth()+1) + '/' + date.getDate());
let timestamp = new Date(formatDate).getTime();
// console.log('硬币时间戳', timestamp); // 获取当日时间戳
// console.log('今日时间戳', _timestamp); // 获取当日时间戳
let dayc = ((_timestamp - timestamp) / 1000) / 60 / 60 / 24;
let calcDay = dayc - 3 < 0 ? 0 : dayc - 3;
// console.log('创建于', dayc, '天前');
if (_time < 8 && calcDay > 0) {
calcDay--;
}
// console.log('参与计算的天数', calcDay, '天');
if (calcDay >= 1 && calcDay <= 4) {
let scale = (1 - calcDay * 0.2);
circleRadius *= scale;
rightDist *= scale;
topDist *= scale;
} else if (calcDay >= 5) {
circleRadius *= 0.1;
rightDist *= 0.1;
topDist *= 0.1;
}
// 根据线索数计算偏移量
let lonItemDist = rightDist / clueCount
let latItemDist = topDist / clueCount // 每份线索占多少比例(米)
let lonDoneDist = lonItemDist * userClueCount // 已完成数量(米)
let latDoneDist = latItemDist * userClueCount
let logDist = rightDist - lonDoneDist // 最终的经度偏移量
let latDist = topDist - latDoneDist // 最终的纬度偏移量
// 经度偏移
let d = logDist / EARTH_RADIUS
let cs = Math.cos(originLatitude * Math.PI / 180.0)
let c = d / cs * 180.0 / Math.PI
// 纬度偏移
let d2 = latDist / EARTH_RADIUS
let c2 = d2 / Math.PI * 180.0
// 确认圆环半径
let circleItem = circleRadius / clueCount
let circleDone = circleItem * userClueCount
let circleRes = circleRadius - circleDone
return {
newLongitude: originLongitude + c,
newLatitude: originLatitude + c2,
circleRadius: circleRes
}
}
// 切换地图类型
const switchPageCoinType = () => {
app.globalData.isReloadMarkers = true
if (curPageCoinType.value === 1) {
uni.showToast({
title: '已切换为银币、铜币视角',
icon: 'none'
})
curPageCoinType.value = 2
calcMapMarkers() // 重新计算地图markers
} else {
curPageCoinType.value = 1
if (coinGoldMapList.length === 0) {
// 请求金币
uni.showLoading({
title: '切换为金币视角'
})
mapScale.value = 12
loadData(true)
} else {
uni.showToast({
title: '已切换为金币视角',
icon: 'none'
})
calcMapMarkers() // 重新计算地图markers
}
}
}
// 去“我的”页面
const goMy = () => {
// #ifdef MP-WEIXIN
if (!app.globalData.token) {
uni.navigateTo({
url: '/pages/index/index'
})
return
}
// #endif
uni.navigateTo({
url: '/pages/my/my'
})
}
// 定位我的位置
const myPosition = () => {
app.playAudio() // 点击音效
// if (isShanghai.value) {
uni.getLocation({
type: 'gcj02',
altitude: true,
isHighAccuracy: true,
success(res) {
longitude.value = res.longitude
latitude.value = res.latitude
mapContext.value.moveToLocation({
longitude: res.longitude,
latitude: res.latitude,
success(res) {
// console.log('移动坐标成功')
}
})
},
fail(err) {
console.log('定位错误', err)
}
})
// } else {
// uni.showToast({
// title: '您的定位不在上海,无法定位',
// icon: 'none'
// })
// }
}
// 点击marker弹出踪迹弹窗
const markerclick = (e) => {
console.log(e);
app.playAudio() // 点击音效
// #ifdef MP-WEIXIN
if (!app.globalData.token) {
uni.navigateTo({
url: '/pages/index/index'
})
return
}
// #endif
const gold = coinGoldMapList.find(function(item) {
return item.id === e.detail.markerId
})
if (gold) {
popupOpenState.value = true
pTrace.value.open(gold)
} else {
const curcoin = coinMapList.find(function(item) {
return item.id === e.detail.markerId
})
if (!curcoin) return
popupOpenState.value = true;
mapContext.value.getScale({
success(res) {
if (res.scale < 14) {
if (mapScale.value === 14) {
mapScale.value = 14.1;
} else {
mapScale.value = 14;
}
}
}
});
// #ifdef H5
mapContext.value.moveToLocation({
longitude: e.detail.longitude,
latitude: e.detail.latitude
});
// #endif
// #ifdef MP-WEIXIN
const curmarker = markers.value.find(function(item) {
return item.id === e.detail.markerId
})
mapContext.value.moveToLocation({
longitude: curmarker.longitude,
latitude: curmarker.latitude
});
// #endif
if (curcoin.is_unlock === 1) {
pFindvideo.value.open(curcoin)
} else {
pTrace.value.open(curcoin)
}
}
}
// 踪迹弹窗的监听窗口,可能需要更新页面进行缩圈
const traceClose = (res) => {
popupOpenState.value = false
if (app.globalData.isReloadMarkers) {
if (res === 1) {
uni.showLoading({
title: '正在刷新金币'
})
} else {
uni.showLoading({
title: '硬币范围正在缩小'
})
}
loadData(true)
}
}
// 公共关闭弹窗事件,允许页面滑动
const publicClose = () => {
popupOpenState.value = false
}
// 微信扫一扫
const scanQRCode = () => {
// #ifdef H5
if (proxy.$wx && app.isWechat()) {
proxy.$wx.scanQRCode({
needResult: 1, // 默认为0扫描结果由微信处理1则直接返回扫描结果
success: function(res) {
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
let data = JSON.parse(result)
uni.showLoading()
uni.request({
url: app.globalData.requestUrl + '/api/coin/getCoinInfo',
header: {
'Authorization': 'Bearer ' + app.globalData.token
},
data: data,
success: (res) => {
console.log(res.data)
if (res.data.code === 200) {
findCoinInfo.value = res.data.data
pFindcoin.value.open() // 发现硬币,进入认领流程
} else {
//说明参数不合法
uni.showToast({
title: res.data.msg,
icon: 'none'
})
}
},
complete: () => {
uni.hideLoading()
}
})
},
fail: function(err) {
console.log(err)
}
})
} else {
uni.showToast({
title: '使用扫一扫功能,请在微信客户端打开本页面',
icon: 'none'
})
}
// #endif
// #ifdef MP-WEIXIN
uni.scanCode({
scanType: 'qrCode',
success: function (res) {
let data = JSON.parse(res.result)
uni.showLoading()
uni.request({
url: app.globalData.requestUrl + '/api/coin/getCoinInfo',
header: {
'Authorization': 'Bearer ' + app.globalData.token
},
data: data,
success: (res) => {
console.log(res.data)
if (res.data.code === 200) {
findCoinInfo.value = res.data.data
pFindcoin.value.open() // 发现硬币,进入认领流程
} else {
//说明参数不合法
uni.showToast({
title: res.data.msg,
icon: 'none'
})
}
},
complete: () => {
uni.hideLoading()
}
})
}
});
// #endif
}
// 打开赏金任务弹窗
const openPopupTask = () => {
app.playAudio() // 点击音效
// #ifdef MP-WEIXIN
if (!app.globalData.token) {
uni.navigateTo({
url: '/pages/index/index'
})
return
}
// #endif
popupOpenState.value = true
pTask.value.open()
}
// 打开签到弹窗
const openPopupSignin = () => {
app.playAudio()
// #ifdef MP-WEIXIN
if (!app.globalData.token) {
uni.navigateTo({
url: '/pages/index/index'
})
return
}
// #endif
popupOpenState.value = true
pSign.value.open()
}
// 打开系统设置弹窗
const openPopupSetSystem = () => {
app.playAudio()
popupOpenState.value = true
pSetsystem.value.open()
}
// 打开踪迹弹窗
const openPopupTrace = () => {
app.playAudio()
// #ifdef MP-WEIXIN
if (!app.globalData.token) {
uni.navigateTo({
url: '/pages/index/index'
})
return
}
// #endif
popupOpenState.value = true
pTrace.value.open()
}
</script>
<!--这里引入分离的界面样式代码-->
<style scoped>
@import './game.css';
</style>