VUE拼图游戏

 引入ping组件即可

<template>
  <div id="app">
      <v-ping></v-ping>
  </div>
</template>
<script>
    import VPing from '@/views/Ping.vue'

    export default {
        components: {
            VPing
        },
    }
</script>
<style>

</style>

ping.vue,这里需要一个图片,最好是500*500的图片,自己可以写个数组,替换图片

<template>
  <div >
    <div :style="{width: gamePram.width+'px',height:gamePram.height+'px' }" class="mainDiv">
      <v-block v-bind="gamePram"  @next="nextGame"/>
    </div>
  </div>
</template>

<script>
import VBlock from '@/components/Block.vue'

export default {
  name: 'ping',
  components: {
    VBlock
  },
  data (){
    return {
      gamePram: {
        width:500,
        height:500,
        picUrl:'1.png',
        rowNum:3,
        colNum:3,
      },
    }
  },
  methods:{
    nextGame() {
      this.gamePram.rowNum++;
      this.gamePram.colNum++;
      debugger
      if(this.gamePram.rowNum===10)
        this.gamePram.rowNum=3
      if(this.gamePram.colNum===10)
        this.gamePram.colNum=3
    }
  }

}
</script>
<style>
  .mainDiv{
    border: 1px solid #ccc;
    position: relative;
  }
</style>

block.vue

<template>
    <div>
        <div v-for="(item,index) in sortdataArr"  class="blocks"
        :style="{
            width: item.width+'px',
            height: item.height+'px',
            left:item.dataleft+'px',
            top:item.datatop+'px',
            backgroundImage: `url(${picUrl})`,
            backgroundPositionX: dataArr[index].backleft+'px',
            backgroundPositionY:dataArr[index].backtop+'px',
            opacity:index===dataArr.length-1?0:1
        }"
        :key="item.id"
        @click="handClick"
        :ref="index===(dataArr.length-1)?'empty':'block'
        "
        :data-correctX="item.dataleft"
        :data-correctY="item.datatop"
        >
        </div>
    </div>
</template>

<script>
export default {
  data () {
      return {
      }
  },
  props: {
      width: {
          type: Number,
          default: 500,
      },
      height: {
          type: Number,
          default: 500,
      },
      picUrl: {
       type: String,
       default: '1.png',
      },
      rowNum: {
       type: Number,
       default: 3
      },
      colNum: {
          type: Number,
          default: 3
      }
  },
  methods: {
      handClick(e){
          const clickDom=e.target;
          const emptyDom=this.$refs.empty[0]
          const flag=this.canChange(clickDom,emptyDom)
          if(!flag){
              return ;
          }
          const clickleft=clickDom.style.left;
          const clicktop=clickDom.style.top;
          const emptyleft=emptyDom.style.left;
          const emptytop=emptyDom.style.top;
          clickDom.style.left=emptyleft
          clickDom.style.top=emptytop
          emptyDom.style.left=clickleft
          emptyDom.style.top=clicktop
          const isSuccess= this.isSuccess();
          console.log(isSuccess)
          if(isSuccess){
              setTimeout(()=>{
                  const emptyDom=this.$refs.empty[0]
                  emptyDom.style.opacity=1
                  setTimeout(()=>{
                      const next= confirm("是否进行下一关");
                      if(next){
                          this.$emit('next', '我是父组件!')
                      }
                  },300)

              },300)
          }
      },
      isSuccess(){
          const blockarr=this.$refs.block;
         return  blockarr.every(dom=>{
             const {correctx,correcty}= dom.dataset
              const {left,top}=  dom.style
            if(parseInt(correctx)===parseInt(left)&&parseInt(correcty)===parseInt(top))
                return true;
            return false
          })
      },
      canChange(clickDom,emptyDom){
          const {top:clickTop,left:clickLeft,height,width}=clickDom.style;
          const {top:emptyTop,left:emptyLeft}=emptyDom.style;
          const xdis=Math.floor(Math.abs(parseFloat(clickLeft) -parseFloat(emptyLeft)))
          const ydis=Math.floor(Math.abs(parseFloat(clickTop)-parseFloat(emptyTop)))
          //计算是否可以互换
          //同行,列相邻,同列行相邻
          const flag =true;
          if((clickTop===emptyTop&&xdis===parseInt(width))
              ||(clickLeft==emptyLeft&&ydis===parseInt(height)) )
              return flag
          return false;
      }
  },
  computed: {
      dataArr() {
        const {width,height,rowNum,colNum}=this;
        const dataWidth=width/colNum;
        const dataHeight=width/rowNum;
        const dataArr=[];
        for (let i=0;i<this.rowNum;i++){
            for (let j=0;j<this.colNum;j++){
                dataArr.push({
                    width:dataWidth,
                    height:dataHeight,
                    dataleft:dataWidth*i,
                    datatop:dataHeight*j,
                    backleft:-dataWidth*i,
                    backtop:-dataHeight*j,
                    id:new Date().getTime()+Math.random()*100
                })
            }
        }
        return dataArr;
      },
      sortdataArr() {
        const sortArr=this.dataArr
        const length=sortArr.length;
        const lastDom=sortArr[length-1];
        const newArr=[...sortArr];
        newArr.length=length-1;
        newArr.sort(()=>Math.random()-0.5);
        newArr.push(lastDom);
        return newArr;
      }
  }
}
</script>

<style scoped>
    .blocks{
        border: 1px solid red;
        box-sizing: border-box;
        position: absolute;
        transition: all 0.3s;
    }
</style>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值