Skip to content

Commit 991f111

Browse files
committed
Merge branch 'dev'
2 parents 20e0dba + 52f4bba commit 991f111

File tree

8 files changed

+79
-36
lines changed

8 files changed

+79
-36
lines changed

public/assets/question.png

1.28 KB
Loading

src/App.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const goToBoothsList = () => {
1313
router.push({ path: '/booths', query: { token: token.value } })
1414
}
1515
16-
const scanQRCode = () => {
17-
router.push({ path: '/qrcode-scanner', query: { token: token.value } })
16+
const showMyQrCode = () => {
17+
router.push({path: '/my-qrcode',query: { token: token.value } })
1818
}
1919
2020
const goToProfile = () => {
@@ -42,9 +42,9 @@ provide('token', token)
4242
<span>遊戲畫面</span>
4343
</button>
4444

45-
<button class="button button-qrcode" v-else @click="scanQRCode">
46-
<Icon icon="tabler:scan" class="icon" />
47-
<span>掃描 QR Code</span>
45+
<button class="button button-qrcode" v-else @click="showMyQrCode">
46+
<Icon icon="tabler:qrcode" class="icon"></Icon>
47+
<span>顯示 QR Code</span>
4848
</button>
4949

5050
<button class="button button-profile" @click="goToProfile">

src/components/PhaserGame.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const popupData = ref()
2020
const comments = ref()
2121
const newMessage = ref('')
2222
const renderer = new marked.Renderer()
23+
const tutorialRef = ref()
2324
renderer.link = function ({href, title, text}) {
2425
return `<a href="${href}" target="_blank">${text}</a>`
2526
}
@@ -45,9 +46,13 @@ onMounted(async () => {
4546
showPopup.value = true
4647
})
4748
48-
EventBus.on('add-new-hextile', (boothId: string) => {
49+
EventBus.on('add-new-hextile', (boothId: string) => {
4950
scene.value.addNextHexTile(boothId);
50-
});
51+
})
52+
53+
EventBus.on('show-tutorial', () => {
54+
tutorialRef.value?.startTutorial()
55+
})
5156
})
5257
5358
onUnmounted(() => {
@@ -142,7 +147,7 @@ watch([showPopup, popupData], async ([isOpen, data]) => {
142147
</script>
143148

144149
<template>
145-
<Tutorial v-if="scene" :scene="scene"/>
150+
<Tutorial ref="tutorialRef" v-if="scene" :scene="scene" />
146151
<div id="game-container" :style="{ bottom: `${GameData.bottomBarHeight}px` }" />
147152
<div class="popup-overlay" id="popup" v-if="showPopup">
148153
<div class="popup-content">

src/components/QRCodeScanner.vue renamed to src/components/QRCode.vue

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import { Icon } from '@iconify/vue'
77
import { EventBus } from '../game/EventBus'
88
99
const route = useRoute()
10-
const router = useRouter()
10+
const router = useRouter()
1111
const token = computed(() => route.query.token)
12-
const showMyQrCode = ref(false)
12+
const showMyQrCode = ref(true)
1313
1414
const onDetect = (decodedText: string) => {
1515
const boothToken = decodedText[0].rawValue
@@ -20,24 +20,24 @@ const onDetect = (decodedText: string) => {
2020

2121
<template>
2222
<div class="qr-scanner-container">
23-
<div v-if="!showMyQrCode" class="qr-code-scanner">
24-
<qrcode-stream @detect="onDetect"></qrcode-stream>
25-
</div>
26-
<div v-show="showMyQrCode" class="my-qr-code-container" @click.stop="showMyQrCode = false">
23+
<div v-if="showMyQrCode" class="my-qr-code-container">
2724
<div class="my-qr-code">
2825
<qrcode-vue :value="token" :size="250" />
2926
</div>
30-
<p class="qrcode-instruction">點擊任意處回到掃描畫面</p>
3127
</div>
28+
29+
<div v-else class="qr-code-scanner">
30+
<qrcode-stream @detect="onDetect"></qrcode-stream>
31+
</div>
32+
3233
<button class="show-my-qr-button" @click="showMyQrCode = !showMyQrCode">
33-
<Icon icon="tabler:qrcode" class="qr-code-icon"></Icon>
34-
<span>顯示行動條碼</span>
34+
<Icon :icon="showMyQrCode ? 'tabler:scan' : 'tabler:qrcode'" class="button-icon"></Icon>
35+
<span>{{ showMyQrCode ? '掃描 QR Code' : '顯示 QR Code' }}</span>
3536
</button>
3637
</div>
3738
</template>
3839

3940
<style scoped>
40-
4141
.qr-scanner-container {
4242
position: fixed;
4343
top: 0;
@@ -61,7 +61,6 @@ const onDetect = (decodedText: string) => {
6161
width: 90vw;
6262
aspect-ratio: 1 / 1;
6363
z-index: 100;
64-
6564
border: 10px solid #f30000;
6665
}
6766
@@ -115,9 +114,10 @@ const onDetect = (decodedText: string) => {
115114
justify-content: center;
116115
font-size: 1em;
117116
gap: 5px;
117+
-webkit-tap-highlight-color: transparent;
118118
}
119119
120-
.qr-code-icon {
120+
.button-icon {
121121
width: 20px;
122122
height: 20px;
123123
}

src/components/Tutorial.vue

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,29 @@ const images = ref<HTMLImageElement[]>([])
1111
onMounted(() => {
1212
const seen = localStorage.getItem("hasSeenTutorial")
1313
if (!seen) {
14-
show.value = true
15-
props.scene.input.enabled = false
16-
for (let i = 1; i <= total; i++) {
17-
const img = new Image()
18-
img.onload = () => {
19-
console.log(`Tutorial image ${i} loaded.`)
20-
}
21-
img.src = `/assets/tutorial-${i}.png`
22-
images.value.push(img)
23-
}
14+
startTutorial()
2415
}
2516
})
2617
18+
defineExpose({
19+
startTutorial
20+
})
21+
22+
function startTutorial() {
23+
page.value = 0
24+
show.value = true
25+
props.scene.input.enabled = false
26+
images.value = []
27+
for (let i = 1; i <= total; i++) {
28+
const img = new Image()
29+
img.onload = () => {
30+
console.log(`Tutorial image ${i} loaded.`)
31+
}
32+
img.src = `/assets/tutorial-${i}.png`
33+
images.value.push(img)
34+
}
35+
}
36+
2737
function nextPage() {
2838
if (page.value < total - 1) {
2939
const nextImage = images.value[page.value + 1]

src/config/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
22
import PhaserGame from '../components/PhaserGame.vue'
33
import BoothsList from '../components/BoothsList.vue'
4-
import QRCodeScanner from '../components/QRCodeScanner.vue'
4+
import MyQRcode from '../components/QRCode.vue'
55
import MyProfile from '../components/MyProfile.vue'
66

77
const routes: Array<RouteRecordRaw> = [
@@ -16,9 +16,9 @@ const routes: Array<RouteRecordRaw> = [
1616
component: BoothsList
1717
},
1818
{
19-
path: '/qrcode-scanner',
20-
name: 'qrcode-scanner',
21-
component: QRCodeScanner,
19+
path: '/my-qrcode',
20+
name: 'my-qrcode',
21+
component: MyQRcode,
2222
},
2323
{
2424
path: '/profile',

src/data/AchievementsData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ export const achievements: Medal[] = [
1010
{ id: 2, icon: 'mdi:account-group', name: '開始融入', unlocked: false }, // 聊天室發 8 則留言
1111
{ id: 3, icon: 'mdi:forum', name: '意見領袖', unlocked: false }, // 聊天室發 20 則留言
1212

13-
{ id: 10, icon: 'mingcute:sunrise-fill', name: '早起的鳥兒有蟲吃', unlocked: false }, // 參與第一天或第二天的開幕
13+
{ id: 10, icon: 'mingcute:sunrise-fill', name: '早起的鳥兒有蟲吃', unlocked: false }, // 參與第一天的開幕
1414
{ id: 11, icon: 'mdi:flag-checkered', name: '最後一哩路', unlocked: false }, // 參與第一天的閉幕
15-
{ id: 12, icon: 'mdi:infinity', name: '有始有終', unlocked: false }, // 參與開幕與閉幕
15+
{ id: 12, icon: 'mdi:infinity', name: '有始有終', unlocked: false }, // 參與第二天的開幕
1616
// 贊助攤位 12 個社群攤位 32 個共 44 個,教室 25 間,共 69 個板塊
1717
{ id: 13, icon: 'mdi:foot-print', name: '第一哩路', unlocked: false }, // 獲得 1 個板塊
1818
{ id: 14, icon: 'mdi:map-marker-multiple', name: '攻城掠地', unlocked: false }, // 獲得 20 個板塊

src/game/scenes/Game.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class Game extends Scene {
2727
})
2828
this.load.image('eye', '/assets/eye.png')
2929
this.load.image('no-eye', '/assets/no-eye.png')
30+
this.load.image('question', '/assets/question.png')
3031
let playerCharacterPath = localStorage.getItem('playerCharacter');
3132

3233
if (!playerCharacterPath) {
@@ -177,6 +178,33 @@ export class Game extends Scene {
177178
}
178179
})
179180

181+
const canvas2 = this.textures.createCanvas('tutorial-button', canvaSize, canvaSize)
182+
const ctx2 = canvas2!.getContext()
183+
184+
// set button background
185+
ctx2.fillStyle = '#ffffff'
186+
ctx2.beginPath()
187+
ctx2.arc(canvaSize / 2, canvaSize / 2, buttonSize / 2 - 5, 0, Math.PI * 2)
188+
ctx2.fill()
189+
190+
// add button shadow
191+
ctx2.shadowColor = 'rgba(0, 0, 0, 0.3)'
192+
ctx2.shadowBlur = 10
193+
ctx2.shadowOffsetX = 4
194+
ctx2.shadowOffsetY = 4
195+
ctx2.fill()
196+
197+
canvas2!.refresh()
198+
199+
this.add.image(GameData.screenWidth - 40, 110, 'tutorial-button').setOrigin(0.5)
200+
201+
const tutorialBtn = this.add.image(GameData.screenWidth - 40, 110, 'question').setOrigin(0.5).setScale(0.5).setInteractive()
202+
tutorialBtn.setScrollFactor(0)
203+
204+
tutorialBtn.on('pointerup', () => {
205+
EventBus.emit('show-tutorial')
206+
})
207+
180208
EventBus.emit('current-scene-ready', this)
181209
}
182210

0 commit comments

Comments
 (0)