美文网首页
【游戏系列】用vue做个看图猜成语游戏吧

【游戏系列】用vue做个看图猜成语游戏吧

作者: 凡繁烦 | 来源:发表于2021-04-29 11:12 被阅读0次

    前几年看图猜成语一类游戏风靡一时,很多人玩这个游戏,我当时也是其中之一,如今当了一个没多少头发的程序员,有时间的时候,也会去研究一下以前的那些小游戏

    • vue怎么创建项目这里就不介绍了,后面有时间再写一篇文章专门讲一下怎么创建vue项目

    • 项目结构如下

    image.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上看一看,附上地址

    可以的话,点个小心心吧😘

    image.png

    游戏预览地址

    相关文章

      网友评论

          本文标题:【游戏系列】用vue做个看图猜成语游戏吧

          本文链接:https://www.haomeiwen.com/subject/jtoirltx.html