按键精灵/触控精灵 多点找怪,多点找色算法思路,附带动态分析图,以及算法代码

上面的两张动图是5宫格,6宫格动图;

先说下思路

按键/触动精灵只提供了单个找色函数,所以如果想在屏幕上找多个怪物,这里我设计的是按照屏幕大小,分成一个个小格子,然后便利格子,调用他们的单个找色函数;这样的话,我们可以把找怪单独放到一个进程,然后异步去找怪,找到怪,放到一个全局数组供函数使用;

分析如下:

1.屏幕按照宽高等比例分割,这里算法只支持等分的行格子数=列格子数!(否则不好找九宫格规律) 格子数量可自己定义 如:row =  5 或6

2.九宫格有奇数与偶数之分,可以看到5宫格(奇数格子)时,第一次查询index=1时,是最中心的一个格子,而6宫格(偶数格子)index=1时,找的区域是中间4个格子

3.index代表的是第几环查询,如index=1,查询第一环的格子,index=2时,查第二环的格子

4. 在实际使用的时候,每次可以查询第几环的二维数组,然后根据数组计算出屏幕的像素查询开始结束为止,然后调用找色找字函数

具体的代码我放在下面,用vue写的. 想运行的话,需要用vue框架:>

<template>
  <div class="boxContainer">
    <div v-for="indexRow in row" :key="indexRow" >
       <div v-for="indexCol in row" class="mybox" :key="indexCol" :class="{isShow:isShow(indexRow,indexCol)}"
        :style="{width:boxWidth+'px',height:boxHeight+'px'}"
        :width="boxWidth" :hight="boxHeight">
          {{indexRow}} - {{indexCol}}
      </div>
    </div>
    <div class="clear"></div>
    <div>
      <input type="text"  v-model="row">宫格<br/>
      <select v-model="currentIndex">
        <option :key="indexRow" :value="indexRow"  v-for="indexRow in maxIndex">{{indexRow}}</option>
      </select>
      几环
    </div>
  </div>
</template>
<script>
export default {
  name:'Home',
  data () {
    return {
      row:5,
      boxWidth:0,
      boxHeight:0,
      currentIndex:1,
      maxIndex:0,
      currentArr:[]
    }
  },
  watch:{
     currentIndex: {
      handler(newName, oldName) {
        this.currentIndex = parseInt(newName)
        this.initBox()
      }
    },
    row:{
      handler(newVal,oldVal){
          this.row = parseInt(newVal)
          this.initBox()
      }
    }
  },
  mounted(){
    this.initBox()
  },
  methods:{
    initBox(){
      let boxEle = document.getElementsByClassName("boxContainer")[0];
      let {width,height} = boxEle.getClientRects()[0]
      this.boxWidth = Math.floor(parseInt(width)/this.row); // 屏幕总宽度
      this.boxHeight = Math.floor((parseInt(height)-200)/this.row); // 屏幕总高度
      this.maxIndex = this.getMaxIndex(this.row);  // 最多环数
      this.getBoxArr() 
    },
    getBoxArr(){
        let currentArr = []
        if(this.row%2==0){
          currentArr = this.calcByRowAndColOuShu(this.currentIndex,this.row,this.row)
        }else{
          currentArr = this.calcByRowAndColJiShu(this.currentIndex,this.row,this.row)
        }
        this.currentArr = currentArr
    },
    isShow(row,col){
      if(this.currentArr.findIndex(item=>{
        return item.row == row && item.col == col
      })!=-1){
        return true
      }else{
        return false
      }
    },
    getMaxIndex(rowSize){
       return Math.floor((rowSize+1)/2)
    },
    calcByRowAndColJiShu(index,rowSize,colSize){
      //计算出中奖的位置,奇数, 计算技巧
      /***
       * 假设row =5 ,index=2, 则 centerRow = 3
       * 那么二维码左上角为(2,2) 右下角为(4,4)
       * boxColStart = 2 boxColEnd=4
       * boxRowStart =2 boxRowEnd=4
       *  */ 
      let ret = []
      let centerRow = Math.floor(rowSize/2) + 1
      let centerCol = Math.floor(colSize/2) + 1
      let boxColStart = centerCol - index +1 // 2 = 3 - index(2) + ? 
      let boxColEnd = centerCol + index -1  // 4 = 3 + index(2) +?
      let boxRowStart = centerRow - index +1 //二维数组上边的行数  2 = 3 - index(2) +?
      let boxRowEnd = centerRow + index -1 //二维数组下边的行数 4 = 3 + index(2) +?
      // 正方形上边
         if( index == 1 ){ //奇数时,第一次,只需要执行一次即可
           ret.push({row:boxRowStart,col:boxRowStart})
        }else{
            for(let i=boxColStart;i<=boxColEnd;i++){
                ret.push({row:boxRowStart,col:i})
            }
            // 正方形下边
            for(let i=boxColStart;i<=boxColEnd;i++){
              ret.push({row:centerRow+(index-1),col:i})
            }
            // 左边
            for(let i=boxRowStart+1;i<=boxRowEnd-1;i++){
              ret.push({row:i,col:boxRowStart})
            }
            // 右边
            for(let i=boxRowStart+1;i<=boxRowEnd-1;i++){
              ret.push({row:i,col:boxRowEnd})
            }}  
       }


      return ret;
    },
    calcByRowAndColOuShu(index,rowSize,colSize){
      //计算出中奖的位置,偶数
      let ret = []
      let centerRow = Math.floor(rowSize/2) 
      let centerCol = Math.floor(colSize/2)  
  
      let boxColStart = centerCol - index +1
      let boxColEnd = centerCol + index 
      let boxRowStart = centerRow - index +1  //二维数组上边的行数
      let boxRowEnd = centerRow + index  //二维数组下边的行数
      // 正方形上边
      for(let i=boxColStart;i<=boxColEnd;i++){
          ret.push({row:boxRowStart,col:i})
      }
      // 正方形下边
      for(let i=boxColStart;i<=boxColEnd;i++){
         ret.push({row:centerRow+index,col:i})
      }
      for(let i=boxRowStart+1;i<=boxRowEnd-1;i++){
         ret.push({row:i,col:boxRowStart})
      }
      for(let i=boxRowStart+1;i<=boxRowEnd-1;i++){
         ret.push({row:i,col:boxRowEnd})
      }
      return ret;
    }
  }
}
</script>
<style scoped lang="css">
.boxContainer{
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  position: absolute;
}
.mybox{
  background:#ffffff;
  float:left;
  border:1px solid #333;
  box-sizing:border-box;
  color:#333;
  display: flex;
  align-self: center;
  align-items: center;
  justify-content: center;
}
.isShow{
  background: #666;
}
.clear{
  clear: both;
}
</style>

 

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值