[common] bullet with bricks collision

This commit is contained in:
2018-01-07 20:33:05 +03:00
parent 12328a8a5e
commit 348d31d754
33 changed files with 277 additions and 217 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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<Entity> {
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();
}
}

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
package ru.m.core;
package ru.m;
import haxe.io.Bytes;
import haxe.crypto.BaseCode;

View File

@@ -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<IConnectionHandler>;

View File

@@ -1,4 +1,4 @@
package ru.m.core.connect;
package ru.m.connect;
import haxework.dispath.IDispatcher;
import haxe.io.Bytes;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -0,0 +1,29 @@
package ru.m.geom;
import haxe.ds.IntMap;
class Direction {
private static var directions:IntMap<Direction> = new IntMap<Direction>();
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);
}
}

View File

@@ -1,4 +1,4 @@
package ru.m.tankz.core;
package ru.m.geom;
class Point {
public var x(default, default):Float;

View File

@@ -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));
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -1,29 +0,0 @@
package ru.m.tankz.core;
import haxe.ds.IntMap;
class Direction {
private static var directions:IntMap<Direction> = new IntMap<Direction>();
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);
}
}

View File

@@ -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';
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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<Bullet> {
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;

View File

@@ -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> = [
BrickType.BRICK, BrickType.ARMOR, BrickType.WATER
BrickType.BORDER, BrickType.BRICK, BrickType.ARMOR, BrickType.WATER
];
private static var BULLET_BRICKS:Array<BrickType> = [
BrickType.BORDER, BrickType.BRICK, BrickType.ARMOR
];
public var config(default, default):Config;
public var map(default, null):ILevelMap;
public var tanks(default, null):Map<Int, Tank>;
public var mobileEntities(default, null):Map<Int, IMobileEntity>;
public var entities(default, null):Map<Int, IEntity>;
public var removedEntities(default, null):Array<String>;
private var x_limit:Float;
private var y_limit:Float;
private var playerTanks(default, null):Map<Int, Tank>;
public function new() {}
public function clear():Void {
tanks = new Map<Int, Tank>();
playerTanks = new Map<Int, Tank>();
}
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<Int, Tank>();
mobileEntities = new Map<Int, IMobileEntity>();
playerTanks = new Map<Int, Tank>();
entities = new Map<Int, IEntity>();
removedEntities = new Array<String>();
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<Brick> {
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<GameChange> {
var changes = new Array<GameChange>();
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;
}
}
}
}

View File

@@ -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<Int, Tank>;
public var mobileEntities(default, null):Map<Int, IMobileEntity>;
public var entities(default, null):Map<Int, IEntity>;
public var removedEntities(default, null):Array<String>;
public function clear():Void;
public function init(config:Config):Void;

View File

@@ -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) {

View File

@@ -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<Brick>;
public var borders(default, null):Array<Brick>;
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];
}

View File

@@ -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;

View File

@@ -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;