[common] game next function

This commit is contained in:
2018-01-30 22:04:48 +03:00
parent f69c7af618
commit 38e2a39c4a
7 changed files with 124 additions and 38 deletions

View File

@@ -89,8 +89,15 @@ exports['client:flash'] = gulp.series(prepare(Haxe.ID), generate(), build('flash
exports['client:html5'] = gulp.series(prepare(Haxe.ID), generate(), build('html5')); exports['client:html5'] = gulp.series(prepare(Haxe.ID), generate(), build('html5'));
exports['client:linux'] = gulp.series(prepare(Haxe.ID), generate(), build('linux')); exports['client:linux'] = gulp.series(prepare(Haxe.ID), generate(), build('linux'));
exports['client:webapp'] = webapp; exports['client:webapp'] = webapp;
exports['client'] = gulp.series(prepare(Haxe.ID), generate(), gulp.parallel(build('flash'), build('html5')), exports['client:flash:html'], webapp);
exports['client:deb'] = buildDeb; exports['client:deb'] = buildDeb;
exports['client'] = gulp.series(
prepare(Haxe.ID),
generate(),
gulp.parallel(build('flash'), build('html5'), build('linux')),
exports['client:flash:html'],
webapp,
buildDeb,
);

View File

@@ -1,6 +1,6 @@
{ {
"name": "tankz", "name": "tankz",
"version": "0.2.0", "version": "0.2.1",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"ansi-colors": "^1.0.1", "ansi-colors": "^1.0.1",

View File

@@ -63,10 +63,10 @@ class Client implements IConnectionHandler {
#end #end
//Provider.get(IConnection).handler.addListener(this); //Provider.get(IConnection).handler.addListener(this);
view = new MainView(); view = new MainView();
Provider.set(IFrameSwitcher, view.switcher); Provider.set(IFrameSwitcher, view.switcher);
Root.bind(view); Root.bind(view);
view.content.stage.stageFocusRect = false;
//view.logout.onPress = this; //view.logout.onPress = this;
view.switcher.change(StartFrame.ID); view.switcher.change(StartFrame.ID);

View File

@@ -33,11 +33,13 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
private var game:Game; private var game:Game;
private var timer:Timer; private var timer:Timer;
public function init():Void { public function init():Void {}
}
public function onShow():Void { public function onShow():Void {
var s:GameState = Provider.get(GameState); start(Provider.get(GameState));
}
private function start(s:GameState):Void {
game = Provider.build(Game, s.type); game = Provider.build(Game, s.type);
if (game == null) { if (game == null) {
throw 'Unsupported game type "${s.type}"'; throw 'Unsupported game type "${s.type}"';
@@ -52,8 +54,23 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
state.text = stateString(s); state.text = stateString(s);
} }
private function stop():Void {
//Provider.get(IConnection).packetHandler.removeListener(this);
if (timer != null) {
timer.stop();
timer = null;
}
content.removeEventListener(Event.ENTER_FRAME, redraw);
if (game != null) {
game.dispose();
game = null;
}
render.reset();
}
private function stateString(state:GameState):String { private function stateString(state:GameState):String {
var result:Array<String> = []; var result:Array<String> = [];
result.push('Level: ${state.level}');
for (teamId in state.teams.keys()) { for (teamId in state.teams.keys()) {
var ts:TeamState = state.teams[teamId]; var ts:TeamState = state.teams[teamId];
if (ts.lose) { if (ts.lose) {
@@ -69,7 +86,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
} }
} }
} }
return result.join(' '); return '[ ${result.join(' | ')} ]';
} }
private function onGameStateChange(s:GameState):GameState { private function onGameStateChange(s:GameState):GameState {
@@ -83,18 +100,17 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
state.text = stateString(s); state.text = stateString(s);
case Option.None: case Option.None:
} }
Provider.get(IFrameSwitcher).change(StartFrame.ID); switch (game.next()) {
case Option.Some(s):
stop();
start(s);
case Option.None:
Provider.get(IFrameSwitcher).change(StartFrame.ID);
}
} }
public function onHide():Void { public function onHide():Void {
//Provider.get(IConnection).packetHandler.removeListener(this); stop();
if (timer != null) {
timer.stop();
timer = null;
}
content.removeEventListener(Event.ENTER_FRAME, redraw);
game.dispose();
render.reset();
} }
private function updateEngine():Void { private function updateEngine():Void {

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import haxe.ds.Option;
import ru.m.tankz.game.GameState.PlayerState; import ru.m.tankz.game.GameState.PlayerState;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
@@ -11,6 +12,9 @@ class ClassicGame extends Game {
public static var HUMAN(default, never):TeamId = 'human'; public static var HUMAN(default, never):TeamId = 'human';
public static var BOT(default, never):TeamId = 'bot'; public static var BOT(default, never):TeamId = 'bot';
private static var HUMAN_LIFE(default, never):Int = 3;
private static var BOT_LIFE(default, never):Int = 20;
public function new() { public function new() {
super(TYPE); super(TYPE);
} }
@@ -20,7 +24,7 @@ class ClassicGame extends Game {
state.type = TYPE; state.type = TYPE;
state.level = level; state.level = level;
state.teams[HUMAN] = {life: -1, players: new Map(), lose: false}; state.teams[HUMAN] = {life: -1, players: new Map(), lose: false};
state.teams[BOT] = {life: 20, players: new Map(), lose: false}; state.teams[BOT] = {life: BOT_LIFE, players: new Map(), lose: false};
for (i in 0...humans) { for (i in 0...humans) {
state.teams[HUMAN].players[i] = { state.teams[HUMAN].players[i] = {
index:i, index:i,
@@ -32,7 +36,7 @@ class ClassicGame extends Game {
type: 'human', type: 'human',
index: i index: i
}, },
life:3, life:HUMAN_LIFE,
}; };
} }
for (i in 0...humans*2+2) { for (i in 0...humans*2+2) {
@@ -51,4 +55,18 @@ class ClassicGame extends Game {
} }
return state; return state;
} }
override public function next():Option<GameState> {
if (!state.teams[HUMAN].lose) {
state.level++;
if (state.level >= config.levels) state.level = 0;
state.teams[BOT].lose = false;
state.teams[BOT].life = BOT_LIFE;
for (ps in state.teams[HUMAN].players) {
if (ps.life > 0) ps.life++;
}
return Option.Some(state);
}
return Option.None;
}
} }

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
import promhx.Deferred; import promhx.Deferred;
import promhx.Stream; import promhx.Stream;
@@ -95,7 +96,9 @@ class Game implements EngineListener {
for (team in teams) { for (team in teams) {
for (player in team.players) { for (player in team.players) {
spawners.get(team.id).push(player.id); if (trySpawn(player.id)) {
spawners.get(team.id).push(player.id);
}
} }
var eaglePoint = spawners.get(team.id).getPoint('eagle'); var eaglePoint = spawners.get(team.id).getPoint('eagle');
if (eaglePoint != null) { if (eaglePoint != null) {
@@ -109,15 +112,23 @@ class Game implements EngineListener {
} }
private function spawn(task:SpawnTask):Void { private function spawn(task:SpawnTask):Void {
var tank = buildTank(task.playerId, config.getTank(task.playerId.team, '0'), task.point); getPlayer(task.playerId).tankId = 0;
var player:Player = teams.get(task.playerId.team).players[task.playerId.index]; if (trySpawn(task.playerId, true)) {
engine.spawn(tank); var tank = buildTank(task.playerId, config.getTank(task.playerId.team, '0'), task.point);
player.tankId = tank.id; var player:Player = getPlayer(task.playerId);
engine.spawn(tank);
player.tankId = tank.id;
} else if (!isTeamAlive(task.playerId.team)) {
state.teams[task.playerId.team].lose = true;
complete();
}
deferred.resolve(state);
} }
private function complete():Void { private function complete():Void {
for (team in teams.iterator()) { for (team in teams.iterator()) {
for (player in team.players) { for (player in team.players) {
player.control.action(TankAction.STOP);
player.control.dispose(); player.control.dispose();
} }
} }
@@ -157,28 +168,51 @@ class Game implements EngineListener {
} }
} }
private function calcTeamLife(ts:TeamState):Int { private function isTeamAlive(team:TeamId):Bool {
return Lambda.fold(ts.players, function(ps, t) return t + ps.life, ts.life); var ts:TeamState = state.teams[team];
var life:Int = Lambda.fold(ts.players, function(ps, t) return t + ps.life, ts.life);
if (life > 0) {
return true;
} else {
for (player in teams[team].players) {
if (player.tankId > 0) {
return true;
}
}
if (spawners[team].active) {
return true;
}
}
return false;
}
private function trySpawn(player:PlayerId, spawn:Bool = false):Bool {
var ts:TeamState = state.teams[player.team];
var ps:PlayerState = ts.players[player.index];
var result = false;
if (ps.life > -1) {
if (ps.life > 0) {
if (spawn) ps.life--;
result = true;
}
} else if (ts.life > -1) {
if (ts.life > 0) {
if (spawn) ts.life--;
result = true;
}
}
return result;
} }
public function onDestroy(entity:EntityType):Void { public function onDestroy(entity:EntityType):Void {
switch (entity) { switch (entity) {
case EntityType.TANK(tank): case EntityType.TANK(tank):
var respawn:Bool = false; getPlayer(tank.playerId).tankId = 0;
var teamState:TeamState = state.teams[tank.playerId.team]; var respawn:Bool = trySpawn(tank.playerId);
if (teamState.life > 0) {
teamState.life--;
respawn = true;
} else {
var playerState:PlayerState = teamState.players[tank.playerId.index];
if (playerState.life > 0) {
playerState.life--;
respawn = true;
}
}
if (respawn) { if (respawn) {
spawners.get(tank.playerId.team).push(tank.playerId); spawners.get(tank.playerId.team).push(tank.playerId);
} else if (calcTeamLife(teamState) < 1) { }
if (!isTeamAlive(tank.playerId.team)) {
state.teams[tank.playerId.team].lose = true; state.teams[tank.playerId.team].lose = true;
complete(); complete();
} }
@@ -197,6 +231,11 @@ class Game implements EngineListener {
} }
public function next():Option<GameState> {
return Option.None;
}
public function dispose():Void { public function dispose():Void {
engine.dispose(); engine.dispose();
} }

View File

@@ -14,6 +14,8 @@ typedef SpawnTask = {
class Spawner { class Spawner {
public var active(get, never):Bool;
private var config:TeamConfig; private var config:TeamConfig;
private var runner:SpawnTask -> Void; private var runner:SpawnTask -> Void;
private var queue:Array<SpawnTask>; private var queue:Array<SpawnTask>;
@@ -80,4 +82,8 @@ class Spawner {
runner(queue.shift()); runner(queue.shift());
} }
} }
private function get_active():Bool {
return queue.length > 0;
}
} }