diff --git a/build/editor.js b/build/editor.js
new file mode 100644
index 0000000..c8da425
--- /dev/null
+++ b/build/editor.js
@@ -0,0 +1,35 @@
+const gulp = require('gulp');
+const yargs = require('yargs');
+const Haxe = require('../tasks/haxe');
+const FlashPlayer = require('../tasks/flashplayer');
+const version = require('./version');
+const prepare = require('./prepare');
+const debug = require('../tasks/debug');
+
+
+const build = (platform) => function build() {
+ const argv = yargs.argv;
+ return gulp.src('.')
+ .pipe(new Haxe().openfl({
+ command: 'build',
+ platform: platform,
+ version: version,
+ values: {
+ build_editor: true
+ },
+ debug: argv.dev,
+ }))
+ .pipe(gulp.dest(`target/${platform}`));
+};
+
+
+const testFlash = function() {
+ const argv = yargs.argv;
+ return build('flash')()
+ .pipe(new FlashPlayer().run(argv.dev))
+ .pipe(debug());
+};
+
+
+exports['editor:flash'] = gulp.series(prepare(Haxe.ID), build('flash'));
+exports['editor:flash:test'] = gulp.series(prepare(Haxe.ID, FlashPlayer.ID), testFlash);
diff --git a/gulpfile.js b/gulpfile.js
index e06e65f..7e45d34 100755
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -29,6 +29,7 @@ const merge = (value) => {
exports.update = prepare.update;
merge('./build/prepare');
merge('./build/client');
+merge('./build/editor');
merge('./build/server');
diff --git a/project.xml b/project.xml
index 0536f4c..fcc9e10 100755
--- a/project.xml
+++ b/project.xml
@@ -20,4 +20,9 @@
+
+
\ No newline at end of file
diff --git a/src/common/haxe/ru/m/tankz/config/LevelBundle.hx b/src/common/haxe/ru/m/tankz/config/LevelBundle.hx
index dd4361f..4976dbd 100644
--- a/src/common/haxe/ru/m/tankz/config/LevelBundle.hx
+++ b/src/common/haxe/ru/m/tankz/config/LevelBundle.hx
@@ -13,10 +13,9 @@ class LevelBundle {
return result;
}
- public static function get(type:GameType, config:Config, level:Int):Array {
- var bricksData:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
+ public static function parse(config:Config, data:String):Array {
var bricks:Array = [];
- for (line in ~/\s+/g.split(bricksData)) {
+ for (line in ~/\s+/g.split(data)) {
for (c in line.split('')) {
if (c.length > 0) {
bricks.push(config.bricks[Std.parseInt(c) + 1]);
@@ -25,4 +24,9 @@ class LevelBundle {
}
return bricks;
}
+
+ public static function get(type:GameType, config:Config, level:Int):Array {
+ var data:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
+ return parse(config, data);
+ }
}
diff --git a/src/editor/haxe/ru/m/tankz/editor/Editor.hx b/src/editor/haxe/ru/m/tankz/editor/Editor.hx
new file mode 100644
index 0000000..66accb3
--- /dev/null
+++ b/src/editor/haxe/ru/m/tankz/editor/Editor.hx
@@ -0,0 +1,81 @@
+package ru.m.tankz.editor;
+
+
+import ru.m.tankz.config.Config;
+import ru.m.tankz.config.LevelBundle;
+import ru.m.tankz.game.ClassicGame;
+import ru.m.tankz.config.ConfigBundle;
+import haxework.gui.ButtonView;
+import haxework.gui.Root;
+import flash.text.Font;
+import haxework.resources.Resources;
+import haxework.resources.IResources;
+import haxework.provider.Provider;
+import haxework.log.TraceLogger;
+import haxework.gui.ViewBuilder;
+import haxework.gui.GroupView;
+import haxework.log.JSLogger;
+import haxework.log.SocketLogger;
+
+
+interface EditorViewLayout {
+ var openButton(default, null):ButtonView;
+ var mapView(default, null):MapEditView;
+}
+
+
+@:template("ru/m/tankz/editor/Editor.json")
+class EditorView extends GroupView implements ViewBuilder implements EditorViewLayout {}
+
+class Editor {
+
+ private static inline var TAG = "Tankz.Editor";
+
+ public static function main() {
+ L.push(new TraceLogger());
+ #if flash
+ L.push(new JSLogger());
+ #end
+ #if debug
+ L.push(new SocketLogger());
+ #end
+ Const.init();
+ L.d(TAG, "Debug: " + Const.DEBUG);
+ L.i(TAG, "Version: " + Const.VERSION);
+ L.i(TAG, "Build: " + Const.BUILD);
+ new Editor();
+ }
+
+
+ private var view:EditorView;
+ private var config:Config;
+
+ public function new() {
+ Provider.setFactory(IResources, Resources);
+
+ var font:Font = Font.enumerateFonts()[0];
+ Provider.get(IResources).text.put("font", "Bookman Old Style");
+ Provider.get(IResources).text.put("version", 'v${Const.VERSION} b${Const.BUILD}');
+
+ view = new EditorView();
+ Root.bind(view);
+ view.content.stage.stageFocusRect = false;
+
+ view.openButton.onPress = this;
+
+ config = ConfigBundle.get(ClassicGame.TYPE);
+ view.mapView.config = config.map;
+ }
+
+ public function onPress(v:ButtonView):Void {
+ switch (v.id) {
+ case 'openButton':
+ L.d(TAG, 'OPEN');
+ FileUtil.browse().then(function(data) {
+ view.mapView.data = LevelBundle.parse(config, data);
+ });
+ case _:
+ }
+ }
+
+}
diff --git a/src/editor/haxe/ru/m/tankz/editor/Editor.json b/src/editor/haxe/ru/m/tankz/editor/Editor.json
new file mode 100644
index 0000000..27ae2b6
--- /dev/null
+++ b/src/editor/haxe/ru/m/tankz/editor/Editor.json
@@ -0,0 +1,37 @@
+{
+ "@type": "haxework.gui.GroupView",
+ "pWidth": 100, "pHeight": 100,
+ "views": [
+ {
+ "@type": "haxework.gui.VGroupView",
+ "pWidth": 100, "pHeight": 100,
+ "views": [
+ {
+ "@type": "haxework.gui.HGroupView",
+ "pWidth": 100, "height": 20,
+ "views": [
+ {
+ "id": "openButton",
+ "@type": "haxework.gui.ButtonView",
+ "text": "Open", "contentSize": true,
+ "skin": {"@type": "haxework.gui.skin.ButtonColorSkin", "color": "#aaff00"}
+ }
+ ]
+ },
+ {
+ "id": "mapView",
+ "@type": "ru.m.tankz.editor.MapEditView",
+ "contentSize": true
+ }
+ ]
+ },
+ {
+ "@type": "haxework.gui.LabelView",
+ "inLayout": false,
+ "contentSize": true,
+ "vAlign": "BOTTOM",
+ "hAlign": "RIGHT",
+ "text": "@res:text:version"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/editor/haxe/ru/m/tankz/editor/FileUtil.hx b/src/editor/haxe/ru/m/tankz/editor/FileUtil.hx
new file mode 100644
index 0000000..d3369bf
--- /dev/null
+++ b/src/editor/haxe/ru/m/tankz/editor/FileUtil.hx
@@ -0,0 +1,34 @@
+package ru.m.tankz.editor;
+
+import promhx.Deferred;
+import flash.events.ProgressEvent;
+import flash.events.IOErrorEvent;
+import flash.events.Event;
+import flash.net.FileReference;
+import promhx.Promise;
+
+
+class FileUtil {
+
+ public static function browse():Promise {
+ var d = new Deferred();
+ var file = new FileReference();
+ file.addEventListener(Event.SELECT, function(event:Event) {
+ cast(event.target, FileReference).load();
+ });
+ file.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent) {
+ d.throwError(event);
+ });
+ file.addEventListener(ProgressEvent.PROGRESS, function(event:ProgressEvent) {
+ trace('progress', '${event}');
+ });
+ file.addEventListener(Event.COMPLETE, function(event:Event) {
+ var bytes = cast(event.target, FileReference).data;
+ var data = bytes.readUTFBytes(bytes.length);
+ d.resolve(data);
+ });
+ file.browse();
+ return d.promise();
+ }
+
+}
diff --git a/src/editor/haxe/ru/m/tankz/editor/MapEditView.hx b/src/editor/haxe/ru/m/tankz/editor/MapEditView.hx
new file mode 100644
index 0000000..21bea35
--- /dev/null
+++ b/src/editor/haxe/ru/m/tankz/editor/MapEditView.hx
@@ -0,0 +1,103 @@
+package ru.m.tankz.editor;
+
+import flash.display.DisplayObjectContainer;
+import flash.display.Graphics;
+import flash.display.Sprite;
+import ru.m.tankz.render.RenderItem;
+import ru.m.tankz.config.Config;
+import ru.m.tankz.map.LevelMap;
+import haxework.gui.SpriteView;
+
+
+//ToDo: copy paste from ru.m.tankz.render.Render
+class MapEditView extends SpriteView {
+
+ public var config(default, set):MapConfig;
+ public var data(default, set):Array;
+ public var map(default, null):LevelMap;
+
+ private var items:Map>;
+
+ private var backgroundLayer:Sprite;
+ private var upLayer:Sprite;
+ private var groundLayer:Sprite;
+
+ public function new() {
+ super();
+ items = new Map();
+ map = null;
+ backgroundLayer = new Sprite();
+ upLayer = new Sprite();
+ groundLayer = new Sprite();
+ contentAsSprite.addChild(backgroundLayer);
+ contentAsSprite.addChild(groundLayer);
+ contentAsSprite.addChild(upLayer);
+ reset();
+ }
+
+ private function clearLayer(layer:DisplayObjectContainer) {
+ while (layer.numChildren > 0) layer.removeChildAt(0);
+ }
+
+ public function reset():Void {
+ for (item in items.iterator()) {
+ item.dispose();
+ }
+ items = new Map();
+ clearLayer(groundLayer);
+ clearLayer(upLayer);
+ }
+
+ private function drawBackground():Void {
+ var mapWidth = map.gridWidth * map.cellWidth;
+ var mapHeight = map.gridHeight * map.cellHeight;
+ var g:Graphics = backgroundLayer.graphics;
+ g.clear();
+ g.beginFill(0x000000);
+ g.drawRect(0, 0, mapWidth, mapHeight);
+ g.endFill();
+ if (contentSize) {
+ width = mapWidth;
+ height = mapHeight;
+ }
+ }
+
+ override public function update():Void {
+ if (this.map != null) {
+ drawBackground();
+ drawMap();
+ }
+ super.update();
+ }
+
+ private function drawMap() {
+ for (brick in map.bricks) if (brick.config.type > 0) {
+ if (!items.exists(brick.key)) {
+ items[brick.key] = new BrickItem(brick);
+ if (brick.config.layer > 2) {
+ upLayer.addChild(items[brick.key].view);
+ } else {
+ groundLayer.addChild(items[brick.key].view);
+ }
+ }
+ }
+ for (item in items) {
+ item.update();
+ }
+ }
+
+ private function set_config(value:MapConfig):MapConfig {
+ config = value;
+ map = new LevelMap(config);
+ invalidate();
+ return config;
+ }
+
+ private function set_data(value:Array):Array {
+ data = value;
+ reset();
+ map.setData(value);
+ invalidate();
+ return data;
+ }
+}