数字拼图vue实现
Vue 实现数字拼图游戏
数字拼图是一种经典的滑块拼图游戏,玩家需要通过移动数字方块,将它们按顺序排列。以下是使用 Vue 3 实现数字拼图游戏的方法。
初始化项目
使用 Vue CLI 或 Vite 创建一个新的 Vue 项目。安装必要的依赖(如需要)。
npm create vue@latest vue-puzzle
cd vue-puzzle
npm install
游戏逻辑实现
创建一个 Vue 组件(如 PuzzleGame.vue),实现数字拼图的核心逻辑。
<template>
<div class="puzzle-container">
<div
v-for="(tile, index) in tiles"
:key="index"
class="tile"
:class="{ 'empty': tile === 0 }"
@click="moveTile(index)"
>
{{ tile !== 0 ? tile : '' }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
size: 4, // 4x4 拼图
tiles: [],
};
},
created() {
this.initGame();
},
methods: {
initGame() {
// 生成有序数组
const orderedTiles = Array.from({ length: this.size * this.size }, (_, i) => i);
// 打乱数组
this.tiles = this.shuffleArray(orderedTiles);
},
shuffleArray(array) {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
},
moveTile(index) {
const emptyIndex = this.tiles.indexOf(0);
const tileValue = this.tiles[index];
// 检查是否可以移动(是否与空白相邻)
if (this.isAdjacent(index, emptyIndex)) {
// 交换位置
this.tiles.splice(emptyIndex, 1, tileValue);
this.tiles.splice(index, 1, 0);
// 检查是否完成
if (this.checkWin()) {
alert('恭喜你完成了拼图!');
}
}
},
isAdjacent(index1, index2) {
const row1 = Math.floor(index1 / this.size);
const col1 = index1 % this.size;
const row2 = Math.floor(index2 / this.size);
const col2 = index2 % this.size;
return (
(Math.abs(row1 - row2) === 1 && col1 === col2) ||
(Math.abs(col1 - col2) === 1 && row1 === row2)
);
},
checkWin() {
for (let i = 0; i < this.tiles.length - 1; i++) {
if (this.tiles[i] !== i + 1) {
return false;
}
}
return this.tiles[this.tiles.length - 1] === 0;
},
},
};
</script>
<style>
.puzzle-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
width: 400px;
margin: 0 auto;
}
.tile {
height: 100px;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
cursor: pointer;
border-radius: 5px;
}
.tile.empty {
background-color: transparent;
cursor: default;
}
</style>
功能扩展
为游戏添加更多功能,如重新开始按钮、移动步数计数和难度选择。
<template>
<div class="game">
<h1>数字拼图</h1>
<div class="controls">
<button @click="initGame">重新开始</button>
<span>步数: {{ moves }}</span>
<select v-model="size" @change="initGame">
<option value="3">3x3</option>
<option value="4">4x4</option>
<option value="5">5x5</option>
</select>
</div>
<!-- 之前的拼图容器 -->
</div>
</template>
<script>
export default {
data() {
return {
size: 4,
tiles: [],
moves: 0,
};
},
methods: {
moveTile(index) {
const emptyIndex = this.tiles.indexOf(0);
if (this.isAdjacent(index, emptyIndex)) {
this.tiles.splice(emptyIndex, 1, this.tiles[index]);
this.tiles.splice(index, 1, 0);
this.moves++;
if (this.checkWin()) {
alert(`恭喜!你用 ${this.moves} 步完成了拼图!`);
}
}
},
// 其他方法保持不变
},
};
</script>
响应式设计
添加媒体查询使游戏在不同屏幕尺寸上都能良好显示。
@media (max-width: 500px) {
.puzzle-container {
width: 300px;
}
.tile {
height: 75px;
font-size: 18px;
}
}
动画效果
为方块的移动添加过渡动画,提升用户体验。
.tile {
transition: transform 0.2s ease;
}
.tile:not(.empty):hover {
transform: scale(1.05);
}
注意事项
- 确保打乱后的拼图有解(空白格在右下角时,逆序数应为偶数)
- 可以添加音效和更多视觉反馈增强游戏体验
- 考虑使用 Vuex 或 Pinia 管理复杂的状态
- 对于大型拼图(如 5x5),可能需要优化渲染性能
这个实现提供了数字拼图游戏的核心功能,可以根据需要进一步扩展和定制。






