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);
}
}