diff --git a/src/pages/equipments/Equipments.vue b/src/pages/equipments/Equipments.vue index ad12a83..bad4c93 100644 --- a/src/pages/equipments/Equipments.vue +++ b/src/pages/equipments/Equipments.vue @@ -1,68 +1,274 @@ - diff --git a/src/pages/fishbaskets/Fishbaskets.vue b/src/pages/fishbaskets/Fishbaskets.vue index 4f41b9c..dd7782b 100644 --- a/src/pages/fishbaskets/Fishbaskets.vue +++ b/src/pages/fishbaskets/Fishbaskets.vue @@ -1,148 +1,342 @@ diff --git a/src/pages/fishing/Fishing.vue b/src/pages/fishing/Fishing.vue index a4629c6..9721ca8 100644 --- a/src/pages/fishing/Fishing.vue +++ b/src/pages/fishing/Fishing.vue @@ -2,7 +2,13 @@
-
+
@@ -52,6 +58,11 @@ const nextPullTime = ref(""); const isFishing = ref(false); const currentCatch = ref(null); const fishingLogs = ref([]); +const clickCount = ref(0); +const targetClicks = ref(0); +const isWaiting = ref(false); +const isReeling = ref(false); +const fishEscapeTimer = ref(null); // 从localStorage加载缓存的钓鱼日志 const loadCachedLogs = () => { @@ -66,20 +77,106 @@ const saveLogs = () => { localStorage.setItem("fishingLogs", JSON.stringify(fishingLogs.value)); }; +// 生成随机点击阈值(1-5秒内的随机次数) +const generateRandomTarget = () => { + return Math.floor(Math.random() * 15) + 5; // 5-20次随机点击 +}; + +// 生成随机等待时间(1-3秒) +const generateWaitTime = () => { + return Math.floor(Math.random() * 2000) + 1000; +}; + +// 生成随机逃跑概率(10%) +const willFishEscape = () => { + return Math.random() < 0.1; +}; + +// 生成随机提竿失败概率(20%) +const willReelFail = () => { + return Math.random() < 0.2; +}; + // 组件挂载时加载缓存的日志 onMounted(() => { loadCachedLogs(); }); -// 组件卸载前清除缓存 +// 组件卸载时清除定时器 onBeforeUnmount(() => { - localStorage.removeItem("fishingLogs"); + if (fishEscapeTimer.value) { + clearTimeout(fishEscapeTimer.value); + } }); const handleFish = async () => { + // 如果正在钓鱼中,不允许操作 if (isFishing.value) return; - isFishing.value = true; + // 第一阶段:开始钓鱼 + if (!isWaiting.value) { + isFishing.value = true; + resultMessage.value = "放下鱼竿,等待中..."; + + // 随机等待时间后判断是否有鱼上钩 + setTimeout(() => { + if (willFishEscape()) { + resultMessage.value = "鱼儿警觉地游走了..."; + ElMessage.info("鱼儿游走了 🐟"); + isFishing.value = false; + return; + } + + isWaiting.value = true; + clickCount.value = 0; + targetClicks.value = generateRandomTarget(); + resultMessage.value = "发现鱼儿上钩了!快点击收杆!"; + + // 设置逃跑计时器 + fishEscapeTimer.value = setTimeout(() => { + if (isWaiting.value) { + isWaiting.value = false; + isFishing.value = false; + resultMessage.value = "鱼儿挣脱逃走了!"; + ElMessage.warning("鱼儿逃走了 🎣"); + } + }, 5000); // 5秒内必须完成提竿 + }, generateWaitTime()); + return; + } + + // 增加点击计数并添加提竿动画效果 + clickCount.value++; + isReeling.value = true; + setTimeout(() => { + isReeling.value = false; + }, 200); + + // 如果点击次数未达到目标,更新提示信息 + if (clickCount.value < targetClicks.value) { + const remainingClicks = targetClicks.value - clickCount.value; + resultMessage.value = `继续点击!还需要${remainingClicks}次!`; + ElMessage.info(`还需点击${remainingClicks}次!`); + return; + } + + // 清除逃跑计时器 + if (fishEscapeTimer.value) { + clearTimeout(fishEscapeTimer.value); + fishEscapeTimer.value = null; + } + + // 第二阶段:达到目标点击次数,判断是否提竿成功 + isWaiting.value = false; + + if (willReelFail()) { + isFishing.value = false; + resultMessage.value = "提竿时机不对,鱼儿溜走了!"; + ElMessage.warning("提竿失败 🎣"); + return; + } + + // 调用钓鱼接口 currentCatch.value = null; resultMessage.value = "正在钓鱼中..."; @@ -168,6 +265,7 @@ const goHome = () => { background: #66b1ff; border-color: #66b1ff; } + .fishing-area { text-align: center; background: #fff; @@ -185,6 +283,7 @@ const goHome = () => { border-radius: 8px; background: #fff; cursor: pointer; + pointer-events: none; } .fishing-scene { @@ -195,12 +294,18 @@ const goHome = () => { left: 0; background: url("@/assets/fishing-scene.svg") no-repeat center; background-size: cover; + transition: transform 0.2s ease; + pointer-events: auto; } .fishing-active .fishing-scene { animation: scene-active 3s ease-in-out infinite; } +.reeling .fishing-scene { + animation: reel 0.2s ease-in-out; +} + .ripple { position: absolute; width: 30px; @@ -217,10 +322,6 @@ const goHome = () => { animation: ripple 2s infinite; } -.fishing-controls { - margin: 20px 0; -} - .result { margin-top: 20px; } @@ -245,4 +346,24 @@ const goHome = () => { transform: scale(1.02); } } + +@keyframes reel { + 0% { + transform: rotate(0deg); + } + 50% { + transform: rotate(-5deg); + } + 100% { + transform: rotate(0deg); + } +} + +.fishing-scene:active { + transform: scale(0.98); +} + +.fishing-animation:not(.fishing-active) .fishing-scene:hover { + transform: scale(1.02); +} diff --git a/src/pages/login/Login.vue b/src/pages/login/Login.vue index 55bc0f3..88e3026 100644 --- a/src/pages/login/Login.vue +++ b/src/pages/login/Login.vue @@ -1,279 +1,289 @@ - diff --git a/src/pages/main/Home.vue b/src/pages/main/Home.vue index b4114be..4e8cd18 100644 --- a/src/pages/main/Home.vue +++ b/src/pages/main/Home.vue @@ -1,131 +1,326 @@ diff --git a/src/pages/market/Market.vue b/src/pages/market/Market.vue index 54f7aeb..2077f15 100644 --- a/src/pages/market/Market.vue +++ b/src/pages/market/Market.vue @@ -1,162 +1,356 @@ diff --git a/src/pages/shop/Shop.vue b/src/pages/shop/Shop.vue index 3b3064d..c85826e 100644 --- a/src/pages/shop/Shop.vue +++ b/src/pages/shop/Shop.vue @@ -1,96 +1,301 @@ - diff --git a/src/style.css b/src/style.css index f691315..d0ff799 100644 --- a/src/style.css +++ b/src/style.css @@ -24,10 +24,9 @@ a:hover { body { margin: 0; - display: flex; - place-items: center; min-width: 320px; - min-height: 100vh; + height: 100vh; + overflow: hidden; } h1 { diff --git a/src/styles/variables.css b/src/styles/variables.css new file mode 100644 index 0000000..bb9f8cb --- /dev/null +++ b/src/styles/variables.css @@ -0,0 +1,35 @@ +:root { + /* 主题色 */ + --primary-color: #00d9ff; + --primary-light: #66b1ff; + --primary-dark: #0088cc; + + /* 背景色 */ + --bg-gradient-primary: linear-gradient(135deg, #001f3f 0%, #003366 100%); + --bg-gradient-secondary: linear-gradient(45deg, #0d47a1, #1976d2); + --bg-white: #ffffff; + --bg-light: #f5f7fa; + --bg-card: rgba(255, 255, 255, 0.1); + + /* 文字颜色 */ + --text-primary: #ffffff; + --text-secondary: rgba(255, 255, 255, 0.8); + --text-muted: rgba(255, 255, 255, 0.7); + --text-dark: #606266; + + /* 边框和阴影 */ + --border-color: rgba(255, 255, 255, 0.2); + --shadow-sm: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.25); + + /* 状态颜色 */ + --success-color: #67c23a; + --warning-color: #e6a23c; + --danger-color: #f56c6c; + --info-color: #909399; + + /* 特效 */ + --glow-primary: 0 0 10px rgba(0, 217, 255, 0.5); + --glow-secondary: 0 0 5px rgba(0, 217, 255, 0.3); +} \ No newline at end of file