Browse Source

添加游戏模块

st 2 months ago
parent
commit
68ec8b7f85

+ 82 - 16
src/pages/play/game.vue

@@ -43,12 +43,12 @@ const missSound = ref<UniApp.InnerAudioContext>()
 
 const audioSources = {
   bgm: {
-    1: '/static/audio/mzdhl.mp3',
-    2: '/static/audio/kn.mp3',
-    3: '/static/audio/M5000016XYcc2hEve0.mp3',
+    1: '/static/audio/play.mp3',
+    2: '/static/audio/play.mp3',
+    3: '/static/audio/play.mp3',
   },
   effects: {
-    miss: '/static/audio/missTS.mp3',
+    miss: '/static/audio/miss.mp3',
   },
 }
 
@@ -453,18 +453,32 @@ onUnmounted(() => {
     <!-- 加载遮罩和开始按钮 -->
     <view
       v-if="(isLoading || showStartButton) && !gameStarted"
-      class="fixed inset-0 bg-black/50 flex flex-col items-center justify-center z-50"
+      class="fixed inset-0 bg-black/50 flex flex-col items-center justify-center z-50 transition-all duration-300"
     >
       <template v-if="isLoading">
-        <view class="text-white text-xl mb-4">loading... {{ loadingProgress }}%</view>
+        <view class="text-white text-xl mb-4">
+          <view class="flex items-center">
+            <view class="loading-spinner mr-2"></view>
+            <text>loading... {{ loadingProgress }}%</text>
+          </view>
+        </view>
       </template>
 
       <template v-else-if="showStartButton && !gameStarted">
         <view
-          class="w-200rpx h-200rpx rounded-full bg-gradient-to-r from-green-400 to-blue-500 flex items-center justify-center text-white text-2xl font-bold shadow-lg cursor-pointer hover:scale-105 active:scale-95 transition-all duration-300 transform"
+          class="relative w-240rpx h-80rpx rounded-lg overflow-hidden flex items-center justify-center text-white font-bold shadow-lg cursor-pointer active:scale-95 transition-all duration-300 transform"
           @click="startGame"
+          style="background-color: #ffd700; box-shadow: 5px 5px 0px #000000"
         >
-          <text class="tracking-wider">START</text>
+          <text
+            class="text-3xl tracking-wider"
+            style="
+              font-family: 'Comic Sans MS', cursive, sans-serif;
+              text-shadow: 2px 2px 4px #000000;
+            "
+          >
+            START
+          </text>
         </view>
       </template>
     </view>
@@ -545,29 +559,71 @@ onUnmounted(() => {
         v-if="showCountdown"
         class="absolute top-1/3 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50"
       >
-        <text :class="['text-8xl font-bold countdown-animation', countdownClass]">
+        <text
+          :class="['text-8xl font-black relative z-10', countdownClass]"
+          :style="{
+            fontFamily: 'Comic Sans MS',
+            textShadow: '2px 2px 4px #000000',
+          }"
+        >
           {{ remainingTime }}
         </text>
       </view>
       <!-- 连击效果 -->
       <view class="w-100% z-100 absolute text-center">
-        <view class="flex flex-col" v-show="isContinuous && continuousData > 1">
+        <view class="flex flex-col items-center" v-show="isContinuous && continuousData > 1">
           <text
-            class="text-white text-[55rpx] fw-800 oblique"
-            :class="{ 'continuous-number': isContinuous }"
+            class="text-yellow-300 text-[60rpx] font-black"
+            :style="{
+              fontFamily: 'Comic Sans MS',
+              textShadow: '2px 2px 4px #000000',
+              transform: `scale(${1 + continuousData / 20})`,
+            }"
           >
             {{ continuousData }}
           </text>
-          <text class="text-white text-[50rpx] fw-800 oblique">continuous</text>
+          <text
+            class="text-white text-[40rpx] font-bold tracking-wider"
+            style="font-family: 'Impact', sans-serif"
+          >
+            COMBO
+          </text>
+          <view
+            class="w-40rpx h-40rpx rounded-full bg-yellow-400 absolute -top-10rpx -left-10rpx blur-[30rpx]"
+          ></view>
         </view>
 
-        <view v-show="isMiss" class="text-white text-[50rpx] fw-1000 oblique miss-text">MISS!</view>
+        <view
+          v-show="isMiss"
+          class="text-red-500 text-[80rpx] font-black tracking-widest relative z-10"
+          style="font-family: 'Impact', sans-serif"
+        >
+          <text
+            style="
+              font-family: 'Comic Sans MS', cursive, sans-serif;
+              text-shadow: '2px 2px 4px #000000';
+              font-size: 36rpx;
+            "
+          >
+            MISS!
+          </text>
+          <view
+            class="w-60rpx h-60rpx rounded-full bg-red-600 absolute -bottom-10rpx -right-10rpx blur-[30rpx]"
+          ></view>
+        </view>
 
         <text
           v-show="continuousData >= 8 && !isContinuous"
-          class="text-[50rpx] text fw-800 text-[italic]"
+          class="text-[60rpx] text-green-400 font-black tracking-wider relative z-10"
+          style="
+            font-family: 'Comic Sans MS', cursive, sans-serif;
+            text-shadow: '2px 2px 4px #000000';
+          "
         >
           Good!
+          <view
+            class="w-50rpx h-50rpx rounded-full bg-green-500 absolute -top-10rpx -right-10rpx blur-[30rpx]"
+          ></view>
         </text>
       </view>
 
@@ -580,6 +636,8 @@ onUnmounted(() => {
           :style="{
             left: `${getLanePosition(note.lane) - 25}rpx`,
             top: `${note.position}rpx`,
+            opacity: 1 - Math.max(0, (note.position - 200) / 800), // 模拟景深效果
+            transform: `scale(${1 + Math.max(0, (100 - note.position) / 200)})`, // 模拟弹跳效果
           }"
         >
           <image :src="`/static/images/play/${note.type}.png`" class="w-92rpx h-150rpx" />
@@ -747,12 +805,20 @@ onUnmounted(() => {
 
 // 添加加载动画
 @keyframes spin {
-  to {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
     transform: rotate(360deg);
   }
 }
 
 .loading-spinner {
+  width: 24rpx;
+  height: 24rpx;
+  border: 4rpx solid #ccc;
+  border-radius: 50%;
+  border-top-color: #333;
   animation: spin 1s linear infinite;
 }
 

BIN
src/static/audio/M5000016XYcc2hEve0.mp3


BIN
src/static/audio/kn.mp3


BIN
src/static/audio/miss.mp3


BIN
src/static/audio/missTS.mp3


BIN
src/static/audio/mzdhl.mp3


BIN
src/static/audio/play.mp3


+ 5 - 88
src/types/auto-import.d.ts

@@ -97,7 +97,7 @@ declare global {
 // for type re-export
 declare global {
   // @ts-ignore
-  export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
+  export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
   import('vue')
 }
 // for vue template auto import
@@ -161,6 +161,7 @@ declare module 'vue' {
     readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
     readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
     readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
+    readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
     readonly provide: UnwrapRef<typeof import('vue')['provide']>
     readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
     readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
@@ -178,97 +179,13 @@ declare module 'vue' {
     readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
     readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
     readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
+    readonly useId: UnwrapRef<typeof import('vue')['useId']>
     readonly useImgPath: UnwrapRef<typeof import('../hooks/useImgPath')['useImgPath']>
+    readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
     readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
     readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
     readonly useTelegramBackButton: UnwrapRef<typeof import('../hooks/useTelegramBackButton')['useTelegramBackButton']>
-    readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
-    readonly watch: UnwrapRef<typeof import('vue')['watch']>
-    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
-    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
-    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
-  }
-}
-declare module '@vue/runtime-core' {
-  interface GlobalComponents {}
-  interface ComponentCustomProperties {
-    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
-    readonly computed: UnwrapRef<typeof import('vue')['computed']>
-    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
-    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
-    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
-    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
-    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
-    readonly formatAmount: UnwrapRef<typeof import('../hooks/moneyProcessing')['formatAmount']>
-    readonly formatAmountNoFloat: UnwrapRef<typeof import('../hooks/moneyProcessing')['formatAmountNoFloat']>
-    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
-    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
-    readonly h: UnwrapRef<typeof import('vue')['h']>
-    readonly inject: UnwrapRef<typeof import('vue')['inject']>
-    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
-    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
-    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
-    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
-    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
-    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
-    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
-    readonly onAddToFavorites: UnwrapRef<typeof import('@dcloudio/uni-app')['onAddToFavorites']>
-    readonly onBackPress: UnwrapRef<typeof import('@dcloudio/uni-app')['onBackPress']>
-    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
-    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
-    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
-    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
-    readonly onError: UnwrapRef<typeof import('@dcloudio/uni-app')['onError']>
-    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
-    readonly onHide: UnwrapRef<typeof import('@dcloudio/uni-app')['onHide']>
-    readonly onLaunch: UnwrapRef<typeof import('@dcloudio/uni-app')['onLaunch']>
-    readonly onLoad: UnwrapRef<typeof import('@dcloudio/uni-app')['onLoad']>
-    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
-    readonly onNavigationBarButtonTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap']>
-    readonly onNavigationBarSearchInputChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged']>
-    readonly onNavigationBarSearchInputClicked: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked']>
-    readonly onNavigationBarSearchInputConfirmed: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed']>
-    readonly onNavigationBarSearchInputFocusChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged']>
-    readonly onPageNotFound: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageNotFound']>
-    readonly onPageScroll: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageScroll']>
-    readonly onPullDownRefresh: UnwrapRef<typeof import('@dcloudio/uni-app')['onPullDownRefresh']>
-    readonly onReachBottom: UnwrapRef<typeof import('@dcloudio/uni-app')['onReachBottom']>
-    readonly onReady: UnwrapRef<typeof import('@dcloudio/uni-app')['onReady']>
-    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
-    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
-    readonly onResize: UnwrapRef<typeof import('@dcloudio/uni-app')['onResize']>
-    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
-    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
-    readonly onShareAppMessage: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareAppMessage']>
-    readonly onShareTimeline: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareTimeline']>
-    readonly onShow: UnwrapRef<typeof import('@dcloudio/uni-app')['onShow']>
-    readonly onTabItemTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onTabItemTap']>
-    readonly onThemeChange: UnwrapRef<typeof import('@dcloudio/uni-app')['onThemeChange']>
-    readonly onUnhandledRejection: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnhandledRejection']>
-    readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
-    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
-    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
-    readonly provide: UnwrapRef<typeof import('vue')['provide']>
-    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
-    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
-    readonly ref: UnwrapRef<typeof import('vue')['ref']>
-    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
-    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
-    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
-    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
-    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
-    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
-    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
-    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
-    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
-    readonly unref: UnwrapRef<typeof import('vue')['unref']>
-    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
-    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
-    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
-    readonly useImgPath: UnwrapRef<typeof import('../hooks/useImgPath')['useImgPath']>
-    readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
-    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
-    readonly useTelegramBackButton: UnwrapRef<typeof import('../hooks/useTelegramBackButton')['useTelegramBackButton']>
+    readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
     readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
     readonly watch: UnwrapRef<typeof import('vue')['watch']>
     readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>