vue新春游戏-拼手速抢车票,学习玩乐两不误(可在线体验)

2,983 阅读6分钟

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

游戏地址: ihope_top.gitee.io/word-ticket…
开发语言:vue
运行平台:Chrome
gitee地址:gitee.com/ihope_top/w…
github地址:github.com/heyongsheng…
游戏已开源,欢迎大家体验

记录一下,本篇文章收录于掘金一周2022.01.19 期

前言

xdm大家新年好,首先感谢大家对我上一篇文章vue新春游戏-年兽大作战,欢欢喜喜过大年的支持,文章第一次这么多人赞,感觉受宠若惊,现在技术不够创意来凑系列第二弹来了——vue新春游戏-拼手速抢车票,老规矩,先点击上面游戏地址体验再看文章(这一次兼容了手机端哦)。

写这个主要是前几天群里运营老师说咋没人写抢车票的,再加上我上一篇文章上了掘金一周,听说多上几次有证书,我还没搞到过掘金证书呢,所以有点蠢蠢欲动,这个小游戏玩法与实现都很简单,创意来自于多年前上学时候,学校电脑上的小游戏——金山打字,里面有一个打英语追小偷的游戏,这里借鉴了一下,废话不多说,下面来看看是如何实现的吧。

小游戏内容较多,不重要的地方会一笔带过或者省略,如果有人对游戏中没有提到的技术感兴趣,可以在评论区提出,后续可以针对性的出文章讲解,另外文中代码仅张贴关键部分代码,如需查看完整代码,请移步gitee或者GitHub。

游戏规则

image.png

上面是游戏的开始界面,在下方横线处输入abandon可以开始游戏,点击右上角问号可以跳转至本文章,点击音乐可以打开声音

image.png

开始游戏后,上方会显示余票和剩余的单词量,余票每秒减一,单词量输对一个就少一个,哪一个先清零都会触发游戏结束,中间部分是我们需要输入的单词,下面是我们输入单词的输入框,输入正确会加载下一个单词,怎么样,规则很简单吧,下面就来看具体代码吧。

进度条

首先就是上面的进度条,进度条以前都是用的组件,我这还是第一次手写进度条,实现方式很简单,一个div套另一个div,控制里面进度条的宽度就行了

我这里在进度条里加入了文字,因为进度部分和整体部分颜色不一样,所以我们要在文字背景是白色的时候,显示绿色文字,背景是绿色的时候显示白色文字,我不太会根据背景颜色切换文字颜色,这里直接准备了两套文字,一套白色的,一套绿色的,通过定位让两个位置重合,又把其中一个放到外层div中,显示绿色,另一个放到内层div中,显示白色,当内层div逐渐变窄的时候,慢慢的隐藏白色文字,显示出下面的绿色文字,这样就实现了文字的颜色变化了。

这里注意要控制里面的文字强制不换行,要不然文字隐藏的时候会一整个一整个的消失,不好看

image.png

  <!-- 进度区 -->
  <div class="progress-wrap">
    <!-- 余票 -->
    <div class="progress">
      <p class="progress-text">余票:{{currentTicketCount}}</p>
      <div class="progress-inside" :style="{width: currentTicketCount / ticketCount * 100 + '%'}">
        <p class="progress-text">余票:{{currentTicketCount}}</p>
      </div>
    </div>
    <!-- 剩余验证码 -->
    <div class="progress">
      <p class="progress-text">剩余验证码:{{currentCodeCount}}</p>
      <div class="progress-inside" :style="{width: currentCodeCount / codeCount * 100 + '%'}">
        <p class="progress-text">剩余验证码:{{currentCodeCount}}</p>
      </div>
    </div>
  </div>
  ticketCount: 60, // 本轮票量
  currentTicketCount: 0, // 当前票量
  codeCount: 50, // 总验证码数
  currentCodeCount: 0, // 剩余验证码数量
/* 进度条样式 */
.progress {
  width: 100%;
  height: 20px;
  background: #fff;
  color: #24de62;
  border-radius: 20px;
  overflow: hidden;
  padding: 5px;
  position: relative;
}
.progress:first-child {
  margin-bottom: 20px;
}
.progress-inside {
  width: 100%;
  height: 100%;
  background: #24de62;
  border-radius: 20px;
  color: #fff;
  z-index: 3;
  position: relative;
  transition: width 1s linear;
  overflow: hidden;
}
.progress-inside .progress-text {
  position: inherit;
  left: 5px;
}
.progress-text {
  position: absolute;
  left: 10px;
  z-index: 2;
  white-space: nowrap;
}

单词展示区

