[common] add Ticker
This commit is contained in:
@@ -21,6 +21,7 @@ class LocalGame extends GameRunner {
|
|||||||
switch event {
|
switch event {
|
||||||
case GameEvent.COMPLETE(_, _):
|
case GameEvent.COMPLETE(_, _):
|
||||||
disconnect(recorder);
|
disconnect(recorder);
|
||||||
|
recorder.onGameEvent(event); //ToDo:
|
||||||
recordStorage.save(recorder.record);
|
recordStorage.save(recorder.record);
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class NetworkGame extends Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function onGameEventProto(game:GameEventResponse):Void {
|
private function onGameEventProto(game:GameEventResponse):Void {
|
||||||
var frame = game.frame;
|
var time = game.time;
|
||||||
var eventStr = game.event;
|
var eventStr = game.event;
|
||||||
var event:GameEvent = Unserializer.run(eventStr);
|
var event:GameEvent = Unserializer.run(eventStr);
|
||||||
gameEventSignal.emit(event);
|
gameEventSignal.emit(event);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class NetworkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function action(tankId:Int, action:TankAction):Void {
|
public function action(tankId:Int, action:TankAction):Void {
|
||||||
connection.send(new Request().setGameEvent(new GameEventRequest().setFrame(0).setEvent(
|
connection.send(new Request().setGameEvent(new GameEventRequest().setTime(0).setEvent(
|
||||||
Serializer.run(GameEvent.ACTION(tankId, action))
|
Serializer.run(GameEvent.ACTION(tankId, action))
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class BotControl extends Control {
|
|||||||
private var tank(get, null):Tank;
|
private var tank(get, null):Tank;
|
||||||
|
|
||||||
private inline function get_tank():Tank {
|
private inline function get_tank():Tank {
|
||||||
return handler == null ? null : engine.getEntity(tankId);
|
return handler == null || tankId == -1 ? null : engine.getEntity(tankId);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function stop():Void {
|
override public function stop():Void {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Control {
|
|||||||
|
|
||||||
public function new(playerId:PlayerId) {
|
public function new(playerId:PlayerId) {
|
||||||
this.playerId = playerId;
|
this.playerId = playerId;
|
||||||
|
this.tankId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function bind(handler:IGame, engine:IEngine):Void {
|
public function bind(handler:IGame, engine:IEngine):Void {
|
||||||
@@ -30,7 +31,7 @@ class Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function action(action:TankAction):Void {
|
public function action(action:TankAction):Void {
|
||||||
if (tankId != 0 && handler != null) {
|
if (tankId > -1 && handler != null) {
|
||||||
handler.gameEventSignal.emit(GameEvent.ACTION(tankId, action));
|
handler.gameEventSignal.emit(GameEvent.ACTION(tankId, action));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,5 +46,6 @@ class Control {
|
|||||||
stop();
|
stop();
|
||||||
handler = null;
|
handler = null;
|
||||||
engine = null;
|
engine = null;
|
||||||
|
tankId = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ import ru.m.tankz.map.LevelMap;
|
|||||||
public var allEntities(default, null):Map<Int, Entity>;
|
public var allEntities(default, null):Map<Int, Entity>;
|
||||||
public var entities(default, null):Map<Int, Entity>;
|
public var entities(default, null):Map<Int, Entity>;
|
||||||
|
|
||||||
private var time:Float;
|
private var ticker:Ticker;
|
||||||
|
|
||||||
public function new(config:Config) {
|
public function new(config:Config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
map = new LevelMap(config.map);
|
map = new LevelMap(config.map);
|
||||||
allEntities = new Map();
|
allEntities = new Map();
|
||||||
entities = new Map();
|
entities = new Map();
|
||||||
time = Date.now().getTime();
|
ticker = new Ticker();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEntity<T:Entity>(entityId:Int):T {
|
public function getEntity<T:Entity>(entityId:Int):T {
|
||||||
@@ -67,9 +67,8 @@ import ru.m.tankz.map.LevelMap;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function update():Void {
|
public function update():Void {
|
||||||
var newTime:Float = Timer.stamp() * 1000;
|
if (!ticker.running) ticker.start();
|
||||||
var d:Float = newTime - time;
|
var d:Float = ticker.passed;
|
||||||
time = newTime;
|
|
||||||
|
|
||||||
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 entityType:EntityType = EntityTypeResolver.of(ent);
|
||||||
|
|||||||
42
src/common/haxe/ru/m/tankz/engine/Ticker.hx
Normal file
42
src/common/haxe/ru/m/tankz/engine/Ticker.hx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package ru.m.tankz.engine;
|
||||||
|
|
||||||
|
class Ticker {
|
||||||
|
public var time(get, null):Int;
|
||||||
|
public var passed(get, null):Int;
|
||||||
|
public var running(default, null):Bool;
|
||||||
|
|
||||||
|
private var begin:Int;
|
||||||
|
private var last:Int;
|
||||||
|
|
||||||
|
private static var TIME = Timer.stamp();
|
||||||
|
|
||||||
|
private inline static function now():Int {
|
||||||
|
return Std.int((Timer.stamp() - TIME) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
begin = 0;
|
||||||
|
last = 0;
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start():Void {
|
||||||
|
last = begin = now();
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stop():Void {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get_time():Int {
|
||||||
|
return now() - begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get_passed():Int {
|
||||||
|
var now = now();
|
||||||
|
var result = now - last;
|
||||||
|
last = now;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,6 @@ import ru.m.tankz.Type;
|
|||||||
public var config(default, null):Config;
|
public var config(default, null):Config;
|
||||||
public var winner(default, null):Null<TeamId>;
|
public var winner(default, null):Null<TeamId>;
|
||||||
public var state(default, null):GameState;
|
public var state(default, null):GameState;
|
||||||
public var frame(default, null):Int;
|
|
||||||
public var engine(default, null):IEngine;
|
public var engine(default, null):IEngine;
|
||||||
public var controlFactory(default, null):IControlFactory;
|
public var controlFactory(default, null):IControlFactory;
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ import ru.m.tankz.Type;
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
this.teams = new Map();
|
this.teams = new Map();
|
||||||
this.config = configBundle.get(type);
|
this.config = configBundle.get(type);
|
||||||
this.frame = 0;
|
|
||||||
this.controlFactory = new NoneControlFactory();
|
this.controlFactory = new NoneControlFactory();
|
||||||
connect(this);
|
connect(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function update():Void {
|
private function update():Void {
|
||||||
frame++;
|
|
||||||
engine.update();
|
engine.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
var actives:Array<TeamId> = [];
|
var actives:Array<TeamId> = [];
|
||||||
for (team in teams.iterator()) {
|
for (team in teams.iterator()) {
|
||||||
if (team.isAlive) {
|
if (team.isAlive) {
|
||||||
if (team.eagleId > 0) {
|
if (team.eagleId > -1) {
|
||||||
if (!cast(engine.entities[team.eagleId], Eagle).death) {
|
if (!cast(engine.entities[team.eagleId], Eagle).death) {
|
||||||
actives.push(team.id);
|
actives.push(team.id);
|
||||||
}
|
}
|
||||||
@@ -341,7 +340,7 @@ class GameRunner extends Game implements EngineListener {
|
|||||||
if (player.control != null) {
|
if (player.control != null) {
|
||||||
player.control.stop();
|
player.control.stop();
|
||||||
}
|
}
|
||||||
player.tankId = 0; //ToDo: ?
|
player.tankId = -1;
|
||||||
team.onDestroy(player.id);
|
team.onDestroy(player.id);
|
||||||
if (player.state.life > 0) {
|
if (player.state.life > 0) {
|
||||||
changeLife(player.id, -1);
|
changeLife(player.id, -1);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ interface IGame extends GameListener {
|
|||||||
public var config(default, null):Config;
|
public var config(default, null):Config;
|
||||||
public var winner(default, null):Null<TeamId>;
|
public var winner(default, null):Null<TeamId>;
|
||||||
public var state(default, null):GameState;
|
public var state(default, null):GameState;
|
||||||
public var frame(default, null):Int;
|
|
||||||
public var controlFactory(default, null):IControlFactory;
|
public var controlFactory(default, null):IControlFactory;
|
||||||
|
|
||||||
public var gameEventSignal(default, null):Signal<GameEvent>;
|
public var gameEventSignal(default, null):Signal<GameEvent>;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Player {
|
|||||||
this.state.reset();
|
this.state.reset();
|
||||||
this.state.life = Math.isNaN(config.life) ? 0 : config.life;
|
this.state.life = Math.isNaN(config.life) ? 0 : config.life;
|
||||||
this.bullets = 0;
|
this.bullets = 0;
|
||||||
|
this.tankId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function set_tankId(value:Int):Int {
|
private function set_tankId(value:Int):Int {
|
||||||
@@ -42,6 +43,6 @@ class Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function get_isAlive():Bool {
|
private function get_isAlive():Bool {
|
||||||
return tankId > 0 || state.life > 0;
|
return tankId > -1 || state.life > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class Team {
|
|||||||
this.id = config.id;
|
this.id = config.id;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
|
this.eagleId = -1;
|
||||||
this.players = new Map();
|
this.players = new Map();
|
||||||
for (playerConfig in config.players) {
|
for (playerConfig in config.players) {
|
||||||
var playerState = state == null ? null : state.players[playerConfig.index];
|
var playerState = state == null ? null : state.players[playerConfig.index];
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ package ru.m.tankz.game.record;
|
|||||||
|
|
||||||
import flash.events.Event;
|
import flash.events.Event;
|
||||||
import flash.Lib;
|
import flash.Lib;
|
||||||
|
import ru.m.tankz.engine.Ticker;
|
||||||
import ru.m.tankz.game.record.GameRecord;
|
import ru.m.tankz.game.record.GameRecord;
|
||||||
|
|
||||||
class GamePlayer extends Game {
|
class GamePlayer extends Game {
|
||||||
|
|
||||||
private var record:GameRecord;
|
private var record:GameRecord;
|
||||||
private var data:Array<EventItem>;
|
private var data:Array<EventItem>;
|
||||||
|
private var ticker:Ticker;
|
||||||
|
|
||||||
public function new(record:GameRecord) {
|
public function new(record:GameRecord) {
|
||||||
super(record.state);
|
super(record.state);
|
||||||
frame = 0;
|
|
||||||
this.record = record;
|
this.record = record;
|
||||||
this.data = null;
|
this.data = null;
|
||||||
|
this.ticker = new Ticker();
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function start():Void {
|
override public function start():Void {
|
||||||
super.start();
|
super.start();
|
||||||
frame = 0;
|
ticker.start();
|
||||||
data = record.events.slice(0);
|
data = record.events.slice(0);
|
||||||
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||||
}
|
}
|
||||||
@@ -28,10 +30,9 @@ class GamePlayer extends Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function onEnterFrame(event:Event):Void {
|
private function onEnterFrame(event:Event):Void {
|
||||||
frame++;
|
|
||||||
var events = 0;
|
var events = 0;
|
||||||
for (event in data) {
|
for (event in data) {
|
||||||
if (event.frame <= frame) {
|
if (event.time <= ticker.time) {
|
||||||
events++;
|
events++;
|
||||||
gameEventSignal.emit(event.event);
|
gameEventSignal.emit(event.event);
|
||||||
switch event.event {
|
switch event.event {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import com.hurlant.crypto.extra.UUID;
|
|||||||
import com.hurlant.crypto.prng.Random;
|
import com.hurlant.crypto.prng.Random;
|
||||||
|
|
||||||
typedef EventItem = {
|
typedef EventItem = {
|
||||||
frame:Int,
|
var time:Int;
|
||||||
event:GameEvent
|
var event:GameEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameRecordInfo {
|
class GameRecordInfo {
|
||||||
|
|||||||
@@ -1,44 +1,31 @@
|
|||||||
package ru.m.tankz.game.record;
|
package ru.m.tankz.game.record;
|
||||||
|
|
||||||
import flash.events.Event;
|
import ru.m.tankz.engine.Ticker;
|
||||||
import flash.Lib;
|
|
||||||
import ru.m.tankz.game.IGame;
|
import ru.m.tankz.game.IGame;
|
||||||
|
|
||||||
class GameRecorder implements GameListener {
|
class GameRecorder implements GameListener {
|
||||||
|
|
||||||
private var frame:Int;
|
|
||||||
public var record(default, null):GameRecord;
|
public var record(default, null):GameRecord;
|
||||||
|
|
||||||
|
private var ticker:Ticker;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
frame = 0;
|
ticker = new Ticker();
|
||||||
record = new GameRecord();
|
record = new GameRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
|
if (!ticker.running) ticker.start();
|
||||||
|
record.events.push({time: ticker.time, event: event});
|
||||||
switch event {
|
switch event {
|
||||||
case GameEvent.START(state):
|
case GameEvent.START(state):
|
||||||
record.info.type = state.type;
|
record.info.type = state.type;
|
||||||
record.info.presetId = state.presetId;
|
record.info.presetId = state.presetId;
|
||||||
record.info.levelId = state.levelId;
|
record.info.levelId = state.levelId;
|
||||||
start();
|
record.info.date = Date.now();
|
||||||
case GameEvent.COMPLETE(_, _):
|
case GameEvent.COMPLETE(_, _):
|
||||||
stop();
|
ticker.stop();
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
record.events.push({frame: frame, event: event});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start():Void {
|
|
||||||
frame = 0;
|
|
||||||
record.info.date = Date.now();
|
|
||||||
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop():Void {
|
|
||||||
Lib.current.stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function onEnterFrame(event:Event):Void {
|
|
||||||
frame++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,12 +70,12 @@ message StartGameResponse {
|
|||||||
|
|
||||||
// Game
|
// Game
|
||||||
message GameEventRequest {
|
message GameEventRequest {
|
||||||
int32 frame = 1;
|
int32 time = 1;
|
||||||
string event = 2;
|
string event = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GameEventResponse {
|
message GameEventResponse {
|
||||||
int32 frame = 1;
|
int32 time = 1;
|
||||||
string event = 2;
|
string event = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class GameSession extends ProtoSession<Response, Request> implements GameManager
|
|||||||
|
|
||||||
public function onEvent(game:ServerGame, event:GameEvent):Void {
|
public function onEvent(game:ServerGame, event:GameEvent):Void {
|
||||||
if (gameId == game.proto.id) {
|
if (gameId == game.proto.id) {
|
||||||
send(new Response().setGameEvent(new GameEventResponse().setFrame(game.frame).setEvent(Serializer.run(event))));
|
send(new Response().setGameEvent(new GameEventResponse().setTime(0).setEvent(Serializer.run(event))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user