diff --git a/package.json b/package.json index ada1420..9fb0d42 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.0.4", + "version": "0.0.5", "private": true, "devDependencies": { "ansi-colors": "^1.0.1", diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index a60c5e2..2cd3f84 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -35,7 +35,7 @@ class BrickState implements IState { class EntityState implements IState { private var x:Float; private var y:Float; - private var level:Int; + private var type:Int; public function new() {} @@ -47,8 +47,8 @@ class EntityState implements IState { } if (Std.is(object, Tank)) { var tank:Tank = cast object; - if (tank.config.level != level) { - level = tank.config.level; + if (tank.config.type != type) { + type = tank.config.type; return true; } } @@ -192,7 +192,7 @@ class Render extends SpriteView implements IRender { var image:String = null; if (Std.is(ent, Tank)) { var tank:Tank = cast ent; - image = 'resources/images/tank/player/tank_p${tank.config.level}_${tank.index}-0.png'; + image = 'resources/images/tank/${tank.config.group}/tank_${tank.config.group.charAt(0)}${tank.config.type}_${tank.index}-0.png'; } else if (Std.is(ent, Bullet)) { var bullet:Bullet = cast ent; image = 'resources/images/bullet/bullet_${bullet.config.piercing > 1 ? 1 : 0}.png'; diff --git a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx index 11000c3..df0cb27 100755 --- a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx @@ -1,5 +1,6 @@ package ru.m.tankz.view.frames; +import ru.m.tankz.config.ConfigBundle; import ru.m.tankz.proto.core.GameType; import ru.m.tankz.proto.core.Game; import ru.m.tankz.core.PlayerControl; @@ -8,11 +9,11 @@ import protohx.Message; import ru.m.tankz.proto.pack.GameUpdateResponse; import ru.m.connect.IConnection; import haxework.gui.ViewBuilder; -import ru.m.tankz.config.Config; import flash.events.Event; import haxework.provider.Provider; import haxework.gui.VGroupView; + @:template("layout/frames/game.json", "layout/styles.json") class GameFrame extends VGroupView implements ViewBuilder implements IPacketHandler { diff --git a/src/client/resources/config/config.yaml b/src/client/resources/config/config.yaml index fc1ab52..1800afe 100644 --- a/src/client/resources/config/config.yaml +++ b/src/client/resources/config/config.yaml @@ -15,34 +15,49 @@ map: x: 16 y: 24 direction: top + - type: bot + index: 1 + x: 0 + y: 0 + direction: bottom + - type: bot + index: 2 + x: 12 + y: 0 + direction: bottom + - type: bot + index: 3 + x: 24 + y: 0 + direction: bottom bricks: - -1: &brick-boder - type: -1 + # border + - type: -1 layer: 2 armor: -1 - 0: &brick-none - type: 0 + # none + - type: 0 layer: 0 armor: 0 - 1: &brick-ace - type: 1 + # ace + - type: 1 layer: 0 armor: 0 - 2: &brick-bush - type: 2 + # bush + - type: 2 layer: 3 armor: 0 - 3: &brick-water - type: 3 + # water + - type: 3 layer: 1 armor: 0 - 4: &brick-armor - type: 4 + # armor + - type: 4 layer: 2 armor: 2 - 5: &brick-brick - type: 5 + # brick + - type: 5 layer: 2 armor: 1 @@ -54,8 +69,7 @@ bullet: &bullet tanks: player: - 0: - level: 0 + - type: 0 width: 36 height: 36 speed: 2.5 @@ -63,8 +77,8 @@ tanks: <<: *bullet speed: 8.0 bullets: 1 - 1: - level: 1 + + - type: 1 width: 40 height: 36 speed: 3.0 @@ -72,8 +86,8 @@ tanks: <<: *bullet speed: 8.5 bullets: 1 - 2: - level: 2 + + - type: 2 width: 40 height: 36 speed: 3.0 @@ -81,8 +95,8 @@ tanks: <<: *bullet speed: 9.0 bullets: 3 - 3: - level: 3 + + - type: 3 width: 42 height: 38 speed: 2.9 @@ -91,3 +105,45 @@ tanks: speed: 9.0 piercing: 3 bullets: 2 + + bot: + - type: 0 + width: 38 + height: 36 + speed: 2.0 + bullet: + <<: *bullet + speed: 7.0 + bullets: 1 + score: 100 + + - type: 1 + width: 40 + height: 36 + speed: 4.0 + bullet: + <<: *bullet + speed: 7.0 + bullets: 1 + score: 200 + + - type: 2 + width: 38 + height: 36 + speed: 2.0 + bullet: + <<: *bullet + speed: 9.0 + bullets: 1 + score: 300 + + - type: 3 + width: 40 + height: 36 + speed: 1.8 + bullet: + <<: *bullet + speed: 8.0 + bullets: 1 + score: 400 + hits: 4 diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index a9ff213..0301229 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -1,19 +1,14 @@ package ru.m.tankz.config; -import Reflect; -import yaml.Parser; -import yaml.Yaml; -import openfl.utils.Assets; -import ru.m.tankz.proto.core.GameType; -@:enum abstract SpawnPointType(String) from String to String { +@:enum abstract EntityType(String) from String to String { var PLAYER = 'player'; var BOT = 'bot'; var EAGLE = 'eagle'; } typedef SpawnPoint = { - var type:SpawnPointType; + var type:EntityType; var index:Int; var x:Int; var y:Int; @@ -43,8 +38,10 @@ typedef BulletConfig = { var piercing:Int; } + typedef TankConfig = { - var level:Int; + var group:String; + var type:Int; var width:Float; var height:Float; var speed:Float; @@ -54,80 +51,47 @@ typedef TankConfig = { class Config { - public var source(default, null):ConfigSource; + public var map(default, null):MapConfig; + public var bricks(default, null):Array; + public var tanks(default, null):Array; - public function new(source: ConfigSource) { - this.source = source; + private var pointMap:Map>; + private var brickMap:Map; + private var tankMap:Map>; + + public function new(map:MapConfig, bricks:Array, tanks:Array) { + this.map = map; + this.bricks = bricks; + this.tanks = tanks; + init(); } - public function getSpawnPoint(type:SpawnPointType, index:Int):SpawnPoint { - for (point in this.source.map.points) { - if (point.type == type && point.index == index) { - return point; - } + private function init() { + pointMap = new Map(); + for (item in map.points) { + if (!pointMap.exists(item.type)) pointMap.set(item.type, new Map()); + pointMap.get(item.type).set(item.index, item); } - return null; + brickMap = new Map(); + for (item in bricks) { + brickMap.set(item.type, item); + } + tankMap = new Map(); + for (item in tanks) { + if (!tankMap.exists(item.group)) tankMap.set(item.group, new Map()); + tankMap.get(item.group).set(item.type, item); + } + } + + public function getSpawnPoint(type:EntityType, index:Int):SpawnPoint { + return pointMap.get(type).get(index); } public function getBrick(type:Int):BrickConfig { - return source.bricks.get(type); + return brickMap.get(type); } - public function getPlayerTank(level:Int):TankConfig { - return source.tanks.player.get(level); - } -} - - -typedef ConfigSource = { - map: MapConfig, - bricks: Map, - tanks: { - player: Map - } -} - - -class ConfigBundle { - - private static function buildMap(object:Dynamic):Map { - var result:Map = new Map(); - for (key in Reflect.fields(object)) { - result.set(Std.parseInt(key), Reflect.field(object, key)); - } - return result; - } - - private static function convert(raw:Dynamic):ConfigSource { - var map: MapConfig = Reflect.getProperty(raw, 'map'); - var bricks: Map = cast buildMap(Reflect.getProperty(raw, 'bricks')); - var players: Map = cast buildMap(Reflect.getProperty(Reflect.getProperty(raw, 'tanks'), 'player')); - return { - map: map, - bricks: bricks, - tanks: { - player: players - } - } - } - - public static function get(type:Int, level:Int):Config { - switch (type) { - case GameType.CLASSIC: - var source:ConfigSource = convert(Yaml.parse(Assets.getText('resources/config/config.yaml'), Parser.options().useObjects())); - var bricksData:String = Assets.getText('resources/levels/level00${level}.txt'); - var bricks:Array = []; - for (line in ~/\s+/g.split(bricksData)) { - for (c in line.split('')) { - if (c.length > 0) { - bricks.push(source.bricks.get(Std.parseInt(c))); - } - } - } - source.map.bricks = bricks; - return new Config(source); - case _: - return null; - } + public function getTank(group:String, type:Int):TankConfig { + return tankMap.get(group).get(type); } } diff --git a/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx b/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx new file mode 100644 index 0000000..f8570b9 --- /dev/null +++ b/src/common/haxe/ru/m/tankz/config/ConfigBundle.hx @@ -0,0 +1,49 @@ +package ru.m.tankz.config; + +import yaml.Parser; +import openfl.Assets; +import yaml.Yaml; +import ru.m.tankz.proto.core.GameType; +import ru.m.tankz.config.Config; + + +typedef ConfigSource = { + var map: MapConfig; + var bricks: Array; + var tanks: Dynamic>; +} + +class ConfigBundle { + + private static function convert(raw:Dynamic):ConfigSource { + return raw; + } + + public static function get(type:Int, level:Int):Config { + switch (type) { + case GameType.CLASSIC: + var source:ConfigSource = convert(Yaml.parse(Assets.getText('resources/config/config.yaml'), Parser.options().useObjects())); + var bricksData:String = Assets.getText('resources/levels/level00${level}.txt'); + var bricks:Array = []; + for (line in ~/\s+/g.split(bricksData)) { + for (c in line.split('')) { + if (c.length > 0) { + bricks.push(source.bricks[Std.parseInt(c) + 1]); + } + } + } + source.map.bricks = bricks; + var tanks:Array = []; + for (group in Reflect.fields(source.tanks)) { + var data:Array = Reflect.field(source.tanks, group); + for (item in data) { + item.group = group; + tanks.push(item); + } + } + return new Config(source.map, source.bricks, tanks); + case _: + return null; + } + } +} diff --git a/src/common/haxe/ru/m/tankz/core/Tank.hx b/src/common/haxe/ru/m/tankz/core/Tank.hx index 0dfef2a..75fa104 100755 --- a/src/common/haxe/ru/m/tankz/core/Tank.hx +++ b/src/common/haxe/ru/m/tankz/core/Tank.hx @@ -44,6 +44,15 @@ class Tank extends MobileEntity { return bullet; } + override public function move(direction:Direction):Void { + // ToDo: spike + if (direction != this.direction) { + rect.x -= this.direction.x * 4; + rect.y -= this.direction.y * 4; + } + super.move(direction); + } + public function onDestroyBullet():Void { bulletsCounter--; } diff --git a/src/common/haxe/ru/m/tankz/engine/Engine.hx b/src/common/haxe/ru/m/tankz/engine/Engine.hx index f1c3982..ce12722 100755 --- a/src/common/haxe/ru/m/tankz/engine/Engine.hx +++ b/src/common/haxe/ru/m/tankz/engine/Engine.hx @@ -6,7 +6,6 @@ import ru.m.tankz.core.Entity; import ru.m.geom.Direction; import ru.m.tankz.config.Config.TankConfig; import ru.m.geom.Point; -import ru.m.tankz.map.Brick; import ru.m.tankz.core.Bullet; import ru.m.tankz.proto.game.GameObjectType; import ru.m.tankz.proto.game.GameChangeType; @@ -43,7 +42,7 @@ class Engine { public function init(config:Config):Void { this.config = config; - map = new LevelMap(config.source.map); + map = new LevelMap(config.map); playerTanks = new Map(); entities = new Map(); removedEntities = new Array(); @@ -54,8 +53,8 @@ class Engine { var changes = new Array(); for (index in 0...players.length) { var player:Player = players[index]; - var point:SpawnPoint = config.getSpawnPoint(SpawnPointType.PLAYER, index); - var tank = buildTank(index, config.getPlayerTank(0), point); + var point:SpawnPoint = config.getSpawnPoint(EntityType.PLAYER, index); + var tank = buildTank(index, config.getTank('player', 0), point); playerTanks.set(player.id, tank); entities.set(tank.id, tank); changes.push(new GameChange() @@ -68,6 +67,12 @@ class Engine { .setDirectionY(tank.direction.y) ); } + + for (index in 1...4) { + var point:SpawnPoint = config.getSpawnPoint(EntityType.BOT, index); + var tank = buildTank(0, config.getTank('bot', 0), point); + entities.set(tank.id, tank); + } return changes; } @@ -83,7 +88,7 @@ class Engine { .setDirectionY(direction.y) );*/ case TankAction.LEVEL_UP(level): - tank.config = config.getPlayerTank(Std.int(Math.min(tank.config.level + level, 3))); + tank.config = config.getTank('player', Std.int(Math.min(tank.config.type + level, 3))); case TankAction.STOP: tank.stop(); /*Provider.get(IConnection).send( diff --git a/src/common/haxe/ru/m/tankz/map/Brick.hx b/src/common/haxe/ru/m/tankz/map/Brick.hx index 5719878..094e784 100644 --- a/src/common/haxe/ru/m/tankz/map/Brick.hx +++ b/src/common/haxe/ru/m/tankz/map/Brick.hx @@ -42,12 +42,15 @@ class Brick implements IKey { public function get_destroyed():Bool { var i = 0; + var result:Bool = false; for (c in cells.iterator()) { if (!c.destroyed) { return false; + } else { + result = true; } } - return true; + return result; } public function set_destroyed(value:Bool):Bool {