[common] added control
This commit is contained in:
@@ -1,26 +1,21 @@
|
|||||||
package ru.m.tankz.core;
|
package ru.m.tankz.control;
|
||||||
|
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
import ru.m.geom.Direction;
|
import ru.m.geom.Direction;
|
||||||
import flash.events.FocusEvent;
|
import flash.events.FocusEvent;
|
||||||
import flash.ui.Keyboard;
|
import flash.ui.Keyboard;
|
||||||
import ru.m.tankz.engine.Engine;
|
|
||||||
import ru.m.tankz.core.Tank.TankAction;
|
|
||||||
import flash.events.KeyboardEvent;
|
import flash.events.KeyboardEvent;
|
||||||
import flash.Lib;
|
import flash.Lib;
|
||||||
|
|
||||||
class PlayerControl {
|
class PlayerControl extends Control {
|
||||||
|
|
||||||
private var engine:Engine;
|
|
||||||
private var tankId:Int;
|
|
||||||
|
|
||||||
private var keyBinding:Map<Int, TankAction>;
|
private var keyBinding:Map<Int, TankAction>;
|
||||||
private var moveQueue:Array<Int>;
|
private var moveQueue:Array<Int>;
|
||||||
private var shotTimer:Timer;
|
private var shotTimer:Timer;
|
||||||
|
|
||||||
public function new(tankId:Int, engine:Engine, keyBinding:Map<Int, TankAction>) {
|
public function new(tankId:Int, keyBinding:Map<Int, TankAction>) {
|
||||||
this.tankId = tankId;
|
super(tankId);
|
||||||
this.engine = engine;
|
|
||||||
this.keyBinding = keyBinding;
|
this.keyBinding = keyBinding;
|
||||||
moveQueue = new Array<Int>();
|
moveQueue = new Array<Int>();
|
||||||
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
||||||
@@ -44,7 +39,7 @@ class PlayerControl {
|
|||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
if (event.keyCode == Keyboard.U) {
|
if (event.keyCode == Keyboard.U) {
|
||||||
engine.action(tankId, TankAction.LEVEL_UP(1));
|
action(TankAction.LEVEL_UP(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,24 +64,24 @@ class PlayerControl {
|
|||||||
|
|
||||||
private function updateMove():Void {
|
private function updateMove():Void {
|
||||||
if (moveQueue.length == 0) {
|
if (moveQueue.length == 0) {
|
||||||
engine.action(tankId, TankAction.STOP);
|
action(TankAction.STOP);
|
||||||
} else {
|
} else {
|
||||||
switch (keyBinding.get(moveQueue[0])) {
|
switch (keyBinding.get(moveQueue[0])) {
|
||||||
case TankAction.MOVE(direction):
|
case TankAction.MOVE(direction):
|
||||||
engine.action(tankId, TankAction.MOVE(direction));
|
action(TankAction.MOVE(direction));
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function shot():Void {
|
private function shot():Void {
|
||||||
engine.action(tankId, TankAction.SHOT);
|
action(TankAction.SHOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function forPlayer(index:Int, tankId:Int, engine:Engine):PlayerControl {
|
public static function forPlayer(index:Int, tankId:Int):PlayerControl {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return new PlayerControl(tankId, engine, [
|
return new PlayerControl(tankId, [
|
||||||
Keyboard.A => TankAction.MOVE(Direction.LEFT),
|
Keyboard.A => TankAction.MOVE(Direction.LEFT),
|
||||||
Keyboard.S => TankAction.MOVE(Direction.BOTTOM),
|
Keyboard.S => TankAction.MOVE(Direction.BOTTOM),
|
||||||
Keyboard.W => TankAction.MOVE(Direction.TOP),
|
Keyboard.W => TankAction.MOVE(Direction.TOP),
|
||||||
@@ -94,7 +89,7 @@ class PlayerControl {
|
|||||||
Keyboard.SPACE => TankAction.SHOT
|
Keyboard.SPACE => TankAction.SHOT
|
||||||
]);
|
]);
|
||||||
case 1:
|
case 1:
|
||||||
return new PlayerControl(tankId, engine, [
|
return new PlayerControl(tankId, [
|
||||||
Keyboard.LEFT => TankAction.MOVE(Direction.LEFT),
|
Keyboard.LEFT => TankAction.MOVE(Direction.LEFT),
|
||||||
Keyboard.DOWN => TankAction.MOVE(Direction.BOTTOM),
|
Keyboard.DOWN => TankAction.MOVE(Direction.BOTTOM),
|
||||||
Keyboard.UP => TankAction.MOVE(Direction.TOP),
|
Keyboard.UP => TankAction.MOVE(Direction.TOP),
|
||||||
@@ -4,7 +4,7 @@ import haxe.Timer;
|
|||||||
import ru.m.tankz.config.ConfigBundle;
|
import ru.m.tankz.config.ConfigBundle;
|
||||||
import ru.m.tankz.proto.core.GameType;
|
import ru.m.tankz.proto.core.GameType;
|
||||||
import ru.m.tankz.proto.core.Game;
|
import ru.m.tankz.proto.core.Game;
|
||||||
import ru.m.tankz.core.PlayerControl;
|
import ru.m.tankz.control.PlayerControl;
|
||||||
import ru.m.tankz.engine.Engine;
|
import ru.m.tankz.engine.Engine;
|
||||||
import protohx.Message;
|
import protohx.Message;
|
||||||
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
||||||
@@ -23,12 +23,10 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
public static inline var ID = "game";
|
public static inline var ID = "game";
|
||||||
|
|
||||||
private var engine:Engine;
|
private var engine:Engine;
|
||||||
private var controls:Map<Int, PlayerControl>;
|
|
||||||
private var timer:Timer;
|
private var timer:Timer;
|
||||||
|
|
||||||
public function init():Void {
|
public function init():Void {
|
||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
controls = new Map<Int, PlayerControl>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onShow():Void {
|
public function onShow():Void {
|
||||||
@@ -39,7 +37,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
for (index in 0...game.players.length) {
|
for (index in 0...game.players.length) {
|
||||||
var playerId:Int = game.players[index].id;
|
var playerId:Int = game.players[index].id;
|
||||||
var tankId:Int = engine.playerTanks.get(playerId).id;
|
var tankId:Int = engine.playerTanks.get(playerId).id;
|
||||||
controls.set(tankId, PlayerControl.forPlayer(index, tankId, engine));
|
engine.bindControl(PlayerControl.forPlayer(index, tankId));
|
||||||
}
|
}
|
||||||
Provider.get(IConnection).packetHandler.addListener(this);
|
Provider.get(IConnection).packetHandler.addListener(this);
|
||||||
render.draw(engine);
|
render.draw(engine);
|
||||||
|
|||||||
@@ -1,38 +1,32 @@
|
|||||||
package ru.m.tankz.bot;
|
package ru.m.tankz.bot;
|
||||||
|
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.geom.Direction;
|
import ru.m.geom.Direction;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
import ru.m.tankz.map.Grid.GridCell;
|
import ru.m.tankz.map.Grid.GridCell;
|
||||||
import ru.m.tankz.core.Tank;
|
import ru.m.tankz.core.Tank;
|
||||||
import Type.ValueType;
|
import Type.ValueType;
|
||||||
import ru.m.tankz.core.Entity;
|
|
||||||
import ru.m.tankz.engine.Engine;
|
|
||||||
|
|
||||||
class Bot implements EngineListener {
|
|
||||||
|
|
||||||
public var tankId(default, null):Int;
|
class Bot extends Control {
|
||||||
private var engine:Engine;
|
|
||||||
|
|
||||||
private var shotTimer:Timer;
|
private var shotTimer:Timer;
|
||||||
private var turnTimer:Timer;
|
private var turnTimer:Timer;
|
||||||
|
|
||||||
public function new(engine:Engine, tankId:Int) {
|
public function new(tankId:Int) {
|
||||||
this.engine = engine;
|
super(tankId);
|
||||||
this.tankId = tankId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onCollision(entity:Entity, with:Dynamic):Void {
|
override public function onCollision(with:Dynamic):Void {
|
||||||
if (entity.id == tankId) {
|
|
||||||
switch (Type.typeof(with)) {
|
switch (Type.typeof(with)) {
|
||||||
case ValueType.TClass(Tank): turn();
|
case ValueType.TClass(Tank): turn();
|
||||||
case ValueType.TClass(GridCell): turn();
|
case ValueType.TClass(GridCell): turn();
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function start():Void {
|
public function start():Void {
|
||||||
engine.action(tankId, TankAction.MOVE(Direction.BOTTOM));
|
action(TankAction.MOVE(Direction.BOTTOM));
|
||||||
shotTimer = new Timer(1000);
|
shotTimer = new Timer(1000);
|
||||||
shotTimer.run = shot;
|
shotTimer.run = shot;
|
||||||
turnTimer = new Timer(3000);
|
turnTimer = new Timer(3000);
|
||||||
@@ -40,11 +34,11 @@ class Bot implements EngineListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function shot():Void {
|
public function shot():Void {
|
||||||
engine.action(tankId, TankAction.SHOT);
|
action(TankAction.SHOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function turn():Void {
|
public function turn():Void {
|
||||||
engine.action(tankId, TankAction.MOVE(randomDirection()));
|
action(TankAction.MOVE(randomDirection()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function randomDirection():Direction {
|
private function randomDirection():Direction {
|
||||||
@@ -56,7 +50,8 @@ class Bot implements EngineListener {
|
|||||||
][Math.floor(Math.random() * 4)];
|
][Math.floor(Math.random() * 4)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dispose():Void {
|
override public function dispose():Void {
|
||||||
|
super.dispose();
|
||||||
if (shotTimer != null) {
|
if (shotTimer != null) {
|
||||||
shotTimer.stop();
|
shotTimer.stop();
|
||||||
shotTimer = null;
|
shotTimer = null;
|
||||||
@@ -65,6 +60,5 @@ class Bot implements EngineListener {
|
|||||||
turnTimer.stop();
|
turnTimer.stop();
|
||||||
turnTimer = null;
|
turnTimer = null;
|
||||||
}
|
}
|
||||||
engine = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/common/haxe/ru/m/tankz/control/Control.hx
Normal file
44
src/common/haxe/ru/m/tankz/control/Control.hx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package ru.m.tankz.control;
|
||||||
|
|
||||||
|
import ru.m.geom.Direction;
|
||||||
|
|
||||||
|
|
||||||
|
enum TankAction {
|
||||||
|
MOVE(direction:Direction);
|
||||||
|
LEVEL_UP(level:Int);
|
||||||
|
STOP;
|
||||||
|
SHOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Control {
|
||||||
|
public var tankId(default, null):Int;
|
||||||
|
private var listener:ControlListener;
|
||||||
|
|
||||||
|
public function new(tankId:Int) {
|
||||||
|
this.tankId = tankId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bind(listener:ControlListener):Void {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function action(action:TankAction):Void {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onAction(tankId, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCollision(with:Dynamic):Void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function dispose():Void {
|
||||||
|
listener = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ControlListener {
|
||||||
|
public function onAction(tankId:Int, action:TankAction):Void;
|
||||||
|
}
|
||||||
@@ -1,19 +1,12 @@
|
|||||||
package ru.m.tankz.core;
|
package ru.m.tankz.core;
|
||||||
|
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
import ru.m.tankz.config.Config.TankConfig;
|
import ru.m.tankz.config.Config;
|
||||||
import ru.m.tankz.core.Bullet;
|
import ru.m.tankz.core.Bullet;
|
||||||
import ru.m.geom.Rectangle;
|
import ru.m.geom.Rectangle;
|
||||||
import ru.m.geom.Direction;
|
import ru.m.geom.Direction;
|
||||||
|
|
||||||
|
|
||||||
enum TankAction {
|
|
||||||
MOVE(direction:Direction);
|
|
||||||
LEVEL_UP(level:Int);
|
|
||||||
STOP;
|
|
||||||
SHOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Tank extends MobileEntity {
|
class Tank extends MobileEntity {
|
||||||
public var index(default, null):Int;
|
public var index(default, null):Int;
|
||||||
public var config(default, set):TankConfig;
|
public var config(default, set):TankConfig;
|
||||||
@@ -45,15 +38,6 @@ class Tank extends MobileEntity {
|
|||||||
return bullet;
|
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 {
|
public function onDestroyBullet():Void {
|
||||||
bulletsCounter--;
|
bulletsCounter--;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.m.tankz.engine;
|
package ru.m.tankz.engine;
|
||||||
|
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.tankz.bot.Bot;
|
import ru.m.tankz.bot.Bot;
|
||||||
import haxe.Constraints.Function;
|
import haxe.Constraints.Function;
|
||||||
import ru.m.geom.Line;
|
import ru.m.geom.Line;
|
||||||
@@ -18,7 +19,7 @@ import ru.m.tankz.core.Tank;
|
|||||||
import ru.m.tankz.map.LevelMap;
|
import ru.m.tankz.map.LevelMap;
|
||||||
|
|
||||||
|
|
||||||
class Engine {
|
class Engine implements ControlListener {
|
||||||
|
|
||||||
public var config(default, default):Config;
|
public var config(default, default):Config;
|
||||||
public var map(default, null):LevelMap;
|
public var map(default, null):LevelMap;
|
||||||
@@ -29,17 +30,13 @@ class Engine {
|
|||||||
public var playerTanks(default, null):Map<Int, Tank>;
|
public var playerTanks(default, null):Map<Int, Tank>;
|
||||||
private var time:Float;
|
private var time:Float;
|
||||||
|
|
||||||
public var listeners(default, null):Array<EngineListener>;
|
private var controls:Map<Int, Control>;
|
||||||
|
|
||||||
private var bots:Map<Int, Bot>;
|
public function new() {}
|
||||||
|
|
||||||
public function new() {
|
|
||||||
listeners = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function clear():Void {
|
public function clear():Void {
|
||||||
playerTanks = new Map<Int, Tank>();
|
playerTanks = new Map<Int, Tank>();
|
||||||
bots = new Map<Int, Bot>();
|
controls = new Map<Int, Control>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildTank(index:Int, config:TankConfig, point:SpawnPoint):Tank {
|
private function buildTank(index:Int, config:TankConfig, point:SpawnPoint):Tank {
|
||||||
@@ -53,7 +50,7 @@ class Engine {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
map = new LevelMap(config.map);
|
map = new LevelMap(config.map);
|
||||||
playerTanks = new Map<Int, Tank>();
|
playerTanks = new Map<Int, Tank>();
|
||||||
bots = new Map<Int, Bot>();
|
controls = new Map<Int, Control>();
|
||||||
entities = new Map<Int, Entity>();
|
entities = new Map<Int, Entity>();
|
||||||
removedEntities = new Array<String>();
|
removedEntities = new Array<String>();
|
||||||
time = Date.now().getTime();
|
time = Date.now().getTime();
|
||||||
@@ -82,15 +79,19 @@ class Engine {
|
|||||||
var point:SpawnPoint = config.getSpawnPoint(EntityType.BOT, index);
|
var point:SpawnPoint = config.getSpawnPoint(EntityType.BOT, index);
|
||||||
var tank = buildTank(0, config.getTank('bot', 0), point);
|
var tank = buildTank(0, config.getTank('bot', 0), point);
|
||||||
entities.set(tank.id, tank);
|
entities.set(tank.id, tank);
|
||||||
var bot = new Bot(this, tank.id);
|
var bot = new Bot(tank.id);
|
||||||
bots.set(tank.id, bot);
|
bindControl(bot);
|
||||||
listeners.push(bot);
|
|
||||||
bot.start();
|
bot.start();
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function action(tankId:Int, action:TankAction):Void {
|
public function bindControl(control:Control):Void {
|
||||||
|
control.bind(this);
|
||||||
|
controls.set(control.tankId, control);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAction(tankId:Int, action:TankAction):Void {
|
||||||
if (!entities.exists(tankId)) return;
|
if (!entities.exists(tankId)) return;
|
||||||
var tank:Tank = cast entities.get(tankId);
|
var tank:Tank = cast entities.get(tankId);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@@ -188,11 +189,10 @@ class Engine {
|
|||||||
if (tank != null) tank.onDestroyBullet();
|
if (tank != null) tank.onDestroyBullet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bots.exists(entity.id)) {
|
if (controls.exists(entity.id)) {
|
||||||
var bot:Bot = bots.get(entity.id);
|
var control:Control = controls.get(entity.id);
|
||||||
bot.dispose();
|
control.dispose();
|
||||||
listeners.remove(bot);
|
controls.remove(entity.id);
|
||||||
bots.remove(entity.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +227,9 @@ class Engine {
|
|||||||
if (cell.layer >= entity.layer && cell.layer < 3) {
|
if (cell.layer >= entity.layer && cell.layer < 3) {
|
||||||
entity.rect.lean(cell.rect);
|
entity.rect.lean(cell.rect);
|
||||||
collision = true;
|
collision = true;
|
||||||
for (listener in listeners) listener.onCollision(ent, cell);
|
if (controls.exists(entity.id)) {
|
||||||
|
controls.get(entity.id).onCollision(cell);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,7 +243,9 @@ class Engine {
|
|||||||
if (fun != null) {
|
if (fun != null) {
|
||||||
var c = Reflect.callMethod(this, fun, [ent, other]);
|
var c = Reflect.callMethod(this, fun, [ent, other]);
|
||||||
if (c) {
|
if (c) {
|
||||||
for (listener in listeners) listener.onCollision(ent, other);
|
if (controls.exists(entity.id)) {
|
||||||
|
controls.get(entity.id).onCollision(other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
collision = c || collision;
|
collision = c || collision;
|
||||||
}
|
}
|
||||||
@@ -279,7 +283,3 @@ class Engine {
|
|||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EngineListener {
|
|
||||||
public function onCollision(entity:Entity, with:Dynamic):Void;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user