vue 拼数字小游戏(设置表白彩蛋)

原文链接: vue 拼数字小游戏(设置表白彩蛋)

上一篇: vue 网格 过渡 动画

下一篇: mpvue 开发小程序 流程

效果

通过点击交换空白格子与周围的格子,将整个格子还原,如果在还原过程中,5,2,1,13,14,这几个数连在一起出现,则触发彩蛋

遇到的问题:

1,数组在改变其中某一项后,并不会刷新视图,这个需要使用$set设置数组的新元素的值,告诉vue,数组已经改变了,或者创建新数组然后重新赋值

this.items = Array.from(this.items)
或者
this.$set(this.items, '' + y, t)

2,判断彩蛋是否出现,使用indexOf,或者正则表达式都可以,但在测试中发现indexOf更快

      isEgg() {
        return this.items.join('').indexOf('5211314') != -1
      }

3,如果是微信小程序,在v-for指令中,需要获取index时,需要加括号,否则会报错

<div class="cell" v-for="(i,index) in items" :key="i" @click="click(i,index)">{{i==16?'':i}}</div>

小程序版本

<template>
  <div class="game">
    <transition-group name="cells" tag="div" class="grid">
      <div class="cell" v-for="(i,index) in items" :key="i" @click="click(i,index)">{{i==16?'':i}}</div>
    </transition-group>

    <div class="egg" v-show="show">
      {{egg}}
    </div>
    <div class="egg" v-show="isPass">
      <h3>
        恭喜拼图成功
      </h3>
    </div>

    <button @click="init" class="reset">重置</button>
  </div>
</template>

<script>
  // import {Toast} from 'mint-ui';
  // import 'mint-ui/lib/style.css'
  // import 'animate.css'

  export default {
    name: "game-card",
    data() {
      return {
        egg: 'hwq,你知道吗,我喜欢你很久了',
        items: Array.from(Array(16)).map((_, index) => index + 1),
        // items: [5, 2, 1, 13, 6, 3, 14, 7, 8, 9, 10, 11, 12, 15, 16, 4],
        showEgg: false,
        show: false,
      }
    },
    watch: {
      items() {
        console.log('watch', this.items)
        if (this.isPass) {
          console.log('pass')
        }

        console.log(this.isEgg)
        if (this.isEgg && !this.showEgg) {
          this.showEgg = true
          this.show = true
          setTimeout(
            () => this.show = false,
            1000
          )

        }
      }
    },
    computed: {
      zero() {
        return this.items.indexOf(16)
      },
      isPass() {
        return this.items.every(
          (item, index) => item == index + 1
        )
      },
      isEgg() {
        console.log(this.items.join(''))
        return this.items.join('').indexOf('5211314') != -1
      }
    },
    methods: {
      // 交换x,y 位置变量
      swap(x, y) {
        let t = this.items[x]
        this.items[x] = this.items[y]
        this.items[y] = t
        // this.$set(this.items, '' + y, t)
        let arr = Array.from(this.items)
        this.items = arr
      },

      // 0,1,2,3 表示上右下左,四个方向
      move(dir) {
        if (dir == 0 && this.zero > 3) {
          console.log('up', this.zero)
          this.swap(this.zero, this.zero - 4)
        } else if (dir == 1 && this.zero % 4 != 3) {
          console.log('right', this.zero)
          this.swap(this.zero, this.zero + 1)
        } else if (dir == 2 && this.zero <= 11) {
          console.log('down', this.zero)
          this.swap(this.zero, this.zero + 4)
        } else if (dir == 3 && this.zero % 4 != 0) {
          console.log('left')
          this.swap(this.zero, this.zero - 1)
        }
      },

      // 随机初始化
      init() {
        let num = parseInt(Math.random() * 1000)
        console.log('init', num)

        for (let i = 0; i < num; i++) {
          let d = parseInt((Math.random() * 100)) % 4
          this.move(d)
          console.log(d)
        }
      },
      click(item, index) {
        console.log('click', item, index)
        if (item == 16)
          return
        if (index + 1 < 16 && this.items[index + 1] == 16) {
          console.log('click move', 3)
          this.move(3)
        } else if (index - 1 >= 0 && this.items[index - 1] == 16) {
          this.move(1)
          console.log('click move', 1)

        } else if (index + 4 < 16 && this.items[index + 4] == 16) {
          this.move(0)
          console.log('click move', 0)

        } else if (index - 4 >= 0 && this.items[index - 4] == 16) {
          this.move(2)
          console.log('click move', 2)

        }
      }
    },
    created() {
      this.init()
    },

  }
</script>

<style scoped>
  .grid {
    position: relative;
    display: grid;
    grid-gap: 5px;
    background-color: rgb(233, 233, 233);
    width: 215px;
    border: 5px rgb(233, 233, 233) solid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
  }

  .cell {
    background-color: lightskyblue;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    /*border: 5px solid white;*/
    box-sizing: border-box;
  }

  /*过渡时间*/
  .cells-move {
    transition: transform 1s;
  }

  .cells-enter-active, .cells-leave-active {
    transition: all 1s;
  }

  /*效果*/
  .cells-enter, .cells-leave-to {
    opacity: 0;
    transform: translateY(30px);
  }

  .game {
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
  }

  .egg {
    position: absolute;
    bottom: 50px;
    background: rgba(0, 0, 0, 0.5);
    /*opacity: 0.8;*/
    border-radius: 20px;
    padding: 10px;
    color: white;
  }

  .reset {
    margin-top: 20px;
  }
</style>

使用面向对象的方式,新增一个对象,然后操作对象即可

class NumGame {
  // 边长
  constructor(size) {
    this.size = size
    this.items = Array.from(Array(size * size)).map((_, index) => index + 1)
    this.blank = size * size
  }

  // 是否完成
  isPass() {
    return this.items.every((item, index) => item == index)
  }

  // 空白块所在位置
  blankPos() {
    return this.items.indexOf(this.blank)
  }

  // 移动
  move(dir) {
    console.log(dir)
    if (dir == 0 && this.blankPos() >= this.size) {
      this.swap(this.blankPos(), this.blankPos() - this.size)
    } else if (dir == 1 && this.blankPos() % this.size != (this.size - 1)) {
      this.swap(this.blankPos(), this.blankPos() + 1)
    } else if (dir == 2 && this.blankPos() < (this.size - 1) * this.size) {
      this.swap(this.blankPos(), this.blankPos() + this.size)
    } else if (dir == 3 && this.blankPos() % this.size != 0) {
      this.swap(this.blankPos(), this.blankPos() - 1)
    }
  }

  // 交换
  swap(x, y) {
    // console.log(x, y)
    let t = this.items[xm]
    this.items[x] = this.items[y]
    this.items[y] = t
  }

  toString() {
    return this.items.toString()
  }
}


let ng = new NumGame(3)
ng.move(0)
console.log(ng.toString())

// 1,2,3,4,5,9,7,8,6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值