[editor] refactor MapEditView

This commit is contained in:
2019-05-20 13:00:04 +03:00
parent 09b188cf24
commit bbe2aeb7fb
11 changed files with 197 additions and 255 deletions

View File

@@ -1,126 +1,65 @@
package ru.m.tankz.editor.level;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import haxework.color.Color;
import haxework.view.SpriteView;
import haxework.view.utils.BitmapUtil;
import openfl.Assets;
import ru.m.geom.Point;
import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config;
import ru.m.tankz.core.Entity;
import ru.m.tankz.game.EntityBuilder;
import ru.m.tankz.game.EventUtil;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.IGame;
import ru.m.tankz.map.Brick;
import ru.m.tankz.map.LevelMap;
import ru.m.tankz.render.RenderItem;
import ru.m.tankz.render.Render;
import ru.m.tankz.Type.PlayerId;
class SpawnPointEntity extends Entity {
public var point(default, null):SpawnPoint;
public function new(id:Int, point:SpawnPoint, rect:Rectangle) {
super(id, rect);
this.point = point;
}
}
class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
private var cellX:Int = -1;
private var cellY:Int = -1;
private var src:String;
private var color:Color;
public function new(value:SpawnPoint, config:Config) {
src = getSrc(value, config);
super(new SpawnPointEntity(0, value, new Rectangle(
value.x * config.map.cellWidth,
value.y * config.map.cellHeight,
config.map.cellWidth * 2,
config.map.cellHeight * 2
)));
color = config.getColor(new PlayerId(value.team, value.index));
}
public static function getSrc(value:SpawnPoint, config:Config):String {
var preset:GamePreset = config.presets[config.presets.length - 1];
var tankConfig:TankConfig = null;
if (value.type == 'tank') {
var player = config.getPlayer(new PlayerId(value.team, value.index < 0 ? 0 : value.index));
var tankType = player.tanks[0];
tankConfig = config.getTank(tankType.type);
}
return switch(value.type) {
case 'eagle': 'resources/image/eagle/eagle.png';
case 'tank': 'resources/image/tank/${tankConfig.skin}-0.png';
case _: 'resources/image/eagle/eagle-death.png';
}
}
override public function update():Void {
super.update();
if (cellX != value.point.x || cellY != value.point.y) {
var image = Assets.getBitmapData(getImage());
cellX = value.point.x;
cellY = value.point.y;
value.rect.x = cellX * (value.rect.width / 2) + (value.rect.width - image.width) / 2;
value.rect.y = cellY * (value.rect.height / 2) + (value.rect.height - image.height) / 2;
redraw();
}
}
override public function redraw():Void {
var image = Assets.getBitmapData(getImage());
if (!color.zero) {
image = BitmapUtil.colorize(image, color);
}
view.bitmapData = image;
}
override private function getImage():String {
return src;
}
}
enum Brush {
POINT(point:SpawnPoint);
BRICK(brick:BrickConfig);
}
//ToDo: copy paste from ru.m.tankz.render.Render
class MapEditView extends SpriteView {
@:dispatcher(GameListener) class MapEditView extends Render {
public var config(default, set):Config;
public var data(get, set):LevelConfig;
public var map(default, null):LevelMap;
public var brush(default, default):Brush;
private var items:Map<String, RenderItem<Dynamic, Dynamic>>;
private var backgroundLayer:Sprite;
private var upLayer:Sprite;
private var groundLayer:Sprite;
private var spawnLayer:Sprite;
private var builder:EntityBuilder;
private var entityId:Int;
private var pointEntities:Map<String, Entity>;
public function new() {
super();
items = new Map();
content.mouseChildren = false;
map = null;
backgroundLayer = new Sprite();
upLayer = new Sprite();
groundLayer = new Sprite();
spawnLayer = new Sprite();
content.addChild(backgroundLayer);
content.addChild(groundLayer);
content.addChild(upLayer);
content.addChild(spawnLayer);
pointEntities = null;
content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
connect(this);
reset();
}
override private function set_config(value:Config):Config {
builder = new EntityBuilder(value);
return super.set_config(value);
}
override private function drawBackground():Void {
super.drawBackground();
var mapWidth = map.gridWidth * map.cellWidth;
var mapHeight = map.gridHeight * map.cellHeight;
var g:Graphics = backgroundLayer.graphics;
g.lineStyle(1, 0x007700);
for (x in 0...map.gridWidth) {
g.moveTo(x * map.cellWidth, 0);
g.lineTo(x * map.cellWidth, mapHeight);
}
for (y in 0...map.gridHeight) {
g.moveTo(0, y * map.cellHeight);
g.lineTo(mapWidth, y * map.cellHeight);
}
}
private function onMouseDown(event:MouseEvent):Void {
content.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
@@ -137,92 +76,21 @@ class MapEditView extends SpriteView {
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();
drawMap();
break;
}
}
case Brush.BRICK(brick):
b.config = brick;
drawMap();
var entity = pointEntities[pointKey(point)];
point.x = b.cellX;
point.y = b.cellY;
var rect = builder.buildRect(point, entity.rect.width, entity.rect.height);
entity.rect.position = rect.position;
gameEventSignal.emit(EventUtil.buildMove(entity));
case Brush.BRICK(brickConfig):
b.config = config.getBrick(brickConfig.type);
gameEventSignal.emit(GameEvent.CHANGE(BRICK(b.id, brickConfig.type)));
}
}
}
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);
clearLayer(spawnLayer);
}
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();
g.lineStyle(1, 0x007700);
for (x in 0...map.gridWidth) {
g.moveTo(x * map.cellWidth, 0);
g.lineTo(x * map.cellWidth, mapHeight);
}
for (y in 0...map.gridHeight) {
g.moveTo(0, y * map.cellHeight);
g.lineTo(mapWidth, y * map.cellHeight);
}
}
override public function update():Void {
if (this.map != null) {
drawBackground();
drawMap();
}
super.update();
}
private function drawMap() {
for (brick in map.bricks) if (brick.config.index > 0) {
var key = Std.string(brick.id);
if (!items.exists(key)) {
items[key] = new BrickItem(brick);
if (brick.config.layer > 2) {
upLayer.addChild(items[key].view);
} else {
groundLayer.addChild(items[key].view);
}
}
}
for (point in config.points) {
var key = '${point.team}:${point.type}:${point.index}';
if (!items.exists(key)) {
items[key] = new SpawnPointItem(point, config);
spawnLayer.addChild(items[key].view);
}
}
for (item in items) {
item.update();
}
}
private function set_config(value:Config):Config {
config = value;
map = new LevelMap(config.map);
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight, "map");
return config;
private static function pointKey(point:SpawnPoint):String {
return '${point.type}:${point.team}:${point.index}';
}
private function get_data():LevelConfig {
@@ -234,16 +102,35 @@ class MapEditView extends SpriteView {
private function set_data(value:LevelConfig):LevelConfig {
reset();
pointEntities = new Map();
map = new LevelMap(config.map);
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight, "map");
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;
}
gameEventSignal.emit(EventUtil.buildBricksSpawn(map));
for (point in config.points) {
switch point.type {
case "eagle":
var eagle = builder.buildEagle(point, point.team);
pointEntities[pointKey(point)] = eagle;
gameEventSignal.emit(EventUtil.buildEagleSpawn(eagle));
case "tank":
var playerId = new PlayerId(point.team, point.index < 0 ? 0 : point.index);
var player = config.getPlayer(playerId);
var tankSpawn = player.tanks[0];
var tank = builder.buildTank(point, playerId, tankSpawn.type, true);
pointEntities[pointKey(point)] = tank;
gameEventSignal.emit(EventUtil.buildTankSpawn(tank));
}
}
if (value.points != null) {
for (point in value.points) {
var entity = pointEntities[pointKey(point)];
var rect = builder.buildRect(point, entity.rect.width, entity.rect.height);
entity.rect.position = rect.position;
gameEventSignal.emit(EventUtil.buildMove(entity));
}
}
draw();
toUpdate();
return value;
}

View File

@@ -1,9 +1,7 @@
package ru.m.tankz.editor.level;
import haxework.color.Color;
import haxework.provider.Provider;
import ru.m.tankz.config.Config;
import ru.m.tankz.editor.level.MapEditView;
import ru.m.tankz.Type.PlayerId;
class SpawnPointView extends BrushView<SpawnPoint> {
@@ -15,7 +13,18 @@ class SpawnPointView extends BrushView<SpawnPoint> {
}
override private function resolveSrc(value:SpawnPoint):String {
return SpawnPointItem.getSrc(value, Provider.get(Config));
var preset:GamePreset = config.presets[config.presets.length - 1];
var tankConfig:TankConfig = null;
if (value.type == 'tank') {
var player = config.getPlayer(new PlayerId(value.team, value.index < 0 ? 0 : value.index));
var tankType = player.tanks[0];
tankConfig = config.getTank(tankType.type);
}
return switch(value.type) {
case 'eagle': 'resources/image/eagle/eagle.png';
case 'tank': 'resources/image/tank/${tankConfig.skin}-0.png';
case _: 'resources/image/eagle/eagle-death.png';
}
}
public static inline function factory(index:Int, value:SpawnPoint) {