用CCC来实现刮刮卡和橡皮擦

研究一下如何实现类似弹坑效果。

我也遇到这个旋转的问题了。请问你解决了吗?

赞 感谢分享

最终我是放弃了 drawSegment 来补间,而是改用 drawQuadBeizier 绘制贝塞尔曲线来补间。效果不错。

不管鼠标拖动速度多快,都可以平滑的补间线条:

不过,我发现引擎对贝塞尔曲线的绘制有一个问题:在绘制贝塞尔曲线的时候,最终其实是调用一个 CCDrawNode 里的 _drawSegments 方法,而这个方法实际是计算出一些三角形然后进行绘制。但是不知道为什么,有时候会出现三角形的顶点偏离太大,出现一些奇怪的棱角:

通过断点我发现在一些情况下,_drawSegments 方法里头的 offset0offset1 两个变量的 x、y 值可能很大,导致绘制出的三角形的某些顶点偏离得特别远,所以就出现了这些棱角。

为了解决这个方法,我仿照着写了一个 drawQuadBezierSegment 方法:

            proto.drawQuadBezierSegment = function (origin, control, destination, segments, lineWidth, color) {
            lineWidth = lineWidth || this._lineWidth;
            color = color || this.getDrawColor();
            if (color.a == null)
                color.a = 255;
            var vertices = [], t = 0.0;
            for (var i = 0; i < segments; i++) {
                var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
                var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
                vertices.push(cc.p(x, y));
                t += 1.0 / segments;
            }
            vertices.push(cc.p(destination.x, destination.y));
            this._drawSegments(vertices, lineWidth, color, false, true);   // 增加最后一个参数传值为true
        };

这个方法和 drawCubicBezier 的区别在于多传了一个参数值为 true。这个参数是用于扩展 _drawSegments 方法,让其支持跳过一些偏离特别大的顶点的三角形绘制。修改后的 _drawSegments 方法如下:

proto._drawSegments = function(verts, borderWidth, borderColor, closePoly, skip){
            borderWidth = (borderWidth == null) ? this._lineWidth : borderWidth;
            borderColor = borderColor || this._drawColor;
            if(borderColor.a == null)
                borderColor.a = 255;
            borderWidth *= 0.5;
            if (borderWidth <= 0)
                return;

            var c4bBorderColor = {r: 0 | borderColor.r, g: 0 | borderColor.g, b: 0 | borderColor.b, a: 0 | borderColor.a };
            var extrude = [], i, v0, v1, v2, count = verts.length;
            for (i = 0; i < count; i++) {                
                v0 = cc.v2(verts[(i - 1 + count) % count]);
                v1 = cc.v2(verts[i]);
                v2 = cc.v2(verts[(i + 1) % count]);
                var n1 = cc.pNormalize(cc.pPerp(cc.pSub(v1, v0)));
                var n2 = cc.pNormalize(cc.pPerp(cc.pSub(v2, v1)));
                var offset = cc.pMult(cc.pAdd(n1, n2), 1.0 / (cc.pDot(n1, n2) + 1.0));
                extrude[i] = {offset: offset, n: n2};
            }

            var triangleCount = 3 * count - 2, vertexCount = 3 * triangleCount;
            this._ensureCapacity(vertexCount);

            var triangleBytesLen = cc.V2F_C4B_T2F_Triangle.BYTES_PER_ELEMENT, trianglesBuffer = this._trianglesArrayBuffer;
            var locBuffer = this._buffer;
            var len = closePoly ? count : count - 1;
            for (i = 0; i < len; i++) {
                var j = (i + 1) % count;
                v0 = cc.v2(verts[i]);
                v1 = cc.v2(verts[j]);

                var n0 = extrude[i].n;
                var offset0 = extrude[i].offset;
                var offset1 = extrude[j].offset;
                // 增加跳过逻辑
                if (skip && (Math.abs(offset0.x) > 1 || Math.abs(offset0.y) > 1 || Math.abs(offset1.x) > 1 || Math.abs(offset1.y) > 1)) {
                    continue;
                }
                ...
}

这样就解决了棱角问题。

3赞

这个方案歇逼了,发现 Native 端的 DrawNode 和 JS 层的 DrawNode 接口还不一致。提了 bug:https://github.com/cocos-creator/engine/issues/2933 不过被关了。

mark

这个方法在2.0.0上不能用了,请问各位有解决方法吗

升级到2.0.1,通过mask._graphics 来实现

mark

mark

mark

mark

cocosCreator 2.0.1
mark 属性检查器 type:rect; inverted:true;
我有mark下的_graphics来实现刮刮卡,现在画大概1300左右的圆mark就会失效,会显示我画的白的图画,求解
var stencil = this.mask._graphics;
stencil.circle(point.x,point.y,20);
stencil.fillColor = cc.Color.WHITE;
stencil.fill();

顶下,找不到原因

mark

mark

这个==你解决了吗?

mark

橡皮檫

牛逼了