45度影子原理

内容纲要

影子实现的方式有很多,原理却不一样,这里使用Typescript实现的一种方案,当然也许有更好的方案。以下是实现原理(请勿直接使用于项目),实现的原理比较简单,不再做详细赘述。

首先是构造、声明和基本的设置:

public static const DIRECTION_RIGHT:number = 1;
public static const DIRECTION_LEFT:number = -1;

private var vertices:Array<number>;
private var indices:Array<number>;
private var uvtData:Array<number>;
private var bmpd:BitmapData;
private var bodySprite:Shape;
private var direction:number;
private var delay:number;
private var matrix:Matrix

public EntityShadow(direction:number = DIRECTION_LEFT) {
    this.direction = direction;
    this.bodySprite = new Shape();
    this.vertices = new Array<number>();
    this.indices = new Array<number>();
    this.uvtData = new Array<number>();
    this.matrix = new Matrix();

    this.mouseChildren = false;
    this.mouseEnabled = false;

    this.indices.push(0, 3, 4);
    this.indices.push(0, 1, 4);
    this.indices.push(1, 4, 5);
    this.indices.push(1, 2, 5);

    this.uvtData.push(1, -1);
    this.uvtData.push(0, -1);
    this.uvtData.push(0, 1);
    this.uvtData.push(1, -1);
    this.uvtData.push(1, -1);
    this.uvtData.push(1, 1);
}

然后是渲染:

public render(oMovieClips:Array):void {
    if (delay <= 0) { //这里只是为了提升效率
        this.delay = 2;
        this.dispose();

        for each (var omc:OMovieClip in oMovieClips) {//自定义的sprite序列动画MovieClip
            if (omc.bitmapData != null) {
                matrix.b = 0;
                matrix.c = 0;
                matrix.d = 1;
                matrix.tx = omc.x;
                matrix.ty = omc.y;
                if (!omc.isMirro) { //位图镜像
                    matrix.a = 1;
                    bodySprite.graphics.beginBitmapFill(omc.bitmapData, matrix);
                    bodySprite.graphics.drawRect(omc.x, omc.y, omc.bitmapData.width, omc.bitmapData.height);
                    bodySprite.graphics.endFill();
                } else {
                    matrix.a = -1;
                    bodySprite.graphics.beginBitmapFill(omc.bitmapData, matrix);
                    bodySprite.graphics.drawRect(omc.x - omc.bitmapData.width, omc.y, omc.bitmapData.width, omc.bitmapData.height);
                    bodySprite.graphics.endFill();
                }
            }
        }

        this.update(bodySprite);
    } else {
        this.delay--;
    }
}

然后对位图拉伸操作:

private update(display:DisplayObject):void {
    var rect:Rectangle = display.getRect(display);
    if (rect.width > 0 && rect.height > 0) {
        var tempH:Number = rect.height;

        this.bmpd = new BitmapData(rect.width, rect.height, true, 0xFFFFFF);
        this.bmpd.lock();
        this.bmpd.draw(display, new Matrix(1, 0, 0, .95, -rect.x, -rect.y));

        this.bmpd.applyFilter(this.bmpd, bmpd.rect, GlobalConst.ZERO_POINT, GlobalConst.ALPHA_BLACK_COLORMATRIXFILTER);
        this.bmpd.unlock();

        this.vertices.splice(0, vertices.length);

        this.vertices.push(0, 0);
        this.vertices.push(tempH * this.direction, 0);
        this.vertices.push(0, rect.height);
        this.vertices.push(rect.width, 0);
        this.vertices.push(rect.width + tempH * this.direction, 0);
        this.vertices.push(rect.width, rect.height);

        this.graphics.beginBitmapFill(bmpd, null, false);
        this.graphics.drawTriangles(vertices, indices, uvtData);
        this.graphics.endFill();
        this.x = rect.x;
        this.y = rect.y;
    }
}

这里是以120*120的矩阵演示。

最后是销毁操作:

public dispose():void {
    this.graphics.clear();
    this.bodySprite.graphics.clear();
    if (this.bmpd != null)
        this.bmpd.dispose();
}

大概实现就是这样,比其他实现方式好理解,而且损耗也少很多。

code enjoy! 😄😄😁

作者:indeex

链接:https://indeex.cc

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


发表评论

您的电子邮箱地址不会被公开。