This commit is contained in:
2014-08-26 12:08:45 +04:00
parent c08638c264
commit d32a35aa2f
22 changed files with 199 additions and 7 deletions

View File

@@ -7,6 +7,10 @@ import ru.m.tankz.proto.LoginResponse;
import ru.m.tankz.proto.PersonSelectRequest;
import ru.m.tankz.proto.PersonSelectResponse;
import ru.m.tankz.proto.ErrorResponse;
import ru.m.tankz.proto.GamesRequest;
import ru.m.tankz.proto.GamesResponse;
import ru.m.tankz.proto.CreateGameRequest;
import ru.m.tankz.proto.CreateGameResponse;
class PacketBuilder implements IPacketBuilder {
@@ -19,6 +23,12 @@ class PacketBuilder implements IPacketBuilder {
0x0002 => LoginResponse,
0x0003 => PersonSelectRequest,
0x0004 => PersonSelectResponse
],
0x02 => [
0x0001 => GamesRequest,
0x0002 => GamesResponse,
0x0003 => CreateGameRequest,
0x0004 => CreateGameResponse,
]
];

View File

@@ -0,0 +1,12 @@
package ru.m.tankz.config;
typedef MapConfig = {
var cellWidth:Float;
var cellHeight:Float;
var gridWidth:Int;
var gridHeight:Int;
}
typedef TankzConfig = {
var map:MapConfig;
}

View File

@@ -0,0 +1,25 @@
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;
public 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);
}
}

View File

@@ -0,0 +1,17 @@
package ru.m.tankz.core;
import flash.geom.Point;
class Entity implements IEntity {
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 function new(position:Point) {
x = position.x;
y = position.y;
}
}

View File

@@ -0,0 +1,9 @@
package ru.m.tankz.core;
interface IEntity {
public var x(default, default):Float;
public var y(default, default):Float;
public var width(default, default):Float;
public var height(default, default):Float;
}

View File

@@ -0,0 +1,12 @@
package ru.m.tankz.core;
interface IMobileEntity extends IEntity {
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 function move(direction:Direction):Void;
public function stop():Void;
}

View File

@@ -0,0 +1,8 @@
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

@@ -0,0 +1,28 @@
package ru.m.tankz.core;
import flash.geom.Point;
class MobileEntity extends Entity implements IMobileEntity {
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 function new(position:Point, speed:Float, ?direction:Direction = null) {
super(position);
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;
}
}

View File

