[common] ticker update

This commit is contained in:
2019-06-02 22:09:13 +03:00
parent fb9a28c126
commit 5a3d5b974e
10 changed files with 114 additions and 42 deletions

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.view; package ru.m.tankz.view;
import ru.m.tankz.game.IGame;
import flash.events.KeyboardEvent; import flash.events.KeyboardEvent;
import flash.ui.Keyboard; import flash.ui.Keyboard;
import haxework.resources.IResources; import haxework.resources.IResources;
@@ -21,6 +22,7 @@ import ru.m.tankz.view.popup.LoginPopup;
@:provide var resources:IResources; @:provide var resources:IResources;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var soundManager:SoundManager; @:provide var soundManager:SoundManager;
@:provide var game:IGame;
public function init():Void { public function init():Void {
resources.text.put('version', '${Const.VERSION}'); resources.text.put('version', '${Const.VERSION}');
@@ -37,6 +39,10 @@ import ru.m.tankz.view.popup.LoginPopup;
switcher.change(StartFrame.ID); switcher.change(StartFrame.ID);
case Keyboard.M: case Keyboard.M:
soundManager.mute = !soundManager.mute; soundManager.mute = !soundManager.mute;
case Keyboard.P:
if (game != null) {
game.pause = !game.pause;
}
} }
}); });
switcher.change(StartFrame.ID); switcher.change(StartFrame.ID);
@@ -54,7 +60,8 @@ import ru.m.tankz.view.popup.LoginPopup;
logoutButton.visible = false; logoutButton.visible = false;
loginButton.visible = true; loginButton.visible = true;
case ERROR(error): case ERROR(error):
L.e("ClientView", 'onConnectionState: ERROR', error); //L.e("ClientView", 'onConnectionState: ERROR', error);
L.w("ClientView", 'onConnectionState: ERROR');
case _: case _:
username.text = ""; username.text = "";
logoutButton.visible = false; logoutButton.visible = false;

View File

@@ -16,11 +16,10 @@ import ru.m.tankz.map.LevelMap;
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 ticker(default, null):ITicker;
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 ticker:Ticker; public var allEntities(default, null):Map<Int, Entity>;
public function new(config:Config) { public function new(config:Config) {
this.config = config; this.config = config;
@@ -67,8 +66,7 @@ import ru.m.tankz.map.LevelMap;
} }
public function update():Void { public function update():Void {
if (!ticker.running) ticker.start(); var d:Float = ticker.tick();
var d:Float = ticker.passed;
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);

View File

@@ -12,6 +12,7 @@ interface IEngine {
public var entities(default, null):Map<Int, Entity>; public var entities(default, null):Map<Int, Entity>;
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 ticker(default, null):ITicker;
public var spawnSignal(default, null):Signal1<EntityType>; public var spawnSignal(default, null):Signal1<EntityType>;
public var collisionSignal(default, null):Signal2<EntityType, EntityType>; public var collisionSignal(default, null):Signal2<EntityType, EntityType>;

View File

@@ -0,0 +1,11 @@
package ru.m.tankz.engine;
interface ITicker {
public var time(get, null):Int;
public var running(default, null):Bool;
public function start():Void;
public function stop():Void;
public function tick():Int;
public function emit(f:Void->Void, delay:Int):Void;
}

View File

@@ -1,12 +1,17 @@
package ru.m.tankz.engine; package ru.m.tankz.engine;
class Ticker { typedef Action = {
var time:Int;
var action:Void->Void;
}
class Ticker implements ITicker {
public var time(get, null):Int; public var time(get, null):Int;
public var passed(get, null):Int;
public var running(default, null):Bool; public var running(default, null):Bool;
private var begin:Int; private var passed:Int;
private var last:Int; private var last_tick:Int;
private var actions:Array<Action>;
private static var TIME = Timer.stamp(); private static var TIME = Timer.stamp();
@@ -15,13 +20,18 @@ class Ticker {
} }
public function new() { public function new() {
begin = 0; passed = 0;
last = 0; last_tick = 0;
running = false; running = false;
actions = [];
}
private function get_time():Int {
return passed;
} }
public function start():Void { public function start():Void {
last = begin = now(); last_tick = now();
running = true; running = true;
} }
@@ -29,14 +39,38 @@ class Ticker {
running = false; running = false;
} }
private function get_time():Int { public function tick():Int {
return now() - begin; if (!running) {
} return 0;
}
private function get_passed():Int {
var now = now(); var now = now();
var result = now - last; var result = now - last_tick;
last = now; last_tick = now;
passed += result;
if (actions.length > 0) {
runActions();
}
return result; return result;
} }
private function runActions():Void {
var it = actions.iterator();
var action = it.next();
var i = 0;
while (action != null && time >= action.time) {
L.d("Ticker", 'run action: $action(${action.time}) on $time');
action.action();
i++;
action = it.next();
}
if (i > 0) {
actions = actions.slice(i);
}
}
public function emit(action:Void->Void, delay:Int):Void {
L.d("Ticker", 'emit: $action on ${time+delay}');
actions.push({action:action, time:time+delay});
actions.sort(function(a, b) return a.time - b.time);
}
} }

View File

