Merge remote-tracking branch 'origin/editor'

This commit is contained in:
2018-02-06 23:20:20 +03:00
17 changed files with 367 additions and 235 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "tankz", "name": "tankz",
"version": "0.4.2", "version": "0.5.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"ansi-colors": "^1.0.1", "ansi-colors": "^1.0.1",

View File

@@ -91,6 +91,7 @@ class BrickItem extends RenderItem<Brick, Shape> {
var g = view.graphics; var g = view.graphics;
g.clear(); g.clear();
if (value.destroyed) return; if (value.destroyed) return;
if (value.config.type > 0) {
g.beginBitmapFill(image); g.beginBitmapFill(image);
g.drawRect(0, 0, value.rect.width, value.rect.height); g.drawRect(0, 0, value.rect.width, value.rect.height);
for (c in value.cells) { for (c in value.cells) {
@@ -101,6 +102,7 @@ class BrickItem extends RenderItem<Brick, Shape> {
} }
g.endFill(); g.endFill();
} }
}
override public function update():Void { override public function update():Void {
super.update(); super.update();

View File

@@ -55,7 +55,7 @@ class StartFrame extends VGroupView implements ViewBuilder implements StartFrame
Provider.get(IFrameSwitcher).change(LevelFrame.ID); Provider.get(IFrameSwitcher).change(LevelFrame.ID);
case DotaGame.TYPE: case DotaGame.TYPE:
Provider.set(GameState, DotaGame.buildState(0, mode)); Provider.set(GameState, DotaGame.buildState(0, mode));
Provider.get(IFrameSwitcher).change(GameFrame.ID); Provider.get(IFrameSwitcher).change(LevelFrame.ID);
} }
} }
} }

View File

@@ -9,89 +9,34 @@ map:
gridHeight: 26 gridHeight: 26
bricks: bricks:
# border - {type: -1, layer: 2, armor: -1} # border
- type: -1 - {type: 0, layer: 0, armor: 0} # none
layer: 2 - {type: 1, layer: 0, armor: 0} # ace
armor: -1 - {type: 2, layer: 3, armor: 0} # bush
# none - {type: 3, layer: 1, armor: 0} # water
- type: 0 - {type: 4, layer: 2, armor: 2} # armor
layer: 0 - {type: 5, layer: 2, armor: 1} # brick
armor: 0
# ace
- type: 1
layer: 0
armor: 0
# bush
- type: 2
layer: 3
armor: 0
# water
- type: 3
layer: 1
armor: 0
# armor
- type: 4
layer: 2
armor: 2
# brick
- type: 5
layer: 2
armor: 1
teams: teams:
- id: human - id: human
spawnInterval: 0 spawnInterval: 0
tanks: tanks:
- group: human - {group: human, type: 0, rate: 1}
type: 0
rate: 1
points:
- type: eagle
index: -1
x: 12
y: 24
direction: right
- type: tank
index: 0
x: 8
y: 24
direction: top
- type: tank
index: 1
x: 16
y: 24
direction: top
- id: bot - id: bot
spawnInterval: 3000 spawnInterval: 3000
tanks: tanks:
- group: bot - {group: bot, type: 0, rate: 0.5}
type: 0 - {group: bot, type: 1, rate: 0.5}
rate: 0.5 - {group: bot, type: 2, rate: 0.5}
- group: bot - {group: bot, type: 3, rate: 0.5}
type: 1
rate: 0.5
- group: bot
type: 2
rate: 0.5
- group: bot
type: 3
rate: 0.5
points: points:
- type: tank - {team: human, type: eagle, index: -1, direction: right, x: 12, y: 24}
index: -1 - {team: human, type: tank, index: 0, direction: top, x: 8, y: 24}
x: 0 - {team: human, type: tank, index: 1, direction: top, x: 16, y: 24}
y: 0 - {team: bot, type: tank, index: -1, direction: bottom, x: 0, y: 0}
direction: bottom - {team: bot, type: tank, index: -1, direction: bottom, x: 12, y: 0}
- type: tank - {team: bot, type: tank, index: -1, direction: bottom, x: 24, y: 0}
index: -1
x: 12
y: 0
direction: bottom
- type: tank
index: -1
x: 24
y: 0
direction: bottom
bullet: &bullet bullet: &bullet
width: 12 width: 12

View File

