diff --git a/package.json b/package.json index 648a6bc..38f50b8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.0.1", + "version": "0.0.2", "private": true, "devDependencies": { "ansi-colors": "^1.0.1", diff --git a/src/client/haxe/ru/m/tankz/Client.hx b/src/client/haxe/ru/m/tankz/Client.hx index c219dc7..79cbc5f 100755 --- a/src/client/haxe/ru/m/tankz/Client.hx +++ b/src/client/haxe/ru/m/tankz/Client.hx @@ -19,7 +19,7 @@ import haxework.provider.Provider; import haxework.gui.frame.FrameSwitcher; import haxework.gui.Root; import openfl.Assets; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; import haxework.log.TraceLogger; @:template("layout/main.json", "layout/styles.json") @@ -56,9 +56,9 @@ class Client implements IConnectionHandler { Provider.set(IPacketBuilder, new PacketBuilder()); #if flash - Provider.set(IConnection, new ru.m.core.connect.flash.FlashConnection("localhost", 5001)); + Provider.set(IConnection, new ru.m.connect.flash.FlashConnection("localhost", 5001)); #elseif html5 - Provider.set(IConnection, new ru.m.core.connect.js.JsConnection("localhost", 5001)); + Provider.set(IConnection, new ru.m.connect.js.JsConnection("localhost", 5001)); #end Provider.get(IConnection).handler.addListener(this); diff --git a/src/client/haxe/ru/m/tankz/core/PlayerControl.hx b/src/client/haxe/ru/m/tankz/core/PlayerControl.hx index 505eee1..633a966 100644 --- a/src/client/haxe/ru/m/tankz/core/PlayerControl.hx +++ b/src/client/haxe/ru/m/tankz/core/PlayerControl.hx @@ -1,5 +1,6 @@ package ru.m.tankz.core; +import ru.m.geom.Direction; import flash.events.FocusEvent; import flash.ui.Keyboard; import ru.m.tankz.engine.IEngine; diff --git a/src/client/haxe/ru/m/tankz/render/IRender.hx b/src/client/haxe/ru/m/tankz/render/IRender.hx index 9fc25a0..eed0729 100755 --- a/src/client/haxe/ru/m/tankz/render/IRender.hx +++ b/src/client/haxe/ru/m/tankz/render/IRender.hx @@ -3,7 +3,8 @@ package ru.m.tankz.render; import haxework.gui.IView; import ru.m.tankz.engine.IEngine; + interface IRender extends IView { - public function draw(game:IEngine):Void; - public function reset():Void; + public function draw(game:IEngine):Void; + public function reset():Void; } diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index d771f7b..2e008b0 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -1,8 +1,9 @@ package ru.m.tankz.render; +import ru.m.tankz.core.IMobileEntity; import ru.m.tankz.core.Entity; import ru.m.tankz.map.Brick; -import ru.m.tankz.core.Direction; +import ru.m.geom.Direction; import flash.geom.Matrix; import openfl.Assets; import ru.m.tankz.core.Bullet; @@ -38,9 +39,9 @@ class EntityState implements IState { public function new() {} public function update(object:Entity):Bool { - if (x != object.x || y != object.y) { - x = object.x; - y = object.y; + if (x != object.rect.x || y != object.rect.y) { + x = object.rect.x; + y = object.rect.y; return true; } return false; @@ -90,7 +91,7 @@ class Render extends SpriteView implements IRender { layersForUpdate[upLayer] = true; } } - for (entry in game.mobileEntities) { + for (entry in game.entities) { if (!states.exists(entry.key)) { states[entry.key] = new EntityState(); } @@ -98,6 +99,12 @@ class Render extends SpriteView implements IRender { layersForUpdate[entryLayer] = true; } } + for (key in game.removedEntities) { + if (states.exists(key)) { + states.remove(key); + layersForUpdate[entryLayer] = true; + } + } } private function drawBackground(game:IEngine):Void { @@ -150,20 +157,21 @@ class Render extends SpriteView implements IRender { if (layersForUpdate[entryLayer]) { var g:Graphics = entryLayer.graphics; g.clear(); - for (e in game.mobileEntities) { + for (ent in game.entities) if (Std.is(ent, IMobileEntity)) { + var e:IMobileEntity = cast ent; if (Std.is(e, Tank)) { var m = new Matrix(); m.rotate(calcRotate(e.direction)); - m.translate(e.x, e.y); + m.translate(e.rect.x, e.rect.y); g.beginBitmapFill(Assets.getBitmapData("resources/images/tank/player/tank_p0_0-0.png"), m); - g.drawRect(e.x, e.y, e.width, e.height); + g.drawRect(e.rect.x, e.rect.y, e.rect.width, e.rect.height); g.endFill(); } else if (Std.is(e, Bullet)) { var m = new Matrix(); m.rotate(calcRotate(e.direction)); - m.translate(e.x, e.y); + m.translate(e.rect.x, e.rect.y); g.beginBitmapFill(Assets.getBitmapData("resources/images/bullet/bullet_0.png"), m); - g.drawRect(e.x, e.y, e.width, e.height); + g.drawRect(e.rect.x, e.rect.y, e.rect.width, e.rect.height); g.endFill(); } } 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 82b33ea..1f2853c 100755 --- a/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/frames/GameFrame.hx @@ -7,7 +7,7 @@ import ru.m.tankz.engine.Engine; import ru.m.tankz.engine.IEngine; import protohx.Message; import ru.m.tankz.proto.pack.GameUpdateResponse; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; import haxework.gui.ViewBuilder; import ru.m.tankz.config.Config; import flash.events.Event; diff --git a/src/common/haxe/ru/m/core/Base64.hx b/src/common/haxe/ru/m/Base64.hx similarity index 98% rename from src/common/haxe/ru/m/core/Base64.hx rename to src/common/haxe/ru/m/Base64.hx index a36dfa3..00d1fe6 100644 --- a/src/common/haxe/ru/m/core/Base64.hx +++ b/src/common/haxe/ru/m/Base64.hx @@ -1,4 +1,4 @@ -package ru.m.core; +package ru.m; import haxe.io.Bytes; import haxe.crypto.BaseCode; diff --git a/src/common/haxe/ru/m/core/connect/BaseConnection.hx b/src/common/haxe/ru/m/connect/BaseConnection.hx similarity index 96% rename from src/common/haxe/ru/m/core/connect/BaseConnection.hx rename to src/common/haxe/ru/m/connect/BaseConnection.hx index 8ae00c1..4f0d5ed 100755 --- a/src/common/haxe/ru/m/core/connect/BaseConnection.hx +++ b/src/common/haxe/ru/m/connect/BaseConnection.hx @@ -1,11 +1,11 @@ -package ru.m.core.connect; +package ru.m.connect; import haxework.dispath.Dispatcher; import haxework.dispath.IDispatcher; import haxework.provider.Provider; import haxe.io.Bytes; import protohx.Message; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; class BaseConnection implements IConnection { public var handler(default,default):IDispatcher; diff --git a/src/common/haxe/ru/m/core/connect/IConnection.hx b/src/common/haxe/ru/m/connect/IConnection.hx similarity index 97% rename from src/common/haxe/ru/m/core/connect/IConnection.hx rename to src/common/haxe/ru/m/connect/IConnection.hx index 809744c..b31f074 100755 --- a/src/common/haxe/ru/m/core/connect/IConnection.hx +++ b/src/common/haxe/ru/m/connect/IConnection.hx @@ -1,4 +1,4 @@ -package ru.m.core.connect; +package ru.m.connect; import haxework.dispath.IDispatcher; import haxe.io.Bytes; diff --git a/src/common/haxe/ru/m/core/connect/PacketQueue.hx b/src/common/haxe/ru/m/connect/PacketQueue.hx similarity index 95% rename from src/common/haxe/ru/m/core/connect/PacketQueue.hx rename to src/common/haxe/ru/m/connect/PacketQueue.hx index 72326b6..e1c1ecf 100755 --- a/src/common/haxe/ru/m/core/connect/PacketQueue.hx +++ b/src/common/haxe/ru/m/connect/PacketQueue.hx @@ -1,6 +1,6 @@ -package ru.m.core.connect; +package ru.m.connect; -import ru.m.core.connect.IConnection.IPacketBuilder; +import ru.m.connect.IConnection.IPacketBuilder; import protohx.Message; import haxe.io.BytesInput; import haxe.io.BytesBuffer; diff --git a/src/common/haxe/ru/m/core/connect/WebSocketTools.hx b/src/common/haxe/ru/m/connect/WebSocketTools.hx similarity index 92% rename from src/common/haxe/ru/m/core/connect/WebSocketTools.hx rename to src/common/haxe/ru/m/connect/WebSocketTools.hx index 7f3cb52..39dfea8 100644 --- a/src/common/haxe/ru/m/core/connect/WebSocketTools.hx +++ b/src/common/haxe/ru/m/connect/WebSocketTools.hx @@ -1,8 +1,8 @@ -package ru.m.core.connect; +package ru.m.connect; import haxe.io.Bytes; import haxe.io.BytesOutput; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; import protohx.Message; class WebSocketTools { diff --git a/src/common/haxe/ru/m/core/connect/flash/FlashConnection.hx b/src/common/haxe/ru/m/connect/flash/FlashConnection.hx similarity index 96% rename from src/common/haxe/ru/m/core/connect/flash/FlashConnection.hx rename to src/common/haxe/ru/m/connect/flash/FlashConnection.hx index 8ab1825..b4eb852 100755 --- a/src/common/haxe/ru/m/core/connect/flash/FlashConnection.hx +++ b/src/common/haxe/ru/m/connect/flash/FlashConnection.hx @@ -1,6 +1,6 @@ -package ru.m.core.connect.flash; +package ru.m.connect.flash; -import ru.m.core.connect.IConnection.IConnectionHandler; +import ru.m.connect.IConnection.IConnectionHandler; import flash.utils.Endian; import haxe.io.BytesOutput; import protohx.Message; diff --git a/src/common/haxe/ru/m/core/connect/js/JsConnection.hx b/src/common/haxe/ru/m/connect/js/JsConnection.hx similarity index 95% rename from src/common/haxe/ru/m/core/connect/js/JsConnection.hx rename to src/common/haxe/ru/m/connect/js/JsConnection.hx index 3ad0f64..4cb165e 100644 --- a/src/common/haxe/ru/m/core/connect/js/JsConnection.hx +++ b/src/common/haxe/ru/m/connect/js/JsConnection.hx @@ -1,7 +1,7 @@ -package ru.m.core.connect.js; +package ru.m.connect.js; import ru.m.core.Base64; -import ru.m.core.connect.IConnection.IConnectionHandler; +import ru.m.connect.IConnection.IConnectionHandler; import protohx.Message; import haxe.io.Bytes; diff --git a/src/common/haxe/ru/m/core/connect/neko/NekoConnection.hx b/src/common/haxe/ru/m/connect/neko/NekoConnection.hx similarity index 89% rename from src/common/haxe/ru/m/core/connect/neko/NekoConnection.hx rename to src/common/haxe/ru/m/connect/neko/NekoConnection.hx index 8ed549c..00fb58a 100755 --- a/src/common/haxe/ru/m/core/connect/neko/NekoConnection.hx +++ b/src/common/haxe/ru/m/connect/neko/NekoConnection.hx @@ -1,10 +1,10 @@ -package ru.m.core.connect.neko; +package ru.m.connect.neko; import haxe.io.BytesOutput; import protohx.Message; import haxe.io.Bytes; import sys.net.Socket; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; class NekoConnection extends BaseConnection { diff --git a/src/common/haxe/ru/m/core/connect/neko/NekoWebConnection.hx b/src/common/haxe/ru/m/connect/neko/NekoWebConnection.hx similarity index 98% rename from src/common/haxe/ru/m/core/connect/neko/NekoWebConnection.hx rename to src/common/haxe/ru/m/connect/neko/NekoWebConnection.hx index 1bda625..a188f4f 100644 --- a/src/common/haxe/ru/m/core/connect/neko/NekoWebConnection.hx +++ b/src/common/haxe/ru/m/connect/neko/NekoWebConnection.hx @@ -1,11 +1,11 @@ -package ru.m.core.connect.neko; +package ru.m.connect.neko; import haxe.crypto.BaseCode; import haxe.crypto.Sha1; import protohx.Message; import haxe.io.Bytes; import sys.net.Socket; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; class NekoWebConnection extends NekoConnection { diff --git a/src/common/haxe/ru/m/geom/Direction.hx b/src/common/haxe/ru/m/geom/Direction.hx new file mode 100644 index 0000000..4c9b0ae --- /dev/null +++ b/src/common/haxe/ru/m/geom/Direction.hx @@ -0,0 +1,29 @@ +package ru.m.geom; + +import haxe.ds.IntMap; + +class Direction { + private static var directions:IntMap = new IntMap(); + + public static var LEFT(default, null) = new Direction(-1, 0); + public static var TOP(default, null) = new Direction(0, -1); + public static var RIGHT(default, null) = new Direction(1, 0); + public static var BOTTOM(default, null) = new Direction(0, 1); + + public var x(default, null):Int; + public var y(default, null):Int; + + private function new(x, y) { + this.x = x; + this.y = y; + directions.set(x + y * 10, this); + } + + public function reverse():Direction { + return from(-x, -y); + } + + public static function from(x:Int, y:Int):Direction { + return directions.get(x + y * 10); + } +} diff --git a/src/common/haxe/ru/m/tankz/core/Point.hx b/src/common/haxe/ru/m/geom/Point.hx similarity index 92% rename from src/common/haxe/ru/m/tankz/core/Point.hx rename to src/common/haxe/ru/m/geom/Point.hx index 681e419..8bdbba9 100644 --- a/src/common/haxe/ru/m/tankz/core/Point.hx +++ b/src/common/haxe/ru/m/geom/Point.hx @@ -1,4 +1,4 @@ -package ru.m.tankz.core; +package ru.m.geom; class Point { public var x(default, default):Float; diff --git a/src/common/haxe/ru/m/geom/Rectangle.hx b/src/common/haxe/ru/m/geom/Rectangle.hx new file mode 100644 index 0000000..98beec9 --- /dev/null +++ b/src/common/haxe/ru/m/geom/Rectangle.hx @@ -0,0 +1,31 @@ +package ru.m.geom; + +class Rectangle { + public var x(default, default):Float; + public var y(default, default):Float; + public var width(default, default):Float; + public var height(default, default):Float; + public var center(get, set):Point; + + public function new(x:Float, y:Float, width:Float, height:Float) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + private function get_center():Point { + return new Point(x + width / 2, y + height / 2); + } + + private function set_center(value:Point):Point { + this.x = value.x - width / 2; + this.y = value.y - height / 2; + return value; + } + + public function getSide(direction:Direction):Point { + return center.add(new Point(direction.x * width / 2, direction.y * height / 2)); + } + +} diff --git a/src/common/haxe/ru/m/tankz/PacketBuilder.hx b/src/common/haxe/ru/m/tankz/PacketBuilder.hx index 126d457..faa7db0 100755 --- a/src/common/haxe/ru/m/tankz/PacketBuilder.hx +++ b/src/common/haxe/ru/m/tankz/PacketBuilder.hx @@ -4,7 +4,7 @@ import ru.m.tankz.proto.pack.LeaveGameRequest; import ru.m.tankz.proto.pack.LeaveGameResponse; import ru.m.tankz.proto.pack.GameUpdateResponse; import ru.m.tankz.proto.pack.GameActionRequest; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; import protohx.Message; import ru.m.tankz.proto.pack.ErrorResponse; import ru.m.tankz.proto.pack.GameListRequest; diff --git a/src/common/haxe/ru/m/tankz/config/Config.hx b/src/common/haxe/ru/m/tankz/config/Config.hx index 50e550a..57fd290 100644 --- a/src/common/haxe/ru/m/tankz/config/Config.hx +++ b/src/common/haxe/ru/m/tankz/config/Config.hx @@ -3,7 +3,7 @@ package ru.m.tankz.config; import openfl.utils.Assets; import ru.m.tankz.map.Brick.BrickType; import ru.m.tankz.proto.core.GameType; -import ru.m.tankz.core.Direction; +import ru.m.geom.Direction; typedef MapConfig = { var cellWidth:Float; diff --git a/src/common/haxe/ru/m/tankz/core/Bullet.hx b/src/common/haxe/ru/m/tankz/core/Bullet.hx index 45f95be..f993d40 100644 --- a/src/common/haxe/ru/m/tankz/core/Bullet.hx +++ b/src/common/haxe/ru/m/tankz/core/Bullet.hx @@ -1,13 +1,15 @@ package ru.m.tankz.core; +import ru.m.geom.Rectangle; +import ru.m.geom.Direction; + + class Bullet extends MobileEntity { - public var personId(default, null):Int; + public var tankId(default, null):Int; - public function new(personId:Int, id:Int, x:Float, y:Float, speed:Float, direction:Direction) { - super(id, x, y, speed, direction); - this.personId = personId; - this.width = 12; - this.height = 12; - } + public function new(tankId:Int, x:Float, y:Float, speed:Float, direction:Direction) { + super(new Rectangle(x, y, 12, 12), speed, direction); + this.tankId = tankId; + } } diff --git a/src/common/haxe/ru/m/tankz/core/Direction.hx b/src/common/haxe/ru/m/tankz/core/Direction.hx deleted file mode 100644 index 1c8de77..0000000 --- a/src/common/haxe/ru/m/tankz/core/Direction.hx +++ /dev/null @@ -1,29 +0,0 @@ -package ru.m.tankz.core; - -import haxe.ds.IntMap; - -class Direction { - private static var directions:IntMap = new IntMap(); - - public static var LEFT(default, null) = new Direction(-1, 0); - public static var TOP(default, null) = new Direction(0, -1); - public static var RIGHT(default, null) = new Direction(1, 0); - public static var BOTTOM(default, null) = new Direction(0, 1); - - public var x(default, null):Int; - public var y(default, null):Int; - - private function new(x, y) { - this.x = x; - this.y = y; - directions.set(x + y * 10, this); - } - - public function reverse():Direction { - return directions.get(-x + (-y) * 10); - } - - public static function from(x:Int, y:Int):Direction { - return directions.get(x + y * 10); - } -} diff --git a/src/common/haxe/ru/m/tankz/core/Entity.hx b/src/common/haxe/ru/m/tankz/core/Entity.hx index 04dd395..9d9c7a3 100755 --- a/src/common/haxe/ru/m/tankz/core/Entity.hx +++ b/src/common/haxe/ru/m/tankz/core/Entity.hx @@ -1,32 +1,21 @@ package ru.m.tankz.core; +import ru.m.geom.Rectangle; -class Entity extends Point implements IEntity { - public var width(default, default):Float; - public var height(default, default):Float; +class Entity implements IEntity { + private static var idCounter:Int = 0; + + public var id(default, null):Int; public var key(get, null):String; - public var center(get, set):Point; + public var rect(default, null):Rectangle; - public function new(x:Float, y:Float) { - super(x, y); - } - - private function get_center():Point { - return new Point(x + width / 2, y + height / 2); - } - - private function set_center(value:Point):Point { - this.x = value.x - width / 2; - this.y = value.y - height / 2; - return value; - } - - public function getSide(direction:Direction):Point { - return center.add(new Point(direction.x * width / 2, direction.y * height / 2)); + public function new(rect:Rectangle) { + this.id = ++idCounter; + this.rect = rect; } private function get_key():String { - return '${Type.getClassName(Type.getClass(this))}'; + return '${Type.getClassName(Type.getClass(this))}:$id'; } } diff --git a/src/common/haxe/ru/m/tankz/core/IEntity.hx b/src/common/haxe/ru/m/tankz/core/IEntity.hx index 92eeee8..7c07f27 100755 --- a/src/common/haxe/ru/m/tankz/core/IEntity.hx +++ b/src/common/haxe/ru/m/tankz/core/IEntity.hx @@ -1,11 +1,9 @@ package ru.m.tankz.core; -interface IEntity extends IKey { - public var x(default, default):Float; - public var y(default, default):Float; - public var center(get, set):Point; - public function getSide(direction:Direction):Point; +import ru.m.geom.Rectangle; - public var width(default, default):Float; - public var height(default, default):Float; + +interface IEntity extends IKey { + public var id(default, null):Int; + public var rect(default, null):Rectangle; } diff --git a/src/common/haxe/ru/m/tankz/core/IMobileEntity.hx b/src/common/haxe/ru/m/tankz/core/IMobileEntity.hx index 2467e96..eb4fc80 100755 --- a/src/common/haxe/ru/m/tankz/core/IMobileEntity.hx +++ b/src/common/haxe/ru/m/tankz/core/IMobileEntity.hx @@ -1,14 +1,15 @@ package ru.m.tankz.core; +import ru.m.geom.Direction; + + interface IMobileEntity extends IEntity { - public var id(default, null):Int; + public var mx(default, default):Float; + public var my(default, default):Float; - public var mx(default, default):Float; - public var my(default, default):Float; + public var speed(default, null):Float; + public var direction(default, default):Direction; - public var speed(default, null):Float; - public var direction(default, default):Direction; - - public function move(direction:Direction):Void; - public function stop():Void; + public function move(direction:Direction):Void; + public function stop():Void; } diff --git a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx index b35adcc..aeebe87 100755 --- a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx +++ b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx @@ -1,35 +1,30 @@ package ru.m.tankz.core; +import ru.m.geom.Direction; +import ru.m.geom.Rectangle; + + class MobileEntity extends Entity implements IMobileEntity { - private static var idCounter:Int = 0; + public var mx(default, default):Float = 0; + public var my(default, default):Float = 0; - public var id(default, null):Int; + public var speed(default, null):Float = 0; + public var direction(default, default):Direction; - public var mx(default, default):Float = 0; - public var my(default, default):Float = 0; + public function new(rect:Rectangle, speed:Float, direction:Direction) { + super(rect); + this.speed = speed; + this.direction = direction; + } - public var speed(default, null):Float = 0; - public var direction(default, default):Direction; + public function move(direction:Direction):Void { + this.direction = direction; + mx = direction.x * speed; + my = direction.y * speed; + } - public function new(id:Int = 0, x:Float = 0, y:Float = 0, speed:Float = 0, direction:Direction = null) { - super(x, y); - this.id = id == 0 ? ++idCounter : id; - this.speed = speed; - this.direction = direction == null ? Direction.BOTTOM : direction; - } - - public function move(direction:Direction):Void { - this.direction = direction; - mx = direction.x * speed; - my = direction.y * speed; - } - - public function stop():Void { - mx = 0; - my = 0; - } - - override private function get_key():String { - return '${super.get_key()}:${id}'; - } + public function stop():Void { + mx = 0; + my = 0; + } } diff --git a/src/common/haxe/ru/m/tankz/core/Tank.hx b/src/common/haxe/ru/m/tankz/core/Tank.hx index 068facd..c2f85fc 100755 --- a/src/common/haxe/ru/m/tankz/core/Tank.hx +++ b/src/common/haxe/ru/m/tankz/core/Tank.hx @@ -1,5 +1,9 @@ package ru.m.tankz.core; +import ru.m.geom.Rectangle; +import ru.m.geom.Direction; + + enum TankAction { MOVE(direction:Direction); STOP; @@ -8,20 +12,15 @@ enum TankAction { class Tank extends MobileEntity { - public var personId(default, null):Int; - public var bulletsCount:Int = 0; - public function new(personId:Int, id:Int, x:Float, y:Float, direction:Direction) { - super(id, x, y, 4, direction); - this.personId = personId; - width = 36; - height = 36; + public function new(x:Float, y:Float, direction:Direction) { + super(new Rectangle(x, y, 36, 36), 4, direction); } public function shot():Null { if (bulletsCount >= 5) return null; - var bullet = new Bullet(personId, 0, x + width / 2 - 5, y + height / 2 - 5, 6, direction); + var bullet = new Bullet(id, rect.x + rect.width / 2 - 5, rect.y + rect.height / 2 - 5, 6, direction); bullet.move(direction); bulletsCount++; return bullet; diff --git a/src/common/haxe/ru/m/tankz/engine/Engine.hx b/src/common/haxe/ru/m/tankz/engine/Engine.hx index 8a5d786..13535a8 100755 --- a/src/common/haxe/ru/m/tankz/engine/Engine.hx +++ b/src/common/haxe/ru/m/tankz/engine/Engine.hx @@ -1,49 +1,58 @@ package ru.m.tankz.engine; -import ru.m.tankz.core.Point; -import ru.m.tankz.map.Brick.BrickType; +import ru.m.tankz.core.IEntity; +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; import ru.m.tankz.proto.game.GameChange; import ru.m.tankz.proto.core.Player; -import ru.m.tankz.core.Direction; +import ru.m.geom.Direction; import ru.m.tankz.core.IMobileEntity; import ru.m.tankz.config.Config; import ru.m.tankz.core.Tank; import ru.m.tankz.map.LevelMap; import ru.m.tankz.map.ILevelMap; + class Engine implements IEngine { private static var STOP_BRICKS:Array = [ - BrickType.BRICK, BrickType.ARMOR, BrickType.WATER + BrickType.BORDER, BrickType.BRICK, BrickType.ARMOR, BrickType.WATER + ]; + + private static var BULLET_BRICKS:Array = [ + BrickType.BORDER, BrickType.BRICK, BrickType.ARMOR ]; public var config(default, default):Config; public var map(default, null):ILevelMap; - public var tanks(default, null):Map; - public var mobileEntities(default, null):Map; + public var entities(default, null):Map; + public var removedEntities(default, null):Array; private var x_limit:Float; private var y_limit:Float; + private var playerTanks(default, null):Map; + public function new() {} public function clear():Void { - tanks = new Map(); + playerTanks = new Map(); } - private function buildTank(personId:Int, id:Int, cellX:Float, cellY:Float, direction:Direction):Tank { - return new Tank(personId, id, cellX * map.cellWidth, cellY * map.cellHeight, direction); + private function buildTank(cellX:Float, cellY:Float, direction:Direction):Tank { + return new Tank(cellX * map.cellWidth, cellY * map.cellHeight, direction); } public function init(config:Config):Void { this.config = config; map = new LevelMap(config.map); - tanks = new Map(); - mobileEntities = new Map(); + playerTanks = new Map(); + entities = new Map(); + removedEntities = new Array(); x_limit = map.gridWidth * map.cellWidth; y_limit = map.gridHeight * map.cellHeight; } @@ -53,24 +62,24 @@ class Engine implements IEngine { for (index in 0...players.length) { var player:Player = players[index]; var point:SpawnPoint = config.getSpawnPoint(SpawnPointType.PLAYER, index); - var tank = buildTank(player.id, 0, point.x, point.y, point.direction); - this.tanks.set(tank.personId, tank); - this.mobileEntities.set(tank.id, tank); + var tank = buildTank(point.x, point.y, point.direction); + playerTanks.set(player.id, tank); + entities.set(tank.id, tank); changes.push(new GameChange() - .setType(GameChangeType.APPEND) - .setObjectType(GameObjectType.TANK) - .setObjectId(tank.id) - .setX(tank.x) - .setY(tank.y) - .setDirectionX(tank.direction.x) - .setDirectionY(tank.direction.y) + .setType(GameChangeType.APPEND) + .setObjectType(GameObjectType.TANK) + .setObjectId(tank.id) + .setX(tank.rect.x) + .setY(tank.rect.y) + .setDirectionX(tank.direction.x) + .setDirectionY(tank.direction.y) ); } return changes; } - public function action(tankId:Int, action:TankAction):Void { - var tank:Tank = tanks.get(tankId); + public function action(playerId:Int, action:TankAction):Void { + var tank:Tank = playerTanks.get(playerId); switch (action) { case TankAction.MOVE(direction): tank.move(direction); @@ -89,7 +98,7 @@ class Engine implements IEngine { case TankAction.SHOT: var bullet = tank.shot(); if (bullet != null) { - mobileEntities.set(bullet.id, bullet); + entities.set(bullet.id, bullet); } /*Provider.get(IConnection).send( Map GameActionRequest() @@ -126,48 +135,49 @@ class Engine implements IEngine { } }*/ + private function getBricks(entity:IMobileEntity):Array { + var target:Point = entity.rect.getSide(entity.direction); + var cellX:Int = Math.floor(target.x / map.cellWidth); + var cellY:Int = Math.floor(target.y / map.cellHeight); + var brick1 = map.getBrick(cellX, cellY); + var brick2 = map.getBrick(cellX - entity.direction.y * entity.direction.y, cellY - entity.direction.x * entity.direction.x); + return [brick1, brick2]; + } + public function update():Array { var changes = new Array(); - for (entiny in mobileEntities) { + for (ent in entities) if (Std.is(ent, IMobileEntity)) { + var entity:IMobileEntity = cast ent; + var objectType = -1; - var personId = Reflect.hasField(entiny, "personId") ? Reflect.field(entiny, "personId") : -1; - if (Std.is(entiny, Tank)) objectType = GameObjectType.TANK; - if (Std.is(entiny, Bullet)) objectType = GameObjectType.BULLET; + if (Std.is(entity, Tank)) objectType = GameObjectType.TANK; + if (Std.is(entity, Bullet)) objectType = GameObjectType.BULLET; if (objectType == GameObjectType.TANK) { - if (entiny.direction.x != 0) { - entiny.y = Math.round((entiny.y + entiny.height / 2) / config.map.cellHeight) * config.map.cellHeight - entiny.height / 2; + if (entity.direction.x != 0) { + entity.rect.y = Math.round((entity.rect.y + entity.rect.height / 2) / config.map.cellHeight) * config.map.cellHeight - entity.rect.height / 2; } - if (entiny.direction.y != 0) { - entiny.x = Math.round((entiny.x + entiny.width / 2) / config.map.cellWidth) * config.map.cellWidth - entiny.width / 2; + if (entity.direction.y != 0) { + entity.rect.x = Math.round((entity.rect.x + entity.rect.width / 2) / config.map.cellWidth) * config.map.cellWidth - entity.rect.width / 2; } } - if (entiny.mx != 0 || entiny.my != 0) { - entiny.x += entiny.mx; - entiny.y += entiny.my; + if (entity.mx != 0 || entity.my != 0) { + entity.rect.x += entity.mx; + entity.rect.y += entity.my; + var bricks = getBricks(entity); if (objectType == GameObjectType.TANK) { - if (entiny.x < 0) entiny.x = 0; - if (entiny.x + entiny.width > x_limit) entiny.x = x_limit - entiny.width; - if (entiny.y < 0) entiny.y = 0; - if (entiny.y + entiny.height > y_limit) entiny.y = y_limit - entiny.height; - - var target:Point = entiny.getSide(entiny.direction); - - var cellX:Int = Math.floor(target.x / map.cellWidth); - var cellY:Int = Math.floor(target.y / map.cellHeight); - - var brick1 = map.getBrick(cellX, cellY); - var brick2 = map.getBrick(cellX - entiny.direction.y * entiny.direction.y, cellY - entiny.direction.x * entiny.direction.x); - - if (brick1 != null && STOP_BRICKS.indexOf(brick1.type) > -1 || brick2 != null && STOP_BRICKS.indexOf(brick2.type) > -1) { - if (entiny.direction.x != 0) { - entiny.x = brick1.cellX * map.cellWidth + map.cellWidth / 2 - entiny.direction.x * map.cellWidth / 2 - entiny.direction.x * entiny.width / 2 - entiny.width / 2; - } - if (entiny.direction.y != 0) { - entiny.y = brick1.cellY * map.cellHeight + map.cellHeight / 2 - entiny.direction.y * map.cellHeight / 2 - entiny.direction.y * entiny.height / 2 - entiny.height / 2; + for (brick in bricks) { + if (STOP_BRICKS.indexOf(brick.type) > -1) { + if (entity.direction.x != 0) { + entity.rect.x = brick.cellX * map.cellWidth + map.cellWidth / 2 - entity.direction.x * map.cellWidth / 2 - entity.direction.x * entity.rect.width / 2 - entity.rect.width / 2; + } + if (entity.direction.y != 0) { + entity.rect.y = brick.cellY * map.cellHeight + map.cellHeight / 2 - entity.direction.y * map.cellHeight / 2 - entity.direction.y * entity.rect.height / 2 - entity.rect.height / 2; + } + break; } } } @@ -175,21 +185,30 @@ class Engine implements IEngine { changes.push(new GameChange() .setType(GameChangeType.MOVED) .setObjectType(objectType) - .setObjectId(entiny.id) - .setX(entiny.x) - .setY(entiny.y) + .setObjectId(entity.id) + .setX(entity.rect.x) + .setY(entity.rect.y) ); if (objectType == GameObjectType.BULLET) { - if (entiny.x < 0 || entiny.x + entiny.width > x_limit || entiny.y < 0 || entiny.y + entiny.height > y_limit) { - mobileEntities.remove(entiny.id); - var tank:Tank = tanks.get(personId); - tank.onDestroyBullet(); - changes.push(new GameChange() - .setType(GameChangeType.DESTROED) - .setObjectType(objectType) - .setObjectId(entiny.id) - ); + for (brick in bricks) { + if (BULLET_BRICKS.indexOf(brick.type) > -1) { + entities.remove(entity.id); + var tank:Tank = cast entities.get(cast(entity, Bullet).tankId); + tank.onDestroyBullet(); + changes.push(new GameChange() + .setType(GameChangeType.DESTROED) + .setObjectType(objectType) + .setObjectId(entity.id) + ); + removedEntities.push(entity.key); + break; + } + } + for (brick in bricks) { + if (brick.type == BrickType.BRICK || brick.type == BrickType.BUSH) { + brick.type = BrickType.NONE; + } } } } diff --git a/src/common/haxe/ru/m/tankz/engine/IEngine.hx b/src/common/haxe/ru/m/tankz/engine/IEngine.hx index 27369f2..81b64d9 100755 --- a/src/common/haxe/ru/m/tankz/engine/IEngine.hx +++ b/src/common/haxe/ru/m/tankz/engine/IEngine.hx @@ -1,7 +1,7 @@ package ru.m.tankz.engine; +import ru.m.tankz.core.IEntity; import ru.m.tankz.proto.game.GameChange; -import ru.m.tankz.core.IMobileEntity; import ru.m.tankz.core.Tank; import ru.m.tankz.proto.core.Player; import ru.m.tankz.config.Config; @@ -10,8 +10,9 @@ import ru.m.tankz.map.ILevelMap; interface IEngine { public var config(default, default):Config; public var map(default, null):ILevelMap; - public var tanks(default, null):Map; - public var mobileEntities(default, null):Map; + + public var entities(default, null):Map; + public var removedEntities(default, null):Array; public function clear():Void; public function init(config:Config):Void; diff --git a/src/common/haxe/ru/m/tankz/map/Brick.hx b/src/common/haxe/ru/m/tankz/map/Brick.hx index d7f6fd2..19783b6 100644 --- a/src/common/haxe/ru/m/tankz/map/Brick.hx +++ b/src/common/haxe/ru/m/tankz/map/Brick.hx @@ -4,6 +4,7 @@ import ru.m.tankz.core.IKey; @:enum abstract BrickType(Int) from Int to Int { + var BORDER = -1; var NONE = 0; var ACE = 1; var BUSH = 2; @@ -16,7 +17,7 @@ import ru.m.tankz.core.IKey; class Brick implements IKey { public var cellX(default, null):Int; public var cellY(default, null):Int; - public var type(default, null):BrickType; + public var type(default, default):BrickType; public var key(get, null):String; public function new(type:BrickType, cellX:Int, cellY:Int) { diff --git a/src/common/haxe/ru/m/tankz/map/LevelMap.hx b/src/common/haxe/ru/m/tankz/map/LevelMap.hx index 78d29a8..021425c 100755 --- a/src/common/haxe/ru/m/tankz/map/LevelMap.hx +++ b/src/common/haxe/ru/m/tankz/map/LevelMap.hx @@ -1,5 +1,6 @@ package ru.m.tankz.map; +import ru.m.tankz.map.Brick.BrickType; import ru.m.tankz.config.Config.MapConfig; class LevelMap implements ILevelMap { @@ -10,16 +11,29 @@ class LevelMap implements ILevelMap { public var gridHeight(default, null):Int; public var bricks(default, null):Array; + public var borders(default, null):Array; public function new(config:MapConfig) { cellWidth = config.cellWidth; cellHeight = config.cellHeight; gridWidth = config.gridWidth; gridHeight = config.gridHeight; + borders = []; bricks = Lambda.array(Lambda.mapi(config.bricks, function(i, type):Brick return new Brick(type, Std.int(i % gridWidth), Std.int(Math.floor(i / gridHeight))))); } + private function getBorderBrick(cellX:Int, cellY:Int):Brick { + var index:Int = cellX + cellY * gridWidth; + if (borders[index] == null) { + borders[index] = new Brick(BrickType.BORDER, cellX, cellY); + } + return borders[index]; + } + public function getBrick(cellX:Int, cellY:Int):Brick { + if (cellX < 0 || cellX >= gridWidth || cellY < 0 || cellY >= gridHeight) { + return getBorderBrick(cellX, cellY); + } return bricks[cellY * gridWidth + cellX]; } diff --git a/src/server/haxe/ru/m/tankz/server/Server.hx b/src/server/haxe/ru/m/tankz/server/Server.hx index d73aa76..8f95db8 100755 --- a/src/server/haxe/ru/m/tankz/server/Server.hx +++ b/src/server/haxe/ru/m/tankz/server/Server.hx @@ -1,7 +1,7 @@ package ru.m.tankz.server; import haxework.log.SocketLogger; -import ru.m.core.connect.IConnection.IPacketBuilder; +import ru.m.connect.IConnection.IPacketBuilder; import haxework.provider.Provider; import haxework.log.TraceLogger; import ru.m.tankz.server.session.Session; diff --git a/src/server/haxe/ru/m/tankz/server/session/Session.hx b/src/server/haxe/ru/m/tankz/server/session/Session.hx index ea15c10..0a6805f 100755 --- a/src/server/haxe/ru/m/tankz/server/session/Session.hx +++ b/src/server/haxe/ru/m/tankz/server/session/Session.hx @@ -9,19 +9,19 @@ import ru.m.tankz.proto.StartGameRequest; import ru.m.tankz.proto.Person; import ru.m.tankz.proto.JoinGameRequest; import ru.m.tankz.proto.CreateGameRequest; -import ru.m.core.connect.neko.NekoWebConnection; +import ru.m.connect.neko.NekoWebConnection; import haxe.io.Bytes; import ru.m.tankz.proto.PersonSelectResponse; import ru.m.tankz.proto.PersonSelectRequest; import ru.m.tankz.proto.Account; -import ru.m.core.connect.neko.NekoConnection; +import ru.m.connect.neko.NekoConnection; import ru.m.tankz.proto.ErrorResponse; import ru.m.tankz.server.db.DbProvider; import ru.m.tankz.proto.LoginResponse; import ru.m.tankz.proto.LoginRequest; import ru.m.tankz.proto.GamesResponse; import protohx.Message; -import ru.m.core.connect.IConnection; +import ru.m.connect.IConnection; import sys.net.Socket;