@@ -0,0 +1,51 @@
package ru.m.tankz.core;
import flash.geom.Point;
import ru.m.tankz.core.Tank.TankAction;
import flash.events.KeyboardEvent;
import flash.Lib;
class PlayerTank extends Tank {
private var keyBinding:Map<Int, TankAction>;
private var moveQueue:Array<Int>;
public function new(position:Point, keyBinding:Map<Int, TankAction>) {
super(position);
this.keyBinding = keyBinding;
moveQueue = new Array<Int>();
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
Lib.current.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
private function onKeyDown(event:KeyboardEvent):Void {
switch (keyBinding.get(event.keyCode)) {
case TankAction.MOVE(direction):
if (moveQueue.indexOf(event.keyCode) == -1) {
moveQueue.unshift(event.keyCode);
updateMove();
}
case TankAction.SHOT: shot();
}
}
private function onKeyUp(event:KeyboardEvent):Void {
switch (keyBinding.get(event.keyCode)) {
case TankAction.MOVE(direction):
moveQueue.remove(event.keyCode);
updateMove();
case _: {};
}
}
private function updateMove():Void {
if (moveQueue.length == 0) {
stop();
} else {
switch (keyBinding.get(moveQueue[0])) {
case TankAction.MOVE(direction): move(direction);
case _: {};
}
}
}
}

View File

@@ -0,0 +1,33 @@
package ru.m.tankz.core;
import flash.geom.Point;
enum TankAction {
MOVE(direction:Direction);
SHOT;
}
class Tank extends MobileEntity implements ITank {
public var bullets:Array<IMobileEntity>;
public function new(position:Point) {
super(position, 4);
bullets = new Array<IMobileEntity>();
width = 34;
height = 34;
}
public function shot():Void {
if (bullets.length >= 5) return;
var bullet = new MobileEntity(new Point(x + width / 2 - 5, y + height / 2 - 5), 6, direction);
bullet.width = 10;
bullet.height = 10;
bullet.move(direction);
bullets.push(bullet);
}
public function destroyBullet(bullet:IMobileEntity):Void {
bullets.remove(bullet);
}
}

View File

@@ -0,0 +1,15 @@
package ru.m.tankz.game;
import ru.m.tankz.config.TankzConfig;
import ru.m.tankz.core.ITank;
import ru.m.tankz.map.ITankzMap;
interface ITankz {
public var config(default, default):TankzConfig;
public var map(default, null):ITankzMap;
public var tanks(default, null):Array<ITank>;
public function clear():Void;
public function init(config:TankzConfig):Void;
public function update():Void;
}

View File

@@ -0,0 +1,116 @@
package ru.m.tankz.game;
import ru.m.tankz.core.Direction;
import ru.m.tankz.core.IMobileEntity;
import flash.geom.Point;
import flash.ui.Keyboard;
import flash.geom.Rectangle;
import ru.m.tankz.config.TankzConfig;
import ru.m.tankz.core.Tank;
import ru.m.tankz.core.PlayerTank;
import ru.m.tankz.map.TankzMap;
import ru.m.tankz.core.ITank;
import ru.m.tankz.map.ITankzMap;
class Tankz implements ITankz {
public var config(default, default):TankzConfig;
public var map(default, null):ITankzMap;
public var tanks(default, null):Array<ITank>;
private var x_limit:Float;
private var y_limit:Float;
public function new() {}
public function clear():Void {
tanks = [];
}
public function init(config:TankzConfig):Void {
this.config = config;
map = new TankzMap(config.map);
tanks = [
new PlayerTank(new Point(0, 0), [
Keyboard.A => TankAction.MOVE(Direction.LEFT),
Keyboard.S => TankAction.MOVE(Direction.BOTTOM),
Keyboard.W => TankAction.MOVE(Direction.TOP),
Keyboard.D => TankAction.MOVE(Direction.RIGHT),
Keyboard.SPACE => TankAction.SHOT
]),
new PlayerTank(new Point(100, 0), [
Keyboard.LEFT => TankAction.MOVE(Direction.LEFT),
Keyboard.DOWN => TankAction.MOVE(Direction.BOTTOM),
Keyboard.UP => TankAction.MOVE(Direction.TOP),
Keyboard.RIGHT => TankAction.MOVE(Direction.RIGHT),
Keyboard.SHIFT => TankAction.SHOT
])
];
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;
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;
}
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);
}
}
private function updateBullets(tank:ITank):Void {
for (bullet in tank.bullets) {
bullet.x += bullet.mx;
bullet.y += bullet.my;
var bulletR = new Rectangle(bullet.x, bullet.y, bullet.width, bullet.height);
var i = 0;
while (i < tanks.length) {
var t = tanks[i++];
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 (bullet.x < 0 || bullet.x + bullet.width > x_limit || bullet.y < 0 || bullet.y + bullet.height > y_limit) {
tank.destroyBullet(bullet);
}
}
}
}

View File

@@ -0,0 +1,8 @@
package ru.m.tankz.map;
interface ITankzMap {
public var cellWidth(default, null):Float;
public var cellHeight(default, null):Float;
public var gridWidth(default, null):Int;
public var gridHeight(default, null):Int;
}

View File

@@ -0,0 +1,18 @@
package ru.m.tankz.map;
import ru.m.tankz.config.TankzConfig.MapConfig;
class TankzMap implements ITankzMap {
public var cellWidth(default, null):Float;
public var cellHeight(default, null):Float;
public var gridWidth(default, null):Int;
public var gridHeight(default, null):Int;
public function new(config:MapConfig) {
cellWidth = config.cellWidth;
cellHeight = config.cellHeight;
gridWidth = config.gridWidth;
gridHeight = config.gridHeight;
}
}