主页 > 其他  > 

vue2+element-ui开发网站拼图小游戏-前端项目

vue2+element-ui开发网站拼图小游戏-前端项目

我们在学习前端开发的时候,除了要学习基础编程知识,也需要项目来练习我们所学的编程知识,让我们学的知识有更深的体会,这样才可以做到学以致用。 最近在学习前端开发,除了学习 html css js 这些基础知识以为 ,也开始学习 vue2 的相关知识,今天就分享一个 使用 vue2 和 element-ui 组件 开发的一个网站拼图小游戏项目。我觉得这个项目是非常有意思的,但是我发现 这个小游戏 能过到第10关 还是有一定难度的。 先给大家分享一下使用的技术: 前端框架:Vue2 UI 组件库:Element-UI(提供交互组件,如按钮、弹窗等) 编程语言:HTML、CSS、JavaScript node版本: 16.20 构建与部署:支持 Nginx 或静态服务器部署

接下来给大家看一下 这个拼图游戏的样子

先简单的介绍一下 这个游戏的规则 : 拼图游戏共 十关,每一关的拼图难度逐步增加: 第 1 关:2×2 拼图 第 2 关:3×3 拼图 第 3 关:4×4 拼图 第 4 关:5×5 拼图 第 5 关:6×6 拼图 第 6 关:7×7 拼图 第 7 关:8×8 拼图 第 8 关:9×9 拼图 第 9 关:10×10 拼图 第 10 关:11×11 拼图 游戏通过 打乱图片顺序 让玩家进行拼接,玩家需要拖拽或点击来移动拼图块,直到完整还原原始图片。随着关卡的提升,拼图块的数量增加,挑战难度逐步加大。 功能特点: 逐级解锁:必须完成当前关卡,才能进入下一关。 随机打乱拼图:每次挑战都充满新鲜感。 计时功能:可统计玩家完成每一关所用时间,增加挑战性。

好了,大概的网站样子已经分享完了。接下来 看一下项目的目录结构 项目目录结构还是比较简单的,实际一共做了两个页面 , 一个开始页面:

