[common] added game package
This commit is contained in:
13
WORK.md
13
WORK.md
@@ -20,6 +20,12 @@
|
|||||||
* bonuses 0%
|
* bonuses 0%
|
||||||
* eagle 0%
|
* eagle 0%
|
||||||
|
|
||||||
|
* game
|
||||||
|
* classic
|
||||||
|
* state 0%
|
||||||
|
* bot 5%
|
||||||
|
* player: 50%
|
||||||
|
|
||||||
* render
|
* render
|
||||||
* map 100%
|
* map 100%
|
||||||
* tanks 100%
|
* tanks 100%
|
||||||
@@ -34,6 +40,7 @@
|
|||||||
|
|
||||||
* proto
|
* proto
|
||||||
|
|
||||||
* common
|
|
||||||
* bot 0%
|
* webapp
|
||||||
* single game 20%
|
* angular app 0%
|
||||||
|
* google analytics 0%
|
||||||
@@ -14,8 +14,8 @@ class PlayerControl extends Control {
|
|||||||
private var moveQueue:Array<Int>;
|
private var moveQueue:Array<Int>;
|
||||||
private var shotTimer:Timer;
|
private var shotTimer:Timer;
|
||||||
|
|
||||||
public function new(tankId:Int, keyBinding:Map<Int, TankAction>) {
|
public function new(keyBinding:Map<Int, TankAction>) {
|
||||||
super(tankId);
|
super();
|
||||||
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);
|
||||||
@@ -78,10 +78,10 @@ class PlayerControl extends Control {
|
|||||||
action(TankAction.SHOT);
|
action(TankAction.SHOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function forPlayer(index:Int, tankId:Int):PlayerControl {
|
public static function forPlayer(index:Int):PlayerControl {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return new PlayerControl(tankId, [
|
return new PlayerControl([
|
||||||
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),
|
||||||
@@ -89,7 +89,7 @@ class PlayerControl extends Control {
|
|||||||
Keyboard.SPACE => TankAction.SHOT
|
Keyboard.SPACE => TankAction.SHOT
|
||||||
]);
|
]);
|
||||||
case 1:
|
case 1:
|
||||||
return new PlayerControl(tankId, [
|
return new PlayerControl([
|
||||||
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),
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ class Render extends SpriteView {
|
|||||||
entryLayer.addChild(items[entity.key].view);
|
entryLayer.addChild(items[entity.key].view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (key in game.removedEntities) {
|
/*for (key in game.removedEntities) {
|
||||||
if (items.exists(key)) {
|
if (items.exists(key)) {
|
||||||
var view:DisplayObject = items[key].view;
|
var view:DisplayObject = items[key].view;
|
||||||
view.parent.removeChild(view);
|
view.parent.removeChild(view);
|
||||||
items.remove(key);
|
items.remove(key);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
item.update();
|
item.update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package ru.m.tankz.view.frames;
|
package ru.m.tankz.view.frames;
|
||||||
|
|
||||||
|
import flash.events.Event;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
|
import haxework.gui.VGroupView;
|
||||||
|
import haxework.gui.ViewBuilder;
|
||||||
|
import haxework.provider.Provider;
|
||||||
|
import protohx.Message;
|
||||||
|
import ru.m.connect.IConnection;
|
||||||
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.Game;
|
|
||||||
import ru.m.tankz.control.PlayerControl;
|
import ru.m.tankz.control.PlayerControl;
|
||||||
import ru.m.tankz.engine.Engine;
|
import ru.m.tankz.engine.Engine;
|
||||||
import protohx.Message;
|
import ru.m.tankz.game.ClassicGame;
|
||||||
|
import ru.m.tankz.game.Game;
|
||||||
|
import ru.m.tankz.player.Player;
|
||||||
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
||||||
import ru.m.connect.IConnection;
|
|
||||||
import haxework.gui.ViewBuilder;
|
|
||||||
import flash.events.Event;
|
|
||||||
import haxework.provider.Provider;
|
|
||||||
import haxework.gui.VGroupView;
|
|
||||||
|
|
||||||
|
|
||||||
@:template("layout/frames/game.json", "layout/styles.json")
|
@:template("layout/frames/game.json", "layout/styles.json")
|
||||||
@@ -22,25 +23,20 @@ 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 game:Game;
|
||||||
private var timer:Timer;
|
private var timer:Timer;
|
||||||
|
|
||||||
public function init():Void {
|
public function init():Void {
|
||||||
engine = new Engine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onShow():Void {
|
public function onShow():Void {
|
||||||
var game:Game = Provider.get(Game);
|
game = new ClassicGame(ConfigBundle.get(ClassicGame.TYPE, 0));
|
||||||
engine.init(ConfigBundle.get(GameType.CLASSIC, 0));
|
game.start([
|
||||||
engine.initTanks(game.players);
|
new Player(1)
|
||||||
|
]);
|
||||||
content.addEventListener(Event.ENTER_FRAME, redraw);
|
content.addEventListener(Event.ENTER_FRAME, redraw);
|
||||||
for (index in 0...game.players.length) {
|
|
||||||
var playerId:Int = game.players[index].id;
|
|
||||||
var tankId:Int = engine.playerTanks.get(playerId).id;
|
|
||||||
engine.bindControl(PlayerControl.forPlayer(index, tankId));
|
|
||||||
}
|
|
||||||
Provider.get(IConnection).packetHandler.addListener(this);
|
Provider.get(IConnection).packetHandler.addListener(this);
|
||||||
render.draw(engine);
|
render.draw(game.engine);
|
||||||
timer = new Timer(10);
|
timer = new Timer(10);
|
||||||
timer.run = updateEngine;
|
timer.run = updateEngine;
|
||||||
}
|
}
|
||||||
@@ -52,21 +48,21 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
timer = null;
|
timer = null;
|
||||||
}
|
}
|
||||||
content.removeEventListener(Event.ENTER_FRAME, redraw);
|
content.removeEventListener(Event.ENTER_FRAME, redraw);
|
||||||
engine.clear();
|
game.dispose();
|
||||||
render.reset();
|
render.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateEngine():Void {
|
private function updateEngine():Void {
|
||||||
engine.update();
|
game.engine.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function redraw(_):Void {
|
private function redraw(_):Void {
|
||||||
render.draw(engine);
|
render.draw(game.engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onGameUpdateResponse(packet:GameUpdateResponse):Void {
|
public function onGameUpdateResponse(packet:GameUpdateResponse):Void {
|
||||||
//engine.updateFromChanges(packet.changes);
|
//engine.updateFromChanges(packet.changes);
|
||||||
render.draw(engine);
|
render.draw(game.engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPacket(packet:Message):Void {}
|
public function onPacket(packet:Message):Void {}
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
package ru.m.tankz.config;
|
package ru.m.tankz.config;
|
||||||
|
|
||||||
|
|
||||||
@:enum abstract EntityType(String) from String to String {
|
|
||||||
var PLAYER = 'player';
|
|
||||||
var BOT = 'bot';
|
|
||||||
var EAGLE = 'eagle';
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef SpawnPoint = {
|
typedef SpawnPoint = {
|
||||||
var type:EntityType;
|
var type:String;
|
||||||
var index:Int;
|
var index:Int;
|
||||||
var x:Int;
|
var x:Int;
|
||||||
var y:Int;
|
var y:Int;
|
||||||
@@ -55,7 +49,7 @@ class Config {
|
|||||||
public var bricks(default, null):Array<BrickConfig>;
|
public var bricks(default, null):Array<BrickConfig>;
|
||||||
public var tanks(default, null):Array<TankConfig>;
|
public var tanks(default, null):Array<TankConfig>;
|
||||||
|
|
||||||
private var pointMap:Map<EntityType, Map<Int, SpawnPoint>>;
|
private var pointMap:Map<String, Map<Int, SpawnPoint>>;
|
||||||
private var brickMap:Map<Int, BrickConfig>;
|
private var brickMap:Map<Int, BrickConfig>;
|
||||||
private var tankMap:Map<String, Map<Int, TankConfig>>;
|
private var tankMap:Map<String, Map<Int, TankConfig>>;
|
||||||
|
|
||||||
@@ -83,7 +77,7 @@ class Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSpawnPoint(type:EntityType, index:Int):SpawnPoint {
|
public function getSpawnPoint(type:String, index:Int):SpawnPoint {
|
||||||
return pointMap.get(type).get(index);
|
return pointMap.get(type).get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package ru.m.tankz.config;
|
package ru.m.tankz.config;
|
||||||
|
|
||||||
|
import ru.m.tankz.game.ClassicGame;
|
||||||
import yaml.Parser;
|
import yaml.Parser;
|
||||||
import openfl.Assets;
|
import openfl.Assets;
|
||||||
import yaml.Yaml;
|
import yaml.Yaml;
|
||||||
import ru.m.tankz.proto.core.GameType;
|
|
||||||
import ru.m.tankz.config.Config;
|
import ru.m.tankz.config.Config;
|
||||||
|
|
||||||
|
|
||||||
@@ -19,9 +19,9 @@ class ConfigBundle {
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get(type:Int, level:Int):Config {
|
public static function get(type:String, level:Int):Config {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GameType.CLASSIC:
|
case ClassicGame.TYPE:
|
||||||
var source:ConfigSource = convert(Yaml.parse(Assets.getText('resources/config/config.yaml'), Parser.options().useObjects()));
|
var source:ConfigSource = convert(Yaml.parse(Assets.getText('resources/config/config.yaml'), Parser.options().useObjects()));
|
||||||
var bricksData:String = Assets.getText('resources/levels/level00${level}.txt');
|
var bricksData:String = Assets.getText('resources/levels/level00${level}.txt');
|
||||||
var bricks:Array<BrickConfig> = [];
|
var bricks:Array<BrickConfig> = [];
|
||||||
|
|||||||
@@ -12,19 +12,17 @@ enum TankAction {
|
|||||||
|
|
||||||
|
|
||||||
class Control {
|
class Control {
|
||||||
public var tankId(default, null):Int;
|
public var tankId(default, default):Int;
|
||||||
private var listener:ControlListener;
|
private var listener:ControlListener;
|
||||||
|
|
||||||
public function new(tankId:Int) {
|
public function new() {}
|
||||||
this.tankId = tankId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bind(listener:ControlListener):Void {
|
public function bind(listener:ControlListener):Void {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function action(action:TankAction):Void {
|
public function action(action:TankAction):Void {
|
||||||
if (listener != null) {
|
if (tankId != 0 && listener != null) {
|
||||||
listener.onAction(tankId, action);
|
listener.onAction(tankId, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/common/haxe/ru/m/tankz/core/Eagle.hx
Normal file
11
src/common/haxe/ru/m/tankz/core/Eagle.hx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package ru.m.tankz.core;
|
||||||
|
|
||||||
|
import ru.m.geom.Rectangle;
|
||||||
|
|
||||||
|
|
||||||
|
class Eagle extends Entity {
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
super(new Rectangle(0, 0, 10, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/common/haxe/ru/m/tankz/core/EntityType.hx
Normal file
26
src/common/haxe/ru/m/tankz/core/EntityType.hx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package ru.m.tankz.core;
|
||||||
|
|
||||||
|
import Type.ValueType;
|
||||||
|
import ru.m.tankz.map.Grid.GridCell;
|
||||||
|
|
||||||
|
|
||||||
|
enum EntityType {
|
||||||
|
EAGLE(eagle:Eagle);
|
||||||
|
TANK(tank:Tank);
|
||||||
|
BULLET(bullet:Bullet);
|
||||||
|
CELL(cell:GridCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EntityTypeResolver {
|
||||||
|
|
||||||
|
public static function of(entity:Dynamic):EntityType {
|
||||||
|
return switch (Type.typeof(entity)) {
|
||||||
|
case ValueType.TClass(Eagle): EntityType.EAGLE(cast entity);
|
||||||
|
case ValueType.TClass(Tank): EntityType.TANK(cast entity);
|
||||||
|
case ValueType.TClass(Bullet): EntityType.BULLET(cast entity);
|
||||||
|
case ValueType.TClass(GridCell): EntityType.CELL(cast entity);
|
||||||
|
case x: null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,209 +1,139 @@
|
|||||||
package ru.m.tankz.engine;
|
package ru.m.tankz.engine;
|
||||||
|
|
||||||
import ru.m.tankz.control.Control;
|
|
||||||
import ru.m.tankz.bot.Bot;
|
|
||||||
import haxe.Constraints.Function;
|
|
||||||
import ru.m.geom.Line;
|
import ru.m.geom.Line;
|
||||||
import ru.m.tankz.core.MobileEntity;
|
|
||||||
import ru.m.tankz.core.Entity;
|
|
||||||
import ru.m.geom.Direction;
|
|
||||||
import ru.m.tankz.config.Config.TankConfig;
|
|
||||||
import ru.m.geom.Point;
|
|
||||||
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.config.Config;
|
import ru.m.tankz.config.Config;
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
|
import ru.m.tankz.core.Bullet;
|
||||||
|
import ru.m.tankz.core.Entity;
|
||||||
|
import ru.m.tankz.core.EntityType;
|
||||||
|
import ru.m.tankz.core.MobileEntity;
|
||||||
import ru.m.tankz.core.Tank;
|
import ru.m.tankz.core.Tank;
|
||||||
import ru.m.tankz.map.LevelMap;
|
import ru.m.tankz.map.LevelMap;
|
||||||
|
|
||||||
|
|
||||||
class Engine implements ControlListener {
|
|
||||||
|
interface EngineListener {
|
||||||
|
public function onSpawn(entity:EntityType):Void;
|
||||||
|
public function onCollision(entity:EntityType, with:EntityType):Void;
|
||||||
|
public function onDestroy(entity:EntityType):Void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CollisionProcessor implements EngineListener {
|
||||||
|
|
||||||
|
private var engine:Engine;
|
||||||
|
|
||||||
|
public function new(engine:Engine) {
|
||||||
|
this.engine = engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSpawn(entity:EntityType):Void {}
|
||||||
|
|
||||||
|
private function checkTankBullet(tank:Tank, bullet:Bullet):Bool {
|
||||||
|
return tank.config.group != bullet.tankConfig.group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCollision(entity:EntityType, with:EntityType):Void {
|
||||||
|
switch (entity) {
|
||||||
|
case EntityType.TANK(tank1):
|
||||||
|
switch (with) {
|
||||||
|
case EntityType.TANK(tank2):
|
||||||
|
tank1.rect.lean(tank2.rect);
|
||||||
|
case EntityType.BULLET(bullet2):
|
||||||
|
if (checkTankBullet(tank1, bullet2)) {
|
||||||
|
engine.destroy(tank1);
|
||||||
|
engine.destroy(bullet2);
|
||||||
|
}
|
||||||
|
case EntityType.EAGLE(eagle):
|
||||||
|
tank1.rect.lean(eagle.rect);
|
||||||
|
case EntityType.CELL(cell):
|
||||||
|
tank1.rect.lean(cell.rect);
|
||||||
|
}
|
||||||
|
case EntityType.BULLET(bullet1):
|
||||||
|
switch (with) {
|
||||||
|
case EntityType.TANK(tank2):
|
||||||
|
if (checkTankBullet(tank2, bullet1)) {
|
||||||
|
engine.destroy(bullet1);
|
||||||
|
engine.destroy(tank2);
|
||||||
|
}
|
||||||
|
case EntityType.BULLET(bullet2):
|
||||||
|
engine.destroy(bullet1);
|
||||||
|
engine.destroy(bullet2);
|
||||||
|
case EntityType.EAGLE(eagle):
|
||||||
|
engine.destroy(bullet1);
|
||||||
|
engine.destroy(eagle);
|
||||||
|
case EntityType.CELL(cell):
|
||||||
|
engine.destroy(bullet1);
|
||||||
|
}
|
||||||
|
case _:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onDestroy(entity:EntityType):Void { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Engine {
|
||||||
|
|
||||||
public var config(default, default):Config;
|
public var config(default, default):Config;
|
||||||
public var map(default, null):LevelMap;
|
public var map(default, null):LevelMap;
|
||||||
|
|
||||||
public var entities(default, null):Map<Int, Entity>;
|
public var entities(default, null):Map<Int, Entity>;
|
||||||
public var removedEntities(default, null):Array<String>;
|
public var listeners(default, null):Array<EngineListener>;
|
||||||
|
|
||||||
|
private var collision:CollisionProcessor;
|
||||||
|
|
||||||
public var playerTanks(default, null):Map<Int, Tank>;
|
|
||||||
private var time:Float;
|
private var time:Float;
|
||||||
|
|
||||||
private var controls:Map<Int, Control>;
|
public function new(config:Config) {
|
||||||
|
|
||||||
public function new() {}
|
|
||||||
|
|
||||||
public function clear():Void {
|
|
||||||
playerTanks = new Map<Int, Tank>();
|
|
||||||
controls = new Map<Int, Control>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildTank(index:Int, config:TankConfig, point:SpawnPoint):Tank {
|
|
||||||
var tank = new Tank(index, config);
|
|
||||||
tank.rect.center = new Point((point.x + 1) * map.cellWidth, (point.y + 1) * map.cellHeight);
|
|
||||||
tank.rect.direction = Direction.fromString(point.direction);
|
|
||||||
return tank;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init(config:Config):Void {
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
listeners = [];
|
||||||
map = new LevelMap(config.map);
|
map = new LevelMap(config.map);
|
||||||
playerTanks = new Map<Int, Tank>();
|
|
||||||
controls = new Map<Int, Control>();
|
|
||||||
entities = new Map<Int, Entity>();
|
entities = new Map<Int, Entity>();
|
||||||
removedEntities = new Array<String>();
|
|
||||||
time = Date.now().getTime();
|
time = Date.now().getTime();
|
||||||
|
collision = new CollisionProcessor(this);
|
||||||
|
listeners.push(collision);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initTanks(players:Array<Player>):Array<GameChange> {
|
public function spawn(entity:Entity):Void {
|
||||||
var changes = new Array<GameChange>();
|
entities.set(entity.id, entity);
|
||||||
for (index in 0...players.length) {
|
var type = EntityTypeResolver.of(entity);
|
||||||
var player:Player = players[index];
|
for (l in listeners) l.onSpawn(type);
|
||||||
var point:SpawnPoint = config.getSpawnPoint(EntityType.PLAYER, index);
|
|
||||||
var tank = buildTank(index, config.getTank('player', 0), point);
|
|
||||||
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.rect.x)
|
|
||||||
.setY(tank.rect.y)
|
|
||||||
.setDirectionX(tank.rect.direction.x)
|
|
||||||
.setDirectionY(tank.rect.direction.y)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (index in 1...4) {
|
public function destroy(entity:Entity):Void {
|
||||||
var point:SpawnPoint = config.getSpawnPoint(EntityType.BOT, index);
|
if (entities.exists(entity.id)) {
|
||||||
var tank = buildTank(0, config.getTank('bot', 0), point);
|
var type = EntityTypeResolver.of(entity);
|
||||||
entities.set(tank.id, tank);
|
for (l in listeners) l.onDestroy(type);
|
||||||
var bot = new Bot(tank.id);
|
entities.remove(entity.id);
|
||||||
bindControl(bot);
|
|
||||||
bot.start();
|
|
||||||
}
|
}
|
||||||
return changes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function bindControl(control:Control):Void {
|
public function action(tankId:Int, action:TankAction):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) {
|
||||||
case TankAction.MOVE(direction):
|
case TankAction.MOVE(direction):
|
||||||
tank.move(direction);
|
tank.move(direction);
|
||||||
/*Provider.get(IConnection).send(
|
|
||||||
Map GameActionRequest()
|
|
||||||
.setType(GameActionType.MOVE)
|
|
||||||
.setDirectionX(direction.x)
|
|
||||||
.setDirectionY(direction.y)
|
|
||||||
);*/
|
|
||||||
case TankAction.LEVEL_UP(level):
|
case TankAction.LEVEL_UP(level):
|
||||||
tank.config = config.getTank('player', Std.int(Math.min(tank.config.type + level, 3)));
|
tank.config = config.getTank('player', Std.int(Math.min(tank.config.type + level, 3)));
|
||||||
case TankAction.STOP:
|
case TankAction.STOP:
|
||||||
tank.stop();
|
tank.stop();
|
||||||
/*Provider.get(IConnection).send(
|
|
||||||
Map GameActionRequest()
|
|
||||||
.setType(GameActionType.STOP)
|
|
||||||
);*/
|
|
||||||
case TankAction.SHOT:
|
case TankAction.SHOT:
|
||||||
var bullet = tank.shot();
|
var bullet = tank.shot();
|
||||||
if (bullet != null) {
|
if (bullet != null) {
|
||||||
entities.set(bullet.id, bullet);
|
entities.set(bullet.id, bullet);
|
||||||
}
|
}
|
||||||
/*Provider.get(IConnection).send(
|
|
||||||
Map GameActionRequest()
|
|
||||||
.setType(GameActionType.SHOT)
|
|
||||||
);*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public function updateFromChanges(changes:Array<GameChange>):Void {
|
public function update():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, Direction.from(change.directionX, change.directionY));
|
|
||||||
mobileEntities.set(tank.id, tank);
|
|
||||||
tanks.set(tank.personId, tank);
|
|
||||||
case GameObjectType.BULLET:
|
|
||||||
var bullet:Bullet = Map Bullet(change.personId, change.objectId, change.x, change.y, 0, Direction.from(change.directionX, change.directionY));
|
|
||||||
mobileEntities.set(bullet.id, bullet);
|
|
||||||
}
|
|
||||||
case GameChangeType.DESTROED:
|
|
||||||
mobileEntities.remove(change.objectId);
|
|
||||||
case GameChangeType.DIRECTION:
|
|
||||||
var target = mobileEntities.get(change.objectId);
|
|
||||||
target.direction = Direction.from(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 collisionTankTank(a:Tank, b:Tank):Bool {
|
|
||||||
a.rect.lean(b.rect);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function collisionBulletTank(a:Bullet, b:Tank):Bool {
|
|
||||||
if (a.tankConfig.group != b.config.group) {
|
|
||||||
removeEntity(a);
|
|
||||||
removeEntity(b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function collisionTankBullet(a:Tank, b:Bullet):Bool {
|
|
||||||
if (a.config.group != b.tankConfig.group) {
|
|
||||||
removeEntity(a);
|
|
||||||
removeEntity(b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function collisionBulletBullet(a:Bullet, b:Bullet):Bool {
|
|
||||||
removeEntity(a);
|
|
||||||
removeEntity(b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeEntity(entity:Entity):Void {
|
|
||||||
if (entities.exists(entity.id)) {
|
|
||||||
entities.remove(entity.id);
|
|
||||||
removedEntities.push(entity.key);
|
|
||||||
if (Std.is(entity, Bullet)) {
|
|
||||||
var tank:Tank = cast entities.get(cast(entity, Bullet).tankId);
|
|
||||||
if (tank != null) tank.onDestroyBullet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (controls.exists(entity.id)) {
|
|
||||||
var control:Control = controls.get(entity.id);
|
|
||||||
control.dispose();
|
|
||||||
controls.remove(entity.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update():Array<GameChange> {
|
|
||||||
var newTime:Float = Date.now().getTime();
|
var newTime:Float = Date.now().getTime();
|
||||||
var d:Float = newTime - time;
|
var d:Float = newTime - time;
|
||||||
time = newTime;
|
time = newTime;
|
||||||
|
|
||||||
var changes = new Array<GameChange>();
|
|
||||||
|
|
||||||
for (ent in entities) if (Std.is(ent, MobileEntity)) {
|
for (ent in entities) if (Std.is(ent, MobileEntity)) {
|
||||||
|
var entityType:EntityType = EntityTypeResolver.of(ent);
|
||||||
var entity:MobileEntity = cast ent;
|
var entity:MobileEntity = cast ent;
|
||||||
|
|
||||||
/*if (Std.is(entity, Tank)) {
|
/*if (Std.is(entity, Tank)) {
|
||||||
@@ -227,9 +157,8 @@ class Engine implements ControlListener {
|
|||||||
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;
|
||||||
if (controls.exists(entity.id)) {
|
var with = EntityTypeResolver.of(cell);
|
||||||
controls.get(entity.id).onCollision(cell);
|
for (l in listeners) l.onCollision(entityType, with);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,18 +166,8 @@ class Engine implements ControlListener {
|
|||||||
for (other in entities.iterator()) {
|
for (other in entities.iterator()) {
|
||||||
if (other != ent && other != null) {
|
if (other != ent && other != null) {
|
||||||
if (other.rect.intersection2(side)) {
|
if (other.rect.intersection2(side)) {
|
||||||
//if (ent.rect.intersection(other.rect)) {
|
var with = EntityTypeResolver.of(other);
|
||||||
var funName = 'collision${ent.type}${other.type}';
|
for (l in listeners) l.onCollision(entityType, with);
|
||||||
var fun:Function = Reflect.field(this, funName);
|
|
||||||
if (fun != null) {
|
|
||||||
var c = Reflect.callMethod(this, fun, [ent, other]);
|
|
||||||
if (c) {
|
|
||||||
if (controls.exists(entity.id)) {
|
|
||||||
controls.get(entity.id).onCollision(other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
collision = c || collision;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,19 +186,10 @@ class Engine implements ControlListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeEntity(entity);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*changes.push(new GameChange()
|
|
||||||
.setType(GameChangeType.MOVED)
|
|
||||||
.setObjectType(objectType)
|
|
||||||
.setObjectId(entity.id)
|
|
||||||
.setX(entity.rect.x)
|
|
||||||
.setY(entity.rect.y)
|
|
||||||
);*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/common/haxe/ru/m/tankz/game/ClassicGame.hx
Normal file
13
src/common/haxe/ru/m/tankz/game/ClassicGame.hx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
|
import ru.m.tankz.config.Config;
|
||||||
|
|
||||||
|
|
||||||
|
class ClassicGame extends Game {
|
||||||
|
|
||||||
|
public static var TYPE(default, never):String = Type.getClassName(ClassicGame);
|
||||||
|
|
||||||
|
public function new(config:Config) {
|
||||||
|
super(TYPE, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/common/haxe/ru/m/tankz/game/Game.hx
Normal file
69
src/common/haxe/ru/m/tankz/game/Game.hx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.EntityType;
|
||||||
|
import ru.m.geom.Direction;
|
||||||
|
import ru.m.geom.Point;
|
||||||
|
import ru.m.tankz.config.Config;
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
|
import ru.m.tankz.core.Tank;
|
||||||
|
import ru.m.tankz.engine.Engine;
|
||||||
|
import ru.m.tankz.player.Player;
|
||||||
|
|
||||||
|
|
||||||
|
class Game implements EngineListener implements ControlListener {
|
||||||
|
|
||||||
|
public var type(default, null):String;
|
||||||
|
public var config(default, null):Config;
|
||||||
|
public var engine(default, null):Engine;
|
||||||
|
|
||||||
|
|
||||||
|
public function new(type:String, config:Config) {
|
||||||
|
this.type = type;
|
||||||
|
this.config = config;
|
||||||
|
this.engine = new Engine(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildTank(index:Int, config:TankConfig, point:SpawnPoint):Tank {
|
||||||
|
var tank = new Tank(index, config);
|
||||||
|
tank.rect.center = new Point((point.x + 1) * engine.map.cellWidth, (point.y + 1) * engine.map.cellHeight);
|
||||||
|
tank.rect.direction = Direction.fromString(point.direction);
|
||||||
|
return tank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start(players:Array<Player>):Void {
|
||||||
|
for (index in 0...players.length) {
|
||||||
|
var player:Player = players[index];
|
||||||
|
var point:SpawnPoint = config.getSpawnPoint('player', index);
|
||||||
|
var tank = buildTank(index, config.getTank('player', 0), point);
|
||||||
|
engine.spawn(tank);
|
||||||
|
}
|
||||||
|
for (index in 1...4) {
|
||||||
|
var point:SpawnPoint = config.getSpawnPoint('bot', index);
|
||||||
|
var tank = buildTank(0, config.getTank('bot', 0), point);
|
||||||
|
engine.spawn(tank);
|
||||||
|
/*var bot = new Bot(tank.id);
|
||||||
|
bindControl(bot);
|
||||||
|
bot.start();*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSpawn(entity:EntityType):Void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCollision(entity:EntityType, with:EntityType):Void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onDestroy(entity:EntityType):Void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAction(tankId:Int, action:TankAction):Void {
|
||||||
|
engine.action(tankId, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dispose():Void {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/common/haxe/ru/m/tankz/player/Player.hx
Normal file
14
src/common/haxe/ru/m/tankz/player/Player.hx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.m.tankz.player;
|
||||||
|
|
||||||
|
import ru.m.tankz.control.Control;
|
||||||
|
|
||||||
|
|
||||||
|
class Player extends Control {
|
||||||
|
|
||||||
|
public var index(default, null):Int;
|
||||||
|
|
||||||
|
public function new(index:Int) {
|
||||||
|
super();
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user