[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,10 +1,11 @@
package ru.m.tankz.render; package ru.m.tankz.render;
import haxework.view.IView; import haxework.view.IView;
import ru.m.tankz.config.Config;
import ru.m.tankz.game.IGame; import ru.m.tankz.game.IGame;
interface IRender extends IView<Dynamic> { interface IRender extends IView<Dynamic> extends GameListener {
public var game(default, set):IGame; public var config(default, set):Config;
public function draw():Void; public function draw():Void;
public function reset():Void; public function reset():Void;
} }

View File

@@ -14,17 +14,17 @@ import ru.m.geom.Point;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.IGame;
import ru.m.tankz.render.item.BonusRenderItem; import ru.m.tankz.render.item.BonusRenderItem;
import ru.m.tankz.render.item.BrickRenderItem; import ru.m.tankz.render.item.BrickRenderItem;
import ru.m.tankz.render.item.BulletRenderItem; import ru.m.tankz.render.item.BulletRenderItem;
import ru.m.tankz.render.item.EagleRenderItem; import ru.m.tankz.render.item.EagleRenderItem;
import ru.m.tankz.render.item.IRenderItem; import ru.m.tankz.render.item.IRenderItem;
import ru.m.tankz.render.item.TankRenderItem; import ru.m.tankz.render.item.TankRenderItem;
import ru.m.tankz.Type;
class Render extends SpriteView implements IRender implements GameListener { class Render extends SpriteView implements IRender {
public var game(default, set):IGame; public var config(default, set):Config;
private var backgroundLayer:Sprite; private var backgroundLayer:Sprite;
private var groundLayer:Sprite; private var groundLayer:Sprite;
@@ -32,7 +32,6 @@ class Render extends SpriteView implements IRender implements GameListener {
private var upLayer:Sprite; private var upLayer:Sprite;
private var upperLayer:Sprite; private var upperLayer:Sprite;
private var background:Sprite;
private var items:Map<Int, IRenderItem>; private var items:Map<Int, IRenderItem>;
public function new() { public function new() {
@@ -51,13 +50,11 @@ class Render extends SpriteView implements IRender implements GameListener {
reset(); reset();
} }
private function set_game(value:IGame):IGame { private function set_config(value:Config):Config {
game = value; return config = value;
game.connect(this);
return game;
} }
private function drawBackground(config:Config):Void { private function drawBackground():Void {
var width = config.map.cellWidth * config.map.gridWidth; var width = config.map.cellWidth * config.map.gridWidth;
var height = config.map.cellHeight * config.map.gridHeight; var height = config.map.cellHeight * config.map.gridHeight;
var g:Graphics = backgroundLayer.graphics; var g:Graphics = backgroundLayer.graphics;
@@ -72,9 +69,6 @@ class Render extends SpriteView implements IRender implements GameListener {
for (item in items) { for (item in items) {
item.update(); item.update();
} }
if (background == null) {
drawBackground(game.config);
}
} }
private function onEnterFrame(event:Event):Void { private function onEnterFrame(event:Event):Void {
@@ -91,10 +85,6 @@ class Render extends SpriteView implements IRender implements GameListener {
item.dispose(); item.dispose();
} }
items = new Map(); items = new Map();
if (background != null) {
backgroundLayer.removeChild(background);
background = null;
}
clearLayer(entryLayer); clearLayer(entryLayer);
clearLayer(groundLayer); clearLayer(groundLayer);
clearLayer(upLayer); clearLayer(upLayer);
@@ -108,9 +98,10 @@ class Render extends SpriteView implements IRender implements GameListener {
case COMPLETE(_, _): case COMPLETE(_, _):
content.removeEventListener(Event.ENTER_FRAME, onEnterFrame); content.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
case SPAWN(BRICK(bricks)): case SPAWN(BRICK(bricks)):
drawBackground();
for (brick in bricks) { for (brick in bricks) {
var item:IRenderItem = new BrickRenderItem(brick.rect, brick.type); var item:IRenderItem = new BrickRenderItem(brick.rect, brick.type);
var config = game.config.getBrick(brick.type); var config = config.getBrick(brick.type);
items[brick.id] = item; items[brick.id] = item;
if (config.layer > 2) { if (config.layer > 2) {
upLayer.addChild(item.view); upLayer.addChild(item.view);
@@ -119,15 +110,15 @@ class Render extends SpriteView implements IRender implements GameListener {
} }
} }
case SPAWN(EAGLE(id, rect, teamId)): case SPAWN(EAGLE(id, rect, teamId)):
var item = new EagleRenderItem(rect); var item = new EagleRenderItem(rect, config.getColor(new PlayerId(teamId, -1)));
items.set(id, item); items.set(id, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
item.update(); item.update();
case SPAWN(TANK(id, rect, playerId, info)): case SPAWN(TANK(id, rect, playerId, info)):
var item = new TankRenderItem(rect); var item = new TankRenderItem(rect);
var config = game.config.getTank(info.type); var tankConfig = config.getTank(info.type);
item.color = game.config.getColor(playerId); item.color = config.getColor(playerId);
item.skin = config.skin; item.skin = tankConfig.skin;
item.hits = info.hits; item.hits = info.hits;
item.bonus = info.bonus; item.bonus = info.bonus;
items.set(id, item); items.set(id, item);
@@ -144,6 +135,11 @@ class Render extends SpriteView implements IRender implements GameListener {
items.set(id, item); items.set(id, item);
upperLayer.addChild(item.view); upperLayer.addChild(item.view);
item.update(); item.update();
case MOVE(EAGLE(id, position)):
if (items.exists(id)) {
var item = items[id];
item.move(position);
}
case MOVE(BULLET(id, position)): case MOVE(BULLET(id, position)):
if (items.exists(id)) { if (items.exists(id)) {
var item = items[id]; var item = items[id];
@@ -163,7 +159,7 @@ class Render extends SpriteView implements IRender implements GameListener {
case CHANGE(TANK(id, type, hits, bonus)): case CHANGE(TANK(id, type, hits, bonus)):
if (items.exists(id)) { if (items.exists(id)) {
var item:TankRenderItem = cast items[id]; var item:TankRenderItem = cast items[id];
item.skin = game.config.getTank(type).skin; item.skin = config.getTank(type).skin;
item.hits = hits; item.hits = hits;
item.bonus = bonus; item.bonus = bonus;
} }
@@ -177,6 +173,11 @@ class Render extends SpriteView implements IRender implements GameListener {
var item:EagleRenderItem = cast items[id]; var item:EagleRenderItem = cast items[id];
item.protect = state; item.protect = state;
} }
case CHANGE(BRICK(id, type)):
if (items.exists(id)) {
var item:BrickRenderItem = cast items[id];
item.type = type;
}
case DESTROY(TANK(id, shot)): case DESTROY(TANK(id, shot)):
if (items.exists(id)) { if (items.exists(id)) {
var item = items[id]; var item = items[id];

View File

@@ -26,14 +26,13 @@ class BrickRenderItem extends RenderItem {
public function new(rect:Rectangle, type:BrickType) { public function new(rect:Rectangle, type:BrickType) {
super(rect); super(rect);
this.shape = new Shape(); this.shape = new Shape();
this.type = type;
cells = [ cells = [
new Point(0, 0), new Point(0, 0),
new Point(0, 1), new Point(0, 1),
new Point(1, 0), new Point(1, 0),
new Point(1, 1), new Point(1, 1),
]; ];
redraw(); this.type = type;
move(rect.position); move(rect.position);
} }
@@ -53,6 +52,7 @@ class BrickRenderItem extends RenderItem {
if (type != value) { if (type != value) {
type = value; type = value;
image = Assets.getBitmapData('resources/image/map/${type}.png'); image = Assets.getBitmapData('resources/image/map/${type}.png');
redraw();
} }
return type; return type;
} }
@@ -69,6 +69,7 @@ class BrickRenderItem extends RenderItem {
public function redraw():Void { public function redraw():Void {
shape.graphics.clear(); shape.graphics.clear();
if (type == "none") return;
switch state { switch state {
case UNBROKEN: case UNBROKEN:
shape.graphics.beginBitmapFill(image); shape.graphics.beginBitmapFill(image);

View File

@@ -2,18 +2,22 @@ package ru.m.tankz.render.item;
import flash.display.DisplayObject; import flash.display.DisplayObject;
import flash.display.Sprite; import flash.display.Sprite;
import haxework.color.Color;
import haxework.view.utils.BitmapUtil;
import ru.m.animate.Animate; import ru.m.animate.Animate;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
class EagleRenderItem extends BitmapRenderItem { class EagleRenderItem extends BitmapRenderItem {
public var color(default, default):Color;
public var death(default, set):Bool = true; public var death(default, set):Bool = true;
public var protect(default, set):Bool; public var protect(default, set):Bool;
private var container:Sprite; private var container:Sprite;
private var protectView:Animate; private var protectView:Animate;
public function new(rect:Rectangle) { public function new(rect:Rectangle, color:Color) {
super(rect); super(rect);
this.color = color;
container = new Sprite(); container = new Sprite();
container.addChild(bitmap); container.addChild(bitmap);
protectView = AnimateBundle.tankProtect(); protectView = AnimateBundle.tankProtect();
@@ -45,6 +49,9 @@ class EagleRenderItem extends BitmapRenderItem {
death = value; death = value;
var suffix = death ? '-death' : ''; var suffix = death ? '-death' : '';
image = 'resources/image/eagle/eagle${suffix}.png'; image = 'resources/image/eagle/eagle${suffix}.png';
if (!color.zero) {
bitmap.bitmapData = bitmapData = BitmapUtil.colorize(bitmapData, color);
}
} }
return death; return death;
} }

View File

@@ -50,7 +50,8 @@ import ru.m.tankz.view.game.GameView;
private function start(state:GameState):Void { private function start(state:GameState):Void {
gameView.type = state.type; gameView.type = state.type;
game = new Game(state); game = new Game(state);
gameView.render.game = game; gameView.render.config = game.config;
game.connect(gameView.render);
game.connect(soundManager); game.connect(soundManager);
game.connect(this); game.connect(this);
if (gameView.panel != null) { if (gameView.panel != null) {
@@ -67,7 +68,8 @@ import ru.m.tankz.view.game.GameView;
private function play(record:GameRecord):Void { private function play(record:GameRecord):Void {
gameView.type = record.info.type; gameView.type = record.info.type;
game = new Game(record.state); game = new Game(record.state);
gameView.render.game = game; gameView.render.config = game.config;
game.connect(gameView.render);
game.connect(soundManager); game.connect(soundManager);
//game.connect(this); //game.connect(this);
if (gameView.panel != null) { if (gameView.panel != null) {

View File

@@ -19,12 +19,14 @@ typedef EntityPoint = {
class EntityBuilder { class EntityBuilder {
private var config:Config; private var config:Config;
private var entityId:Int;
public function new(config:Config) { public function new(config:Config) {
this.config = config; this.config = config;
this.entityId = 0;
} }
private function buildRect(point:EntityPoint, width:Float, height:Float):Rectangle { public function buildRect(point:EntityPoint, width:Float, height:Float):Rectangle {
return new Rectangle( return new Rectangle(
(point.x + 1) * config.map.cellWidth - width / 2, (point.x + 1) * config.map.cellWidth - width / 2,
(point.y + 1) * config.map.cellHeight - height / 2, (point.y + 1) * config.map.cellHeight - height / 2,
@@ -34,35 +36,37 @@ class EntityBuilder {
); );
} }
public function buildEagle(id:Int, point:EntityPoint, teamId:TeamId):Eagle { public function buildEagle(point:EntityPoint, teamId:TeamId):Eagle {
var eageleConfig = config.getTeam(teamId).eagle; var eageleConfig = config.getTeam(teamId).eagle;
var eagle = new Eagle(id, buildRect(point, config.map.cellWidth * 2, config.map.cellHeight * 2), teamId, eageleConfig); var eagle = new Eagle(++entityId, buildRect(point, config.map.cellWidth * 2, config.map.cellHeight * 2), teamId, eageleConfig);
eagle.color = config.getColor(new PlayerId(teamId, -1)); eagle.color = config.getColor(new PlayerId(teamId, -1));
return eagle; return eagle;
} }
public function buildTank(id:Int, point:EntityPoint, playerId:PlayerId, type:TankType):Tank { public function buildTank(point:EntityPoint, playerId:PlayerId, type:TankType, bonusOff:Bool = false):Tank {
var playerConfig = config.getPlayer(playerId); var playerConfig = config.getPlayer(playerId);
var tankConfig = config.getTank(type); var tankConfig = config.getTank(type);
var tank = new Tank(id, buildRect(point, tankConfig.width, tankConfig.height), playerId, tankConfig); var tank = new Tank(++entityId, buildRect(point, tankConfig.width, tankConfig.height), playerId, tankConfig);
tank.color = config.getColor(playerId); tank.color = config.getColor(playerId);
tank.bonus = Math.random() < playerConfig.bonus; if (!bonusOff) {
tank.bonus = Math.random() < playerConfig.bonus;
}
if (playerConfig.protect > 0) { if (playerConfig.protect > 0) {
tank.protect.on(playerConfig.protect); tank.protect.on(playerConfig.protect);
} }
return tank; return tank;
} }
public function buildBullet(id:Int, point:Point, direction:Direction, playerId:PlayerId, type:TankType):Bullet { public function buildBullet(point:Point, direction:Direction, playerId:PlayerId, type:TankType):Bullet {
var tankConfig = config.getTank(type); var tankConfig = config.getTank(type);
var bulletConfig = tankConfig.bullet; var bulletConfig = tankConfig.bullet;
var bullet = new Bullet(id, new Rectangle(point.x - bulletConfig.width / 2, point.y - bulletConfig.height / 2, bulletConfig.width, bulletConfig.height, direction), playerId, bulletConfig); var bullet = new Bullet(++entityId, new Rectangle(point.x - bulletConfig.width / 2, point.y - bulletConfig.height / 2, bulletConfig.width, bulletConfig.height, direction), playerId, bulletConfig);
return bullet; return bullet;
} }
public function buildBonus(id:Int, point:EntityPoint, type:BonusType):Bonus { public function buildBonus(point:EntityPoint, type:BonusType):Bonus {
var bonusConfig = config.getBonus(type); var bonusConfig = config.getBonus(type);
var bonus = new Bonus(id, buildRect(point, config.map.cellWidth * 2, config.map.cellHeight * 2), bonusConfig); var bonus = new Bonus(++entityId, buildRect(point, config.map.cellWidth * 2, config.map.cellHeight * 2), bonusConfig);
return bonus; return bonus;
} }
} }

View File

@@ -0,0 +1,50 @@
package ru.m.tankz.game;
import ru.m.tankz.core.EntityType.EntityTypeResolver;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Tank;
import ru.m.tankz.map.Brick;
import ru.m.tankz.game.GameEvent;
import ru.m.tankz.map.LevelMap;
class EventUtil {
public static function buildBricksSpawn(map:LevelMap):GameEvent {
var bricks = map.bricks.map(function(item:Brick):BrickInfo {
return {
id: item.id,
x: item.cellY,
y: item.cellY,
rect: item.rect,
type: item.config.type,
}
});
return GameEvent.SPAWN(BRICK(bricks));
}
public static function buildEagleSpawn(eagle:Eagle):GameEvent {
return GameEvent.SPAWN(EAGLE(eagle.id, eagle.rect, eagle.team));
}
public static function buildTankSpawn(tank:Tank):GameEvent {
return GameEvent.SPAWN(TANK(tank.id, tank.rect.clone(), tank.playerId, {
type:tank.config.type,
hits:tank.hits,
bonus:tank.bonus
}));
}
public static function buildMove(entity:Entity):GameEvent {
return switch EntityTypeResolver.of(entity) {
case EAGLE(eagle):
GameEvent.MOVE(EAGLE(entity.id, entity.rect.position));
case TANK(tank):
GameEvent.MOVE(TANK(entity.id, entity.rect.position));
case BULLET(bullet):
GameEvent.MOVE(BULLET(entity.id, entity.rect.position));
case _:
null;
}
}
}

View File

@@ -48,6 +48,7 @@ enum DestroyEvent {
} }
enum MoveEvent { enum MoveEvent {
EAGLE(id:Int, position:Position);
TANK(id:Int, position:Position); TANK(id:Int, position:Position);
BULLET(id:Int, position:Position); BULLET(id:Int, position:Position);
} }
@@ -65,6 +66,7 @@ enum ChangeEvent {
PLAYER_LIFE(playerId:PlayerId, value:Int); PLAYER_LIFE(playerId:PlayerId, value:Int);
TEAM_SCORE(teamId:TeamId, value:Int); TEAM_SCORE(teamId:TeamId, value:Int);
TEAM_LIFE(teamId:TeamId, value:Int); TEAM_LIFE(teamId:TeamId, value:Int);
BRICK(id:Int, type:BrickType);
} }
enum GameEvent { enum GameEvent {

View File

@@ -3,10 +3,8 @@ package ru.m.tankz.game;
import haxe.ds.Option; import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
import haxework.signal.Signal; import haxework.signal.Signal;
import ru.m.geom.Direction;
import ru.m.geom.Line; import ru.m.geom.Line;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.geom.Position;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.control.Controller; import ru.m.tankz.control.Controller;
import ru.m.tankz.control.IControlFactory; import ru.m.tankz.control.IControlFactory;
@@ -19,7 +17,6 @@ import ru.m.tankz.engine.IEngine;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.IGame; import ru.m.tankz.game.IGame;
import ru.m.tankz.game.Spawner; import ru.m.tankz.game.Spawner;
import ru.m.tankz.map.Brick;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class GameRunner implements EngineListener implements GameListener { class GameRunner implements EngineListener implements GameListener {
@@ -27,7 +24,6 @@ class GameRunner implements EngineListener implements GameListener {
private var game(default, null):IGame; private var game(default, null):IGame;
private var gameEventSignal(get, null):Signal<GameEvent>; private var gameEventSignal(get, null):Signal<GameEvent>;
private var entityId:Int;
private var timer:Timer; private var timer:Timer;
private var builder:EntityBuilder; private var builder:EntityBuilder;
@@ -36,7 +32,6 @@ class GameRunner implements EngineListener implements GameListener {
this.builder = new EntityBuilder(this.game.config); this.builder = new EntityBuilder(this.game.config);
this.game.connect(this); this.game.connect(this);
this.game.engine.connect(this); this.game.engine.connect(this);
this.entityId = 0;
} }
private inline function get_gameEventSignal():Signal<GameEvent> { private inline function get_gameEventSignal():Signal<GameEvent> {
@@ -56,14 +51,6 @@ class GameRunner implements EngineListener implements GameListener {
game.engine.disconnect(this); game.engine.disconnect(this);
} }
private function pointToPosition(point:{x:Int, y:Int, direction:String}):Position {
return {
x: (point.x + 1) * game.config.map.cellWidth,
y: (point.y + 1) * game.config.map.cellHeight,
direction: Direction.fromString(point.direction),
}
}
public function start(state:GameState):Void { public function start(state:GameState):Void {
for (team in game.teams.iterator()) { for (team in game.teams.iterator()) {
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
@@ -80,23 +67,14 @@ class GameRunner implements EngineListener implements GameListener {
} }
} }
if (team.config.eagle != null) { if (team.config.eagle != null) {
var point = game.config.getPoint(team.id, "eagle"); var point = team.spawner.getPoint("eagle");
var eagle = builder.buildEagle(++entityId, point, team.id); var eagle = builder.buildEagle(point, team.id);
game.engine.spawn(eagle); game.engine.spawn(eagle);
gameEventSignal.emit(GameEvent.SPAWN(EAGLE(eagle.id, eagle.rect, eagle.team))); gameEventSignal.emit(EventUtil.buildEagleSpawn(eagle));
eagle.protect.connect(onEagleProtectChange); eagle.protect.connect(onEagleProtectChange);
} }
} }
var bricks = game.engine.map.bricks.map(function(item:Brick):BrickInfo { gameEventSignal.emit(EventUtil.buildBricksSpawn(game.engine.map));
return {
id: item.id,
x: item.cellY,
y: item.cellY,
rect: item.rect,
type: item.config.type,
}
});
gameEventSignal.emit(GameEvent.SPAWN(BRICK(bricks)));
gameEventSignal.emit(GameEvent.START(state)); gameEventSignal.emit(GameEvent.START(state));
} }
@@ -112,9 +90,9 @@ class GameRunner implements EngineListener implements GameListener {
} }
private function spawn(task:SpawnTask):Void { private function spawn(task:SpawnTask):Void {
var tank = builder.buildTank(++entityId, task.point, task.playerId, task.tankType); var tank = builder.buildTank(task.point, task.playerId, task.tankType);
game.engine.spawn(tank); game.engine.spawn(tank);
gameEventSignal.emit(GameEvent.SPAWN(TANK(tank.id, tank.rect.clone(), tank.playerId, {type:tank.config.type, hits:tank.hits, bonus:tank.bonus}))); gameEventSignal.emit(EventUtil.buildTankSpawn(tank));
tank.protect.connect(onTankProtectChange); tank.protect.connect(onTankProtectChange);
tank.freezing.connect(onTankFreezingChange); tank.freezing.connect(onTankFreezingChange);
} }
@@ -265,7 +243,7 @@ class GameRunner implements EngineListener implements GameListener {
y: Math.floor(Math.random() * (game.engine.map.gridHeight - 1)), y: Math.floor(Math.random() * (game.engine.map.gridHeight - 1)),
direction: "right", direction: "right",
} }
var bonus = builder.buildBonus(++entityId, point, type); var bonus = builder.buildBonus(point, type);
game.engine.spawn(bonus); game.engine.spawn(bonus);
gameEventSignal.emit(GameEvent.SPAWN(BONUS(bonus.id, bonus.rect.clone(), bonus.config.type))); gameEventSignal.emit(GameEvent.SPAWN(BONUS(bonus.id, bonus.rect.clone(), bonus.config.type)));
} }
@@ -353,7 +331,7 @@ class GameRunner implements EngineListener implements GameListener {
if (!tank.freezing.active && player.bullets < tank.config.bullets) { if (!tank.freezing.active && player.bullets < tank.config.bullets) {
var rect = tank.rect; var rect = tank.rect;
var point = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y)); var point = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y));
var bullet = builder.buildBullet(++entityId, point, rect.direction, player.id, tank.config.type); var bullet = builder.buildBullet(point, rect.direction, player.id, tank.config.type);
bullet.tank = tank; bullet.tank = tank;
bullet.move(bullet.rect.direction); bullet.move(bullet.rect.direction);
game.engine.spawn(bullet); game.engine.spawn(bullet);

View File

@@ -1,126 +1,65 @@
package ru.m.tankz.editor.level; package ru.m.tankz.editor.level;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics; import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent; 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.Point;
import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.core.Entity; 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.Brick;
import ru.m.tankz.map.LevelMap; import ru.m.tankz.map.LevelMap;
import ru.m.tankz.render.RenderItem; import ru.m.tankz.render.Render;
import ru.m.tankz.Type.PlayerId; 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 { enum Brush {
POINT(point:SpawnPoint); POINT(point:SpawnPoint);
BRICK(brick:BrickConfig); BRICK(brick:BrickConfig);
} }
//ToDo: copy paste from ru.m.tankz.render.Render @:dispatcher(GameListener) class MapEditView extends Render {
class MapEditView extends SpriteView {
public var config(default, set):Config;
public var data(get, set):LevelConfig; public var data(get, set):LevelConfig;
public var map(default, null):LevelMap; public var map(default, null):LevelMap;
public var brush(default, default):Brush; public var brush(default, default):Brush;
private var items:Map<String, RenderItem<Dynamic, Dynamic>>; private var builder:EntityBuilder;
private var entityId:Int;
private var backgroundLayer:Sprite; private var pointEntities:Map<String, Entity>;
private var upLayer:Sprite;
private var groundLayer:Sprite;
private var spawnLayer:Sprite;
public function new() { public function new() {
super(); super();
items = new Map(); content.mouseChildren = false;
map = null; map = null;
backgroundLayer = new Sprite(); pointEntities = null;
upLayer = new Sprite();
groundLayer = new Sprite();
spawnLayer = new Sprite();
content.addChild(backgroundLayer);
content.addChild(groundLayer);
content.addChild(upLayer);
content.addChild(spawnLayer);
content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
connect(this);
reset(); 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 { private function onMouseDown(event:MouseEvent):Void {
content.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); content.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
@@ -137,92 +76,21 @@ class MapEditView extends SpriteView {
if (b != null) { if (b != null) {
switch (brush) { switch (brush) {
case Brush.POINT(point): case Brush.POINT(point):
for (p in config.points) { var entity = pointEntities[pointKey(point)];
if (p.team == point.team && p.type == point.type && p.index == point.index) { point.x = b.cellX;
p.x = b.cellX; point.y = b.cellY;
p.y = b.cellY; var rect = builder.buildRect(point, entity.rect.width, entity.rect.height);
drawMap(); entity.rect.position = rect.position;
drawMap(); gameEventSignal.emit(EventUtil.buildMove(entity));
break; case Brush.BRICK(brickConfig):
} b.config = config.getBrick(brickConfig.type);
} gameEventSignal.emit(GameEvent.CHANGE(BRICK(b.id, brickConfig.type)));
case Brush.BRICK(brick):
b.config = brick;
drawMap();
} }
} }
} }
private function clearLayer(layer:DisplayObjectContainer) { private static function pointKey(point:SpawnPoint):String {
while (layer.numChildren > 0) layer.removeChildAt(0); return '${point.type}:${point.team}:${point.index}';
}
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 function get_data():LevelConfig { private function get_data():LevelConfig {
@@ -234,16 +102,35 @@ class MapEditView extends SpriteView {
private function set_data(value:LevelConfig):LevelConfig { private function set_data(value:LevelConfig):LevelConfig {
reset(); reset();
pointEntities = new Map();
map = new LevelMap(config.map);
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight, "map");
map.setData(value.data); map.setData(value.data);
if (value.points != null) for (point in value.points) { gameEventSignal.emit(EventUtil.buildBricksSpawn(map));
for (p in config.points) { for (point in config.points) {
if (p.team == point.team && p.type == point.type && p.index == point.index) { switch point.type {
p.x = point.x; case "eagle":
p.y = point.y; var eagle = builder.buildEagle(point, point.team);
break; 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(); toUpdate();
return value; return value;
} }

View File

@@ -1,9 +1,7 @@
package ru.m.tankz.editor.level; package ru.m.tankz.editor.level;
import haxework.color.Color; import haxework.color.Color;
import haxework.provider.Provider;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.editor.level.MapEditView;
import ru.m.tankz.Type.PlayerId; import ru.m.tankz.Type.PlayerId;
class SpawnPointView extends BrushView<SpawnPoint> { class SpawnPointView extends BrushView<SpawnPoint> {
@@ -15,7 +13,18 @@ class SpawnPointView extends BrushView<SpawnPoint> {
} }
override private function resolveSrc(value:SpawnPoint):String { 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) { public static inline function factory(index:Int, value:SpawnPoint) {