@@ -26,6 +26,7 @@ import ru.m.tankz.Type;
public var state(default, null):GameState; public var state(default, null):GameState;
public var engine(default, null):IEngine; public var engine(default, null):IEngine;
public var controlFactory(default, null):IControlFactory; public var controlFactory(default, null):IControlFactory;
public var pause(default, set):Bool;
@:provide var configBundle:IConfigBundle; @:provide var configBundle:IConfigBundle;
@@ -35,9 +36,20 @@ import ru.m.tankz.Type;
this.teams = new Map(); this.teams = new Map();
this.config = configBundle.get(type); this.config = configBundle.get(type);
this.controlFactory = new NoneControlFactory(); this.controlFactory = new NoneControlFactory();
this.pause = false;
connect(this); connect(this);
} }
private function set_pause(value:Bool):Bool {
if (pause != value) {
pause = value;
changePause(pause);
}
return pause;
}
private function changePause(value:Bool):Void {}
private function applyPosition(entity:Entity, position:Position):Void { private function applyPosition(entity:Entity, position:Position):Void {
entity.rect.center = new Point(position.x, position.y); entity.rect.center = new Point(position.x, position.y);
if (position.direction != null) { if (position.direction != null) {

View File

@@ -1,6 +1,5 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import haxework.color.Color;
import ru.m.geom.Line; import ru.m.geom.Line;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
@@ -27,6 +26,14 @@ class GameRunner extends Game implements EngineListener {
this.engine.connect(this); this.engine.connect(this);
} }
override function changePause(value:Bool):Void {
if (value) {
engine.ticker.stop();
} else {
engine.ticker.start();
}
}
private function update():Void { private function update():Void {
engine.update(); engine.update();
} }
@@ -47,7 +54,7 @@ class GameRunner extends Game implements EngineListener {
team.spawner.runner = spawn; team.spawner.runner = spawn;
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
if (team.tryRespawn(player.id)) { if (team.tryRespawn(player.id)) {
team.spawner.push(player.id); team.spawner.push(engine.ticker, player.id);
} }
} }
if (team.config.eagle != null) { if (team.config.eagle != null) {
@@ -293,12 +300,20 @@ class GameRunner extends Game implements EngineListener {
} }
override public function onGameEvent(event:GameEvent):Void { override public function onGameEvent(event:GameEvent):Void {
if (pause) {
switch event {
case ACTION(_): return;
case _:
}
}
super.onGameEvent(event); super.onGameEvent(event);
switch event { switch event {
case START(_): case START(_):
engine.ticker.start();
timer = new Timer(30); timer = new Timer(30);
timer.run = update; timer.run = update;
case COMPLETE(_, _): case COMPLETE(_, _):
engine.ticker.stop();
if (timer != null) { if (timer != null) {
timer.stop(); timer.stop();
timer = null; timer = null;
@@ -351,7 +366,7 @@ class GameRunner extends Game implements EngineListener {
} }
var respawn:Bool = team.tryRespawn(player.id); var respawn:Bool = team.tryRespawn(player.id);
if (respawn) { if (respawn) {
team.spawner.push(player.id); team.spawner.push(engine.ticker, player.id);
} }
if (!team.isAlive) { if (!team.isAlive) {
checkComplete(); checkComplete();

View File

@@ -12,6 +12,7 @@ interface IGame extends GameListener {
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 controlFactory(default, null):IControlFactory; public var controlFactory(default, null):IControlFactory;
public var pause(default, set):Bool;
public var gameEventSignal(default, null):Signal<GameEvent>; public var gameEventSignal(default, null):Signal<GameEvent>;

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.engine.ITicker;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.Timer; import ru.m.Timer;
@@ -18,7 +19,6 @@ class Spawner {
private var config:TeamConfig; private var config:TeamConfig;
private var points:Array<SpawnPoint>; private var points:Array<SpawnPoint>;
private var queue:Array<SpawnTask>; private var queue:Array<SpawnTask>;
private var timer:Timer;
private var indexedPoints:Map<Int, SpawnPoint>; private var indexedPoints:Map<Int, SpawnPoint>;
private var anyPoints:Array<SpawnPoint>; private var anyPoints:Array<SpawnPoint>;
@@ -61,7 +61,7 @@ class Spawner {
return null; return null;
} }
public function push(playerId:PlayerId):Void { public function push(ticker:ITicker, playerId:PlayerId):Void {
var point:SpawnPoint = null; var point:SpawnPoint = null;
if (indexedPoints.exists(playerId.index)) { if (indexedPoints.exists(playerId.index)) {
point = indexedPoints.get(playerId.index); point = indexedPoints.get(playerId.index);
@@ -71,24 +71,16 @@ class Spawner {
} }
if (point != null) { if (point != null) {
queue.push({playerId:playerId, point:point, tankType:getPlayerTank(playerId)}); queue.push({playerId:playerId, point:point, tankType:getPlayerTank(playerId)});
run(); if (config.spawnInterval == null) {
} ticker.emit(spawn, 500);
} } else {
ticker.emit(spawn, 500 + config.spawnInterval * queue.length);
private function run():Void { }
if (timer == null) {
timer = new Timer(config.spawnInterval == null ? 500 : config.spawnInterval);
timer.run = spawn;
} }
} }
private function spawn():Void { private function spawn():Void {
if (queue.length == 0) { if (queue.length > 0) {
if (timer != null) {
timer.stop();
timer = null;
}
} else {
runner(queue.shift()); runner(queue.shift());
} }
} }

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game.record; package ru.m.tankz.game.record;
import ru.m.tankz.engine.ITicker;
import ru.m.tankz.engine.Ticker; import ru.m.tankz.engine.Ticker;
import ru.m.tankz.game.IGame; import ru.m.tankz.game.IGame;
@@ -7,7 +8,7 @@ class GameRecorder implements GameListener {
public var record(default, null):GameRecord; public var record(default, null):GameRecord;
private var ticker:Ticker; private var ticker:ITicker;
public function new() { public function new() {
ticker = new Ticker(); ticker = new Ticker();
@@ -15,10 +16,9 @@ class GameRecorder implements GameListener {
} }
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):
ticker.start();
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;
@@ -27,5 +27,6 @@ class GameRecorder implements GameListener {
ticker.stop(); ticker.stop();
case _: case _:
} }
record.events.push({time: ticker.time, event: event});
} }
} }