[common] ticker update
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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>;
|
||||
|
||||
11
src/common/haxe/ru/m/tankz/engine/ITicker.hx
Normal file
11
src/common/haxe/ru/m/tankz/engine/ITicker.hx
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user