@@ -9,120 +9,41 @@ map:
gridHeight: 30 gridHeight: 30
bricks: bricks:
# border - {type: -1, layer: 2, armor: -1} # border
- type: -1 - {type: 0, layer: 0, armor: 0} # none
layer: 2 - {type: 1, layer: 0, armor: 0} # ace
armor: -1 - {type: 2, layer: 3, armor: 0} # bush
# none - {type: 3, layer: 1, armor: 0} # water
- type: 0 - {type: 4, layer: 2, armor: 2} # armor
layer: 0 - {type: 5, layer: 2, armor: 1} # brick
armor: 0
# ace
- type: 1
layer: 0
armor: 0
# bush
- type: 2
layer: 3
armor: 0
# water
- type: 3
layer: 1
armor: 0
# armor
- type: 4
layer: 2
armor: 2
# brick
- type: 5
layer: 2
armor: 1
team_tanks: &team_tanks team_tanks: &team_tanks
tanks: tanks:
- group: any - {group: any, type: 0, rate: 0.25}
type: 0 - {group: any, type: 1, rate: 0.25}
rate: 0.25 - {group: any, type: 2, rate: 0.25}
- group: any
type: 1
rate: 0.25
- group: any
type: 2
rate: 0.25
# - group: any
# type: 3
# rate: 0.25
teams: teams:
- <<: *team_tanks - <<: *team_tanks
id: radiant id: radiant
spawnInterval: 0 spawnInterval: 0
points:
- type: eagle
index: -1
x: 0
y: 28
direction: right
- type: tank
index: 0
x: 0
y: 0
direction: right
- type: tank
index: 1
x: 6
y: 10
direction: right
- type: tank
index: 2
x: 6
y: 16
direction: right
- type: tank
index: 3
x: 6
y: 22
direction: right
- type: tank
index: 4
x: 10
y: 28
direction: right
- <<: *team_tanks - <<: *team_tanks
id: dire id: dire
spawnInterval: 0 spawnInterval: 0
points:
- type: eagle
index: -1
x: 38
y: 0
direction: right
- type: tank
index: 0
x: 38
y: 28
direction: left
- type: tank
index: 1
x: 32
y: 18
direction: left
- type: tank
index: 2
x: 32
y: 12
direction: left
- type: tank
index: 3
x: 32
y: 6
direction: left
- type: tank
index: 4
x: 28
y: 0
direction: left
points:
- {team: radiant, type: eagle, index: -1, direction: right, x: 0, y: 28}
- {team: radiant, type: tank, index: 0, direction: right, x: 0, y: 0}
- {team: radiant, type: tank, index: 1, direction: right, x: 6, y: 10}
- {team: radiant, type: tank, index: 2, direction: right, x: 6, y: 16}
- {team: radiant, type: tank, index: 3, direction: right, x: 6, y: 22}
- {team: radiant, type: tank, index: 4, direction: right, x: 10, y: 28}
- {team: dire, type: eagle, index: -1, direction: right, x: 38, y: 0}
- {team: dire, type: tank, index: 0, direction: left, x: 38, y: 28}
- {team: dire, type: tank, index: 1, direction: left, x: 32, y: 18}
- {team: dire, type: tank, index: 2, direction: left, x: 32, y: 12}
- {team: dire, type: tank, index: 3, direction: left, x: 32, y: 6}
- {team: dire, type: tank, index: 4, direction: left, x: 28, y: 0}
bullet: &bullet bullet: &bullet
width: 12 width: 12

View File

