[client] add RecordFrame
This commit is contained in:
@@ -69,10 +69,6 @@ class Init {
|
||||
controlFactory = new ClientControlFactory();
|
||||
popupManager = new PopupManager();
|
||||
|
||||
for (record in recordStorage) {
|
||||
L.w("RECORD", '${record.id}. ${record.date}');
|
||||
}
|
||||
|
||||
popupManager.showAnimateFactory = function(v) return new UnFadeAnimate(v, 100);
|
||||
popupManager.closeAnimateFactory = function(v) return new FadeAnimate(v, 100);
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ class Render extends SpriteView implements GameListener implements EngineListene
|
||||
var item = new BulletItem(bullet);
|
||||
items.set(bullet.key, item);
|
||||
entryLayer.addChild(item.view);
|
||||
item.update();
|
||||
case BONUS(bonus):
|
||||
var item = new BonusItem(bonus);
|
||||
items.set(bonus.key, item);
|
||||
|
||||
@@ -17,3 +17,5 @@ views:
|
||||
$type: ru.m.tankz.view.ResultFrame
|
||||
- id: settings
|
||||
$type: ru.m.tankz.view.SettingsFrame
|
||||
- id: record
|
||||
$type: ru.m.tankz.view.RecordFrame
|
||||
|
||||
43
src/client/haxe/ru/m/tankz/view/RecordFrame.hx
Normal file
43
src/client/haxe/ru/m/tankz/view/RecordFrame.hx
Normal file
@@ -0,0 +1,43 @@
|
||||
package ru.m.tankz.view;
|
||||
|
||||
import haxework.view.frame.FrameSwitcher;
|
||||
import haxework.view.list.ListView.IListItemView;
|
||||
import haxework.view.list.VListView;
|
||||
import haxework.view.VGroupView;
|
||||
import ru.m.tankz.game.record.GameRecord;
|
||||
import ru.m.tankz.preset.ClassicGame;
|
||||
import ru.m.tankz.preset.DeathGame;
|
||||
import ru.m.tankz.preset.DotaGame;
|
||||
import ru.m.tankz.storage.RecordStorage;
|
||||
import ru.m.tankz.view.classic.ClassicGameFrame;
|
||||
import ru.m.tankz.view.death.DeathGameFrame;
|
||||
import ru.m.tankz.view.dota.DotaGameFrame;
|
||||
|
||||
@:template class RecordFrame extends VGroupView {
|
||||
public static var ID(default, never):String = "record";
|
||||
|
||||
@:view var data:VListView<GameRecord>;
|
||||
|
||||
@:provide var recordStorage:RecordStorage;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
@:provide var record:GameRecord;
|
||||
|
||||
public function onShow():Void {
|
||||
data.data = Lambda.array(recordStorage);
|
||||
}
|
||||
|
||||
private function onRecordSelect(item:IListItemView<GameRecord>):Void {
|
||||
record = item.data;
|
||||
// ToDo: copy@paste from LevelFrame
|
||||
switcher.change(switch record.type {
|
||||
case ClassicGame.TYPE: ClassicGameFrame.ID;
|
||||
case DotaGame.TYPE: DotaGameFrame.ID;
|
||||
case DeathGame.TYPE: DeathGameFrame.ID;
|
||||
case _: StartFrame.ID;
|
||||
});
|
||||
}
|
||||
|
||||
private function close() {
|
||||
switcher.change(StartFrame.ID);
|
||||
}
|
||||
}
|
||||
20
src/client/haxe/ru/m/tankz/view/RecordFrame.yaml
Normal file
20
src/client/haxe/ru/m/tankz/view/RecordFrame.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
views:
|
||||
- $type: haxework.view.VGroupView
|
||||
skinId: container
|
||||
views:
|
||||
- $type: haxework.view.LabelView
|
||||
skinId: text.header
|
||||
text: Records
|
||||
- id: data
|
||||
$type: haxework.view.list.VListView
|
||||
factory: $code:function() return new haxework.view.list.LabelListItem()
|
||||
+onItemSelect: $this:onRecordSelect
|
||||
geometry.margin.top: 20
|
||||
geometry.size.stretch: true
|
||||
- $type: haxework.view.HGroupView
|
||||
skinId: panel
|
||||
views:
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button.close
|
||||
+onPress: $code:close()
|
||||
@@ -11,13 +11,13 @@ import ru.m.tankz.view.popup.FontPopup;
|
||||
public static var ID(default, never):String = "start";
|
||||
|
||||
@:provide var state:GameState;
|
||||
@:provide var swicther:FrameSwitcher;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
|
||||
private var fontPopup:FontPopup;
|
||||
|
||||
private function startGame(type:GameType):Void {
|
||||
state = new GameState(type);
|
||||
swicther.change(LevelFrame.ID);
|
||||
switcher.change(LevelFrame.ID);
|
||||
}
|
||||
|
||||
private function choiceFont():Void {
|
||||
|
||||
@@ -21,13 +21,17 @@ views:
|
||||
skinId: button
|
||||
+onPress: $code:startGame('death')
|
||||
text: DeathMatch
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:switcher.change('record')
|
||||
text: Records
|
||||
- $type: haxework.view.HGroupView
|
||||
skinId: panel
|
||||
views:
|
||||
- id: settings
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button.settings
|
||||
+onPress: $code:swicther.change('settings')
|
||||
+onPress: $code:switcher.change('settings')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.width: 100%
|
||||
- $type: haxework.view.LabelView
|
||||
|
||||
@@ -37,20 +37,20 @@ import ru.m.tankz.view.common.LifeView;
|
||||
switch event {
|
||||
case START(state):
|
||||
refresh(state);
|
||||
case CHANGE(TEAM_LIFE(team, life)):
|
||||
if (team.id == ClassicGame.BOT) {
|
||||
case CHANGE(TEAM_LIFE(teamId, life)):
|
||||
if (teamId == ClassicGame.BOT) {
|
||||
bot.life = life;
|
||||
}
|
||||
case CHANGE(PLAYER_LIFE(player, life)):
|
||||
if (player.id == player1Id) {
|
||||
case CHANGE(PLAYER_LIFE(playerId, life)):
|
||||
if (playerId == player1Id) {
|
||||
player1.life = life;
|
||||
} else if (player.id == player2Id) {
|
||||
} else if (playerId == player2Id) {
|
||||
player2.life = life;
|
||||
}
|
||||
case CHANGE(PLAYER_SCORE(player, score)):
|
||||
if (player.id == player1Id) {
|
||||
case CHANGE(PLAYER_SCORE(playerId, score)):
|
||||
if (playerId == player1Id) {
|
||||
player1.score = score;
|
||||
} else if (player.id == player2Id) {
|
||||
} else if (playerId == player2Id) {
|
||||
player2.score = score;
|
||||
}
|
||||
case _:
|
||||
|
||||
@@ -9,6 +9,8 @@ import ru.m.tankz.game.GameEvent;
|
||||
import ru.m.tankz.game.GameRunner;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.game.IGame;
|
||||
import ru.m.tankz.game.record.GamePlayer;
|
||||
import ru.m.tankz.game.record.GameRecord;
|
||||
import ru.m.tankz.game.record.GameRecorder;
|
||||
import ru.m.tankz.network.NetworkManager;
|
||||
import ru.m.tankz.render.Render;
|
||||
@@ -27,6 +29,7 @@ class GameFrame extends GroupView implements GameListener {
|
||||
@:provide var network:NetworkManager;
|
||||
@:provide var soundManager:SoundManager;
|
||||
@:provide var state:GameState;
|
||||
@:provide var record:GameRecord;
|
||||
@:provide("result") var result:GameState;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
@:provide var gameStorage:GameStorage;
|
||||
@@ -35,6 +38,7 @@ class GameFrame extends GroupView implements GameListener {
|
||||
private var game:IGame;
|
||||
private var runner:GameRunner;
|
||||
private var recorder:GameRecorder;
|
||||
private var player:GamePlayer;
|
||||
|
||||
private function get_render():Render {
|
||||
throw "Not implemented";
|
||||
@@ -45,11 +49,16 @@ class GameFrame extends GroupView implements GameListener {
|
||||
}
|
||||
|
||||
public function onShow():Void {
|
||||
start(state);
|
||||
if (record != null) {
|
||||
play(record);
|
||||
record = null;
|
||||
} else {
|
||||
start(state);
|
||||
}
|
||||
}
|
||||
|
||||
private function start(state:GameState):Void {
|
||||
game = new Game(state.type);
|
||||
game = new Game(state);
|
||||
game.connect(render);
|
||||
game.engine.connect(render);
|
||||
game.connect(soundManager);
|
||||
@@ -66,6 +75,21 @@ class GameFrame extends GroupView implements GameListener {
|
||||
render.draw(game.engine);
|
||||
}
|
||||
|
||||
private function play(record:GameRecord):Void {
|
||||
game = new Game(record.state);
|
||||
game.connect(render);
|
||||
game.engine.connect(render);
|
||||
game.connect(soundManager);
|
||||
//game.connect(this);
|
||||
if (panel != null) {
|
||||
game.connect(panel);
|
||||
}
|
||||
player = new GamePlayer(game, record);
|
||||
player.start();
|
||||
content.addEventListener(Event.ENTER_FRAME, _redraw);
|
||||
render.draw(game.engine);
|
||||
}
|
||||
|
||||
private function stop():Void {
|
||||
content.removeEventListener(Event.ENTER_FRAME, _redraw);
|
||||
if (runner != null) {
|
||||
@@ -83,7 +107,7 @@ class GameFrame extends GroupView implements GameListener {
|
||||
switch event {
|
||||
case GameEvent.COMPLETE(state, winner):
|
||||
// ToDo:
|
||||
//recordStorage.save(recorder.record);
|
||||
recordStorage.save(recorder.record);
|
||||
result = state;
|
||||
this.state = switch runner.next() {
|
||||
case Some(s):
|
||||
|
||||
@@ -35,10 +35,10 @@ import ru.m.tankz.view.common.LifeView;
|
||||
switch event {
|
||||
case START(state):
|
||||
refresh(state);
|
||||
case CHANGE(TEAM_LIFE(team, life)):
|
||||
getLifeView(team.id).life = life;
|
||||
case CHANGE(TEAM_SCORE(team, score)):
|
||||
getLifeView(team.id).score = score;
|
||||
case CHANGE(TEAM_LIFE(teamId, life)):
|
||||
getLifeView(teamId).life = life;
|
||||
case CHANGE(TEAM_SCORE(teamId, score)):
|
||||
getLifeView(teamId).score = score;
|
||||
case _:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,8 +152,9 @@ import ru.m.tankz.map.LevelMap;
|
||||
}
|
||||
|
||||
public function dispose():Void {
|
||||
entities = null;
|
||||
map = null;
|
||||
// ToDo: set to null
|
||||
entities = new Map();
|
||||
//map = null;
|
||||
spawnSignal.dispose();
|
||||
collisionSignal.dispose();
|
||||
moveSignal.dispose();
|
||||
|
||||
@@ -29,13 +29,25 @@ import ru.m.tankz.Type;
|
||||
|
||||
@:provide var configBundle:IConfigBundle;
|
||||
|
||||
public function new(type:GameType) {
|
||||
this.type = type;
|
||||
public function new(state:GameState) {
|
||||
this.type = state.type;
|
||||
this.teams = new Map();
|
||||
this.config = configBundle.get(type);
|
||||
this.engine = new Engine(config);
|
||||
this.builder = new EntityBuilder(config);
|
||||
connect(this);
|
||||
prepare(state);
|
||||
}
|
||||
|
||||
private function prepare(state:GameState):Void {
|
||||
var level:LevelConfig = state.level;
|
||||
var points:Array<SpawnPoint> = level.points != null ? level.points : config.points;
|
||||
engine.map.setData(level.data);
|
||||
for (teamConfig in state.preset.teams) {
|
||||
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
|
||||
var team:Team = new Team(teamConfig, teamPoints, state.teams[teamConfig.id]);
|
||||
teams[team.id] = team;
|
||||
}
|
||||
}
|
||||
|
||||
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
|
||||
|
||||
@@ -30,10 +30,10 @@ enum DestroyEvent {
|
||||
}
|
||||
|
||||
enum ChangeEvent {
|
||||
PLAYER_SCORE(player:Player, value:Int);
|
||||
PLAYER_LIFE(player:Player, value:Int);
|
||||
TEAM_SCORE(team:Team, value:Int);
|
||||
TEAM_LIFE(team:Team, value:Int);
|
||||
PLAYER_SCORE(playerId:PlayerId, value:Int);
|
||||
PLAYER_LIFE(playerId:PlayerId, value:Int);
|
||||
TEAM_SCORE(teamId:TeamId, value:Int);
|
||||
TEAM_LIFE(teamId:TeamId, value:Int);
|
||||
}
|
||||
|
||||
enum GameEvent {
|
||||
|
||||
@@ -23,7 +23,6 @@ class GameRunner implements EngineListener implements GameListener {
|
||||
|
||||
private var game(default, null):IGame;
|
||||
private var gameEventSignal(get, null):Signal<GameEvent>;
|
||||
private var points:Array<SpawnPoint>;
|
||||
|
||||
private var timer:Timer;
|
||||
|
||||
@@ -52,13 +51,7 @@ class GameRunner implements EngineListener implements GameListener {
|
||||
}
|
||||
|
||||
public function start(state:GameState):Void {
|
||||
var level:LevelConfig = state.level;
|
||||
points = level.points != null ? level.points : game.config.points;
|
||||
game.engine.map.setData(level.data);
|
||||
for (teamConfig in state.preset.teams) {
|
||||
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
|
||||
var team:Team = new Team(teamConfig, teamPoints, state.teams[teamConfig.id]);
|
||||
game.teams[team.id] = team;
|
||||
for (team in game.teams.iterator()) {
|
||||
for (player in team.players.iterator()) {
|
||||
var control = controlFactory.build(player.id, AController.fromString(player.config.control));
|
||||
if (control != null) {
|
||||
@@ -67,8 +60,6 @@ class GameRunner implements EngineListener implements GameListener {
|
||||
}
|
||||
}
|
||||
team.spawner.runner = spawn;
|
||||
}
|
||||
for (team in game.teams.iterator()) {
|
||||
for (player in team.players.iterator()) {
|
||||
if (team.tryRespawn(player.id)) {
|
||||
team.spawner.push(player.id);
|
||||
@@ -250,20 +241,20 @@ class GameRunner implements EngineListener implements GameListener {
|
||||
var player = game.getPlayer(playerId);
|
||||
var team = game.getTeam(playerId.team);
|
||||
player.state.score += score;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_SCORE(player, player.state.score)));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_SCORE(team, game.state.getTeamScore(team.id))));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_SCORE(playerId, player.state.score)));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_SCORE(playerId.team, game.state.getTeamScore(team.id))));
|
||||
}
|
||||
|
||||
private function changeLife(playerId:PlayerId, life:Int):Void {
|
||||
var player = game.getPlayer(playerId);
|
||||
player.state.life += life;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_LIFE(player, player.state.life)));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(PLAYER_LIFE(playerId, player.state.life)));
|
||||
}
|
||||
|
||||
private function changeTeamLife(teamId:TeamId, life:Int):Void {
|
||||
var team = game.getTeam(teamId);
|
||||
team.state.life += life;
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_LIFE(team, team.state.life)));
|
||||
gameEventSignal.emit(GameEvent.CHANGE(TEAM_LIFE(teamId, team.state.life)));
|
||||
}
|
||||
|
||||
public function onGameEvent(event:GameEvent):Void {
|
||||
|
||||
@@ -18,13 +18,6 @@ class GamePlayer {
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
public function onGameEvent(event:GameEvent):Void {
|
||||
switch event {
|
||||
case GameEvent.COMPLETE(_, _):
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
public function start():Void {
|
||||
frame = 0;
|
||||
data = record.events.slice(0);
|
||||
@@ -42,15 +35,16 @@ class GamePlayer {
|
||||
if (event.frame <= frame) {
|
||||
events++;
|
||||
game.gameEventSignal.emit(event.event);
|
||||
switch event {
|
||||
switch event.event {
|
||||
case GameEvent.COMPLETE(_, _):
|
||||
stop();
|
||||
case _:
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (event > 0) {
|
||||
if (events > 0) {
|
||||
data = data.slice(events);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.game.record;
|
||||
|
||||
import ru.m.tankz.Type;
|
||||
import com.hurlant.crypto.extra.UUID;
|
||||
import com.hurlant.crypto.prng.Random;
|
||||
|
||||
@@ -11,11 +12,24 @@ typedef EventItem = {
|
||||
class GameRecord {
|
||||
public var id(default, default):String;
|
||||
public var date(default, default):Date;
|
||||
public var type(default, default):GameType;
|
||||
public var presetId(default, default):PresetId;
|
||||
public var levelId(default, default):LevelId;
|
||||
public var events(default, default):Array<EventItem>;
|
||||
|
||||
public var state(get, null):GameState;
|
||||
|
||||
public function new() {
|
||||
this.id = UUID.generateRandom(new Random()).toString();
|
||||
this.date = null;
|
||||
this.events = [];
|
||||
}
|
||||
|
||||
private inline function get_state():GameState {
|
||||
return new GameState(type, presetId, levelId);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return 'GameRecord{id=$id,date=$date,type=$type,preset=$presetId,level=$levelId,events=${events.length}}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@ class GameRecorder implements GameListener {
|
||||
|
||||
public function onGameEvent(event:GameEvent):Void {
|
||||
switch event {
|
||||
case GameEvent.START(_):
|
||||
case GameEvent.START(state):
|
||||
record.type = state.type;
|
||||
record.presetId = state.presetId;
|
||||
record.levelId = state.levelId;
|
||||
start();
|
||||
case GameEvent.COMPLETE(_, _):
|
||||
stop();
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
package ru.m.tankz.network;
|
||||
|
||||
import ru.m.tankz.proto.game.GameChangeProto;
|
||||
import ru.m.tankz.proto.core.GameProto;
|
||||
import ru.m.tankz.Type;
|
||||
import ru.m.tankz.game.Game;
|
||||
|
||||
import ru.m.tankz.proto.core.GameProto;
|
||||
import ru.m.tankz.proto.game.GameChangeProto;
|
||||
|
||||
class NetworkGame extends Game {
|
||||
|
||||
private static var TAG(default, never):String = 'NetworkGame';
|
||||
|
||||
public function new(type:GameType) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
public function load(proto:GameProto):Void {
|
||||
L.w(TAG, 'load: ${proto}');
|
||||
// ToDo:
|
||||
|
||||
@@ -163,7 +163,7 @@ presets:
|
||||
- {<<: *team_human}
|
||||
- id: bot
|
||||
spawnInterval: 3000
|
||||
life: 10
|
||||
life: 1
|
||||
players:
|
||||
- {<<: *bot, index: 0, control: bot-stupid}
|
||||
- {<<: *bot, index: 1, control: bot-stupid}
|
||||
|
||||
Reference in New Issue
Block a user