前几年看图猜成语一类游戏风靡一时,很多人玩这个游戏,我当时也是其中之一,如今当了一个没多少头发的程序员,有时间的时候,也会去研究一下以前的那些小游戏
-
vue怎么创建项目这里就不介绍了,后面有时间再写一篇文章专门讲一下怎么创建vue项目
-
项目结构如下
![](https://img.haomeiwen.com/i13648864/3ae845be9eae6e92.png)
1、项目依赖
项目比较简单,依赖不多,目前除了基本的之外,只引入了有赞的移动端UI框架vant
# Vue 2 项目,安装 Vant 2:
npm i vant -S
# Vue 3 项目,安装 Vant 3:
npm i vant@next -S
2、收集资源
在网上收集关于看图猜成语的图片资源,推荐汉辞网
若侵权请联系作者删除
- 在src->assets目录下新建一个词条文件word.json
- 因为木有搭后台,直接就将词条信息写死在word.json文件了,下面简单列一下
[
{
"id": 1,
"word": "鱼贯而入",
"picture": "http://www.hydcd.com/cy/fkccy/images/CF91100-50.png",
"mean": "象游鱼一样一个跟着一个地接连着走。形容一个接一个地依次序进入。",
"story": "东晋集团苟安江南,南昌守将庾翼率军向北挺进,准备收复北方,统一中国,驻守襄阳一带。他手下官吏范汪向晋成帝上书说当前任务是练兵,积蓄粮草,待时机成熟再兴兵北伐。他说:“沔汉干涸,皆当鱼贯而行,推排而进”,反对北伐"
},
{
"id": 2,
"word": "四通八达",
"picture": "http://www.hydcd.com/cy/fkccy/images/CF91100-51.png",
"mean": "四面八方都有路可通。形容交通极便利。也形容通向各方。"
}
]
3、编写vue模板
下面引入了两个媒体文件,一个是背景音乐,一个是错误提示音,将他们都隐藏,只在后台播放
<template>
<div class="container">
<van-nav-bar
style="background-color:#643D12"
>
<span slot="title" style="color:#fff">第{{id}} / {{array.length}}关</span>
<span slot="right" style="color:#C1A06D">{{score}}</span>
</van-nav-bar>
<div class="picture">
<van-image :src="obj.picture" class="img" />
</div>
<div class="tips">
<van-button type="warning" size="small" @click="jumpLevel(id-1)" :disabled="!showPrev">上一关</van-button>
<van-button type="warning" size="small" @click="checkLevel" style="margin: 0 10px 0 20px">选 关</van-button>
<span>{{time+1}}</span>
<van-button type="warning" size="small" @click="handlePrompt" style="margin: 0 20px 0 10px">提 示</van-button>
<van-button type="warning" size="small" @click="jumpLevel(id+1)" :disabled="!showNext">下一关</van-button>
</div>
<div class="result">
<div v-for="(item,i) in choiced" :key="i">
<span @click="handleCancel(i)" class="choiced-text">{{item}}</span>
</div>
</div>
<div class="choice">
<div v-for="(item,i) in choices.slice(0,8)" :key="i">
<span @click="handleChoice(item,i)" class="choice-text">{{item}}</span>
</div>
</div>
<div class="choice">
<div v-for="(item,i) in choices.slice(8,16)" :key="i">
<span @click="handleChoice(item,i+8)" class="choice-text">{{item}}</span>
</div>
</div>
<div class="choice">
<div v-for="(item,i) in choices.slice(16,24)" :key="i">
<span @click="handleChoice(item,i+16)" class="choice-text">{{item}}</span>
</div>
</div>
<div style="width:100%;text-align:center">
<van-button type="warning" size="small" style="margin: 20px auto" @click="clearGame">重置记录</van-button>
<p style="color:#666;font-size:12px">copyright: <a href="https://www.52fansite.com" target="_blank">凡繁烦</a></p>
</div>
<van-popup v-model="showLevel" position="bottom" style="height:40%">
<div class="levels">
<div v-for="(item,i) in array" :key="i" :class="['level-item',id==item.id ? 'active':'',item.played?'played':'']" @click="handleClickLevel(item)">
<p>第{{i+1}}关</p>
<p>
<van-rate :value="item.star" count="3" size="16px" color="#FFD21E" readonly/>
</p>
</div>
</div>
</van-popup>
<div :class="['music-btn',isPlay == '0'? 'bgm':'']" @click="handleClickBgm()" ref="playbtn">
<van-icon name="music-o" size="36px"/>
<div v-if="isPlay=='1'" class="stop-play"></div>
</div>
<audio src="../assets/music/bgm.mp3" controls="true" ref="bgm" style="display:none" loop="loop"></audio>
<audio src="../assets/music/error.wav" controls="true" ref="error" style="display:none" ></audio>
</div>
</template>
4、编写js逻辑
4.1引入vant弹框组件和轻提示组件
import { Dialog,Toast } from 'vant';
components: {
[Dialog.Component.name]: Dialog.Component,
[Toast.Component]: Toast.Component
},
4.2data变量声明
data(){
return {
id: null,
score: 100,
data: require('../assets/word'),
array: [],
obj: {},
choices: [],
choiced: [],
showPrev: false,
showNext: false,
showLevel: false,
star: 0,
time: 1,
timer: null,
prompt: 0,
isPlay: "0",
}
},
4.3监听部分变量值变化
这里使用vue的watch钩子监听,不了解的同学可以看一下vue watch的文档
- 监听关卡变化,我这里直接将id当成关卡处理了,如果真的要接后台的话,
要自行增加关卡字段
id(val) {
if(val <= 10){
this.step = 2;
}else if(val > 10 && val < 20){
this.step = 5;
}
localStorage.setItem('level',val);
if(val >=2){
this.showPrev = true;
}else{
this.showPrev = false;
}
let playedArr = this.array.filter(it=>{
return it.id>this.id && it.played
})
if(playedArr.length > 0 || this.obj.played){
this.showNext = true;
}else{
this.showNext = false;
}
}
- 监听分数变化,将当前的分数存储到localStorage,避免刷新后重置
score(val){
localStorage.setItem('score',val);
}
- 监听已选汉字,处理错误逻辑
choiced(val){
if(val.join('').length == 4){
let wordArr = this.obj.word.split('');
let doms = document.getElementsByClassName('choiced-text');
let count = 0;
wordArr.map((a,i) =>{
if(a != val[i]){
doms[i].style.color='red';
count = count+1;
}else{
doms[i].style.color='#E3D479'
}
})
if(count>0){
this.$refs.error.play();
if(this.isPlay=='0'){
this.$refs.bgm.pause();
this.$refs.error.addEventListener('ended',()=>{
this.$refs.bgm.play();
})
}
}
}
}
后面的逻辑也不再一一赘述了,有兴趣的同学可以去github上看一看,附上地址
可以的话,点个小心心吧😘
![](https://img.haomeiwen.com/i13648864/0cb43f1272b2ad59.png)
网友评论