@@ -1 +1,2 @@
005500330033003300333300330033003300550000550033003300330033330033003300330055000000000000330033000000003300330000000000000000000033003300000000330033000000000000550033000000330000000033000000330055000055003300000033000000003300000033005500000000330000003300333300330000003300000000000033000000330033330033000000330000000055000000330033003333003300330000005500005500000033003300333300330033000000550000000033003300330033330033003300330000000000003300330033003333003300330033000000005500330000003300333300330000003300550000550033000000330033330033000000330055000000000000330033003333003300330000000000000000000033003300333300330033000000000000550033003300330033330033003300330055000055003300330033003333003300330033005500000000330033003300333300330033003300000000000033003300330033330033003300330000005555553300330033003333003300330033555555555555330033003300333300330033003355555555555533003300330033330033003300335555555555553300330033003333003300330033555555440000330033000000333300000033000000004444000033003300000033330000003300000000440000443300330000003333000000330033440000000044330033000000333300000033003344000000440033003300330033330033003300330044000044003300330033003333003300330033004400 points: [{index: -1, direction: right, team: radiant, type: eagle, y: 28, x: 0}, {index: 0, direction: right, team: radiant, type: tank, y: 2, x: 2}, {index: 1, direction: right, team: radiant, type: tank, y: 6, x: 2}, {index: 2, direction: right, team: radiant, type: tank, y: 10, x: 2}, {index: 3, direction: right, team: radiant, type: tank, y: 14, x: 2}, {index: 4, direction: right, team: radiant, type: tank, y: 18, x: 2}, {index: -1, direction: right, team: dire, type: eagle, y: 28, x: 38}, {index: 0, direction: left, team: dire, type: tank, y: 2, x: 36}, {index: 1, direction: left, team: dire, type: tank, y: 6, x: 36}, {index: 2, direction: left, team: dire, type: tank, y: 10, x: 36}, {index: 3, direction: left, team: dire, type: tank, y: 14, x: 36}, {index: 4, direction: left, team: dire, type: tank, y: 18, x: 36}]
data: "005500330033003300333300330033003300550000550033003300330033330033003300330055000000000000330033000000003300330000000000000000000033003300000000330033000000000000550033000000330000000033000000330055000055003300000033000000003300000033005500000000330000003300333300330000003300000000000033000000330033330033000000330000000055000000330033003333003300330000005500005500000033003300333300330033000000550000000033003300330033330033003300330000000000003300330033003333003300330033000000005500330000003300333300330000003300550000550033000000330033330033000000330055000000000000330033003333003300330000000000000000000033003300333300330033000000000000550033003300330033330033003300330055000055003300330033003333003300330033005500000000330033003300333300330033003300000000000033003300330033330033003300330000005555553300330033003333003300330033555555555555330033003300333300330033003355555555555533003300330033330033003300335555555555553300330033003333003300330033555555440000330033000000333300000033000000004444000033003300000033330000003300000000440000443300330000003333000000330033440000000044330033000000333300000033003344000000440033003300330033330033003300330044000044003300330033003333003300330033004400"

View File

@@ -1 +1,2 @@
000000000000000000000000000000440000000000000000000000000000000000000044000000000044003300005500440000440055000000000000004400330000550044000044005500000000000000000000440000000000000000000055004400000000000044000000000000000000005500440000003300000000330044003300440000000000000000330000000033004400330044000000000000000000440055000000000000000000005500003300000044005500000000000000000000550000330000000000000055000044005500440000004400000000000000005500004400550044000000440000555500003300000000000000000000000000555555550000330000000000000000000000000055550055440000004400330000000000003300445500005544000000440033000000000000330044550055550000440000000044004400550000000055555555000044000000004400440055000000005555000000000000000000000000000044000044000000000000000000000000000000004400004400000044000044000044005500004400000000000000004400004400004400550000440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003300000000550000330055003300005500440000330000000055000033005500330000550044000000440033000000440000000000440000000000000044003300000044000000000044000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 data: "000000000000000000000000000000440000000000000000000000000000000000000044000000000044003300005500440000440055000000000000004400330000550044000044005500000000000000000000440000000000000000000055004400000000000044000000000000000000005500440000003300000000330044003300440000000000000000330000000033004400330044000000000000000000440055000000000000000000005500003300000044005500000000000000000000550000330000000000000055000044005500440000004400000000000000005500004400550044000000440000555500003300000000000000000000000000555555550000330000000000000000000000000055550055440000004400330000000000003300445500005544000000440033000000000000330044550055550000440000000044004400550000000055555555000044000000004400440055000000005555000000000000000000000000000044000044000000000000000000000000000000004400004400000044000044000044005500004400000000000000004400004400004400550000440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003300000000550000330055003300005500440000330000000055000033005500330000550044000000440033000000440000000000440000000000000044003300000044000000000044000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
points: [{direction: right, team: radiant, x: 0, type: eagle, y: 14, index: -1}, {direction: right, team: radiant, x: 0, type: tank, y: 0, index: 0}, {direction: right, team: radiant, x: 6, type: tank, y: 10, index: 1}, {direction: right, team: radiant, x: 6, type: tank, y: 16, index: 2}, {direction: right, team: radiant, x: 6, type: tank, y: 22, index: 3}, {direction: right, team: radiant, x: 10, type: tank, y: 28, index: 4}, {direction: right, team: dire, x: 38, type: eagle, y: 14, index: -1}, {direction: left, team: dire, x: 38, type: tank, y: 28, index: 0}, {direction: left, team: dire, x: 32, type: tank, y: 18, index: 1}, {direction: left, team: dire, x: 32, type: tank, y: 12, index: 2}, {direction: left, team: dire, x: 32, type: tank, y: 6, index: 3}, {direction: left, team: dire, x: 28, type: tank, y: 0, index: 4}]