这个在上一篇文章中已经多次用到了,抽取问题、抽取弹幕,都是一个原理,先准备一个单词库,然后获取词库单词数,之后获取一个小于等于这个数字的随机整数,之后取这个整数下标的单词就可以了,如果想一轮游戏出现的单词不重复,那我们就用 splice ,如果不限制是否重复,我们就直接赋值就好了

image.png

<!-- 单词展示区 -->
<div class="show-wrap">
    <div class="word">{{ currentWord.word }}</div>
    <div class="mean">{{ currentWord.mean }}</div>
</div>
wordLibrary: require('@/assets/data/word.json'), // 单词库
currentWordLibrary: [], // 当前单词库
currentWord: {}, // 当前单词

/**
 * @description: 抽取单词
 * @param {*}
 * @return {*}
 */
drawWord () {
  let dataLength = this.currentWordLibrary.length
  let randomIndex = Math.floor(Math.random() * dataLength)
  this.currentWord = this.currentWordLibrary.splice(randomIndex, 1)[0]
},

输入框

输入框也特别简单,就是一个输入框,定位到下面,然后监听输入的值,触发相关的事件就好了

image.png

游戏玩法相关

开始游戏

开始游戏时首先判断声音是否打开,如果打开就播放背景音乐(因为游戏结束时候会自动暂停),之后就是重置各种参数,这里我们引入了一个轮数的概念,因为玩家水平高低的不同,导致有的玩家很难在一分钟内输入40(本来设置的50个,为了用户体验,优化到40)个单词,为了良好的游戏体验,我们允许玩家在失败后重新来过,并且下一轮票量+5,也就是游戏时间+5秒,每多一轮,游戏时间就会加5秒,直到用户可以打完40个单词为止。

/**
 * @description: 开始游戏
 * @param {*}
 * @return {*}
 */
startGame () {
  // 如果声音开关打开,则播放背景音乐
  if (this.audioState) {
    this.bgAudio.play()
  }
  // 改变游戏状态
  this.gameStatus = 'start'
  // 游戏轮数加一
  this.round++
  // 重置本轮游戏词库
  this.currentWordLibrary = [...this.wordLibrary]
  // 根据轮数设置游戏时间
  this.ticketCount = this.ticketCount + (this.round - 1 ) * 5
  // 重置时间
  this.currentTicketCount = this.ticketCount
  // 清空输入框
  this.wordInput = ''
  // 重置距离
  this.currentCodeCount = this.codeCount
  // 随机获取一个单词
  this.drawWord()
  // 开始检票
  this.ticketCheck()
},

检票

检票其实就是让票数一秒减一

单词检测

单词检测就是检测下方用户输入的内容,因为我们游戏开始,重新游戏都是通过输入关键字触发的,所以这里我们不仅要判断用户输入单词是否正确,还要判断用户是否输入的关键字,当然还要控制游戏进行中不可输入关键字再次开始游戏

如果用户单词输入正确,则单词量减一,并抽取下一个单词

/**
 * @description: 单词检测
 * @param {*}
 * @return {*}
 */
wordCheck () {
  // 检测关键词
  if (this.wordInput === 'abandon' || this.wordInput === 'again') {
    if (this.gameStatus !== 'start') {
      this.startGame()
    }
  }
  // 判断是否答对
  if (this.wordInput === this.currentWord.word) {
    // 播放音效
    this.playAudio(this.dingMedia)
    // 重置输入框
    this.wordInput = ''
    // 验证码数量减一
    this.currentCodeCount-=10
    if (this.currentCodeCount <= 0) {
      this.gameOver()
      return
    }
    // 抽取下一个单词
    this.drawWord()
  }
},

游戏结束

游戏结束分为两种情况,一种是抢到票了,一种是没抢到票,我们只需要在触发游戏结束时判断余票是否大于0就好了,大于0就是抢到了,小于0就是没抢到。

/**
 * @description: 游戏结束
 * @param {*}
 * @return {*}
 */    
gameOver () {
  if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
    this.$refs.wordInput.blur()
  }
  // 暂停背景音乐
  this.bgAudio.pause()
  // 清除检票定时器
  clearInterval(this.ticketCheckInterval)
  // 判断胜负
  if (this.currentTicketCount > 0) {
    // 更改胜利状态
    this.result = 'success'
    // 播放胜利音效
    this.playAudio(this.successMedia)
  } else {
    // 失败
    this.result = 'fail'
    // 播放失败音效
    this.playAudio(this.failMedia)
  }
  this.gameStatus = 'end'
},

抢票成功

image.png

抢票失败

image.png

本篇文章就到这里了,希望对大家有所帮助,祝大家新年快乐,身体健康,万事如意