This commit is contained in:
2015-08-13 14:18:22 +03:00
parent a37712136e
commit f2cbdbf341
16 changed files with 229 additions and 256 deletions

View File

@@ -42,11 +42,11 @@ class BaseConnection implements IConnection {
}
}
public function send(packet:Message):Void {
//L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop());
#if proto_debug L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
}
public function receive(packet:Message):Void {
//L.d("Receive", Type.getClassName(Type.getClass(packet)).split(".").pop());
#if proto_debug L.d("Receive", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
var name = "on" + Type.getClassName(Type.getClass(packet)).split(".").pop();
packetHandler.dispatch(function(h) {
var method = Reflect.field(h, name);

View File

@@ -17,7 +17,7 @@ class NekoWebConnection extends NekoConnection {
}
override public function send(packet:Message):Void {
//L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop());
#if proto_debug L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
try {
var data = WebSocketTools.packet2string(packet, builder);
writeData(data, socket);

View File

@@ -0,0 +1,13 @@
package ru.m.tankz.core;
class Bullet extends MobileEntity {
public var personId(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 = 10;
this.height = 10;
}
}

View File

@@ -1,8 +0,0 @@
package ru.m.tankz.core;
interface ITank extends IMobileEntity {
public var bullets:Array<IMobileEntity>;
public function shot():Void;
public function destroyBullet(bullet:IMobileEntity):Void;
}

View File

@@ -1,6 +1,8 @@
package ru.m.tankz.core;
class MobileEntity extends Entity implements IMobileEntity {
private static var idCounter:Int = 0;
public var id(default, null):Int;
public var mx(default, default):Float = 0;
@@ -9,9 +11,9 @@ class MobileEntity extends Entity implements IMobileEntity {
public var speed(default, null):Float = 0;
public var direction(default, default):Direction;
public function new(id:Int, x:Float, y:Float, speed:Float, direction:Direction = null) {
public function new(id:Int = 0, x:Float = 0, y:Float = 0, speed:Float = 0, direction:Direction = null) {
super(x, y);
this.id = id;
this.id = id == 0 ? ++idCounter : id;
this.speed = speed;
this.direction = direction == null ? Direction.BOTTOM : direction;
}

View File

@@ -5,30 +5,28 @@ enum TankAction {
SHOT;
}
class Tank extends MobileEntity implements ITank {
class Tank extends MobileEntity {
private static var bulletIdCounter:Int = -1;
public var personId(default, null):Int;
public var bullets:Array<IMobileEntity>;
public var bulletsCount:Int = 0;
public function new(id:Int, x:Float, y:Float) {
super(id, x, y, 4);
this.id = id;
bullets = new Array<IMobileEntity>();
public function new(personId:Int, id:Int, x:Float, y:Float, direction:Directiondo apt-g) {
super(id, x, y, 4, direction);
this.personId = personId;
width = 34;
height = 34;
}
public function shot():Void {
if (bullets.length >= 5) return;
var bullet = new MobileEntity(bulletIdCounter--, x + width / 2 - 5, y + height / 2 - 5, 6, direction);
bullet.width = 10;
bullet.height = 10;
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);
bullet.move(direction);
bullets.push(bullet);
bulletsCount++;
return bullet;
}
public function destroyBullet(bullet:IMobileEntity):Void {
bullets.remove(bullet);
public function onDestroyBullet():Void {
bulletsCount--;
}
}

View File

@@ -1,5 +1,9 @@
package ru.m.tankz.engine;
import ru.m.tankz.core.Bullet;
import ru.m.tankz.proto.GameObjectType;
import ru.m.tankz.proto.GameChangeType;
import ru.m.tankz.proto.GameChange;
import ru.m.tankz.proto.Person;
import ru.m.tankz.core.Direction;
import ru.m.tankz.core.IMobileEntity;
@@ -7,14 +11,15 @@ import ru.m.tankz.core.IMobileEntity;
import ru.m.tankz.config.TankzConfig;
import ru.m.tankz.core.Tank;
import ru.m.tankz.map.TankzMap;
import ru.m.tankz.core.ITank;
import ru.m.tankz.map.ITankzMap;
class Engine implements IEngine {
public var config(default, default):TankzConfig;
public var map(default, null):ITankzMap;
public var tanks(default, null):Array<ITank>;
public var tanks(default, null):Map<Int, Tank>;
public var mobileEntities(default, null):Map<Int, IMobileEntity>;
private var x_limit:Float;
private var y_limit:Float;
@@ -22,87 +27,144 @@ class Engine implements IEngine {
public function new() {}
public function clear():Void {
tanks = [];
tanks = new Map<Int, Tank>();
}
private function buildTank(id:Int, x:Float, y:Float):ITank {
return new Tank(id, x, y);
private function buildTank(personId:Int, id:Int, x:Float, y:Float, direction:Direction):Tank {
return new Tank(personId, id, x, y, direction);
}
public function init(persons:Array<Person>, config:TankzConfig):Void {
public function init(config:TankzConfig):Void {
this.config = config;
map = new TankzMap(config.map);
tanks = [];
for (person in persons) {
var x = 0;
var y = 100 * persons.indexOf(person);
tanks.push(buildTank(person.id, x, y));
}
tanks = new Map<Int, Tank>();
mobileEntities = new Map<Int, IMobileEntity>();
x_limit = map.gridWidth * map.cellWidth;
y_limit = map.gridHeight * map.cellHeight;
}
public function update():Void {
for (tank in tanks) {
if (tank.direction.x != 0) {
tank.y = Math.round((tank.y + tank.height / 2) / config.map.cellHeight) * config.map.cellHeight - tank.height / 2;
}
if (tank.direction.y != 0) {
tank.x = Math.round((tank.x + tank.width / 2) / config.map.cellWidth) * config.map.cellWidth - tank.width / 2;
}
tank.x += tank.mx;
tank.y += tank.my;
public function initTanks(persons:Array<Person>):Array<GameChange> {
var changes = new Array<GameChange>();
for (person in persons) {
var x = 0;
var y = 100 * persons.indexOf(person);
var tank = buildTank(person.id, 0, x, y, Direction.BOTTOM);
this.tanks.set(tank.personId, tank);
this.mobileEntities.set(tank.id, tank);
changes.push(new GameChange()
.setType(GameChangeType.APPEND)
.setObjectType(GameObjectType.TANK)
.setPersonId(tank.personId)
.setObjectId(tank.id)
.setX(tank.x)
.setY(tank.y)
.setDirectionX(tank.direction.x)
.setDirectionY(tank.direction.y)
);
}
return changes;
}
/*var tankR = new Rectangle(tank.x, tank.y, tank.width, tank.height);
for (t in tanks) if (t != tank) {
var r = new Rectangle(t.x, t.y, t.width, t.height);
if (tankR.intersects(r)) {
if (tank.direction.x > 0) {
if (tank.x + tank.width > t.x) tank.x = t.x - tank.width;
} else if (tank.direction.x < 0) {
if (tank.x < t.x + t.width) tank.x = t.x + t.width;
public function updateFromChanges(changes:Array<GameChange>):Void {
for (change in changes) {
switch (change.type) {
case GameChangeType.APPEND:
switch (change.objectType) {
case GameObjectType.TANK:
var tank:Tank = buildTank(change.personId, change.objectId, change.x, change.y, new Direction(change.directionY, change.directionY));
mobileEntities.set(tank.id, tank);
tanks.set(tank.personId, tank);
case GameObjectType.BULLET:
var bullet:Bullet = new Bullet(change.personId, change.objectId, change.x, change.y, 0, new Direction(change.directionY, change.directionY));
mobileEntities.set(bullet.id, bullet);
}
if (tank.direction.y > 0) {
if (tank.y + tank.height > t.y) tank.y = t.y - tank.height;
} else if (tank.direction.y < 0) {
if (tank.y < t.y + t.height) tank.y = t.y + t.height;
}
}
}*/
if (tank.x < 0) tank.x = 0;
if (tank.x + tank.width > x_limit) tank.x = x_limit - tank.width;
if (tank.y < 0) tank.y = 0;
if (tank.y + tank.height > y_limit) tank.y = y_limit - tank.height;
updateBullets(tank);
case GameChangeType.DESTROED:
mobileEntities.remove(change.objectId);
case GameChangeType.DIRECTION:
var target = mobileEntities.get(change.objectId);
target.direction = new Direction(change.directionX, change.directionY);
case GameChangeType.MOVED:
var target = mobileEntities.get(change.objectId);
target.x = change.x;
target.y = change.y;
case GameChangeType.MODIFIED:
//
}
}
}
private function updateBullets(tank:ITank):Void {
for (bullet in tank.bullets) {
bullet.x += bullet.mx;
bullet.y += bullet.my;
public function update():Array<GameChange> {
var changes = new Array<GameChange>();
/*var bulletR = new Rectangle(bullet.x, bullet.y, bullet.width, bullet.height);
for (entiny in mobileEntities) {
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;
var i = 0;
while (i < tanks.length) {
var t = tanks[i++];
if (t != tank) {
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 (entiny.direction.y != 0) {
entiny.x = Math.round((entiny.x + entiny.width / 2) / config.map.cellWidth) * config.map.cellWidth - entiny.width / 2;
}
}
if (entiny.mx != 0 || entiny.my != 0) {
entiny.x += entiny.mx;
entiny.y += entiny.my;
/*var tankR = new Rectangle(tank.x, tank.y, tank.width, tank.height);
for (t in tanks) if (t != tank) {
var r = new Rectangle(t.x, t.y, t.width, t.height);
if (bulletR.intersects(r)) {
tank.destroyBullet(bullet);
tanks.remove(t);
i--;
if (tankR.intersects(r)) {
if (tank.direction.x > 0) {
if (tank.x + tank.width > t.x) tank.x = t.x - tank.width;
} else if (tank.direction.x < 0) {
if (tank.x < t.x + t.width) tank.x = t.x + t.width;
}
if (tank.direction.y > 0) {
if (tank.y + tank.height > t.y) tank.y = t.y - tank.height;
} else if (tank.direction.y < 0) {
if (tank.y < t.y + t.height) tank.y = t.y + t.height;
}
}
}*/
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;
}
changes.push(new GameChange()
.setType(GameChangeType.MOVED)
.setObjectType(objectType)
.setPersonId(personId)
.setObjectId(entiny.id)
.setX(entiny.x)
.setY(entiny.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 = tanks.get(personId);
tank.onDestroyBullet();
changes.push(new GameChange()
.setType(GameChangeType.DESTROED)
.setObjectType(objectType)
.setPersonId(personId)
.setObjectId(entiny.id)
);
}
}
}*/
if (bullet.x < 0 || bullet.x + bullet.width > x_limit || bullet.y < 0 || bullet.y + bullet.height > y_limit) {
tank.destroyBullet(bullet);
}
}
return changes;
}
}

View File

@@ -1,16 +1,21 @@
package ru.m.tankz.engine;
import ru.m.tankz.proto.GameChange;
import ru.m.tankz.core.IMobileEntity;
import ru.m.tankz.core.Tank;
import ru.m.tankz.proto.Person;
import ru.m.tankz.config.TankzConfig;
import ru.m.tankz.core.ITank;
import ru.m.tankz.map.ITankzMap;
interface IEngine {
public var config(default, default):TankzConfig;
public var map(default, null):ITankzMap;
public var tanks(default, null):Array<ITank>;
public var tanks(default, null):Map<Int, Tank>;
public var mobileEntities(default, null):Map<Int, IMobileEntity>;
public function clear():Void;
public function init(persons:Array<Person>, config:TankzConfig):Void;
public function update():Void;
public function init(config:TankzConfig):Void;
public function initTanks(persons:Array<Person>):Array<GameChange>;
public function updateFromChanges(changes:Array<GameChange>):Void;
public function update():Array<GameChange>;
}

View File

@@ -126,8 +126,8 @@ enum GameChangeType {
message GameChange {
required GameChangeType type = 1;
required GameObjectType objectType = 2;
required int32 objectId = 3;
optional int32 parentObjectId = 4;
optional int32 personId = 3;
required int32 objectId = 4;
optional float x = 5;
optional float y = 6;
optional int32 directionX = 7;