View File

@@ -7,6 +7,7 @@ typedef GameConfig = {
} }
typedef SpawnPoint = { typedef SpawnPoint = {
var team:String;
var type:String; var type:String;
var index:Int; var index:Int;
var x:Int; var x:Int;
@@ -59,7 +60,12 @@ typedef TeamConfig = {
var size:Int; var size:Int;
var spawnInterval:Int; var spawnInterval:Int;
var tanks:Array<TankSpawn>; var tanks:Array<TankSpawn>;
var points:Array<SpawnPoint>; }
typedef LevelConfig = {
var data:Array<BrickConfig>;
@:optional var points:Array<SpawnPoint>;
} }
@@ -70,17 +76,27 @@ class Config {
public var bricks(default, null):Array<BrickConfig>; public var bricks(default, null):Array<BrickConfig>;
public var tanks(default, null):Array<TankConfig>; public var tanks(default, null):Array<TankConfig>;
public var teams(default, null):Array<TeamConfig>; public var teams(default, null):Array<TeamConfig>;
public var points(default, null):Array<SpawnPoint>;
private var brickMap:Map<Int, BrickConfig>; private var brickMap:Map<Int, BrickConfig>;
private var tankMap:Map<String, Map<String, TankConfig>>; private var tankMap:Map<String, Map<String, TankConfig>>;
private var teamMap:Map<String, TeamConfig>; private var teamMap:Map<String, TeamConfig>;
public function new(type:String, game:GameConfig, map:MapConfig, bricks:Array<BrickConfig>, teams:Array<TeamConfig>, tanks:Array<TankConfig>) { public function new(
type:String,
game:GameConfig,
map:MapConfig,
bricks:Array<BrickConfig>,
teams:Array<TeamConfig>,
points:Array<SpawnPoint>,
tanks:Array<TankConfig>
) {
this.type = type; this.type = type;
this.game = game; this.game = game;
this.map = map; this.map = map;
this.bricks = bricks; this.bricks = bricks;
this.teams = teams; this.teams = teams;
this.points = points;
this.tanks = tanks; this.tanks = tanks;
init(); init();
} }

View File

@@ -11,6 +11,7 @@ typedef ConfigSource = {
var map: MapConfig; var map: MapConfig;
var bricks: Array<BrickConfig>; var bricks: Array<BrickConfig>;
var teams: Array<TeamConfig>; var teams: Array<TeamConfig>;
var points: Array<SpawnPoint>;
var tanks: Dynamic<Array<TankConfig>>; var tanks: Dynamic<Array<TankConfig>>;
} }
@@ -30,6 +31,6 @@ class ConfigBundle {
tanks.push(item); tanks.push(item);
} }
} }
return new Config(type, source.game, source.map, source.bricks, source.teams, tanks); return new Config(type, source.game, source.map, source.bricks, source.teams, source.points, tanks);
} }
} }

View File

