美文网首页
微信小程序——用canvas做个层叠消融游戏(一)

微信小程序——用canvas做个层叠消融游戏(一)

作者: KroketTian | 来源:发表于2018-06-14 17:03 被阅读0次

本篇为小程序的一学习笔记,以一小游戏‘层叠消融’为例子,对canvas组件进行展开学习。

开场白就没了,直奔主题。先来看看小程序在组件使用上,对canvas做了什么。

em……,首先,指定了作为唯一标识符的属性canvas-id,因为小程序搭了一套MV*框架,所以对于元素绑定这个,和用原生的js的方式不同。然后就是一系列的手势触发事件。其他的,其实在使用上也没做什么特别的处理嘛。既然如此,那就直接贴上对canvas进行元素绑定的代码吧。

<!-- canvas.wxml -->

<canvas canvas-id="testCanvas"></canvas>

<!-- canvas.js -->

Page({

    onReady: function(e) {

        // 使用wx.createContext获取绘图上下文 context

        var context = wx.createCanvasContext('testCanvas');

        context.setStrokeStyle('#00ff00');

        context.rect(0,0,200,200);

        context.draw();

    }

})

因为小程序的canvas元素默认宽高是不会覆盖全屏的,所以在初始化canvas之后要进行重新设置宽高。屏幕的宽高可以通过API:wx.getSystemInfo获得。

接下来就是画图了。‘层叠消融’这个游戏的主要效果就是图片叠加部分双数相消。具体效果如图:

上面的图形由三个基本图形(正方形)组成,用这三个基本图形拼出上面的目标图案,则算通关。

需求:多图形相叠双数相消。要实现这个效果,用传统的css是很麻烦的,这时canvas的灵活性就体现出来了。canvas对图片图形的处理是像素级的,其本身提供了一系列的图形遮盖策略。globalCompositeOperation这个属性设定了在画新图形时采用的遮盖策略,其值是一个标识12种遮盖方式的字符串。其中‘xor’方式正能实现我们双数相消的需求。

立即贴上主要的代码:

//绘制一个反相图案

let revert = function(path){

    this.context.beginPath();

    this.context.fillStyle="#000";

    this.context.globalCompositeOperation="xor";

    for(let i=0;i<path.length;i++){

        if(i==0){

            this.context.moveTo(path[i].x,path[i].y);

        }else{

            this.context.lineTo(path[i].x,path[i].y);

        }

    }

    this.context.fill();

    return this;

}

(小程序的onReady函数,这里具体的调用我打包了一下,具体打包细节我就不再这里细讲了)

onReady: function(){

    let canvasCtl = new this.canvasCtl();

    canvasCtl.init(this);

    let block1 = new util.block([{x:200,y:50},{x:100,y:150},{x:100,y:50}],canvasCtl);

    block1.initBlock();

    let block2 = new util.block([{x:150,y:70},{x:250,y:70},{x:250,y:200}],canvasCtl);

    block2.initBlock();

    let block3 = new util.block([{x:50,y:60},{x:110,y:60},{x:110,y:110},{x:50,y:110}],canvasCtl);

    block3.initBlock();

    this.blockList.push(block1);

    this.blockList.push(block2);

    this.blockList.push(block3);

},

效果图如下:

既然是小游戏,那就要会动是不是。需求:手指点上时,选中图片跟着移动。

这时,就要用上小程序给我们提供的手势触发了,用到的有这两个:

bindtouchstart用于判断手指选中那个图形,bindtouchmove用于图形移动。

对于判定选中图形这个问题,赶紧回忆起你的小学数学:沿着判定点向图形方向画一条射线,若相交点为单数,则判定点在图形中,否则,判定点在图形外。转换为代码模式如下:

block.prototype.checkPointInRegion = function(pt){

    let nCross = 0; // 定义变量,统计目标点向右画射线与多边形相交次数

    for (let i = 0; i < this.path.length; i++) { //遍历多边形每一个节点

        let p1 = this.path[i];

        let p2 = this.path[(i+1)%this.path.length];

        // p1是这个节点,p2是下一个节点,两点连线是多边形的一条边

        // 以下算法是用是先以y轴坐标来判断的

        if ( p1.y == p2.y )continue;//如果这条边是水平的,跳过

        if ( pt.y < ((p1.y= ((p1.y>p2.y)?p1.y:p2.y))continue;//如果目标点高于这个线段,跳过

        //那么下面的情况就是:如果过p1画水平线,过p2画水平线,目标点在这两条线中间

        let x = (pt.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;

        // 这段的几何意义是 过目标点,画一条水平线,x是这条线与多边形当前边的交点x坐标

        if ( x > pt.x ) nCross++; //如果交点在右边,统计加一。这等于从目标点向右发一条射线(ray),与多边形各边的相交(crossing)次数

    }

    if (nCross % 2 == 1) {

        return true; //如果是奇数,说明在多边形里

    } else {

        return false; //否则在多边形外 或 边上

    }

}

下面就是移动了,canvas的图形的移动很粗暴,那就是擦掉旧的重新画上新的。需要记录下多次bindtouchmove触发时手指的位移->计算出图形移动后的新定点坐标->在画布上擦掉旧图形->根据新坐标画上新图形。下面贴上主要代码:

searchBlock:function(e){ 

    if(this.movePath.length>10){ 

         this.movePath.shift(); 

     }

     this.movePath.push(e);

    for(let i = 0; i < this.blockList.length; i++){//让新选中的图形永远处于第一位

      if(this.blockList[i].checkPointInRegion({ x: e.touches[0].x , y:e.touches[0].y })){

        [this.blockList[0],this.blockList[i]] = [this.blockList[i],this.blockList[0]]

      };

    }

  }, 

 moveBlock:function(e){

    if(this.movePath.length>10){

      this.movePath.shift();

    }

    this.movePath.push(e);

    let oldPath = this.movePath[this.movePath.length-2]?this.movePath[this.movePath.length-2]:null;

    let newPath = e;

    this.blockList[0].move(oldPath.touches[0],newPath.touches[0]);

  },

block.prototype.move = function(oldPath,newPath){

    if(oldPath){

      var x = newPath.x - oldPath.x;

      var y = newPath.y - oldPath.y;

      this.changeLocation(x,y);

    }

}

效果图如下:

接下去就是通关判定、关卡设置、关卡选择……有点多,这些内容就留到下期吧。

相关文章

网友评论

      本文标题:微信小程序——用canvas做个层叠消融游戏(一)

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