Some questions about copyChannel on the HTML5&C++ platform


#1

I am using the copyChannel to implement the erase function, but I have encountered some strange problems:

  1. In the C++ platform, when I simply use copyChannel Api, it will cause the entire bitmap to be black. But I confirm that it is colored.
    (But this problem, I solved it after re-picking through copyPixels)

  2. In the HTML5 platform, my newly drawn line has used copyChannel to set some unwanted content to be transparent at the same time, but this does not seem to take effect immediately, resulting in an opaque black image.
    (In the HTML5 platform, it does not require copyPixels, the color is displayed normally)

Code:

 #if cpp
        //C++版本需要实现以下逻辑
        _yazi.bitmapData.copyPixels(bitmapData,rect,pos);
        _draw.copyChannel(bitmapData,rect,pos, BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        _yazi.bitmapData.copyChannel(_draw,rect,pos, BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        #elseif html5
        //HTML5需要实现以下逻辑,HTML5的渲染貌似有延迟,会导致迟早会有个黑块在
        // _draw.copyChannel(bitmapData,bitmapData.rect,new Point(), BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        // _yazi.bitmapData.copyChannel(_draw,_draw.rect,new Point(), BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        _draw.copyChannel(bitmapData,rect,pos, BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        _yazi.bitmapData.copyChannel(_draw,rect,pos, BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        #end       

#2

Complete heavy modern code:

package game.levels;

import zygame.display.Image;
import openfl.Assets;
import openfl.events.MouseEvent;
import openfl.display.Sprite;
import openfl.display.BlendMode;
import openfl.geom.Rectangle;
import openfl.geom.Point;
import openfl.display.BitmapDataChannel;
import openfl.display.BitmapData;
import openfl.display.Bitmap;
import zygame.filters.MaskFilter;
import zygame.components.ZLable;

/**
 * 擦拭关卡实现demo
 */
class ClearDemoLevel extends BaseLevel {

    private var _yazi:Image;
    
    private var _draw:BitmapData;

    private var _isDown:Bool = false;

    private var _lastPos:Point = new Point();

    /**
     * 百分比网格
     */
    private var _drawArray:Array<Array<Bool>> = [];
    private var _drawTrueCount:Int = 0;
    private var _drawAllTrueCount:Int = 0;


    private var _lable:ZLable;

    public function new(id:Int){
        super(1);
    }

    /**
     * 开始创建关卡
     */
    override public function onLevelCreate():Void
    {
        super.onLevelCreate();

        var yazi1:Image = new Image(Assets.getBitmapData("assets/levels/5/level5_yazi1.png"));
        yazi1.alignPivot();
        this.addChild(yazi1);
        yazi1.x = getStageWidth()/2;
        yazi1.y = getStageHeight()/2;

        var bitmap:BitmapData = Assets.getBitmapData("assets/levels/5/level5_yazi2.png").clone();
        var yazi2:Image = new Image(bitmap);
        yazi2.alignPivot();
        this.addChild(yazi2);
        yazi2.x = getStageWidth()/2;
        yazi2.y = getStageHeight()/2;
        _yazi = yazi2;

        _draw = new BitmapData(Std.int(yazi2.width),Std.int(yazi2.height),true,0x0);
        updateBitmapData();

        for(ix in 0...Std.int(yazi2.width/5))
        {
            _drawArray[ix] = [];
            for(iy in 0...Std.int(yazi2.height/5))
            {
                _drawArray[ix][iy] = false;
                _drawAllTrueCount++;
            }
        }

        _lable = new ZLable();
        _lable.setFontColor(0x0);
        _lable.setFontSize(32);
        _lable.dataProvider = "0%";
        _lable.width = 300;
        _lable.height = 64;
        _lable.y = 32;
        _lable.x = 32;
        this.addChild(_lable);

        //测试用
        // var bitmap:Bitmap = new Bitmap(_draw);
        // this.addChild(bitmap);
        // bitmap.x = _yazi.x - _yazi.width/2;
        // bitmap.y = _yazi.y - _yazi.height/2;
        // bitmap.alpha = 0.5;

        stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
        stage.addEventListener(MouseEvent.MOUSE_UP,onUp);
        stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);

        
    }

    private function onMove(e:MouseEvent):Void
    {
        if(!_isDown)
            return;
        //绘制逻辑
        var newLine:Sprite = new Sprite();
        newLine.graphics.beginFill(0xff0000,1);
        newLine.graphics.lineStyle(40,0xff0000,1);
        newLine.graphics.moveTo(_lastPos.x,_lastPos.y);
        newLine.graphics.lineTo(this.mouseX - _yazi.x + _yazi.width/2,this.mouseY - _yazi.y  + _yazi.height/2);
        newLine.graphics.endFill();


        _draw.draw(newLine);
        var rect:Rectangle = newLine.getBounds(null);
        updateBitmapData(rect,new Point(rect.x,rect.y));
        
        // trace("ID:",Std.int(rect.x/5),Std.int(rect.y/5),Std.int(rect.width/5),Std.int(rect.height/5));
        var xid:Int = Std.int(rect.x/5);
        var yid:Int = Std.int(rect.y/5);
        var wlen:Int = Std.int(rect.width/5);
        var hlen:Int = Std.int(rect.height/5);
        for(ix in xid...xid+wlen)
        {
            for(iy in yid...yid+hlen)
            {
                if(_draw.getPixel(ix*5,iy*5) != 0)
                {
                    if(_drawArray[ix][iy] == false)
                    {
                        _drawArray[ix][iy] = true;
                        _drawTrueCount++;
                    }
                }
            }
        }

        // trace("已绘制:"+Std.int(_drawTrueCount/_drawAllTrueCount*100)+"%");
         _lable.dataProvider = "已擦除:"+Std.int(_drawTrueCount/_drawAllTrueCount*100)+"%";

        _lastPos.x = this.mouseX - _yazi.x + _yazi.width/2;
        _lastPos.y = this.mouseY - _yazi.y + _yazi.height/2;
        
    }

    private function updateBitmapData(rect:Rectangle = null,pos:Point = null):Void
    {
        if(rect == null)
            rect = new Rectangle(0,0,_draw.width,_draw.height);
        if(rect.x < 0)
        {
            rect.width += rect.x;
            rect.x = 0;
            pos.x = 0;
        }
        if(rect.y < 0)
        {
            rect.height += rect.y;
            rect.y = 0;
            pos.y = 0;
        }
        if(pos == null)
            pos = new Point();
        var bitmapData:BitmapData = Assets.getBitmapData("assets/levels/5/level5_yazi2.png");
        #if cpp
        //C++版本需要实现以下逻辑
        _yazi.bitmapData.copyPixels(bitmapData,rect,pos);
        _draw.copyChannel(bitmapData,rect,pos, BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        _yazi.bitmapData.copyChannel(_draw,rect,pos, BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        #elseif html5
        //HTML5需要实现以下逻辑,HTML5的渲染貌似有延迟,会导致迟早会有个黑块在
        // _draw.copyChannel(bitmapData,bitmapData.rect,new Point(), BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        // _yazi.bitmapData.copyChannel(_draw,_draw.rect,new Point(), BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        _draw.copyChannel(bitmapData,rect,pos, BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);
        _yazi.bitmapData.copyChannel(_draw,rect,pos, BitmapDataChannel.RED,BitmapDataChannel.ALPHA);
        #end       
    }

    private function onUp(e:MouseEvent):Void
    {
        _isDown = false;
    }

    private function onDown(e:MouseEvent):Void
    {
        _isDown = true;
        _lastPos.x = this.mouseX - _yazi.x + _yazi.width/2;
        _lastPos.y = this.mouseY - _yazi.y + _yazi.height/2;
        onMove(null);
    }
    

}

#3

Library version: openfl8.2.0
I hope to have a solution, worry:thinking:


#4


HTML5 platform