@@ -1,10 +1,19 @@
package ru.m.tankz.config; package ru.m.tankz.config;
import yaml.Renderer;
import yaml.Parser;
import yaml.Yaml;
import openfl.Assets; import openfl.Assets;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
typedef LevelSource = {
var data:String;
@:optional var points:Array<SpawnPoint>;
}
class LevelBundle { class LevelBundle {
private static function formatLevel(level:Int):String { private static function formatLevel(level:Int):String {
@@ -13,27 +22,48 @@ class LevelBundle {
return result; return result;
} }
public static function loads(config:Config, data:String):Array<BrickConfig> { public static function loadsOld(config:Config, data:String):LevelConfig {
var bricks:Array<BrickConfig> = []; var bricks:Array<BrickConfig> = [];
for (line in ~/\s+/g.split(data)) { for (line in ~/\s+/g.split(data)) {
for (c in line.split('')) { for (c in line.split('')) {
if (c.length > 0) { if (c.length > 0) {
bricks.push(config.bricks[Std.parseInt(c) + 1]); bricks.push(config.getBrick(Std.parseInt(c)));
} }
} }
} }
return bricks; return {
data: bricks
}
} }
public static function dumps(config:Config, bricks:Array<BrickConfig>):String { public static function loads(config:Config, data:String):LevelConfig {
return bricks.map(function(brick:BrickConfig) return Std.string(brick.type)).join(''); try {
var obj:LevelSource = Yaml.parse(data, Parser.options().useObjects());
return {
data: obj.data.split('').map(function(c) return config.getBrick(Std.parseInt(c))),
points: obj.points,
}
} catch (error:Dynamic) {
L.w('LevelBundle', '${error}');
return loadsOld(config, data);
}
} }
public static function empty(config:Config):Array<BrickConfig> { public static function dumps(config:Config, level:LevelConfig):String {
return [for (i in 0...config.map.gridWidth*config.map.gridHeight) config.bricks[1]]; var bricksStr = level.data.map(function(brick:BrickConfig) return brick.type).join('');
return Yaml.render({
data: bricksStr,
points: level.points,
}, Renderer.options().setFlowLevel(1));
} }
public static function get(type:GameType, config:Config, level:Int):Array<BrickConfig> { public static function empty(config:Config):LevelConfig {
return {
data: [for (i in 0...config.map.gridWidth * config.map.gridHeight) config.bricks[1]]
}
}
public static function get(type:GameType, config:Config, level:Int):LevelConfig {
var data:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt'); var data:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
return loads(config, data); return loads(config, data);
} }

View File

@@ -44,6 +44,7 @@ class Game implements EngineListener {
public var config(default, null):Config; public var config(default, null):Config;
public var engine(default, null):Engine; public var engine(default, null):Engine;
private var points:Array<SpawnPoint>;
private var spawners:Map<TeamId, Spawner>; private var spawners:Map<TeamId, Spawner>;
private var deferred:Deferred<GameState>; private var deferred:Deferred<GameState>;
private var stream:Stream<GameState>; private var stream:Stream<GameState>;
@@ -76,8 +77,9 @@ class Game implements EngineListener {
public function start(state:GameState):Stream<GameState> { public function start(state:GameState):Stream<GameState> {
this.deferred = new Deferred(); this.deferred = new Deferred();
this.state = state; this.state = state;
var bricks = LevelBundle.get(type, config, state.level); var level = LevelBundle.get(type, config, state.level);
engine.map.setData(bricks); points = level.points != null ? level.points : config.points;
engine.map.setData(level.data);
teams = new Map<TeamId, Team>(); teams = new Map<TeamId, Team>();
spawners = new Map<TeamId, Spawner>(); spawners = new Map<TeamId, Spawner>();
var humanControlIndex = 0; var humanControlIndex = 0;
@@ -101,7 +103,8 @@ class Game implements EngineListener {
} }
} }
} }
spawners[team.id] = new Spawner(team.config, spawn); var teamPoints = points.filter(function(p:SpawnPoint) return p.team == team.id);
spawners[team.id] = new Spawner(team.config, teamPoints, spawn);
} }
for (team in teams) { for (team in teams) {

View File

@@ -17,6 +17,7 @@ class Spawner {
public var active(get, never):Bool; public var active(get, never):Bool;
private var config:TeamConfig; private var config:TeamConfig;
private var points:Array<SpawnPoint>;
private var runner:SpawnTask -> Void; private var runner:SpawnTask -> Void;
private var queue:Array<SpawnTask>; private var queue:Array<SpawnTask>;
private var timer:Timer; private var timer:Timer;
@@ -25,13 +26,14 @@ class Spawner {
private var anyPoints:Array<SpawnPoint>; private var anyPoints:Array<SpawnPoint>;
private var index:Int; private var index:Int;
public function new(config:TeamConfig, runner:SpawnTask -> Void) { public function new(config:TeamConfig, points:Array<SpawnPoint>, runner:SpawnTask -> Void) {
this.config = config; this.config = config;
this.points = points;
this.runner = runner; this.runner = runner;
queue = []; queue = [];
indexedPoints = new Map(); indexedPoints = new Map();
anyPoints = []; anyPoints = [];
for (point in config.points) { for (point in points) {
if (point.type == 'tank') { if (point.type == 'tank') {
if (point.index > -1) { if (point.index > -1) {
indexedPoints.set(point.index, point); indexedPoints.set(point.index, point);
@@ -43,7 +45,7 @@ class Spawner {
} }
public function getPoint(type:String, index:Int=-1):Null<SpawnPoint> { public function getPoint(type:String, index:Int=-1):Null<SpawnPoint> {
for (point in config.points) { for (point in points) {
if (point.type == type && point.index == index) { if (point.type == type && point.index == index) {
return point; return point;
} }

View File

@@ -1,26 +1,53 @@
package ru.m.tankz.editor; package ru.m.tankz.editor;
import flash.display.Bitmap; import flash.display.Bitmap;
import haxework.gui.list.ListView.IListItemView; import flash.display.Shape;
import haxework.gui.list.ListView;
import haxework.gui.SpriteView; import haxework.gui.SpriteView;
import openfl.utils.Assets; import openfl.utils.Assets;
import ru.m.tankz.config.Config.BrickConfig; import ru.m.tankz.config.Config;
class BrickView extends SpriteView implements IListItemView<BrickConfig> { class BrickView extends SpriteView implements IListItemView<BrickConfig> {
public var item_index(default, default):Int; public var item_index(default, default):Int;
public var data(default, set):BrickConfig; public var data(default, set):BrickConfig;
public var selected(default, set):Bool;
private var imageView:Bitmap;
private var selectView:Shape;
public function new() {
super();
width = 26;
height = 26;
selectView = createSelectView(width, height);
selectView.visible = false;
contentAsSprite.addChild(selectView);
imageView = new Bitmap();
contentAsSprite.addChild(imageView);
}
private static function createSelectView(width:Float, height:Float):Shape {
var view = new Shape();
view.graphics.lineStyle(4, 0x33ff00);
view.graphics.drawRect(0, 0, width, height);
view.graphics.lineStyle();
return view;
}
private function set_data(value:BrickConfig):BrickConfig { private function set_data(value:BrickConfig):BrickConfig {
data = value; data = value;
if (value.type > -1) {
var src = 'resources/images/map/map_${value.type}.png'; var src = 'resources/images/map/map_${value.type}.png';
var image = Assets.getBitmapData(src); imageView.bitmapData = Assets.getBitmapData(src);
contentAsSprite.addChild(new Bitmap(image)); imageView.x = (width - imageView.width) / 2;
width = image.width; imageView.y = (height - imageView.height) / 2;
height = image.height;
}
return data; return data;
} }
private function set_selected(value:Bool):Bool {
selected = value;
selectView.visible = value;
return selected;
}
} }

View File

@@ -1,6 +1,7 @@
package ru.m.tankz.editor; package ru.m.tankz.editor;
import ru.m.tankz.editor.MapEditView.Brush;
import ru.m.tankz.game.DotaGame; import ru.m.tankz.game.DotaGame;
import haxework.gui.list.ListView; import haxework.gui.list.ListView;
import haxework.gui.list.VListView; import haxework.gui.list.VListView;
@@ -28,10 +29,10 @@ interface EditorViewLayout {
var saveButton(default, null):ButtonView; var saveButton(default, null):ButtonView;
var fileNameLabel(default, null):LabelView; var fileNameLabel(default, null):LabelView;
var mapView(default, null):MapEditView; var mapView(default, null):MapEditView;
var spawnPointList(default, null):VListView<SpawnPoint>;
var brickList(default, null):VListView<BrickConfig>; var brickList(default, null):VListView<BrickConfig>;
} }
@:template("ru/m/tankz/editor/Editor.yaml") @:template("ru/m/tankz/editor/Editor.yaml")
class EditorView extends GroupView implements ViewBuilder implements EditorViewLayout {} class EditorView extends GroupView implements ViewBuilder implements EditorViewLayout {}
@@ -73,12 +74,38 @@ class Editor {
view.saveButton.onPress = this; view.saveButton.onPress = this;
config = ConfigBundle.get(DotaGame.TYPE); config = ConfigBundle.get(DotaGame.TYPE);
view.mapView.config = config.map; view.mapView.config = config;
view.mapView.data = LevelBundle.empty(config); view.mapView.data = LevelBundle.empty(config);
view.mapView.brick = config.bricks[0];
view.brickList.data = config.bricks; view.brickList.data = config.bricks.filter(function(brick) return brick.type > -1);
view.brickList.dispatcher.addListener(this); view.spawnPointList.data = config.points;
var resetSelected = function() {
for (v in view.brickList.items) {
cast(v, BrickView).selected = false;
}
for (v in view.spawnPointList.items) {
cast(v, SpawnPointView).selected = false;
}
};
view.brickList.dispatcher.addListener({
onListItemClick: function(item:IListItemView<BrickConfig>) {
view.mapView.brush = Brush.BRICK(item.data);
resetSelected();
cast(item, BrickView).selected = true; }
});
view.spawnPointList.dispatcher.addListener({
onListItemClick: function(item:IListItemView<SpawnPoint>) {
view.mapView.brush = Brush.POINT(item.data);
resetSelected();
cast(item, SpawnPointView).selected = true;
}
});
view.mapView.brush = Brush.BRICK(view.brickList.data[0]);
cast(view.brickList.items[0], BrickView).selected = true;
} }
public function onPress(v:ButtonView):Void { public function onPress(v:ButtonView):Void {
@@ -98,8 +125,4 @@ class Editor {
case _: case _:
} }
} }
public function onListItemClick(item:IListItemView<BrickConfig>):Void {
view.mapView.brick = item.data;
}
} }

View File

@@ -30,6 +30,21 @@ views:
- $type: haxework.gui.HGroupView - $type: haxework.gui.HGroupView
contentSize: true contentSize: true
views: views:
- id: spawnPointList
$type: haxework.gui.list.VListView<SpawnPoint>
factory: '@class:ru.m.tankz.editor.SpawnPointView'
width: 56
pHeight: 100
scroll:
$type: haxework.gui.list.VScrollView
width: 0
pHeight: 100
skin:
$type: haxework.gui.list.VScrollSkin
skin:
$type: haxework.gui.skin.ColorSkin
color: 0x000000
alpha: 0.0
- id: mapView - id: mapView
$type: ru.m.tankz.editor.MapEditView $type: ru.m.tankz.editor.MapEditView
contentSize: true contentSize: true
@@ -40,7 +55,7 @@ views:
pHeight: 100 pHeight: 100
scroll: scroll:
$type: haxework.gui.list.VScrollView $type: haxework.gui.list.VScrollView
width: 10 width: 0
pHeight: 100 pHeight: 100
skin: skin:
$type: haxework.gui.list.VScrollSkin $type: haxework.gui.list.VScrollSkin

View File

@@ -1,5 +1,7 @@
package ru.m.tankz.editor; package ru.m.tankz.editor;
import ru.m.geom.Rectangle;
import ru.m.tankz.core.Entity;
import ru.m.geom.Point; import ru.m.geom.Point;
import flash.events.MouseEvent; import flash.events.MouseEvent;
import ru.m.tankz.map.Brick; import ru.m.tankz.map.Brick;
@@ -12,19 +14,71 @@ import ru.m.tankz.map.LevelMap;
import haxework.gui.SpriteView; import haxework.gui.SpriteView;
class SpawnPointEntity extends Entity {
public var point(default, null):SpawnPoint;
public function new(point:SpawnPoint, rect:Rectangle) {
super(rect);
this.point = point;
}
}
class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
private var cellX:Int;
private var cellY:Int;
public function new(value:SpawnPoint, config:MapConfig) {
super(new SpawnPointEntity(value, new Rectangle(
value.x * config.cellWidth,
value.y * config.cellHeight,
config.cellWidth * 2,
config.cellHeight * 2
)));
}
override public function update():Void {
super.update();
if (cellX != value.point.x || cellY != value.point.y) {
cellX = value.point.x;
cellY = value.point.y;
value.rect.x = cellX * (value.rect.width / 2);
value.rect.y = cellY * (value.rect.height / 2);
redraw();
}
}
override private function getImage():String {
return switch(value.point.type) {
case 'eagle': 'resources/images/eagle/eagle-0.png';
case 'tank': 'resources/images/tank/bot/tank_b0_0-0.png';
case x: 'resources/images/eagle/eagle-1.png';
}
}
}
enum Brush {
POINT(point:SpawnPoint);
BRICK(brick:BrickConfig);
}
//ToDo: copy paste from ru.m.tankz.render.Render //ToDo: copy paste from ru.m.tankz.render.Render
class MapEditView extends SpriteView { class MapEditView extends SpriteView {
public var config(default, set):MapConfig; public var config(default, set):Config;
public var data(get, set):Array<BrickConfig>; public var data(get, set):LevelConfig;
public var map(default, null):LevelMap; public var map(default, null):LevelMap;
public var brick(default, default):BrickConfig; public var brush(default, default):Brush;
private var items:Map<String, RenderItem<Dynamic, Dynamic>>; private var items:Map<String, RenderItem<Dynamic, Dynamic>>;
private var backgroundLayer:Sprite; private var backgroundLayer:Sprite;
private var upLayer:Sprite; private var upLayer:Sprite;
private var groundLayer:Sprite; private var groundLayer:Sprite;
private var spawnLayer:Sprite;
public function new() { public function new() {
super(); super();
@@ -33,9 +87,11 @@ class MapEditView extends SpriteView {
backgroundLayer = new Sprite(); backgroundLayer = new Sprite();
upLayer = new Sprite(); upLayer = new Sprite();
groundLayer = new Sprite(); groundLayer = new Sprite();
spawnLayer = new Sprite();
contentAsSprite.addChild(backgroundLayer); contentAsSprite.addChild(backgroundLayer);
contentAsSprite.addChild(groundLayer); contentAsSprite.addChild(groundLayer);
contentAsSprite.addChild(upLayer); contentAsSprite.addChild(upLayer);
contentAsSprite.addChild(spawnLayer);
contentAsSprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); contentAsSprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
reset(); reset();
} }
@@ -54,10 +110,22 @@ class MapEditView extends SpriteView {
private function onMouseMove(event:MouseEvent):Void { private function onMouseMove(event:MouseEvent):Void {
var b = map.getPointBrick(new Point(event.localX, event.localY)); var b = map.getPointBrick(new Point(event.localX, event.localY));
if (b != null) { if (b != null) {
switch (brush) {
case Brush.POINT(point):
for (p in config.points) {
if (p.team == point.team && p.type == point.type && p.index == point.index) {
p.x = b.cellX;
p.y = b.cellY;
drawMap();
break;
}
}
case Brush.BRICK(brick):
b.config = brick; b.config = brick;
drawMap(); drawMap();
} }
} }
}
private function clearLayer(layer:DisplayObjectContainer) { private function clearLayer(layer:DisplayObjectContainer) {
while (layer.numChildren > 0) layer.removeChildAt(0); while (layer.numChildren > 0) layer.removeChildAt(0);
@@ -70,6 +138,7 @@ class MapEditView extends SpriteView {
items = new Map(); items = new Map();
clearLayer(groundLayer); clearLayer(groundLayer);
clearLayer(upLayer); clearLayer(upLayer);
clearLayer(spawnLayer);
} }
private function drawBackground():Void { private function drawBackground():Void {
@@ -114,25 +183,44 @@ class MapEditView extends SpriteView {
} }
} }
} }
for (point in config.points) {
var key = '${point.team}:${point.type}:${point.index}';
if (!items.exists(key)) {
items[key] = new SpawnPointItem(point, config.map);
spawnLayer.addChild(items[key].view);
}
}
for (item in items) { for (item in items) {
item.update(); item.update();
} }
} }
private function set_config(value:MapConfig):MapConfig { private function set_config(value:Config):Config {
config = value; config = value;
map = new LevelMap(config); map = new LevelMap(config.map);
invalidate(); invalidate();
return config; return config;
} }
private function get_data():Array<BrickConfig> { private function get_data():LevelConfig {
return map.bricks.map(function(brick:Brick) return brick.config); return {
data: map.bricks.map(function(brick:Brick) return brick.config),
points: config.points,
}
} }
private function set_data(value:Array<BrickConfig>):Array<BrickConfig> { private function set_data(value:LevelConfig):LevelConfig {
reset(); reset();
map.setData(value); map.setData(value.data);
if (value.points != null) for (point in value.points) {
for (p in config.points) {
if (p.team == point.team && p.type == point.type && p.index == point.index) {
p.x = point.x;
p.y = point.y;
break;
}
}
}
invalidate(); invalidate();
return value; return value;
} }

View File

@@ -0,0 +1,57 @@
package ru.m.tankz.editor;
import flash.display.Bitmap;
import flash.display.Shape;
import haxework.gui.list.ListView;
import haxework.gui.SpriteView;
import openfl.utils.Assets;
import ru.m.tankz.config.Config;
class SpawnPointView extends SpriteView implements IListItemView<SpawnPoint> {
public var item_index(default, default):Int;
public var data(default, set):SpawnPoint;
public var selected(default, set):Bool;
private var imageView:Bitmap;
private var selectView:Shape;
public function new() {
super();
width = 52;
height = 52;
selectView = createSelectView(width, height);
selectView.visible = false;
contentAsSprite.addChild(selectView);
imageView = new Bitmap();
contentAsSprite.addChild(imageView);
}
private static function createSelectView(width:Float, height:Float):Shape {
var view = new Shape();
view.graphics.lineStyle(4, 0x33ff00);
view.graphics.drawRect(0, 0, width, height);
view.graphics.lineStyle();
return view;
}
private function set_data(value:SpawnPoint):SpawnPoint {
data = value;
var src = switch(value.type) {
case 'eagle': 'resources/images/eagle/eagle-0.png';
case 'tank': 'resources/images/tank/bot/tank_b0_0-0.png';
case x: 'resources/images/eagle/eagle-1.png';
}
imageView.bitmapData = Assets.getBitmapData(src);
imageView.x = (width - imageView.width) / 2;
imageView.y = (height - imageView.height) / 2;
return data;
}
private function set_selected(value:Bool):Bool {
selected = value;
selectView.visible = value;
return selected;
}
}