<template> <div class="home"> <div class="container"> <h1 class="title">拼图十关</h1> <div class="card game-levels"> <h2>关卡选择</h2> <p class="level-description">从简单到困难,挑战10个精彩关卡!</p> <div class="levels-grid"> <div v-for="level in 10" :key="level" class="level-item" :class="{ active: level === currentLevel, locked: level > highestLevel }" @click="selectLevel(level)" > <div class="level-content"> <span class="level-number">{{ level }}</span> <div class="level-preview"> <img :src="getImageForLevel(level)" alt="关卡预览" /> <div class="level-difficulty">{{ getDifficultyText(level) }}</div> </div> <div class="level-status"> <i v-if="level > highestLevel" class="el-icon-lock"></i> <i v-else-if="level < currentLevel" class="el-icon-check"></i> <i v-else class="el-icon-right"></i> </div> </div> </div> </div> <div class="level-actions"> <el-button type="primary" @click="startGame" :disabled="currentLevel > highestLevel"> 开始游戏 </el-button> </div> </div> </div> </div> </template> <script> import { mapGetters } from 'vuex' export default { name: 'Home', data() { return { currentLevel: 1, gameImages: [ require('@/assets/images/1.jpeg'), require('@/assets/images/2.jpeg'), require('@/assets/images/3.jpeg'), require('@/assets/images/4.jpeg'), require('@/assets/images/5.jpeg'), require('@/assets/images/6.jpeg'), require('@/assets/images/7.jpeg'), require('@/assets/images/8.jpeg'), require('@/assets/images/9.jpeg'), require('@/assets/images/10.jpeg') ] } }, computed: { ...mapGetters([ 'getHighestLevel' ]), highestLevel() { return this.getHighestLevel } }, created() { // 初始化应用,加载最高关卡 this.$store.dispatch('initApp') }, methods: { selectLevel(level) { // 只能选择已解锁的关卡 if (level <= this.highestLevel) { this.currentLevel = level } }, startGame() { // 初始化游戏,设置当前关卡 this.$store.dispatch('initGame', { level: this.currentLevel }) // 跳转到游戏页面 this.$router.push('/game') }, getImageForLevel(level) { return this.gameImages[level - 1] }, getDifficultyText(level) { const difficulty = level + 1 return `${difficulty}×${difficulty}` } } } </script> <style lang="scss" scoped> .home { height: 100vh; display: flex; align-items: center; justify-content: center; background-color: #f5f7fa; } .container { width: 100%; max-width: 900px; padding: 20px; } .title { font-size: 36px; margin-bottom: 30px; color: #303133; text-align: center; } .game-levels { width: 100%; h2 { margin-bottom: 10px; color: #303133; text-align: center; } .level-description { text-align: center; color: #606266; margin-bottom: 30px; } } .levels-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px; margin-bottom: 30px; @media (max-width: 768px) { grid-template-columns: repeat(3, 1fr); } @media (max-width: 480px) { grid-template-columns: repeat(2, 1fr); } } .level-item { border-radius: 8px; overflow: hidden; cursor: pointer; border: 2px solid #dcdfe6; transition: all 0.3s ease; &.active { border-color: #409EFF; transform: scale(1.05); box-shadow: 0 0 10px rgba(64, 158, 255, 0.5); } &.locked { opacity: 0.7; cursor: not-allowed; filter: grayscale(50%); } .level-content { position: relative; display: flex; flex-direction: column; height: 100%; } .level-number { position: absolute; top: 5px; left: 5px; background-color: rgba(0, 0, 0, 0.7); color: white; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; z-index: 1; } .level-preview { position: relative; width: 100%; padding-bottom: 100%; img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } .level-difficulty { position: absolute; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 4px; font-size: 12px; text-align: center; } } .level-status { padding: 8px; text-align: center; background-color: #f5f7fa; i { font-size: 16px; } .el-icon-check { color: #67C23A; } .el-icon-lock { color: #909399; } .el-icon-right { color: #409EFF; } } } .level-actions { display: flex; justify-content: center; .el-button { width: 200px; } } </style>

一个玩游戏的页面:

<template> <div class="game-page"> <!-- 左侧区域 --> <div class="left-section"> <!-- 原图预览 --> <div class="preview-container"> <h3>原图预览</h3> <div class="preview-image"> <img :src="imageUrl" alt="拼图预览" /> </div> </div> <!-- 碎片区域 --> <div class="pieces-container"> <h3>拼图碎片</h3> <div class="pieces-area" ref="piecesArea"></div> </div> </div> <!-- 右侧区域 --> <div class="right-section"> <!-- 游戏信息和控制 --> <div class="game-header"> <h2>拼图游戏</h2> <div class="level-badge">第 {{ currentLevel }} 关</div> <div class="game-info"> <div class="info-item"> <span class="info-label">关卡:</span> <span class="info-value">{{ currentLevel }}/10</span> </div> <div class="info-item"> <span class="info-label">难度:</span> <span class="info-value">{{ difficulty }}×{{ difficulty }}</span> </div> <div class="info-item"> <span class="info-label">时间:</span> <span class="info-value">{{ formatTime }}</span> </div> <div class="info-item"> <span class="info-label">步数:</span> <span class="info-value">{{ moves }}</span> </div> </div> <div class="game-controls"> <el-button type="warning" @click="togglePause" v-if="gameStatus === 'playing' || gameStatus === 'paused'" > {{ gameStatus === 'playing' ? '暂停' : '继续' }} </el-button> <el-button type="danger" @click="resetGame">重置</el-button> <el-button @click="backToHome">返回首页</el-button> </div> <div class="game-instructions"> <p>游戏说明:将左侧的拼图碎片拖放到右侧的目标区域中,完成拼图。</p> <p class="tip"><i class="el-icon-back"></i> <strong>重要提示:</strong>已放置的碎片<span style="color: #F56C6C; font-weight: bold;">只能通过点击取回</span>,不能拖动到其他位置</p> </div> </div> <!-- 目标区域(凹槽) --> <div class="target-container"> <div class="target-area" ref="targetArea"> <template v-if="gameStatus === 'idle'"> <div class="loading-overlay"> <i class="el-icon-loading"></i> <p>正在加载游戏...</p> </div> </template> <template v-else-if="gameStatus === 'paused'"> <div class="paused-overlay"> <i class="el-icon-video-pause"></i> <p>游戏已暂停</p> <el-button type="primary" @click="togglePause">继续游戏</el-button> </div> </template> </div> <!-- 游戏完成覆盖层 --> <div class="completed-overlay" v-if="gameStatus === 'completed'"> <i :class="isLastLevel && currentLevel === 10 ? 'el-icon-medal' : 'el-icon-trophy'"></i> <h2 v-if="isLastLevel && currentLevel === 10">恭喜你通关成功!</h2> <h2 v-else>恭喜你完成了第{{ currentLevel }}关!</h2> <p class="level-message">{{ levelCompleteMessage }}</p> <p>用时: {{ formatTime }}</p> <p>步数: {{ moves }}</p> <div class="action-buttons"> <el-button type="primary" @click="nextLevel" v-if="!isLastLevel">下一关</el-button> <el-button type="success" @click="resetGame" v-if="isLastLevel">再玩一次</el-button> <el-button @click="backToHome">返回首页</el-button> </div> </div> <!-- 拼图错误覆盖层 --> <div class="incorrect-overlay" v-if="gameStatus === 'incorrect'"> <i class="el-icon-warning-outline"></i> <h2>拼图似乎有些问题...</h2> <p class="error-message">{{ errorMessage }}</p> <div class="action-buttons"> <el-button type="primary" @click="continueGame">继续调整当前拼图</el-button> <el-button type="info" @click="showHint">查看提示</el-button> <el-button type="danger" @click="resetGame">重新开始本关</el-button> </div> </div> </div> </div> <!-- 隐藏的拼图组件,用于处理游戏逻辑 --> <puzzle-board v-show="false" ref="puzzleBoard" :difficulty="difficulty" :image-url="imageUrl" @move="handleMove" @complete="handleComplete" @incorrect="handleIncorrect" @pieces-initialized="handlePiecesInitialized" /> </div> </template> <script> import PuzzleBoard from '@/components/PuzzleBoard.vue' import { mapGetters } from 'vuex' export default { name: 'Game', components: { PuzzleBoard }, data() { return { timer: null, placedCount: 0, totalPieces: 0 } }, computed: { ...mapGetters([ 'getGameStatus', 'getDifficulty', 'getTime', 'getMoves', 'getImageUrl', 'getCurrentLevel', 'getLevelCompleteMessage', 'isLastLevel', 'getErrorMessage' ]), gameStatus() { return this.getGameStatus }, difficulty() { return this.getDifficulty }, time() { return this.getTime }, moves() { return this.getMoves }, imageUrl() { return this.getImageUrl }, currentLevel() { return this.getCurrentLevel }, levelCompleteMessage() { return this.getLevelCompleteMessage }, errorMessage() { return this.getErrorMessage }, formatTime() { const minutes = Math.floor(this.time / 60) const seconds = this.time % 60 return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` }, remainingPieces() { return Math.max(0, this.totalPieces - this.placedCount) } }, created() { // 如果没有设置图片URL,返回首页 if (!this.imageUrl) { this.$router.push('/') return } }, mounted() { // 开始游戏 this.startGame() // 监听窗口大小变化,调整布局 window.addEventListener('resize', this.adjustLayout) this.adjustLayout() }, beforeDestroy() { // 清除计时器 this.clearTimer() // 移除事件监听 window.removeEventListener('resize', this.adjustLayout) }, methods: { startGame() { this.$store.dispatch('startGame') this.startTimer() }, togglePause() { if (this.gameStatus === 'playing') { this.$store.dispatch('pauseGame') this.clearTimer() } else if (this.gameStatus === 'paused') { this.$store.dispatch('startGame') this.startTimer() } }, resetGame() { this.clearTimer() // 重新初始化游戏 this.$store.dispatch('initGame', { level: this.currentLevel }) // 开始游戏 this.startGame() // 重新获取拼图碎片 this.$nextTick(() => { this.$refs.puzzleBoard.initializePuzzle() }) }, nextLevel() { this.clearTimer() // 进入下一关 this.$store.dispatch('nextLevel') // 开始游戏 this.startGame() // 重新获取拼图碎片 this.$nextTick(() => { this.$refs.puzzleBoard.initializePuzzle() }) }, backToHome() { this.clearTimer() this.$router.push('/') }, startTimer() { this.clearTimer() this.timer = setInterval(() => { this.$store mit('incrementTime') }, 1000) }, clearTimer() { if (this.timer) { clearInterval(this.timer) this.timer = null } }, handleMove() { this.$store mit('incrementMoves') }, handleComplete() { console.log('游戏完成事件被触发') this.clearTimer() this.$store.dispatch('completeGame') }, handlePiecesInitialized(pieces, targetCells) { this.$nextTick(() => { // 重置已放置计数 this.placedCount = 0 this.totalPieces = pieces.length // 清空现有内容 this.$refs.piecesArea.innerHTML = '' this.$refs.targetArea.innerHTML = '' // 创建目标区域(凹槽) const targetGrid = document.createElement('div') targetGrid.className = 'puzzle-target-grid' targetGrid.style.display = 'grid' targetGrid.style.gridTemplateColumns = `repeat(${this.difficulty}, 1fr)` targetGrid.style.gridTemplateRows = `repeat(${this.difficulty}, 1fr)` targetGrid.style.gap = '1px' targetGrid.style.width = '100%' targetGrid.style.height = '100%' targetGrid.style.border = '2px solid #ddd' // 添加目标单元格 targetCells.forEach(cell => { const cellElement = document.createElement('div') cellElement.className = 'puzzle-cell' cellElement.dataset.index = cell.index cellElement.style.backgroundColor = 'rgba(255, 255, 255, 0.1)' cellElement.style.borderRadius = '2px' cellElement.style.border = '1px dashed rgba(0, 0, 0, 0.2)' cellElement.style.position = 'relative' // 添加序号以显示位置(难度大于6时不显示序号) if (this.difficulty <= 6) { const cellNumber = document.createElement('div') cellNumber.className = 'cell-number' cellNumber.textContent = cell.index + 1 cellNumber.style.position = 'absolute' cellNumber.style.top = '50%' cellNumber.style.left = '50%' cellNumber.style.transform = 'translate(-50%, -50%)' cellNumber.style.fontSize = this.difficulty <= 4 ? '14px' : '10px' cellNumber.style.color = 'rgba(0, 0, 0, 0.3)' cellNumber.style.pointerEvents = 'none' cellElement.appendChild(cellNumber) } // 添加拖拽事件 cellElement.addEventListener('dragover', (e) => e.preventDefault()) cellElement.addEventListener('drop', (e) => { e.preventDefault() const pieceId = e.dataTransfer.getData('text/plain') this.$refs.puzzleBoard.handleExternalDrop(parseInt(pieceId), cell.index) }) targetGrid.appendChild(cellElement) }) this.$refs.targetArea.appendChild(targetGrid) // 计算碎片大小,根据难度调整 const pieceSize = this.calculatePieceSize(this.difficulty) // 创建拼图碎片 pieces.forEach(piece => { const pieceElement = document.createElement('div') pieceElement.className = 'puzzle-piece' pieceElement.dataset.id = piece.id pieceElement.draggable = true // 设置样式 pieceElement.style.width = `${pieceSize}px` pieceElement.style.height = `${pieceSize}px` pieceElement.style.borderRadius = '2px' pieceElement.style.cursor = 'grab' pieceElement.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.2)' pieceElement.style.transition = 'transform 0.2s ease' pieceElement.style.margin = '3px' // 设置背景图片 const pieceWidth = 100 / this.difficulty const pieceHeight = 100 / this.difficulty pieceElement.style.backgroundImage = `url(${this.imageUrl})` pieceElement.style.backgroundSize = `${this.difficulty * 100}% ${this.difficulty * 100}%` // 使用原始索引(originalIndex)来确定背景位置,而不是当前的row和col const originalRow = Math.floor(piece.originalIndex / this.difficulty) const originalCol = piece.originalIndex % this.difficulty pieceElement.style.backgroundPosition = `-${originalCol * 100}% -${originalRow * 100}%` // 添加拖拽事件 pieceElement.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text/plain', piece.id) e.dataTransfer.effectAllowed = 'move' }) // 添加到碎片区域 this.$refs.piecesArea.appendChild(pieceElement) // 监听拼图碎片状态变化 this.$watch( () => this.$refs.puzzleBoard.availablePieces.find(p => p.id === piece.id).isPlaced, (isPlaced) => { if (isPlaced) { pieceElement.style.opacity = '0.3' pieceElement.style.pointerEvents = 'none' pieceElement.style.filter = 'grayscale(100%)' pieceElement.style.transform = 'scale(0.85)' pieceElement.style.border = '2px dashed #999' } else { pieceElement.style.opacity = '1' pieceElement.style.pointerEvents = 'auto' pieceElement.style.filter = 'none' pieceElement.style.transform = 'scale(1)' pieceElement.style.border = 'none' } } ) }) // 监听目标单元格状态变化 targetCells.forEach(cell => { this.$watch( () => this.$refs.puzzleBoard.targetCells[cell.index].pieceId, (pieceId, oldPieceId) => { // 更新计数 if (pieceId !== null && oldPieceId === null) { this.placedCount++; } else if (pieceId === null && oldPieceId !== null) { this.placedCount--; } const cellElement = targetGrid.children[cell.index] // 清空单元格 while (cellElement.firstChild) { cellElement.removeChild(cellElement.firstChild) } // 如果有拼图碎片,添加到单元格 if (pieceId !== null) { const piece = this.$refs.puzzleBoard.availablePieces.find(p => p.id === pieceId) const placedPiece = document.createElement('div') placedPiece.className = 'puzzle-piece-placed' placedPiece.style.width = '100%' placedPiece.style.height = '100%' placedPiece.style.borderRadius = '2px' placedPiece.style.cursor = 'pointer' // 设置背景图片 const pieceWidth = 100 / this.difficulty const pieceHeight = 100 / this.difficulty placedPiece.style.backgroundImage = `url(${this.imageUrl})` placedPiece.style.backgroundSize = `${this.difficulty * 100}% ${this.difficulty * 100}%` // 使用原始索引(originalIndex)来确定背景位置,而不是当前的row和col const originalRow = Math.floor(piece.originalIndex / this.difficulty) const originalCol = piece.originalIndex % this.difficulty placedPiece.style.backgroundPosition = `-${originalCol * 100}% -${originalRow * 100}%` // 明确设置为不可拖动 placedPiece.draggable = false // 添加阻止拖动的事件处理 placedPiece.addEventListener('dragstart', (e) => { e.preventDefault() e.stopPropagation() return false }) // 添加点击事件,允许取回碎片 placedPiece.addEventListener('click', () => { this.$refs.puzzleBoard.retrievePiece(cell.index) }) // 添加悬停效果 placedPiece.addEventListener('mouseover', () => { placedPiece.style.boxShadow = '0 0 8px rgba(0, 0, 0, 0.5)' placedPiece.style.transform = 'scale(0.95)' // 添加提示文本 const tooltip = document.createElement('div') tooltip.className = 'piece-tooltip' tooltip.textContent = '点击取回' tooltip.style.position = 'absolute' tooltip.style.top = '50%' tooltip.style.left = '50%' tooltip.style.transform = 'translate(-50%, -50%)' tooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.7)' tooltip.style.color = 'white' tooltip.style.padding = '2px 6px' tooltip.style.borderRadius = '4px' tooltip.style.fontSize = '12px' tooltip.style.zIndex = '10' placedPiece.appendChild(tooltip) }) placedPiece.addEventListener('mouseout', () => { placedPiece.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.2)' placedPiece.style.transform = 'scale(1)' // 移除提示文本 const tooltip = placedPiece.querySelector('.piece-tooltip') if (tooltip) { placedPiece.removeChild(tooltip) } }) placedPiece.style.userSelect = 'none' placedPiece.style.webkitUserDrag = 'none' placedPiece.style.MozUserSelect = 'none' placedPiece.style.msUserSelect = 'none' cellElement.appendChild(placedPiece) } else { // 如果没有拼图碎片,添加序号(难度大于6时不显示序号) if (this.difficulty <= 6) { const cellNumber = document.createElement('div') cellNumber.className = 'cell-number' cellNumber.textContent = cell.index + 1 cellNumber.style.position = 'absolute' cellNumber.style.top = '50%' cellNumber.style.left = '50%' cellNumber.style.transform = 'translate(-50%, -50%)' cellNumber.style.fontSize = this.difficulty <= 4 ? '14px' : '10px' cellNumber.style.color = 'rgba(0, 0, 0, 0.3)' cellNumber.style.pointerEvents = 'none' cellElement.appendChild(cellNumber) } } } ) }) }) }, calculatePieceSize(difficulty) { // 根据难度调整碎片大小 if (difficulty <= 3) return 60; if (difficulty <= 5) return 50; if (difficulty <= 7) return 40; if (difficulty <= 9) return 30; return 25; // 对于10×10和11×11的难度 }, adjustLayout() { // 根据窗口大小调整布局 const targetArea = this.$refs.targetArea if (targetArea) { const width = targetArea.clientWidth const height = targetArea.clientHeight const size = Math.min(width, height) * 0.9 const targetGrid = targetArea.querySelector('.puzzle-target-grid') if (targetGrid) { targetGrid.style.width = `${size}px` targetGrid.style.height = `${size}px` targetGrid.style.margin = 'auto' } } }, handleIncorrect() { console.log('拼图错误事件被触发') this.$store.dispatch('incorrectGame') }, continueGame() { // 不重置游戏,只将状态改回 playing,让用户继续尝试调整已放置的拼图 console.log('继续尝试,保留当前拼图状态') this.$store.dispatch('startGame') // 将状态从 incorrect 改回 playing }, showHint() { // 显示提示 this.$alert('提示:仔细对照原图,从边缘开始拼起。特别注意图片的颜色和纹理的连续性。', '拼图提示', { confirmButtonText: '知道了', type: 'info', callback: action => { this.$message({ type: 'info', message: '加油!你一定能完成的!' }); } }); } } } </script> <style lang="scss" scoped> .game-page { width: 100vw; height: 100vh; display: flex; overflow: hidden; } .left-section { width: 40%; height: 100%; display: flex; flex-direction: column; background-color: #f0f0f0; border-right: 1px solid #ddd; } .right-section { width: 60%; height: 100%; display: flex; flex-direction: column; } .preview-container { height: 40%; padding: 20px; display: flex; flex-direction: column; h3 { margin-bottom: 10px; text-align: center; font-size: 18px; } .preview-image { flex: 1; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); img { width: 100%; height: 100%; object-fit: contain; } } } .pieces-container { height: 60%; padding: 20px; display: flex; flex-direction: column; h3 { margin-bottom: 10px; text-align: center; font-size: 18px; } .pieces-area { flex: 1; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); padding: 10px; overflow-y: auto; display: flex; flex-wrap: wrap; align-content: flex-start; justify-content: center; } } .game-header { padding: 20px; background-color: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); position: relative; h2 { margin-bottom: 15px; text-align: center; color: #303133; } .level-badge { position: absolute; top: 20px; right: 20px; padding: 5px 10px; background-color: #409EFF; color: #fff; border-radius: 4px; font-size: 14px; font-weight: bold; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .game-info { display: flex; justify-content: space-around; margin-bottom: 15px; .info-item { text-align: center; .info-label { font-weight: bold; margin-right: 5px; } .info-value { font-size: 18px; } } } .game-controls { display: flex; justify-content: center; gap: 10px; margin-bottom: 15px; } .game-instructions { text-align: center; font-size: 14px; color: #606266; p { margin-bottom: 5px; } .tip { font-size: 12px; color: #909399; font-style: italic; } } } .target-container { flex: 1; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; .target-area { width: 100%; height: 100%; position: relative; display: flex; align-items: center; justify-content: center; background-color: #f8f8f8; border-radius: 8px; box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); } } .loading-overlay, .paused-overlay, pleted-overlay, .incorrect-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: rgba(255, 255, 255, 0.95); z-index: 100; i { font-size: 48px; margin-bottom: 20px; } p { font-size: 18px; margin-bottom: 20px; } } pleted-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: rgba(255, 255, 255, 0.95); z-index: 100; i { font-size: 48px; margin-bottom: 20px; color: #E6A23C; &.el-icon-medal { color: #F56C6C; animation: pulse 1.5s infinite; } } h2 { margin-bottom: 10px; color: #67C23A; } .level-message { font-size: 18px; color: #409EFF; margin-bottom: 20px; text-align: center; font-weight: bold; } p { font-size: 18px; margin-bottom: 10px; } .action-buttons { margin-top: 20px; display: flex; gap: 10px; } } .incorrect-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: rgba(255, 255, 255, 0.95); z-index: 100; i { font-size: 48px; margin-bottom: 20px; color: #E6A23C; } h2 { margin-bottom: 10px; color: #E6A23C; } .error-message { font-size: 18px; color: #F56C6C; margin-bottom: 20px; text-align: center; max-width: 80%; } .action-buttons { margin-top: 20px; display: flex; gap: 10px; } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } </style>

代码内容过多,这边文章里就简单的分享一部分代码了。

如果我们想快速掌握一门编程语言,最好的办法就是多写代码,多练,然后多去看一些完整的项目,看看别人在开发项目的时候 都使用了什么技术,怎么设计一个软件项目,让项目更健壮稳定。

这个拼图小游戏前端基本上算是完成了。bug 也简单的测了一下,但是不保证项目里是否还存在bug。 如果分享的这个拼图小游戏对你有所帮助,源码也已经整理好了,需要的可以去看看。 源码地址: oop /home/Index/projectInfo?goodsId=54&typeParam=2&subKey=1

标签:

vue2+element-ui开发网站拼图小游戏-前端项目由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“vue2+element-ui开发网站拼图小游戏-前端项目