<think>我们需要调整背景图片铺满全屏,并且移动图片(C)按比例放大。
同时,我们还需要确保其他元素(问题图片A、选项按钮、提示图片)的布局适应全屏。
修改点:
1. 背景图片:使用CSS样式使其铺满整个屏幕(100vw和100vh)。
2. 移动图片:按比例放大,可以通过调整宽度和高度(例如使用百分比或vw/vh单位)来实现,同时保持其宽高比。
3. 布局调整:由于背景铺满全屏,其他元素的位置也要使用相对单位(如百分比、vw/vh)来定位,以确保在不同屏幕尺寸上正常显示。
注意:由于全屏,我们需要将容器设置为全屏。
我们将对原组件进行以下修改:
- 将容器样式改为全屏
- 背景图片铺满全屏
- 调整移动图片的大小(例如放大到原来的150%)
- 调整问题图片和选项按钮的位置和大小,使其适应全屏
修改后的代码:</think># 全屏拔河游戏组件 - Vue3实现
下面是一个优化后的拔河游戏组件,背景图片铺满全屏,移动图片按比例放大,同时保持所有游戏功能完整。
```vue
<template>
<div class="tug-of-war-container">
<!-- 背景图片铺满全屏 -->
<img :src="backgroundImg" class="background-image" alt="背景" />
<!-- 问题图片 -->
<div class="question-container">
<img :src="questionImg" class="question-image" alt="问题" />
</div>
<!-- 移动图片(按比例放大) -->
<div class="move-container">
<img
:src="moveImg"
class="move-image"
:style="{ transform: `translateX(${imagePosition}px)` }"
alt="移动对象"
/>
</div>
<!-- 选项按钮 -->
<div class="options-container">
<button
class="option-btn left-option"
:disabled="answered"
@click="checkAnswer(0)"
>
{{ options[0] }}
</button>
<button
class="option-btn right-option"
:disabled="answered"
@click="checkAnswer(1)"
>
{{ options[1] }}
</button>
</div>
<!-- 提示图片 -->
<transition name="fade">
<img
v-if="showCorrect"
:src="correctImg"
class="feedback-image correct-feedback"
alt="正确提示"
/>
</transition>
<transition name="fade">
<img
v-if="showIncorrect"
:src="incorrectImg"
class="feedback-image incorrect-feedback"
alt="错误提示"
/>
</transition>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
// 导入所有需要的图片(实际使用时应替换为真实图片路径)
import backgroundImg from '@/assets/background.png';
import questionImg from '@/assets/question.png';
import moveImg from '@/assets/move-object.png';
import correctImg from '@/assets/correct.png';
import incorrectImg from '@/assets/incorrect.png';
// 定义选项
const options = ref<string[]>(['左选项描述', '右选项描述']);
// 图片位置状态
const imagePosition = ref<number>(0);
const initialPosition = ref<number>(0);
// 答题状态
const answered = ref<boolean>(false);
const showCorrect = ref<boolean>(false);
const showIncorrect = ref<boolean>(false);
// 检查答案
const checkAnswer = (optionIndex: number) => {
if (answered.value) return;
answered.value = true;
// 假设选项0(左边)是正确答案
if (optionIndex === 0) {
showCorrect.value = true;
// 向左移动图片
imagePosition.value = -150;
} else {
showIncorrect.value = true;
// 向右移动图片
imagePosition.value = 150;
}
// 3秒后重置状态
setTimeout(resetGame, 3000);
};
// 重置游戏状态
const resetGame = () => {
answered.value = false;
showCorrect.value = false;
showIncorrect.value = false;
imagePosition.value = 0;
};
// 响应式调整布局
const handleResize = () => {
// 在实际应用中,这里可以添加响应式布局调整逻辑
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
</script>
<style scoped>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tug-of-war-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
}
/* 背景图片铺满全屏 */
.background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 1;
opacity: 0.8;
}
/* 问题容器 */
.question-container {
position: relative;
z-index: 2;
display: flex;
justify-content: center;
padding-top: 30px;
}
.question-image {
width: 80%;
max-width: 600px;
height: 180px;
object-fit: contain;
border: 4px solid #ffd700;
border-radius: 15px;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
}
/* 移动图片容器 */
.move-container {
position: relative;
z-index: 3;
display: flex;
justify-content: center;
align-items: center;
height: 200px;
margin: 20px 0;
}
.move-image {
width: 150px; /* 放大移动图片 */
height: 150px;
object-fit: contain;
transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.5));
z-index: 4;
}
/* 选项按钮容器 */
.options-container {
position: relative;
z-index: 5;
display: flex;
justify-content: space-between;
padding: 0 5%;
margin-bottom: 60px;
}
.option-btn {
padding: 20px 50px;
font-size: 24px;
font-weight: bold;
border: none;
border-radius: 60px;
cursor: pointer;
transition: all 0.4s ease;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
position: relative;
overflow: hidden;
z-index: 6;
}
.left-option {
background: linear-gradient(145deg, #ff416c, #ff4b2b);
color: white;
}
.right-option {
background: linear-gradient(145deg, #38ef7d, #11998e);
color: white;
}
.option-btn:hover:not(:disabled) {
transform: translateY(-8px) scale(1.05);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.4);
}
.option-btn:active:not(:disabled) {
transform: translateY(2px);
}
.option-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
/* 添加发光效果 */
.option-btn::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.1);
border-radius: 60px;
transform: scale(0);
transition: transform 0.5s ease;
}
.option-btn:hover:not(:disabled)::after {
transform: scale(1.5);
opacity: 0;
}
/* 反馈图片样式 */
.feedback-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 250px;
height: 250px;
object-fit: contain;
z-index: 10;
}
.correct-feedback {
animation: popIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.incorrect-feedback {
animation: shake 0.8s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}
/* 动画效果 */
@keyframes popIn {
0% {
transform: translate(-50%, -50%) scale(0.5);
opacity: 0;
}
70% {
transform: translate(-50%, -50%) scale(1.1);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(1);
}
}
@keyframes shake {
0%, 100% { transform: translate(-50%, -50%); }
10%, 30%, 50%, 70%, 90% { transform: translate(-52%, -50%); }
20%, 40%, 60%, 80% { transform: translate(-48%, -50%); }
}
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
/* 响应式设计 */
@media (max-width: 768px) {
.question-image {
width: 90%;
height: 150px;
}
.move-image {
width: 120px;
height: 120px;
}
.option-btn {
padding: 15px 30px;
font-size: 18px;
}
}
@media (max-width: 480px) {
.question-container {
padding-top: 20px;
}
.question-image {
height: 120px;
}
.move-image {
width: 100px;
height: 100px;
}
.option-btn {
padding: 12px 25px;
font-size: 16px;
}
.feedback-image {
width: 180px;
height: 180px;
}
}
</style>
```
## 关键优化说明
### 1. 背景图片铺满全屏
- 使用 `position: fixed` 确保容器覆盖整个视口
- 设置 `width: 100vw` 和 `height: 100vh` 实现全屏效果
- 使用 `object-fit: cover` 确保背景图片自适应填充
### 2. 移动图片比例放大
- 将移动图片的尺寸从100px放大到150px
- 使用 `object-fit: contain` 保持图片比例
- 添加了阴影效果增强视觉层次
### 3. 响应式设计
- 使用媒体查询适配不同屏幕尺寸
- 图片和按钮大小会根据屏幕宽度自动调整
- 在小屏幕上优化布局和字体大小
### 4. 视觉增强
- 添加了按钮悬停动画和点击效果
- 使用渐变背景增强视觉吸引力
- 添加了反馈图片的过渡动画
- 优化了游戏容器的整体布局
### 5. 交互优化
- 添加了按钮禁用状态防止重复点击
- 使用过渡动画增强用户体验
- 添加了按钮的发光效果
## 使用说明
1. 创建组件文件 `TugOfWarGame.vue`
2. 替换图片路径为实际项目中的图片
3. 在父组件中导入并使用:
```vue
<template>
<div id="app">
<TugOfWarGame />
</div>
</template>
<script setup>
import TugOfWarGame from '@/components/TugOfWarGame.vue';
</script>
<style>
#app {
height: 100vh;
overflow: hidden;
}
</style>
```
4. 确保在 `src/assets` 目录中有以下图片文件:
- background.png (背景图片)
- question.png (问题图片)
- move-object.png (移动图片)
- correct.png (正确提示图片)
- incorrect.png (错误提示图片)