Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fc-minigame
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈冲
fc-minigame
Commits
c6bf1726
Commit
c6bf1726
authored
Jun 29, 2026
by
陈冲
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修复
parent
1daec666
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
194 additions
and
39 deletions
+194
-39
Game.vue
frontend-h5/src/pages/game1/Game.vue
+5
-1
PlayingView.vue
frontend-h5/src/pages/game1/views/PlayingView.vue
+9
-3
Game.vue
frontend-h5/src/pages/game2/Game.vue
+15
-8
PlayingView.vue
frontend-h5/src/pages/game2/views/PlayingView.vue
+13
-2
Game3.vue
frontend-h5/src/pages/game3/Game3.vue
+8
-5
ScoreView.vue
frontend-h5/src/pages/game3/views/ScoreView.vue
+84
-3
Game4.vue
frontend-h5/src/pages/game4/Game4.vue
+4
-1
PlayingView.vue
frontend-h5/src/pages/game4/views/PlayingView.vue
+13
-1
Game5.vue
frontend-h5/src/pages/game5/Game5.vue
+3
-3
Game.vue
frontend-h5/src/pages/game6/Game.vue
+13
-6
PlayingView.vue
frontend-h5/src/pages/game6/views/PlayingView.vue
+26
-5
ScoreView.vue
frontend-h5/src/pages/game6/views/ScoreView.vue
+1
-1
No files found.
frontend-h5/src/pages/game1/Game.vue
View file @
c6bf1726
...
...
@@ -32,6 +32,7 @@ const wechat = $getWechat()
const
currentView
=
ref
<
GameView
>
(
'loading'
)
const
countdownInterval
=
ref
(
60
)
const
isDivDescVisible
=
ref
(
false
)
const
isGameEnded
=
ref
(
false
)
const
tick
=
ref
(
0
)
//点击次数
const
rank
=
ref
(
0
)
//排名
const
roomStatus
=
ref
(
0
)
...
...
@@ -141,6 +142,7 @@ function startGameCountdown(seconds = 60) {
countdownInterval
.
value
=
0
gameCountdownTimer
=
undefined
setDivDescVisible
(
false
)
isGameEnded
.
value
=
true
hasFinalScoreResult
.
value
=
false
submitScore
(
true
)
if
(
userTop10RankStatus
.
value
)
{
...
...
@@ -192,6 +194,7 @@ function startGameView() {
currentGuFrame
.
value
=
0
roomStatus
.
value
=
2
hasFinalScoreResult
.
value
=
false
isGameEnded
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
()
}
...
...
@@ -298,6 +301,7 @@ if (wechat) {
showGameRule
.
value
=
false
// showGameRank.value = false
roomStatus
.
value
=
2
isGameEnded
.
value
=
false
hasFinalScoreResult
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
(
...
...
@@ -363,7 +367,7 @@ const showGameRuleHandler = () => {
@
touchGameRule=
"showGameRuleHandler"
/>
<PlayingView
v-else-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"tick"
:rank=
"rank"
:current-gu-frame=
"currentGuFrame"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
touch=
"touchHandler"
:userTop10RankStatus=
"userTop10RankStatus"
/>
:is-div-desc-visible=
"isDivDescVisible"
:is-game-ended=
"isGameEnded"
@
touch=
"touchHandler"
:userTop10RankStatus=
"userTop10RankStatus"
/>
<ScoreView
v-else
:image-urls=
"imageUrls"
:rank=
"rank"
:tick=
"tick"
/>
</MobileStage>
<div
v-else
style=
"text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"
>
...
...
frontend-h5/src/pages/game1/views/PlayingView.vue
View file @
c6bf1726
<
script
setup
lang=
"ts"
>
defineProps
<
{
const
props
=
defineProps
<
{
imageUrls
:
Record
<
string
,
string
>
countdownInterval
:
number
isDivDescVisible
:
boolean
isGameEnded
?:
boolean
tick
:
number
rank
:
number
currentGuFrame
:
number
,
userTop10RankStatus
:
boolean
,
}
>
()
defineEmits
<
{
const
emit
=
defineEmits
<
{
touch
:
[]
}
>
()
function
handleTouch
()
{
if
(
props
.
isGameEnded
)
return
emit
(
'touch'
)
}
</
script
>
<
template
>
...
...
@@ -29,7 +35,7 @@ defineEmits<{
<!--
<div
v-if=
"!userTop10RankStatus"
>
当前排名:
第
<label></label>
名
</div>
-->
</div>
<div
class=
"bg-bottom"
></div>
<div
class=
"play-gu"
:style=
"
{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="
$emit('touch')
">
</div>
<div
class=
"play-gu"
:style=
"
{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="
handleTouch
">
</div>
</div>
</
template
>
...
...
frontend-h5/src/pages/game2/Game.vue
View file @
c6bf1726
...
...
@@ -5,10 +5,11 @@ import MobileStage from '@/components/MobileStage.vue'
import
{
useGameSocket
,
sendGameMessage
,
userJoinStatus
,
userTop10RankStatus
,
joinSharedRoom
}
from
'@/composables/useGameSocket'
import
LoadingView
from
'./views/LoadingView.vue'
import
PlayingView
from
'./views/PlayingView.vue'
import
ScoreView
from
'./views/ScoreView.vue'
import
{
$format_str
,
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
import
{
playGame2Music
,
stopAllMusic
}
from
'@/commons/music'
;
type
GameView
=
'loading'
|
'playing'
type
GameView
=
'loading'
|
'playing'
|
'score'
type
RankPlayer
=
{
rank
:
number
nickname
:
string
...
...
@@ -17,6 +18,8 @@ type RankPlayer = {
}
const
imageUrls
:
Record
<
string
,
string
>
=
{
avatar
:
cssAssetUrl
(
'avatar-yellow.png'
),
scoreBg
:
cssAssetUrl
(
'game1/score-bg.png'
),
bg
:
cssAssetUrl
(
'game2/bg.png'
),
logo
:
cssAssetUrl
(
'logo.png'
),
close
:
cssAssetUrl
(
'game1/close.png'
),
...
...
@@ -35,6 +38,7 @@ const wechat = $getWechat()
const
currentView
=
ref
<
GameView
>
(
'loading'
)
const
countdownInterval
=
ref
(
60
)
const
isDivDescVisible
=
ref
(
false
)
const
isGameEnded
=
ref
(
false
)
const
score
=
ref
(
0
)
const
rank
=
ref
(
0
)
//排名
const
roomStatus
=
ref
(
0
)
...
...
@@ -174,8 +178,8 @@ function startGameCountdown(seconds = 60) {
if
(
countdownInterval
.
value
<=
0
)
{
countdownInterval
.
value
=
0
gameCountdownTimer
=
undefined
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
isGameEnded
.
value
=
true
hasFinalScoreResult
.
value
=
false
submitScore
(
true
)
if
(
userTop10RankStatus
.
value
)
{
...
...
@@ -242,6 +246,7 @@ function startGameView() {
showGameRank
.
value
=
false
roomStatus
.
value
=
2
hasFinalScoreResult
.
value
=
false
isGameEnded
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
()
}
...
...
@@ -249,8 +254,8 @@ function startGameView() {
function
showGameOverRank
()
{
stopGameCountdown
()
setDivDescVisible
(
false
)
currentView
.
value
=
'
loading
'
showGameRank
.
value
=
tru
e
currentView
.
value
=
'
score
'
showGameRank
.
value
=
fals
e
userJoinStatus
.
value
=
false
;
}
...
...
@@ -276,7 +281,7 @@ if (wechat) {
//第一个游戏没有排行榜,只显示结果
showScoreView
();
rankList
.
value
=
data
;
showGameRank
.
value
=
tru
e
;
showGameRank
.
value
=
fals
e
;
},
onGameStart
:
async
()
=>
{
showGameRule
.
value
=
false
;
...
...
@@ -329,6 +334,7 @@ if (wechat) {
showGameRule
.
value
=
false
// showGameRank.value = false
roomStatus
.
value
=
2
isGameEnded
.
value
=
false
hasFinalScoreResult
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
(
...
...
@@ -352,7 +358,7 @@ function showScoreView() {
showGameRule
.
value
=
false
;
stopGameCountdown
()
setDivDescVisible
(
false
)
currentView
.
value
=
'
loading
'
currentView
.
value
=
'
score
'
}
onMounted
(()
=>
{
...
...
@@ -444,8 +450,9 @@ const rankCloseHandler = () => {
</
template
>
<LoadingView
v-if=
"currentView === 'loading'"
:image-urls=
"imageUrls"
:user-join-status=
"userJoinStatus"
@
touchGameRule=
"showGameRuleHandler"
/>
<PlayingView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
touch=
"touchHandler"
/>
<PlayingView
v-else-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
:is-game-ended=
"isGameEnded"
@
touch=
"touchHandler"
/>
<ScoreView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
/>
</MobileStage>
<div
v-else
style=
"text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"
>
请使用微信扫码进入游戏
...
...
frontend-h5/src/pages/game2/views/PlayingView.vue
View file @
c6bf1726
<
script
setup
lang=
"ts"
>
import
{
onBeforeUnmount
,
ref
}
from
'vue'
;
import
{
onBeforeUnmount
,
ref
,
watch
}
from
'vue'
;
import
{
isGameSocketConnected
}
from
'@/composables/useGameSocket'
;
defineProps
<
{
const
props
=
defineProps
<
{
imageUrls
:
Record
<
string
,
string
>
countdownInterval
:
number
isDivDescVisible
:
boolean
isGameEnded
?:
boolean
tick
:
number
rank
:
number
,
// currentGu: string
...
...
@@ -46,6 +47,7 @@ function normalizeAngle(angle: number) {
}
function
startRotation
(
event
:
PointerEvent
)
{
if
(
props
.
isGameEnded
)
return
if
(
activePointerId
!==
null
)
return
stopInertia
()
...
...
@@ -57,6 +59,7 @@ function startRotation(event: PointerEvent) {
}
function
rotateCoin
(
event
:
PointerEvent
)
{
if
(
props
.
isGameEnded
)
return
if
(
event
.
pointerId
!==
activePointerId
)
return
const
currentAngle
=
getPointerAngle
(
event
)
...
...
@@ -122,6 +125,14 @@ function startInertia() {
}
onBeforeUnmount
(
stopInertia
)
watch
(()
=>
props
.
isGameEnded
,
(
isEnded
)
=>
{
if
(
!
isEnded
)
return
activePointerId
=
null
clockwiseAngle
=
0
angularVelocity
=
0
stopInertia
()
})
</
script
>
<
template
>
...
...
frontend-h5/src/pages/game3/Game3.vue
View file @
c6bf1726
...
...
@@ -5,10 +5,11 @@ import MobileStage from '@/components/MobileStage.vue'
import
{
useGameSocket
,
joinSharedRoom
,
sendGameMessage
,
userJoinStatus
,
userTop10RankStatus
}
from
'@/composables/useGameSocket'
import
LoadingView
from
'./views/LoadingView.vue'
import
PlayingView
from
'./views/PlayingView.vue'
import
ScoreView
from
'./views/ScoreView.vue'
import
{
$getWechat
,
$toast
,
$is_run_local
}
from
'@/commons/utils.ts'
import
{
playGame3Music
,
stopAllMusic
}
from
'@/commons/music'
;
type
GameView
=
'loading'
|
'playing'
type
GameView
=
'loading'
|
'playing'
|
'score'
type
RankPlayer
=
{
rank
:
number
nickname
:
string
...
...
@@ -17,6 +18,8 @@ type RankPlayer = {
}
const
imageUrls
:
Record
<
string
,
string
>
=
{
avatar
:
cssAssetUrl
(
'avatar-yellow.png'
),
scoreBg
:
cssAssetUrl
(
'game1/score-bg.png'
),
bg
:
cssAssetUrl
(
'game3/bg.webp'
),
bg3
:
cssAssetUrl
(
'game3/bg3.webp'
),
left
:
cssAssetUrl
(
'game3/icon_zuo.webp'
),
...
...
@@ -192,7 +195,6 @@ function startGameCountdown(seconds = 60) {
if
(
countdownInterval
.
value
<=
0
)
{
countdownInterval
.
value
=
0
gameCountdownTimer
=
undefined
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
hasFinalScoreResult
.
value
=
false
submitScore
(
true
)
...
...
@@ -266,8 +268,8 @@ function startGameView() {
function
showGameOverRank
()
{
stopGameCountdown
()
setDivDescVisible
(
false
)
currentView
.
value
=
'
loading
'
showGameRank
.
value
=
tru
e
currentView
.
value
=
'
score
'
showGameRank
.
value
=
fals
e
userJoinStatus
.
value
=
false
if
(
isLocalMode
&&
!
wechat
)
{
console
.
log
(
'[game3 本地模式] 游戏结束,最终分数:'
,
score
.
value
)
...
...
@@ -477,8 +479,9 @@ const rankCloseHandler = () => {
</
template
>
<LoadingView
v-if=
"currentView === 'loading'"
:image-urls=
"imageUrls"
:user-join-status=
"userJoinStatus"
@
touchGameRule=
"showGameRuleHandler"
/>
<PlayingView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
<PlayingView
v-else
-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
touch=
"touchHandler"
@
score-change=
"scoreChangeHandler"
:userTop10RankStatus=
"userTop10RankStatus"
/>
<ScoreView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
/>
</MobileStage>
<div
v-else
style=
"text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"
>
请使用微信扫码进入游戏
...
...
frontend-h5/src/pages/game3/views/ScoreView.vue
View file @
c6bf1726
<
!-- <
script setup lang="ts">
<
script
setup
lang=
"ts"
>
import
{
$getWechat
}
from
'@/commons/utils'
;
import
{
onMounted
,
ref
}
from
'vue'
;
...
...
@@ -9,12 +9,13 @@ defineProps<{
}
>
()
defineEmits
<
{
showRank: []
replay
:
[]
back
:
[]
}
>
()
const
nickname
=
ref
(
''
);
const
avatar
=
ref
(
''
);
onMounted
(()
=>
{
const
wechat
=
$getWechat
();
nickname
.
value
=
wechat
.
nickname
;
...
...
@@ -25,6 +26,19 @@ onMounted(() => {
<
template
>
<div
class=
"h5-page game-stage"
>
<div
class=
"img-logo"
></div>
<div
class=
"bg-bottom"
></div>
<div
class=
"score-card"
>
<div
class=
"score-avatar"
:style=
"
{ backgroundImage: `url(${avatar})` }">
</div>
<div
class=
"score-content"
>
<div>
{{
nickname
}}
</div>
<div>
您的成绩
</div>
<div>
当前积分
</div>
<div>
{{
tick
}}
</div>
<div>
最终排名
</div>
<div
v-if=
"rank>0"
>
第
<label>
{{
rank
}}
</label>
名
</div>
<div
v-else
>
未上榜
</div>
</div>
</div>
</div>
</
template
>
...
...
@@ -36,6 +50,16 @@ onMounted(() => {
padding
:
0
;
}
.bg-bottom
{
position
:
absolute
;
bottom
:
0
;
left
:
var
(
--stage-viewport-left
,
0
);
width
:
var
(
--stage-viewport-width
,
750px
);
height
:
479px
;
background
:
v-bind
(
'imageUrls.bg2'
)
center
/
cover
;
opacity
:
0.6
;
}
.img-logo
{
position
:
absolute
;
top
:
66px
;
...
...
@@ -46,4 +70,61 @@ onMounted(() => {
transform
:
translateX
(
-50%
);
}
</style> -->
.score-card
{
position
:
absolute
;
top
:
450px
;
left
:
50%
;
width
:
465px
;
height
:
620px
;
border-radius
:
24px
;
background
:
rgba
(
255
,
255
,
255
,
0.92
);
transform
:
translateX
(
-50%
)
scale
(
1.2
);
}
.score-avatar
{
position
:
absolute
;
top
:
-50px
;
left
:
50%
;
width
:
132px
;
height
:
132px
;
border-radius
:
66px
;
background
:
center
/
cover
;
transform
:
translateX
(
-50%
);
}
.score-content
{
position
:
absolute
;
bottom
:
0
;
left
:
0
;
width
:
100%
;
height
:
calc
(
100%
-
100px
);
font-size
:
28pt
;
text-align
:
center
;
}
.score-content
>
div
:nth-child
(
1
)
{
color
:
#E00000
;
font-size
:
32pt
;
font-weight
:
bold
;
}
.score-content
>
div
:nth-child
(
2
)
{
margin-top
:
20px
;
font-size
:
32pt
;
}
.score-content
>
div
:nth-child
(
3
)
{
margin-top
:
40px
;
}
.score-content
>
div
:nth-child
(
4
)
{
margin-top
:
30px
;
color
:
#E00000
;
font-size
:
32pt
;
transform
:
scale
(
1.5
);
}
.score-content
>
div
:nth-child
(
5
)
{
margin-top
:
40px
;
}
</
style
>
frontend-h5/src/pages/game4/Game4.vue
View file @
c6bf1726
...
...
@@ -57,6 +57,7 @@ const stageBackground = computed(() => {
});
const
countdownInterval
=
ref
(
60
);
const
isDivDescVisible
=
ref
(
false
);
const
isGameEnded
=
ref
(
false
);
const
tick
=
ref
(
0
);
// 点击次数/摇动次数
const
rank
=
ref
(
0
);
// 排名
const
roomStatus
=
ref
(
0
)
...
...
@@ -161,6 +162,7 @@ function startGameCountdown(seconds = 60) {
countdownInterval
.
value
=
0
;
gameCountdownTimer
=
undefined
;
setDivDescVisible
(
false
);
isGameEnded
.
value
=
true
;
submitScore
(
true
);
if
(
userTop10RankStatus
.
value
)
{
userJoinStatus
.
value
=
false
;
...
...
@@ -214,6 +216,7 @@ function startGameView() {
stopGameCountdown
();
tick
.
value
=
0
;
currentHorse
.
value
=
imageUrls
.
horse
;
isGameEnded
.
value
=
false
;
currentView
.
value
=
"playing"
;
startGameCountdown
(
60
);
}
...
...
@@ -361,7 +364,7 @@ onBeforeUnmount(() => {
<!-- <PlayingView v-else :image-urls="imageUrls" :tick="tick" :rank="rank" -->
<PlayingView
v-else-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"tick"
:rank=
"rank"
:currentHorse=
"currentHorse"
:currentYaoyiyao=
"currentYaoyiyao"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
touch=
"touchHandler"
:is-div-desc-visible=
"isDivDescVisible"
:is-game-ended=
"isGameEnded"
@
touch=
"touchHandler"
:userTop10RankStatus=
"userTop10RankStatus"
/>
<ScoreView
v-else
:image-urls=
"imageUrls"
:tick=
"tick"
:level=
"rank"
@
replay=
"replayGame"
@
back=
"backToWaiting"
/>
</MobileStage>
...
...
frontend-h5/src/pages/game4/views/PlayingView.vue
View file @
c6bf1726
<
script
setup
lang=
"ts"
>
import
{
onBeforeUnmount
,
onMounted
,
ref
}
from
'vue'
import
{
onBeforeUnmount
,
onMounted
,
ref
,
watch
}
from
'vue'
import
{
assetUrl
}
from
'@/commons/assets'
const
shakeSound
=
assetUrl
(
'game4/yaoyiyao.mp3'
)
...
...
@@ -13,6 +13,7 @@ const props = defineProps<{
rank
:
number
currentHorse
:
string
currentYaoyiyao
:
string
,
isGameEnded
?:
boolean
userTop10RankStatus
:
boolean
}
>
()
...
...
@@ -125,6 +126,7 @@ const playShakeSound = () => {
}
const
handleDeviceMotion
=
(
ev
:
DeviceMotionEvent
)
=>
{
if
(
props
.
isGameEnded
)
return
const
nowTime
=
Date
.
now
()
const
motion
=
ev
.
accelerationIncludingGravity
if
(
!
motion
||
motion
.
x
===
null
)
return
...
...
@@ -213,12 +215,22 @@ onBeforeUnmount(() => {
// 点击马触发:iOS 先请求权限(不触发得分)
const
onTapHorse
=
async
()
=>
{
if
(
props
.
isGameEnded
)
return
if
(
!
motionPermissionGranted
)
{
await
requestMotionPermission
()
showIOSHint
.
value
=
false
}
}
watch
(()
=>
props
.
isGameEnded
,
(
isEnded
)
=>
{
if
(
!
isEnded
)
return
isYaoyiyaoShaking
.
value
=
false
if
(
yaoyiyaoShakeTimer
)
{
clearTimeout
(
yaoyiyaoShakeTimer
)
yaoyiyaoShakeTimer
=
null
}
})
</
script
>
<
template
>
...
...
frontend-h5/src/pages/game5/Game5.vue
View file @
c6bf1726
...
...
@@ -297,8 +297,8 @@ function startGameView() {
function
showGameOverRank
()
{
stopGameCountdown
()
setDivDescVisible
(
false
)
currentView
.
value
=
'
loading
'
showGameRank
.
value
=
tru
e
currentView
.
value
=
'
score
'
showGameRank
.
value
=
fals
e
}
...
...
@@ -465,7 +465,7 @@ const rankCloseHandler = () => {
<PlayingView
v-else-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"tick"
:rank=
"rank"
:current-gu=
"currentGu"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
hit=
"hitHandler"
/>
<
!-- <ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="tick" /> --
>
<
ScoreView
v-else
:image-urls=
"imageUrls"
:rank=
"rank"
:tick=
"tick"
/
>
</MobileStage>
<div
v-else
style=
"text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"
>
请使用微信扫码进入游戏
...
...
frontend-h5/src/pages/game6/Game.vue
View file @
c6bf1726
...
...
@@ -5,10 +5,11 @@ import MobileStage from '@/components/MobileStage.vue'
import
{
useGameSocket
,
sendGameMessage
,
userJoinStatus
,
userTop10RankStatus
,
joinSharedRoom
}
from
'@/composables/useGameSocket'
import
LoadingView
from
'./views/LoadingView.vue'
import
PlayingView
from
'./views/PlayingView.vue'
import
ScoreView
from
'./views/ScoreView.vue'
import
{
$format_str
,
$getWechat
,
$toast
}
from
'@/commons/utils.ts'
import
{
playGame6Music
,
stopAllMusic
}
from
'@/commons/music'
;
type
GameView
=
'loading'
|
'playing'
type
GameView
=
'loading'
|
'playing'
|
'score'
type
RankPlayer
=
{
rank
:
number
nickname
:
string
...
...
@@ -17,6 +18,8 @@ type RankPlayer = {
}
const
imageUrls
:
Record
<
string
,
string
>
=
{
avatar
:
cssAssetUrl
(
'avatar-yellow.png'
),
scoreBg
:
cssAssetUrl
(
'game1/score-bg.png'
),
bg
:
cssAssetUrl
(
'game6/bg.png'
),
logo
:
cssAssetUrl
(
'logo.png'
),
loadingBg1
:
cssAssetUrl
(
'game6/loadingbg1.png'
),
...
...
@@ -42,6 +45,7 @@ const wechat = $getWechat()
const
currentView
=
ref
<
GameView
>
(
'loading'
)
const
countdownInterval
=
ref
(
60
)
const
isDivDescVisible
=
ref
(
false
)
const
isGameEnded
=
ref
(
false
)
const
score
=
ref
(
0
)
const
rank
=
ref
(
0
)
//排名
const
roomStatus
=
ref
(
0
)
...
...
@@ -181,8 +185,8 @@ function startGameCountdown(seconds = 60) {
if
(
countdownInterval
.
value
<=
0
)
{
countdownInterval
.
value
=
0
gameCountdownTimer
=
undefined
currentView
.
value
=
'loading'
setDivDescVisible
(
false
)
isGameEnded
.
value
=
true
hasFinalScoreResult
.
value
=
false
submitScore
(
true
)
if
(
userTop10RankStatus
.
value
)
{
...
...
@@ -248,6 +252,7 @@ function startGameView() {
showGameRank
.
value
=
false
roomStatus
.
value
=
2
hasFinalScoreResult
.
value
=
false
isGameEnded
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
()
}
...
...
@@ -255,8 +260,8 @@ function startGameView() {
function
showGameOverRank
()
{
stopGameCountdown
()
setDivDescVisible
(
false
)
currentView
.
value
=
'
loading
'
showGameRank
.
value
=
tru
e
currentView
.
value
=
'
score
'
showGameRank
.
value
=
fals
e
userJoinStatus
.
value
=
false
;
}
...
...
@@ -335,6 +340,7 @@ if (wechat) {
showGameRule
.
value
=
false
showGameRank
.
value
=
false
roomStatus
.
value
=
2
isGameEnded
.
value
=
false
hasFinalScoreResult
.
value
=
false
currentView
.
value
=
'playing'
startGameCountdown
(
...
...
@@ -442,8 +448,9 @@ const rankCloseHandler = () => {
</
template
>
<LoadingView
v-if=
"currentView === 'loading'"
:image-urls=
"imageUrls"
:user-join-status=
"userJoinStatus"
@
touchGameRule=
"showGameRuleHandler"
/>
<PlayingView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
@
touch=
"touchHandler"
/>
<PlayingView
v-else-if=
"currentView === 'playing'"
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
:countdown-interval=
"countdownInterval"
:is-div-desc-visible=
"isDivDescVisible"
:is-game-ended=
"isGameEnded"
@
touch=
"touchHandler"
/>
<ScoreView
v-else
:image-urls=
"imageUrls"
:tick=
"score"
:rank=
"rank"
/>
</MobileStage>
<div
v-else
style=
"text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"
>
请使用微信扫码进入游戏
...
...
frontend-h5/src/pages/game6/views/PlayingView.vue
View file @
c6bf1726
<
script
setup
lang=
"ts"
>
import
{
onBeforeUnmount
,
onMounted
,
ref
}
from
'vue'
;
import
{
onBeforeUnmount
,
onMounted
,
ref
,
watch
}
from
'vue'
;
defineProps
<
{
const
props
=
defineProps
<
{
imageUrls
:
Record
<
string
,
string
>
countdownInterval
:
number
isDivDescVisible
:
boolean
isGameEnded
?:
boolean
tick
:
number
rank
:
number
}
>
()
...
...
@@ -41,6 +42,13 @@ for (let i = 0; i < 9; i++) {
let
spawnTimer
:
ReturnType
<
typeof
window
.
setTimeout
>
|
undefined
function
clearSpawnTimer
()
{
if
(
spawnTimer
)
{
window
.
clearTimeout
(
spawnTimer
)
spawnTimer
=
undefined
}
}
function
clearTargetTimer
(
item
:
TargetItem
)
{
if
(
item
.
timer
)
{
window
.
clearTimeout
(
item
.
timer
)
...
...
@@ -110,6 +118,9 @@ function spawnRandomTargets(duration = 1000) {
}
function
scheduleRandomTargets
()
{
if
(
props
.
isGameEnded
)
{
return
}
spawnRandomTargets
(
1000
)
spawnTimer
=
window
.
setTimeout
(
scheduleRandomTargets
,
1200
)
}
...
...
@@ -170,10 +181,20 @@ onMounted(() => {
scheduleRandomTargets
()
})
onBeforeUnmount
(()
=>
{
if
(
spawnTimer
)
{
window
.
clearTimeout
(
spawnTimer
)
watch
(()
=>
props
.
isGameEnded
,
(
isEnded
)
=>
{
if
(
!
isEnded
)
{
scheduleRandomTargets
()
return
}
clearSpawnTimer
()
for
(
const
item
of
list
.
value
)
{
resetTarget
(
item
.
id
)
}
})
onBeforeUnmount
(()
=>
{
clearSpawnTimer
()
for
(
const
item
of
list
.
value
)
{
clearTargetTimer
(
item
)
...
...
frontend-h5/src/pages/game6/views/ScoreView.vue
View file @
c6bf1726
...
...
@@ -34,7 +34,7 @@ onMounted(() => {
<div>
击鼓积分
</div>
<div>
{{
tick
}}
</div>
<div>
最终排名
</div>
<div
v-if=
"rank>0"
>
第
<label>
{{
rank
}}
</label>
名
</div>
<div
v-if=
"rank>0"
>
第
<label>
{{
rank
}}
</label>
名
</div>
<div
v-else
>
未上榜
</div>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment