From 421f925a6055e4443342fe1039816e8710ddf1a8 Mon Sep 17 00:00:00 2001 From: shmyga Date: Sun, 4 Feb 2018 23:32:00 +0300 Subject: [PATCH] [editor] added editor module --- build/editor.js | 35 ++++++ gulpfile.js | 1 + project.xml | 5 + .../haxe/ru/m/tankz/config/LevelBundle.hx | 10 +- src/editor/haxe/ru/m/tankz/editor/Editor.hx | 81 ++++++++++++++ src/editor/haxe/ru/m/tankz/editor/Editor.json | 37 +++++++ src/editor/haxe/ru/m/tankz/editor/FileUtil.hx | 34 ++++++ .../haxe/ru/m/tankz/editor/MapEditView.hx | 103 ++++++++++++++++++ 8 files changed, 303 insertions(+), 3 deletions(-) create mode 100644 build/editor.js create mode 100644 src/editor/haxe/ru/m/tankz/editor/Editor.hx create mode 100644 src/editor/haxe/ru/m/tankz/editor/Editor.json create mode 100644 src/editor/haxe/ru/m/tankz/editor/FileUtil.hx create mode 100644 src/editor/haxe/ru/m/tankz/editor/MapEditView.hx 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; + } +}