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

View File

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

View File

@@ -12,6 +12,7 @@ interface IEngine {
public var entities(default, null):Map<Int, Entity>;
public var config(default, default):Config;
public var map(default, null):LevelMap;
public var ticker(default, null):ITicker;
public var spawnSignal(default, null):Signal1<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;
class Ticker {
typedef Action = {
var time:Int;
var action:Void->Void;
}
class Ticker implements ITicker {
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 var passed:Int;
private var last_tick:Int;
private var actions:Array<Action>;
private static var TIME = Timer.stamp();
@@ -15,13 +20,18 @@ class Ticker {
}
public function new() {
begin = 0;
last = 0;
passed = 0;
last_tick = 0;
running = false;
actions = [];
}
private function get_time():Int {
return passed;
}
public function start():Void {
last = begin = now();
last_tick = now();
running = true;
}
@@ -29,14 +39,38 @@ class Ticker {
running = false;
}
private function get_time():Int {
return now() - begin;
}
private function get_passed():Int {
public function tick():Int {
if (!running) {
return 0;
}
var now = now();
var result = now - last;
last = now;
var result = now - last_tick;
last_tick = now;
passed += result;
if (actions.length > 0) {
runActions();
}
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 engine(default, null):IEngine;
public var controlFactory(default, null):IControlFactory;
public var pause(default, set):Bool;
@:provide var configBundle:IConfigBundle;
@@ -35,9 +36,20 @@ import ru.m.tankz.Type;
this.teams = new Map();
this.config = configBundle.get(type);
this.controlFactory = new NoneControlFactory();
this.pause = false;
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 {
entity.rect.center = new Point(position.x, position.y);
if (position.direction != null) {

View File

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

View File

@@ -12,6 +12,7 @@ interface IGame extends GameListener {
public var winner(default, null):Null<TeamId>;
public var state(default, null):GameState;
public var controlFactory(default, null):IControlFactory;
public var pause(default, set):Bool;
public var gameEventSignal(default, null):Signal<GameEvent>;

View File

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

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game.record;
import ru.m.tankz.engine.ITicker;
import ru.m.tankz.engine.Ticker;
import ru.m.tankz.game.IGame;
@@ -7,7 +8,7 @@ class GameRecorder implements GameListener {
public var record(default, null):GameRecord;
private var ticker:Ticker;
private var ticker:ITicker;
public function new() {
ticker = new Ticker();
@@ -15,10 +16,9 @@ class GameRecorder implements GameListener {
}
public function onGameEvent(event:GameEvent):Void {
if (!ticker.running) ticker.start();
record.events.push({time: ticker.time, event: event});
switch event {
case GameEvent.START(state):
ticker.start();
record.info.type = state.type;
record.info.presetId = state.presetId;
record.info.levelId = state.levelId;
@@ -27,5 +27,6 @@ class GameRecorder implements GameListener {
ticker.stop();
case _:
}
record.events.push({time: ticker.time, event: event});
}
}