var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 
{
    "init": function () {

	console.log("插件编写测试");

	// 可以写一些直接执行的代码
	// 在这里写的代码将会在【资源加载前】被执行，此时图片等资源尚未被加载。
	// 请勿在这里对包括bgm，图片等资源进行操作。


	this._afterLoadResources = function () {
		// 本函数将在所有资源加载完毕后，游戏开启前被执行
		// 可以在这个函数里面对资源进行一些操作，比如切分图片等。

		// 这是一个将assets.png拆分成若干个32x32像素的小图片并保存的样例。
		// var arr = core.splitImage("assets.png", 32, 32);
		// for (var i = 0; i < arr.length; i++) {
		//     core.material.images.images["asset"+i+".png"] = arr[i];
		// }

	};

	// 可以在任何地方（如afterXXX或自定义脚本事件）调用函数，方法为 core.plugin.xxx();
	// 从V2.6开始，插件中用this.XXX方式定义的函数也会被转发到core中，详见文档-脚本-函数的转发。
},
    "drawLight": function () {

	// 绘制灯光/漆黑层效果。调用方式 core.plugin.drawLight(...)
	// 【参数说明】
	// name：必填，要绘制到的画布名；可以是一个系统画布，或者是个自定义画布；如果不存在则创建
	// color：可选，只能是一个0~1之间的数，为不透明度的值。不填则默认为0.9。
	// lights：可选，一个数组，定义了每个独立的灯光。
	//        其中每一项是三元组 [x,y,r] x和y分别为该灯光的横纵坐标，r为该灯光的半径。
	// lightDec：可选，0到1之间，光从多少百分比才开始衰减（在此范围内保持全亮），不设置默认为0。
	//        比如lightDec为0.5代表，每个灯光部分内圈50%的范围全亮，50%以后才开始快速衰减。
	// 【调用样例】
	// core.plugin.drawLight('curtain'); // 在curtain层绘制全图不透明度0.9，等价于更改画面色调为[0,0,0,0.9]。
	// core.plugin.drawLight('ui', 0.95, [[25,11,46]]); // 在ui层绘制全图不透明度0.95，其中在(25,11)点存在一个半径为46的灯光效果。
	// core.plugin.drawLight('test', 0.2, [[25,11,46,0.1]]); // 创建一个test图层，不透明度0.2，其中在(25,11)点存在一个半径为46的灯光效果，灯光中心不透明度0.1。
	// core.plugin.drawLight('test2', 0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 创建test2图层，且存在三个灯光效果，分别是中心(25,11)半径46，中心(105,121)半径88，中心(301,221)半径106。
	// core.plugin.drawLight('xxx', 0.3, [[25,11,46],[105,121,88,0.2]], 0.4); // 存在两个灯光效果，它们在内圈40%范围内保持全亮，且40%后才开始衰减。
	this.drawLight = function (name, color, lights, lightDec) {

		// 清空色调层；也可以修改成其它层比如animate/weather层，或者用自己创建的canvas
		var ctx = core.getContextByName(name);
		if (ctx == null) {
			if (typeof name == 'string')
				ctx = core.createCanvas(name, 0, 0, core.__PIXELS__, core.__PIXELS__, 98);
			else return;
		}

		ctx.mozImageSmoothingEnabled = false;
		ctx.webkitImageSmoothingEnabled = false;
		ctx.msImageSmoothingEnabled = false;
		ctx.imageSmoothingEnabled = false;

		core.clearMap(name);
		// 绘制色调层，默认不透明度
		if (color == null) color = 0.9;
		ctx.fillStyle = "rgba(0,0,0," + color + ")";
		ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

		lightDec = core.clamp(lightDec, 0, 1);

		// 绘制每个灯光效果
		ctx.globalCompositeOperation = 'destination-out';
		lights.forEach(function (light) {
			// 坐标，半径，中心不透明度
			var x = light[0],
				y = light[1],
				r = light[2];
			// 计算衰减距离
			var decDistance = parseInt(r * lightDec);
			// 正方形区域的直径和左上角坐标
			var grd = ctx.createRadialGradient(x, y, decDistance, x, y, r);
			grd.addColorStop(0, "rgba(0,0,0,1)");
			grd.addColorStop(1, "rgba(0,0,0,0)");
			ctx.beginPath();
			ctx.fillStyle = grd;
			ctx.arc(x, y, r, 0, 2 * Math.PI);
			ctx.fill();
		});
		ctx.globalCompositeOperation = 'source-over';
		// 可以在任何地方（如afterXXX或自定义脚本事件）调用函数，方法为  core.plugin.xxx();
	}
},
    "eachStep": function () {

	//记录每一步的点位
	this.recordStep = function (reason) {
		core.unshift(core.status.hero.flags.step, [
			[core.status.hero.loc.x, core.status.hero.loc.y, core.status.hero.loc.direction]
		]);
		core.drawBody();
		core.status.hero.experience--;
		if (core.status.hero.experience <= 0) {
			core.newWave();
		}
		if (reason != 'portal') core.handlePortal();
		if (core.hasFlag('showMapGroundFlag')) core.showMapGroundNumber(true);
	};

	//画身子
	this.drawBody = function (refreshAll) {
		if (refreshAll) {
			for (var i = 0; i < core.bigmap.height; i++) {
				for (var j = 0; j < core.bigmap.width; j++) {
					var target = core.getBlockId(j, i);
					if (target && ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9'].indexOf(target) >= 0)
						core.removeBlock(j, i);
				}
			}
		}

		var bodyLen = core.getFlag('bodyLen');
		var i;
		for (i = 1; i < core.status.hero.flags.step.length; i++) {
			if (i > 1 && i < bodyLen && !refreshAll) continue;
			var step = core.status.hero.flags.step[i];
			var step0 = core.status.hero.flags.step[i - 1];

			var dir1 = step[2];
			var dir2 = step0[2];
			if (i == bodyLen) dir1 = null;

			var dir = core.getBodyDirection(dir1, dir2);
			core.setBlock(dir, step[0], step[1]);
			if (i >= bodyLen) break;
		}
		var step2 = core.status.hero.flags.step[i + 1];
		if (step2) {
			if (core.hasFlag('hard')) {
				var target = core.getBlock(step2[0], step2[1]);
				if (target && ['b6', 'b7', 'b8', 'b9'].indexOf(target.block.event.id) >= 0) {
					core.removeBlock(step2[0], step2[1]);
				}
			} else {
				core.removeBlock(step2[0], step2[1]);
			}
		}
	};

	//获得身体的方向块
	this.getBodyDirection = function (dir1, dir2) {
		var dir = '';
		if (dir1 == 'up' && dir2 == 'up') dir = 'b0';
		if (dir1 == 'down' && dir2 == 'down') dir = 'b0';
		if (dir1 == 'up' && dir2 == 'down') dir = 'b0';
		if (dir1 == 'down' && dir2 == 'up') dir = 'b0';
		if (dir1 == 'left' && dir2 == 'left') dir = 'b1';
		if (dir1 == 'right' && dir2 == 'right') dir = 'b1';
		if (dir1 == 'left' && dir2 == 'right') dir = 'b1';
		if (dir1 == 'right' && dir2 == 'left') dir = 'b1';
		if (dir1 == 'left' && dir2 == 'down') dir = 'b2';
		if (dir1 == 'up' && dir2 == 'right') dir = 'b2';
		if (dir1 == 'up' && dir2 == 'left') dir = 'b3';
		if (dir1 == 'right' && dir2 == 'down') dir = 'b3';
		if (dir1 == 'right' && dir2 == 'up') dir = 'b4';
		if (dir1 == 'down' && dir2 == 'left') dir = 'b4';
		if (dir1 == 'down' && dir2 == 'right') dir = 'b5';
		if (dir1 == 'left' && dir2 == 'up') dir = 'b5';
		if (dir2 == 'up' && !dir1) dir = 'b6';
		if (dir2 == 'right' && !dir1) dir = 'b7';
		if (dir2 == 'down' && !dir1) dir = 'b8';
		if (dir2 == 'left' && !dir1) dir = 'b9';
		return dir;
	};

	//战斗后的事件
	this.bodyAfterBattle = function () {
		var x = core.nextX(1);
		var y = core.nextY(1);
		var dir = core.status.hero.loc.direction;
		core.status.hero.loc.x = x;
		core.status.hero.loc.y = y;
		core.drawHero();
		core.status.hero.flags.bodyLen++;
		core.recordStep();
	};

	//出现一波新怪
	this.newWave = function () {
		if (main.mode == "editor") return;
		var levelUpExp = core.getFlag('levelUpExp');
		var wave = core.status.thisMap.name - 0 + 1;
		core.status.thisMap.name = wave;
		core.status.hero.experience = levelUpExp;

		if (core.hasFlag('hard')) {
			var monsterArray = core.getFlag('monsterArray');
			var pts = [];
			var seq = 0;
			for (var i = 0; i < core.bigmap.height; i++) {
				for (var j = 0; j < core.bigmap.width; j++) {
					var target = core.getBlock(j, i);
					var target2 = core.getBgNumber(j, i);
					var target3 = core.status.hero.loc.x == j && core.status.hero.loc.y == i;
					if (target || target2 || target3) continue;
					if (monsterArray.indexOf(seq) >= 0) pts.push([j, i]);
					seq++;
				}
			}
			var obj = core.initMapItem(wave);
			for (var i = 0; i < pts.length; i++) {
				core.setBlock(obj[0][0], pts[i][0], pts[i][1]);
				if (!core.status.hero.flags['monsterCount_' + obj[0][0]]) core.status.hero.flags['monsterCount_' + obj[0][0]] = 0;
				if (!core.status.hero.flags['monsterCountAll_' + obj[0][0]]) core.status.hero.flags['monsterCountAll_' + obj[0][0]] = 0;
				core.status.hero.flags['monsterCount_' + obj[0][0]]++;
				core.status.hero.flags['monsterCountAll_' + obj[0][0]]++;
			}
		} else {
			var arr = core.clone(core.getMapArray(core.status.thisMap.floorId));
			var loopTime = 1;
			var obj = core.initMapItem(wave);
			for (var i = 0; i < obj.length; i++) {
				for (var j = 0; j < obj[i][1]; loopTime++) {
					if (loopTime > 300) break;
					var rd = core.rand(core.bigmap.width * core.bigmap.height);
					var x = rd % core.bigmap.width;
					var y = parseInt(rd / core.bigmap.width);
					if (arr[y][x] != 0) continue;
					if (core.getBgNumber(x, y)) continue;
					if (x == core.status.hero.loc.x && y == core.status.hero.loc.y) continue;

					if (loopTime < 100) {
						if (x > 0 && isNaN(arr[y][x - 1])) continue;
						if (y > 0 && isNaN(arr[y - 1][x])) continue;
						if (x < core.bigmap.width - 1 && isNaN(arr[y][x + 1])) continue;
						if (y < core.bigmap.height - 1 && isNaN(arr[y + 1][x])) continue;
					}

					arr[y][x] = obj[i][0];
					loopTime = 0;
					j++;
				}
			}
			for (var i = 0; i < core.bigmap.height; i++) {
				for (var j = 0; j < core.bigmap.width; j++) {
					var e = arr[i][j];
					core.setBlock(e, j, i);
				}
			}
		}

		if (core.hasFlag('hard')) {
			core.insertAction('第' + wave + '波怪物出现');
			if (wave <= 10) {
				core.getItem('bomb');
				core.getItem('shortPotion', wave);
			}
			core.randomNumber();
		} else {
			if (wave > 1) {
				core.insertAction('第' + wave + '波怪物出现');
				if (wave <= 10) core.getItem('bomb');
			}
		}
	};

	//初始化怪的内容
	this.initMapItem = function (wave) {
		var obj = [];
		var name = 'swordsman';
		if (wave == 1) name = 'greenSlime';
		if (wave == 2) name = 'redSlime';
		if (wave == 3) name = 'bat';
		if (wave == 4) name = 'bluePriest';
		if (wave == 5) name = 'yellowKnight';
		if (wave == 6) name = 'skeleton';
		if (wave == 7) name = 'zombie';
		if (wave == 8) name = 'rock';
		if (wave == 9) name = 'skeletonSoilder';
		if (wave == 10) name = 'swordsman';
		obj.push([name, 20]);
		return obj;
	};

	//处理传送门
	this.handlePortal = function () {
		var x = core.status.hero.loc.x;
		var y = core.status.hero.loc.y;
		var target = core.getBgNumber(x, y);
		if (target == 89) {
			var portals = core.status.hero.flags.portal;
			var choices = [];
			var hasItem = false;
			for (var i in portals) {
				var portal = portals[i];
				if (portal[0] == x && portal[1] == y) continue;
				if (core.getBlock(portal[0], portal[1])) continue;
				var item = {};
				item.text = '传送至（' + portal[0] + ', ' + portal[1] + '）';
				item.action = [{ "type": "function", "function": "function(){ core.usePortal(" + portal[0] + ", " + portal[1] + "); }" }];
				choices.push(item);
				hasItem = true;
			}
			if (hasItem) {
				var item = {};
				item.text = '不传送';
				item.action = [];
				choices.push(item);
				core.insertAction(
					[{
						"type": "choices",
						"text": "要传送吗？",
						"choices": choices
					}]
				);
			}
		}
	};

	//传送
	this.usePortal = function (x, y) {
		core.status.hero.loc.x = x;
		core.status.hero.loc.y = y;
		core.drawHero();
		core.recordStep('portal');
	};

	//显示点位数字
	this.showMapGroundNumber = function (isShow) {
		var seq = 0;
		if (isShow) core.clearMap('fg');
		for (var i = 0; i < core.bigmap.height; i++) {
			for (var j = 0; j < core.bigmap.width; j++) {
				var target = core.getBlock(j, i);
				var target2 = core.getBgNumber(j, i);
				var target3 = core.status.hero.loc.x == j && core.status.hero.loc.y == i;
				if (target || target2 || target3) continue;
				if (isShow) {
					if (isShow == 'all')
						core.fillText('fg', seq, 8 + 32 * j, 20 + 32 * i, '#fff', '13px Arial');
					else if (core.getFlag('monsterArray').indexOf(seq) >= 0)
						core.fillText('fg', '●', 8 + 32 * j, 20 + 32 * i, '#fff', '20px Arial');
				}
				seq++;
			}
		}
		return seq;
	};

	//随机20个数字
	this.randomNumber = function () {
		var count = 20;
		var max = Math.max(core.showMapGroundNumber() - core.itemCount('portalItem') - core.itemCount('redPotion'), count);
		var arr = [];
		for (var i = 0; i < count; i++) {
			var rd = core.rand(max);
			if (arr.indexOf(rd) >= 0) {
				i--;
				continue;
			}
			arr.push(rd);
		}
		var brr = arr.sort(function (x, y) { return x - y; });
		core.setFlag('monsterArray', brr);
		if (core.hasFlag('showMapGroundFlag')) core.showMapGroundNumber(true);
	};

	//是否有特殊属性重写
	core.enemys.hasSpecial = function (special, test) {
		if (core.hasFlag('hard')) {
			var wave = special - 100;
			var obj = core.initMapItem(wave);
			var countOrigin = core.getFlag('monsterCountAll_' + obj[0][0], 0);
			var countNow = core.getFlag('monsterCount_' + obj[0][0], 0);
			if (countNow * 2 <= countOrigin) {
				if (test == 1) return true;
			}
		}

		if (special == null) return false;

		if (special instanceof Array) {
			return special.indexOf(test) >= 0;
		}

		if (typeof special == 'number') {
			return special === test;
		}

		if (typeof special == 'string') {
			return this.hasSpecial(core.material.enemys[special], test);
		}

		if (special.special != null) {
			return this.hasSpecial(special.special, test);
		}

		return false;
	};

	//推箱子后不移动勇士
	core.events.pushBox = function (data) {
		if (data.event.id != 'box' && data.event.id != 'boxed') return;

		// 判断还能否前进，看看是否存在事件
		var direction = core.getHeroLoc('direction'),
			nx = data.x + core.utils.scan[direction].x,
			ny = data.y + core.utils.scan[direction].y;

		// 检测能否推上去
		if (!core.canMoveHero() || !core.canMoveHero(data.x, data.y, direction)) return;
		var nextId = core.getBlockId(nx, ny);
		if (nextId != null && nextId != 'flower') return;

		core.setBlock(nextId == null ? 169 : 170, nx, ny);

		if (data.event.id == 'box')
			core.removeBlock(data.x, data.y);
		else
			core.setBlock(168, data.x, data.y);

		var x = core.status.hero.loc.x;
		var y = core.status.hero.loc.y;
		var target = core.getBgNumber(nx, ny);
		if (target == 89) {
			var portals = core.status.hero.flags.portal;
			for (var i in portals) {
				var portal = portals[i];
				if (portal[0] == x && portal[1] == y) continue;
				if (core.getBlock(portal[0], portal[1])) continue;
				core.removeBlock(nx, ny);
				core.setBlock(169, portal[0], portal[1]);
				break;
			}
		}

		core.updateStatusBar();
		//this._pushBox_moveHero(direction);
		core.status.holdingKeys = [];
	};

	//瘦身
	core.shortBody = function (short_) {
		core.status.hero.flags.bodyLen -= short_;
		if (core.status.hero.flags.bodyLen < 3) core.status.hero.flags.bodyLen = 3;
		core.drawBody(true);
	};
},
    "fangxiang": function () {

	///////////////////// 方向盘
	window.dljgs1 = {};

	// canvas Sprite:>>><<<<<
	// ======  UI组件？ ===========
	// 绑定显示和控制的画布 显示时绘制在UI上(不进存档)
	// 目前存在的几个问题 ：
	// 1. 非lockControl下与系统的操作冲突如何解决？比如点地图应该是点UI 但却变成了行走——必须能够自己定义操作的层级，而不是仅限于UI上，要高于默认操作的层级才能使之有效
	// 2. 组件的绘制速度优化
	// 3. 组件操作与画布的自动绑定（通过指针），而非仅仅判断操作范围
	// 4. 组件对象化（组件是一个基类 可继承）
	// 5. action命名空间污染问题
	// 6.
	window.dljgs1.componentList = [];
	// /////////////////////////////////////////////////////////////////
	/*
	 * name : 组件名称/ID，如果没有传入画布就会用这个名字建立canvas用来绘制组件
	 * rect ： 所占区域的位置：可以是rect表达 也可以是某个画布名（xy坐标将会归零需要重新制定） 或者ctx
	 * draw : 绘制方法，需要处理callback（因为绘制是有可能读数据再绘制的，组件并不知道读了什么数据）
	 * actions : 交互行为，字典格式{'ondown':[], 'XX':[]}
	 * options : 其他选项： 优先级prior 父画布的名称 rootCanvas
	 * ***/

	var componentCanvas = function (name, opt) { //opt就是数据
		this.name = name;
		opt = opt || {};
		opt.hwnd = this; //重要的控制指针
		opt.rect = opt.rect || name;
		opt.draw = opt.draw || function (name, callback) {
			callback();
		}; //默认空组件的绘制行为
		opt.actions = opt.actions || {};
		opt.prior = opt.prior || 0;
		opt.x = opt.x || 0;
		opt.y = opt.y || 0;
		opt.w = opt.w || 0;
		opt.h = opt.h || 0;
		opt.rootCanvas = opt.rootCanvas || 'dljgs1_component';
		//父画布在确定之后能否通过数据修改？理论上可以 但不推荐 因为重定位麻烦
		var ctx = null;
		var canvasName = name;
		var isEnable = false;
		var actions = opt.actions;
		var rect = opt.rect;
		var hwnd = this;

		//console.log(rect)
		if (typeof rect === "object") { //放弃rect表示法吧 ？
			opt.x = rect[0];
			opt.y = rect[1];
			opt.w = rect[2];
			opt.h = rect[3];
		} else if (typeof rect === "string") {
			canvasName = rect;
		} else {
			ctx = rect;
		}

		this.canvasName = canvasName;
		this.children = [];
		// init
		dljgs1.componentList.push(this); //每次new自动注册 不需要注册函数了

		/////////// 画布相关
		var drawOnFather = function () { //快速绘制
			var rootCtx = core.getContextByName(opt.rootCanvas);
			//rootCtx.clearRect(opt.x,opt.y,opt.w,opt.h);//是否必要？？父画布本来就会自己清空一次？
			rootCtx.drawImage(ctx.canvas, opt.x, opt.y, opt.w, opt.h);
		};
		// 刷新
		this.flush = function (callback) {
			var ctx = core.getContextByName(canvasName);
			var ct = this.children.length;
			var children = this.children;
			if (!isEnable) {
				return;
			}
			var afterDraw = function () {
				drawOnFather();
				if (callback) callback();
			};
			core.clearMap(canvasName);
			opt.draw(canvasName, function () {
				//console.log('绘制完毕');
				if (ct === 0) afterDraw();
				children.forEach(function (it) {
					it.flush(function () {
						ct -= 1;
						if (0 === ct) afterDraw(); //所有子画布画完之后再执行本画布往父画布的绘制 保证堆叠有效
					});
				});
			});
		};

		// 重建画布
		this.reConstruct = function (_x, _y, _w, _h) {
			if (main.replayChecking) return;
			_x = _x || opt.x;
			_y = _y || opt.y;
			_w = _w || opt.w;
			_h = _h || opt.h;
			var tmp = core.getContextByName(opt.rootCanvas).canvas;
			if (_w > 1.0) {
				opt.w = _w;
				opt.h = _h;
			} else {
				opt.w = parseInt(tmp.width * _w);
				opt.h = parseInt(tmp.height * _h);
			}
			if (_x < 1.0 && _x > 0 && _y < 1.0 && _y > 0) {
				//根据指定的xy比例自适应调控位置 _x_y指定画布中心相对于整个父画布的偏移 xy最终还是左上角
				var ox = tmp.width * _x,
					oy = tmp.height * _y;
				opt.x = parseInt(ox - opt.w / 2);
				opt.y = parseInt(oy - opt.h / 2);
			} else {
				opt.x = _x;
				opt.y = _y;
			}
			ctx = core.createCanvas(canvasName, opt.x, opt.y, opt.w, opt.h);
			this.flush();
		};

		// 重建所有画布
		this.reMapAll = function () {
			this.reConstruct();
			this.children.forEach(function (it) {
				it.reMapAll()
			});
		};

		////// 显示控制相关：

		// 局部控制：
		// 使用隐藏可以支持快速绘制（canvas处于被保存的状态 如果数据不改变可以不刷新画布直接画上去）
		this.hide = function (keepAction) {
			if (!keepAction) {
				this.disable();
			}
			core.clearMap(opt.rootCanvas);
		};
		this.show = function (noFlush) { //显示并使能 适用于隐藏后恢复
			this.enable();
			if (noFlush) {
				drawOnFather();
			} else {
				this.flush();
			}
		};
		// 整体控制：
		this.enable = function () { //使能会检查画布是否存在 但不会显示 适用于失能后的恢复
			isEnable = true;
			if (!core.getContextByName(canvasName)) {
				//console.log(canvasName+'重建画布');
				this.reMapAll();
			}
			if (opt.construct) { //如果存在构造函数 每次使能的时候调用
				opt.construct();
			}
			this.children.forEach(function (it) {
				it.enable()
			});
		};
		this.disable = function () { //disable不会隐藏只是不能按了
			isEnable = false;
			if (opt.denstruct) { //如果存在析构函数 每次失能的时候调用
				opt.denstruct();
			}
			this.children.forEach(function (it) {
				it.disable()
			});
		};

		////// 数据控制相关
		this.init = function () { //初始化 注册交互行为、画布 根据初始的相对坐标重建
			if (!core.getContextByName(canvasName));
			this.reConstruct();
			//console.log('init '+canvasName);
			for (var a in actions) {
				this.procRegister(a, actions[a]);
			}
			this.children.forEach(function (it) {
				it.init()
			});
		};

		// 移除组件 ： 在很长一段时间都不会使用的情况下用 再使用需要重新注册 会将其子组件也一起移除
		this.remove = function () {
			for (var a in actions) {
				this.procRegister(a, actions[a], true);
			}
			dljgs1.componentList = dljgs1.componentList.filter(function (it) {
				return it.name !== name;
			});
		};

		this.addParent = function (comp) {
			opt.rootCanvas = comp.canvasName;
			this.parent = comp;
		};
		this.appendComponent = function (comp) { //将另一个组件放到当前组件上（可能需要重定位）
			//comp.rootCanvas = name;//光这里改是不行的
			comp.addParent(this);
			this.children.push(comp);
		};
		this.getLocBias = function () {
			var x = opt.x,
				y = opt.y;
			if (this.parent) {
				bias = this.parent.getLocBias();
				x += bias.x;
				y += bias.y;
			}
			return {
				'x': x,
				'y': y
			};
		};
		var controlCon = function () {
			if (isEnable) core.lockControl();
			else core.unLockControl();
		};

		// action交互注册相关： 存在一个问题，即判断action时无法对组件本身进行控制，只能控制“数据”
		// 这样的话需要组件和数据分离 尤其是如果数据需要存储 所以组件的控制应当交由控制接口
		// 比如要实现一个能够拖动的控制盘 就需要控制盘的位置由数据控制，而这个数据被action所改变
		// 数据存在哪里？必须是action和component都能访问的地方，可以存到一个集中管理区
		// 数据如何定义？其实就是每次初始化组件需要传入的所有参数 : opt
		// 注册的函数能否在使用过程中修改行为？暂时不支持，使用者自己控制
		this.procRegister = function (type, dofun, unReg) { //注册与撤销
			var packFun = function () { //对行为函数的基本包装：只有处于enable下才会执行
				if (isEnable) return dofun.apply(this, arguments)
			};
			var parent = this.parent; //向父类获取绝对物理坐标
			var fun = packFun;
			if (!unReg) {
				//console.log('regist : ' + type);
				if (type === 'ondown' || type === 'onclick') { //对存在像素判断的类型进行包装 默认包装ondown与onclick onmove不算在内
					fun = function (_x, _y, px, py) {
						var bias = {
							'x': 0,
							'y': 0
						};
						if (parent) {
							bias = parent.getLocBias(name)
						};
						var lx = bias.x + opt.x,
							ly = bias.y + opt.y;
						var rx = lx + opt.w,
							ry = ly + opt.h;
						if (px < rx && px > lx && py < ry && py > ly) {
							return packFun(_x, _y, px, py);
						}
					}
				}
				core.registerAction(type, name, fun, opt.prior);
			} else { //注销
				//console.log('un reg : ' + unReg + type);
				core.unregisterAction(type, name);
			}
		}
	};

	window.dljgs1.getComponent = function (name) {
		for (var i in this.componentList) {
			if (this.componentList[i].name === name) return this.componentList[i];
		}
	};
	// 初始化组件必备canvas
	window.dljgs1.initComponent = function () {
		if (main.mode == "editor") return;
		core.createCanvas('dljgs1_component', 0, 0, core.__PIXELS__, core.__PIXELS__, 145);
		dljgs1.pannel = dljgs1.pannel || new directionPannel();
		dljgs1.pannel.init();
		if (dljgs1.pannel.isOpen()) {
			dljgs1.pannel.open();
		}
	};
	core.ui.deleteAllCanvas = function () {
		Object.keys(core.dymCanvas).forEach(function (name) {
			if (name.indexOf('dljgs1') == -1) {
				core.dom.gameDraw.removeChild(core.dymCanvas[name].canvas);
				delete core.dymCanvas[name];
			}
		});
	}

	// 控制盘 —— 可以被拖动的一个矩形区域
	var pannel = function (rect) {
		var isdown = false;
		var down_px, down_py;
		var backHwnd;
		rect = rect || [1 / 2, 1 / 2, 1 / 4, 1 / 4];
		var backData = {
			'hwnd': null,
			'rect': rect, //画布相对位置与大小
			'prior': 101,
			'actions': {
				'ondown': function (x, y, px, py) {
					isdown = true;
					down_px = px;
					down_py = py;
					return true;
				},
				'onup': function () {
					isdown = false;
				},
				'onmove': function (x, y, px, py) { //拖动控制盘？只有不是按钮的位置才能拖动 按钮优先级更高
					if (isdown) {
						//console.log('onmove'+px+','+'');
						backHwnd.hide();
						backData.x += px - down_px;
						backData.y += py - down_py; //正常情况需要计算相对位移 直接赋值会导致位置偏差 这里是第一层无所谓
						down_px = px;
						down_py = py;
						backHwnd.show();
						return true;
					}
					return false;
				}
			},
			'draw': function (name, callback) {
				core.setAlpha(name, 0.7);
				core.fillRect(name, 0, 0, 200, 200, "#555555");
				callback();
			}
		};
		backHwnd = new componentCanvas('back', backData);
		this.init = function () {
			backHwnd.init();
		};
		this.open = function () {
			backHwnd.show();
		};
		this.close = function () {
			backHwnd.hide();
		};
		this.hwnd = backHwnd;
	};

	// 简易方向盘
	var directionPannel = function () {
		var back = new pannel([1 / 2, 1 / 2, 1 / 4 * 1.45, 1 / 6 * 1.45]);
		var action = function (dir) {
			if (dir === 'hide') {
				return {
					'ondown': function () {
						back.close();
						return true;
					}
				}
			}
			var mesh = {
				'left': 37,
				'up': 38,
				'right': 39,
				'down': 40
			};
			return {
				'ondown': function () {
					//console.log('ondown '+dir);
					core.actions._sys_onkeyDown({
						'keyCode': mesh[dir],
						'preventDefault': function () {; }
					});
					return true;
				},
				'onup': function () {
					core.status.holdingKeys = core.status.holdingKeys || [];
					core.actions._sys_onkeyUp({
						'keyCode': mesh[dir],
						'preventDefault': function () {; }
					});
					return false;
				}
			};
		};
		var rects = {
			up: [1 / 2, 1 / 4, 1 / 3, 1 / 2],
			left: [1 / 6, 3 / 4, 1 / 3, 1 / 2],
			down: [1 / 2, 3 / 4, 1 / 3, 1 / 2],
			right: [5 / 6, 3 / 4, 1 / 3, 1 / 2],
			//hide:[5/6,1/4,1/3,1/2]
		};
		var data = {};
		var draws = function (dir) {
			return function (name, callback) {
				var w = data[dir].w,
					h = data[dir].h;
				var chrText = {
					'up': '↑',
					'down': '↓',
					'left': '←',
					'right': '→',
					'hide': '[x]'
				};
				core.setAlpha(name, 0.9);
				core.fillRect(name, 1, 1, w - 2, h - 2, "#111444");
				core.setTextBaseline(name, 'middle');
				core.setTextAlign(name, 'center');
				core.setFont(name, core.ui._buildFont(20, true));
				core.fillText(name, chrText[dir], data[dir].w / 2, data[dir].h / 2, "#FFFFFF");
				callback();
			}
		};
		for (var dir in rects) {
			data[dir] = {
				'rect': rects[dir],
				'prior': 102,
				'actions': action(dir),
				'draw': draws(dir)
			};
			back.hwnd.appendComponent(new componentCanvas(dir, data[dir]));
		}
		var is_open = false;
		this.isOpen = function () {
			return is_open;
		}
		this.open = function () {
			is_open = true;
			back.open();
		};
		this.close = function () {
			is_open = false;
			back.close();
		};
		this.init = function () {
			back.init();
		};
		this.switchOff = function () {
			is_open === false ? this.open() : this.close();
			return is_open;
		};
	};

	/////////////////////重写/////////////////
	//var origin_resetGame = core.events.resetGame;
	//core.events.prototype.resetGame = function(hero, hard, floorId, maps, values){
	//	origin_resetGame.bind(core.events)(hero, hard, floorId, maps, values);
	//};
	/// 初始化游戏

	var originAfterStart = core.events._startGame_afterStart;
	core.events._startGame_afterStart = function (nowLoc, callback) {
		originAfterStart.bind(core.events)(nowLoc, callback);
		dljgs1.initComponent();
	}
	main.statusBar.image.keyboard.onclick = function (e) {
		e.stopPropagation();
		if (core.isReplaying()) {
			core.bookReplay();
			return;
		}
		if (main.core.isPlaying())
			dljgs1.pannel.switchOff();
	};
	////////////////////////////////////////////////////////	
}
}