7 Commits
0.8.1 ... 0.8.3

Author SHA1 Message Date
0f5cf7fdc5 [client] fix app icon 2019-03-14 21:26:57 +03:00
426b2718bb [common] game update 2019-03-14 17:49:47 +03:00
8ea862a118 [common] add GameState 2019-03-14 12:58:00 +03:00
1f87a71833 [build] disable server build 2019-03-13 21:17:31 +03:00
56c2cd9437 [client] small fixes 2019-03-13 21:10:46 +03:00
85e5f9a553 [common] add GameStart 2019-03-13 17:11:20 +03:00
d9915120d4 [client] update haxework. ep8 2019-03-13 13:06:48 +03:00
53 changed files with 5545 additions and 2039 deletions

2
gen.sh
View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
haxelib run protohx generate protohx.json haxelib run protohx generate protohx.json
haxelib run orm mysql://shmyga:xkbp8jh9z2@localhost:3306/armageddon \ haxelib run orm mysql://shmyga:password@localhost:3306/armageddon \
-s src-gen/haxe \ -s src-gen/haxe \
-c ru.m.tankz.db \ -c ru.m.tankz.db \
-a ru.m.tankz.db -a ru.m.tankz.db

View File

@@ -34,7 +34,7 @@ const config = new Project.Config({
meta: { meta: {
title: 'Tank\'z', title: 'Tank\'z',
filename: 'tankz', filename: 'tankz',
icon: 'src/client/resources/image/tank/pd-0.png', icon: 'src/client/resources/icon.png',
pack: 'ru.m.tankz', pack: 'ru.m.tankz',
author: 'shmyga <shmyga.z@gmail.com>', author: 'shmyga <shmyga.z@gmail.com>',
company: 'MegaLoMania', company: 'MegaLoMania',
@@ -70,6 +70,10 @@ const client = new Project(
sources: ['src/client/haxe'], sources: ['src/client/haxe'],
main: 'ru.m.tankz.Client', main: 'ru.m.tankz.Client',
assets: ['src/client/resources'], assets: ['src/client/resources'],
meta: {
width: 1024,
height: 768,
},
flags: [ flags: [
//'dom', //'dom',
//'dev_layout', //'dev_layout',
@@ -90,7 +94,14 @@ const editor = new Project(
sources: ['src/client/haxe', 'src/editor/haxe'], sources: ['src/client/haxe', 'src/editor/haxe'],
main: 'ru.m.tankz.editor.Editor', main: 'ru.m.tankz.editor.Editor',
assets: ['src/client/resources'], assets: ['src/client/resources'],
meta: {filename: 'editor'} meta: {
filename: 'editor',
width: 1024,
height: 800,
},
flags: [
//'dev_layout',
]
}) })
).bind(module, gulp); ).bind(module, gulp);
@@ -117,7 +128,7 @@ module.exports.default = gulp.series(
module.exports['client:linux:build'], module.exports['client:linux:build'],
//module.exports['client:android:build'], //module.exports['client:android:build'],
module.exports['editor:flash:build'], module.exports['editor:flash:build'],
module.exports['server:neko:build'], //module.exports['server:neko:build'],
module.exports['client:flash:html'], module.exports['client:flash:html'],
module.exports['client:linux:deb'], module.exports['client:linux:deb'],
); );

6518
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
{ {
"name": "tankz", "name": "tankz",
"version": "0.8.1", "version": "0.8.3",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"dateformat": "^3.0.3", "dateformat": "^3.0.3",
"gulp": "^4.0.0", "gulp": "^4.0.0",
"gulp-add": "0.0.2", "gulp-add": "0.0.2",
"gulp-clean": "^0.4.0", "gulp-clean": "^0.4.0",
"gulp-haxetool": "^0.0.14" "gulp-haxetool": "^0.0.16"
}, },
"haxeDependencies": { "haxeDependencies": {
"haxework": "git@bitbucket.org:shmyga/haxework.git", "haxework": "git@bitbucket.org:shmyga/haxework.git",

View File

@@ -48,7 +48,7 @@ class Client {
public function init():Void { public function init():Void {
var font:Font = Font.enumerateFonts()[0]; var font:Font = Font.enumerateFonts()[0];
resources.text.put('font', 'Bookman Old Style'); resources.text.put('font', 'Bookman Old Style');
resources.text.put('version', 'v${Const.VERSION} b${Const.BUILD}'); resources.text.put('version', 'v${Const.VERSION} (${Const.BUILD})');
Provider.set(FrameSwitcher, switcher); Provider.set(FrameSwitcher, switcher);
} }

View File

@@ -15,7 +15,6 @@ import ru.m.tankz.network.NetworkManager;
import ru.m.tankz.proto.pack.Request; import ru.m.tankz.proto.pack.Request;
import ru.m.tankz.proto.pack.Response; import ru.m.tankz.proto.pack.Response;
import ru.m.tankz.sound.SoundManager; import ru.m.tankz.sound.SoundManager;
import ru.m.tankz.storage.SaveStorage;
import ru.m.tankz.storage.UserStorage; import ru.m.tankz.storage.UserStorage;
#if flash #if flash
import flash.Lib; import flash.Lib;
@@ -46,7 +45,6 @@ class Init {
Provider.setFactory(IResources, Resources); Provider.setFactory(IResources, Resources);
Provider.setFactory(ILevelBundle, LevelBundle); Provider.setFactory(ILevelBundle, LevelBundle);
Provider.setFactory(IConfigBundle, ConfigBundle); Provider.setFactory(IConfigBundle, ConfigBundle);
Provider.setFactory(SaveStorage, SaveStorage);
Provider.setFactory(UserStorage, UserStorage); Provider.setFactory(UserStorage, UserStorage);
Provider.setFactory(SettingsStorage, SettingsStorage); Provider.setFactory(SettingsStorage, SettingsStorage);
Provider.setFactory(SoundManager, SoundManager); Provider.setFactory(SoundManager, SoundManager);

View File

@@ -16,9 +16,20 @@ class Style {
private static var fontFamily = "Courirer New"; private static var fontFamily = "Courirer New";
public static function register() { public static function register() {
resources.skin.put("light", [Skin.color(lightColor)]); resources.skin.put("light", [
resources.skin.put("dark", [Skin.color(darkColor)]); Skin.color(lightColor),
resources.skin.put("text", [Skin.text(textColor, 16, fontFamily)]); ]);
resources.skin.put("dark", [
Skin.color(darkColor),
]);
resources.skin.put("text", [
Skin.text(textColor, 16, fontFamily),
]);
resources.skin.put("text.header", [
Skin.color(lightColor),
Skin.text(textColor, 22, fontFamily),
Skin.size(200, 38),
]);
resources.skin.put("button", [ resources.skin.put("button", [
Skin.buttonColor(lightColor), Skin.buttonColor(lightColor),
Skin.text(textColor, 18, fontFamily), Skin.text(textColor, 18, fontFamily),

View File

@@ -4,26 +4,20 @@ layout.hAlign: center
layout.vAlign: middle layout.vAlign: middle
views: views:
- $type: haxework.gui.LabelView - $type: haxework.gui.LabelView
skinId: text skinId: text.header
geometry.size.fixed.height: 20
text: Settings text: Settings
- $type: haxework.gui.HGroupView - $type: haxework.gui.HGroupView
geometry.size.width: 100% layout.margin: 20
views: views:
- $type: ru.m.tankz.frame.settings.SettingsEditor - $type: ru.m.tankz.frame.settings.SettingsEditor
geometry.size.percent.width: 50
#geometry.size.percent.height: 100
controlIndex: 0 controlIndex: 0
- $type: ru.m.tankz.frame.settings.SettingsEditor - $type: ru.m.tankz.frame.settings.SettingsEditor
geometry.size.percent.width: 50
#geometry.size.percent.height: 100
controlIndex: 1 controlIndex: 1
- id: close - id: close
$type: haxework.gui.ButtonView $type: haxework.gui.ButtonView
skinId: button.close skinId: button.close
+onPress: $this:onPress +onPress: $this:onPress
geometry.position: absolute geometry.position: absolute
geometry.margin.left: 10 geometry.margin: 10
geometry.margin.bottom: 10
geometry.vAlign: bottom geometry.vAlign: bottom
geometry.hAlign: left geometry.hAlign: left

View File

@@ -5,14 +5,12 @@ import ru.m.tankz.frame.dota.DotaLevelFrame;
import haxework.gui.ButtonView; import haxework.gui.ButtonView;
import haxework.gui.frame.FrameSwitcher; import haxework.gui.frame.FrameSwitcher;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import ru.m.tankz.storage.SaveStorage;
@:template class StartFrame extends VGroupView { @:template class StartFrame extends VGroupView {
public static var ID(default, never):String = "start"; public static var ID(default, never):String = "start";
@:provide var frameSwitcher:FrameSwitcher; @:provide var frameSwitcher:FrameSwitcher;
@:provide var storage:SaveStorage;
public function onPress(view:ButtonView):Void { public function onPress(view:ButtonView):Void {
switch (view.id) { switch (view.id) {

View File

@@ -3,10 +3,10 @@ geometry.size.stretch: true
layout.hAlign: center layout.hAlign: center
layout.vAlign: middle layout.vAlign: middle
views: views:
- $type: haxework.gui.ImageView - $type: haxework.gui.ImageView
image: $asset:image:resources/image/ui/logo.png image: $asset:image:resources/image/ui/logo.png
geometry.margin.bottom: 15 geometry.margin.bottom: 15
- $type: haxework.gui.VGroupView - $type: haxework.gui.VGroupView
layout.margin: 3 layout.margin: 3
views: views:
- id: classic - id: classic
@@ -26,19 +26,17 @@ views:
text: Network (in developing) text: Network (in developing)
fontColor: 0xff0000 fontColor: 0xff0000
visible: false visible: false
- $type: haxework.gui.LabelView - $type: haxework.gui.LabelView
skinId: text skinId: text
geometry.position: absolute geometry.position: absolute
geometry.margin.right: 10 geometry.margin: 10
geometry.margin.bottom: 10
geometry.vAlign: bottom geometry.vAlign: bottom
geometry.hAlign: right geometry.hAlign: right
text: $r:text:version text: $r:text:version
- id: settings - id: settings
$type: haxework.gui.ButtonView $type: haxework.gui.ButtonView
geometry.position: absolute geometry.position: absolute
geometry.margin.left: 10 geometry.margin: 10
geometry.margin.bottom: 10
geometry.vAlign: bottom geometry.vAlign: bottom
geometry.hAlign: left geometry.hAlign: left
skinId: button.settings skinId: button.settings

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.frame.classic; package ru.m.tankz.frame.classic;
import haxework.gui.LabelView;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import ru.m.tankz.frame.common.IGamePanel; import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.frame.common.LifeView; import ru.m.tankz.frame.common.LifeView;
@@ -11,16 +12,21 @@ import ru.m.tankz.preset.ClassicGame;
@:view var bot:LifeView; @:view var bot:LifeView;
@:view var player1:LifeView; @:view var player1:LifeView;
@:view var player2:LifeView; @:view var player2:LifeView;
@:view var level:LabelView;
public var game:Game; public var game:Game;
private function updateViews():Void { private function updateViews():Void {
bot.count.text = '${game.teams[ClassicGame.BOT].life}'; level.text = 'Level: ${game.state.level}';
player1.count.text = '${game.teams[ClassicGame.HUMAN].players[0].state.life}'; bot.live = game.teams[ClassicGame.BOT].life;
player1.live = game.teams[ClassicGame.HUMAN].players[0].state.life;
player1.score = game.teams[ClassicGame.HUMAN].players[0].state.score;
if (game.teams[ClassicGame.HUMAN].players[1] != null) { if (game.teams[ClassicGame.HUMAN].players[1] != null) {
player2.count.text = '${game.teams[ClassicGame.HUMAN].players[1].state.life}'; player2.visible = true;
player2.live = game.teams[ClassicGame.HUMAN].players[1].state.life;
player2.score = game.teams[ClassicGame.HUMAN].players[1].state.score;
} else { } else {
player2.count.text = ""; player2.visible = false;
} }
} }

View File

@@ -1,16 +1,26 @@
--- ---
geometry.padding: 5 geometry.padding: 5
geometry.size.height: 100%
layout.margin: 5 layout.margin: 5
layout.hAlign: right layout.hAlign: right
views: views:
- id: level
$type: haxework.gui.LabelView
skinId: text.box
geometry.size.height: 38
geometry.padding: [20, 0]
geometry.hAlign: center
- $type: haxework.gui.SpriteView
geometry.size.height: 50%
- id: bot - id: bot
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
image.image: $asset:image:resources/image/tank/ba-0.png tank: ba
scoreLabel.visible: false
- id: player1 - id: player1
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
image.image: $asset:image:resources/image/tank/pa-0.png tank: pa
image.color: 0xFFFF00 color: 0xFFFF00
- id: player2 - id: player2
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
image.image: $asset:image:resources/image/tank/pa-0.png tank: pa
image.color: 0x15C040 color: 0x15C040

View File

@@ -1,7 +1,8 @@
package ru.m.tankz.frame.classic; package ru.m.tankz.frame.classic;
import haxework.gui.frame.FrameSwitcher; import haxework.gui.ButtonView;
import haxework.gui.DataView; import haxework.gui.DataView;
import haxework.gui.frame.FrameSwitcher;
import haxework.gui.ToggleButtonView; import haxework.gui.ToggleButtonView;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.frame.common.LevelFrame; import ru.m.tankz.frame.common.LevelFrame;
@@ -10,8 +11,8 @@ import ru.m.tankz.preset.ClassicGame;
@:template class ClassicLevelFrame extends LevelFrame { @:template class ClassicLevelFrame extends LevelFrame {
public static inline var ID = "classic.level"; public static inline var ID = "classic.level";
@:view var presets(default, null):DataView<GamePreset>; @:view var presets(default, null):DataView<GamePreset, ToggleButtonView>;
@:view var levels(default, null):DataView<Int>; @:view var levels(default, null):DataView<Int, ButtonView>;
@:provide var frames:FrameSwitcher; @:provide var frames:FrameSwitcher;

View File

@@ -3,8 +3,11 @@ layout:
$type: haxework.gui.layout.VerticalLayout $type: haxework.gui.layout.VerticalLayout
hAlign: center hAlign: center
views: views:
- $type: haxework.gui.LabelView
skinId: text.header
text: Classic
- id: presets - id: presets
$type: haxework.gui.DataView<GamePreset> $type: haxework.gui.DataView
layout: layout:
$type: haxework.gui.layout.HorizontalLayout $type: haxework.gui.layout.HorizontalLayout
hAlign: center hAlign: center
@@ -13,7 +16,7 @@ views:
+onDataSelect: $code:function(value) preset = value +onDataSelect: $code:function(value) preset = value
geometry.padding: 10 geometry.padding: 10
- id: levels - id: levels
$type: haxework.gui.DataView<Int> $type: haxework.gui.DataView
layout: layout:
$type: haxework.gui.layout.TailLayout $type: haxework.gui.layout.TailLayout
rowSize: 10 rowSize: 10

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.frame.common; package ru.m.tankz.frame.common;
import ru.m.tankz.game.GameState;
import flash.events.Event; import flash.events.Event;
import haxe.ds.Option; import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
@@ -7,11 +8,9 @@ import haxework.gui.frame.FrameSwitcher;
import haxework.gui.GroupView; import haxework.gui.GroupView;
import ru.m.tankz.frame.common.IGamePanel; import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
import ru.m.tankz.network.NetworkManager; import ru.m.tankz.network.NetworkManager;
import ru.m.tankz.render.Render; import ru.m.tankz.render.Render;
import ru.m.tankz.sound.SoundManager; import ru.m.tankz.sound.SoundManager;
import ru.m.tankz.storage.SaveStorage;
class GameFrame extends GroupView { class GameFrame extends GroupView {
@@ -23,7 +22,6 @@ class GameFrame extends GroupView {
@:provide var network:NetworkManager; @:provide var network:NetworkManager;
@:provide var sound:SoundManager; @:provide var sound:SoundManager;
@:provide var state:GameState; @:provide var state:GameState;
@:provide var storage:SaveStorage;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
private var game:Game; private var game:Game;
@@ -67,24 +65,15 @@ class GameFrame extends GroupView {
render.reset(); render.reset();
} }
private function onGameStateChange(s:GameState):GameState { private function onGameStateChange(_):Void {
panel.toUpdate(); panel.toUpdate();
return s;
} }
private function onGameComplete(result:Option<GameState>):Void { private function onGameComplete(_):Void {
switch (result) {
case Option.Some(s):
panel.toUpdate();
case Option.None:
}
switch (game.next()) { switch (game.next()) {
case Option.Some(s): case Option.Some(s):
var state = game.save();
this.state = state;
storage.write(state);
stop(); stop();
start(state); start(s);
case Option.None: case Option.None:
switcher.change(StartFrame.ID); switcher.change(StartFrame.ID);
} }

View File

@@ -5,9 +5,7 @@ import haxework.gui.GroupView;
import haxework.resources.IResources; import haxework.resources.IResources;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.storage.SaveStorage;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class LevelFrame extends GroupView { class LevelFrame extends GroupView {
@@ -19,11 +17,10 @@ class LevelFrame extends GroupView {
@:provide var configBundle:IConfigBundle; @:provide var configBundle:IConfigBundle;
@:provide var state:GameState; @:provide var state:GameState;
@:provide var storage:SaveStorage;
@:provide var resources:IResources; @:provide var resources:IResources;
private function set_gameType(value:GameType):GameType { private function set_gameType(value:GameType):GameType {
if (gameType != value) { if (gameType != value || true) { // ToDo:
gameType = value; gameType = value;
config = configBundle.get(gameType); config = configBundle.get(gameType);
preset = config.presets[0]; preset = config.presets[0];
@@ -32,13 +29,13 @@ class LevelFrame extends GroupView {
} }
private function set_preset(value:GamePreset):GamePreset { private function set_preset(value:GamePreset):GamePreset {
if (preset != value) { if (preset != value || true) { // ToDo:
preset = value; preset = value;
state = new GameState(gameType, preset.id); state = new GameState(gameType, preset.id);
for (team in value.teams) { for (team in value.teams) {
for (player in team.players) { for (player in team.players) {
var playerId = new PlayerId(team.id, player.index); var playerId = new PlayerId(team.id, player.index);
state.control.set(playerId, player.control != null ? player.control : Control.BOT); state.players.push(new PlayerState(playerId, player.control, player.life));
} }
} }
} }

View File

@@ -1,20 +0,0 @@
package ru.m.tankz.frame.common;
import haxework.gui.HGroupView;
import haxework.gui.LabelView;
import haxework.gui.list.ListView.IListItemView;
@:template class LevelView extends HGroupView implements IListItemView<Int> {
public var item_index(default, default):Int;
public var data(default, set):Int;
@:view var label(default, null):LabelView;
private function set_data(value:Int):Int {
data = value;
label.text = 'Level ${data}';
return data;
}
}

View File

@@ -1,14 +0,0 @@
---
geometry.size.width: 100%
geometry.size.height: 44
geometry.margin: 5
views:
- id: label
$type: haxework.gui.LabelView
skinId: text
geometry.size.stretch: true
text: ""
skin:
- $type: haxework.gui.skin.ColorSkin
color: 0x000000
alpha: 0.2

View File

@@ -1,10 +1,37 @@
package ru.m.tankz.frame.common; package ru.m.tankz.frame.common;
import openfl.Assets;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.ImageView; import haxework.gui.ImageView;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
@:template class LifeView extends HGroupView { @:template class LifeView extends HGroupView {
@:view public var image:ImageView; @:view("tank") public var tankImage:ImageView;
@:view public var count:LabelView; @:view("live") public var liveLabel:LabelView;
@:view("score") public var scoreLabel:LabelView;
public var tank(null, set):String;
public var color(null, set):Int;
public var live(null, set):Int;
public var score(null, set):Int;
private inline function set_tank(value:String):String {
tankImage.image = Assets.getBitmapData('resources/image/tank/${value}-0.png');
return value;
}
private inline function set_color(value:Int):Int {
tankImage.color = value;
return value;
}
private inline function set_live(value:Int):Int {
liveLabel.text = 'x${value}';
return value;
}
private inline function set_score(value:Int):Int {
scoreLabel.text = '${value}$';
return value;
}
} }

View File

@@ -1,9 +1,13 @@
--- ---
layout.margin: 5 layout.margin: 5
views: views:
- id: image - id: tank
$type: haxework.gui.ImageView $type: haxework.gui.ImageView
- id: count - id: live
$type: haxework.gui.LabelView $type: haxework.gui.LabelView
skinId: text.box skinId: text.box
geometry.size.fixed: [50, 38] geometry.size.fixed: [50, 38]
- id: score
$type: haxework.gui.LabelView
skinId: text.box
geometry.size.fixed: [100, 38]

View File

@@ -1,65 +1,105 @@
package ru.m.tankz.frame.common; package ru.m.tankz.frame.common;
import haxework.color.Color; import ru.m.tankz.control.Control;
import haxework.gui.ButtonView; import haxework.gui.DataView;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.list.ListView; import haxework.gui.skin.ISkin;
import haxework.gui.skin.Skin; import haxework.gui.ToggleButtonView;
import openfl.Assets;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.Type; import ru.m.tankz.Type.TeamId;
@:template class PlayerView extends HGroupView implements IListItemView<PlayerId> { class TeamButton extends ToggleButtonView {
public var team(default, set):TeamId;
public var item_index(default, default):Int; private function set_team(value:TeamId):TeamId {
public var data(default, set):PlayerId; if (team != value) {
team = value;
text = team.substr(0, 1).toUpperCase() + team.substr(1);
}
return team;
}
}
@:view("index") var indexLabel(default, null):LabelView; class TeamSkin implements ISkin<TeamButton> {
@:view var control(default, null):ButtonView;
public var color(default, default):Int;
public function new(color:Int) {
this.color = color;
}
public function draw(view:TeamButton):Void {
view.fontColor = view.on ? 0x000000 : 0xcccccc;
var graphics = view.content.graphics;
graphics.beginFill(view.on ? color : 0x333333);
graphics.lineStyle(1, view.on ? 0x333333 : color);
graphics.drawRect(0, 0, view.width, view.height);
graphics.endFill();
graphics.lineStyle();
}
}
@:template class PlayerView extends HGroupView {
private static inline var NONE:TeamId = "none";
public var item_index(default, set):Int;
public var data(default, set):Array<PlayerState>;
@:view var label(default, null):LabelView;
@:view var teams(default, null):DataView<TeamId, ToggleButtonView>;
@:provide var state:GameState; @:provide var state:GameState;
@:provide var configBundle:IConfigBundle;
private function set_data(value:PlayerId):PlayerId { private var player:PlayerState;
private function teamViewFactory(index:Int, team:TeamId) {
var view = new TeamButton();
view.skin = [new TeamSkin(getTeamColor(team))];
view.geometry.padding = [10, 5];
view.team = team;
view.on = team == NONE;
return view;
}
private function set_data(value:Array<PlayerState>):Array<PlayerState> {
data = value; data = value;
indexLabel.text = '${value.team} ${Std.string(data.index + 1)}'; teams.data = [NONE].concat([for (team in state.preset.teams) team.id]);
var color = 0xffffff;
var config = configBundle.get(state.type);
var preset = config.getPreset(state.presetId);
for (team in preset.teams) {
if (team.id == data.team) {
color = team.color;
for (player in team.players) {
if (player.index == data.index) {
if (!player.color.zero) {
color = player.color;
}
break;
}
}
preset.teams;
}
}
indexLabel.fontColor = color;
var controlType = state.control.get(value);
var image = Assets.getBitmapData('resources/image/ui/control/${controlType}.png');
control.skin = [Skin.buttonBitmap(image)];
indexLabel.update();
return data; return data;
} }
public function toggleControl():Void { private function getTeamColor(teamId:TeamId):Int {
if (data != null && data.index > -1) { var color = 0xcccccc;
var controlType = switch state.control.get(data) { for (team in state.preset.teams) {
case Control.BOT: Control.HUMAN; if (team.id == teamId) {
case Control.HUMAN: Control.BOT; if (!team.color.zero) color = team.color;
case _: Control.BOT; break;
} }
state.control.set(data, controlType); }
this.data = data; return color;
}
private function set_item_index(value:Int):Int {
item_index = value;
label.text = 'Player ${item_index}';
return item_index;
}
private function onTeamSelect(team:TeamId) {
if (player != null) {
player.control = Control.BOT;
player = null;
}
for (p in data) {
if (p.id.team == team && p.control != Control.HUMAN) {
player = p;
player.control = Control.HUMAN;
break;
}
}
for (view in teams.views) {
var button = cast(view, TeamButton);
button.on = team == button.team;
} }
} }
} }

View File

@@ -1,18 +1,15 @@
--- ---
geometry.size.width: 200
geometry.size.height: 44
geometry.margin: 5 geometry.margin: 5
layout.margin: 10 layout.margin: 10
layout.vAlign: middle
views: views:
- id: index - id: label
$type: haxework.gui.LabelView $type: haxework.gui.LabelView
geometry.size.stretch: true skinId: text
skin: - id: teams
- $type: haxework.gui.skin.ColorSkin $type: haxework.gui.DataView
color: 0x000000 factory: $this:teamViewFactory
alpha: 0.2 layout:
shadow: true $type: haxework.gui.layout.HorizontalLayout
shadowColor: 0x000000 margin: 3
- id: control +onDataSelect: $this:onTeamSelect
$type: haxework.gui.ButtonView
+onPress: $code:toggleControl()

View File

@@ -1,43 +1,26 @@
package ru.m.tankz.frame.dota; package ru.m.tankz.frame.dota;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.frame.common.LifeView;
import ru.m.tankz.frame.common.IGamePanel;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
import haxework.gui.LabelView;
import ru.m.tankz.frame.common.IGamePanel;
import ru.m.tankz.frame.common.LifeView;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import ru.m.tankz.preset.DotaGame;
@:template class DotaGamePanel extends HGroupView implements IGamePanel { @:template class DotaGamePanel extends HGroupView implements IGamePanel {
@:view var radiant:LifeView; @:view var radiant:LifeView;
@:view var dire:LifeView; @:view var dire:LifeView;
@:view var level:LabelView;
public var game:Game; public var game:Game;
private function stateString(game:Game):String {
if (game == null) {
return '';
}
var result:Array<String> = [];
result.push('Level: ${game.state.level}');
for (team in game.teams) {
if (game.loser == team.id) {
result.push('${team.id}: LOSE');
} else if (team.life > 0) {
result.push('${team.id}: ${team.life}');
} else {
for (player in team.players) {
if (player.state.life > 0) {
result.push('${player.id.team}${player.id.index}: ${player.state.life}');
}
}
}
}
return '[ ${result.join(' | ')} ]';
}
private function updateViews():Void { private function updateViews():Void {
radiant.count.text = '${game.teams[DotaGame.RADIANT].life}'; level.text = 'Level: ${game.state.level}';
dire.count.text = '${game.teams[DotaGame.DIRE].life}'; radiant.live = game.teams[DotaGame.RADIANT].life;
radiant.score = game.teams[DotaGame.RADIANT].score;
dire.live = game.teams[DotaGame.DIRE].life;
dire.score = game.teams[DotaGame.DIRE].score;
} }
override public function update():Void { override public function update():Void {

View File

@@ -4,11 +4,18 @@ layout.margin: 20
views: views:
- id: radiant - id: radiant
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
image.image: $asset:image:resources/image/tank/bc-0.png tank: bc
image.color: 0xff4422 color: 0xff4422
- $type: haxework.gui.SpriteView - $type: haxework.gui.SpriteView
geometry.size.width: 100% geometry.size.width: 50%
- id: level
$type: haxework.gui.LabelView
skinId: text.box
geometry.size.height: 38
geometry.padding: [20, 0]
- $type: haxework.gui.SpriteView
geometry.size.width: 50%
- id: dire - id: dire
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
image.image: $asset:image:resources/image/tank/bc-0.png tank: bc
image.color: 0x3284ff color: 0x3284ff

View File

@@ -1,36 +1,31 @@
package ru.m.tankz.frame.dota; package ru.m.tankz.frame.dota;
import haxework.gui.ButtonView;
import haxework.gui.DataView; import haxework.gui.DataView;
import haxework.gui.frame.FrameSwitcher; import haxework.gui.frame.FrameSwitcher;
import ru.m.tankz.frame.common.LevelFrame; import ru.m.tankz.frame.common.LevelFrame;
import ru.m.tankz.frame.common.PlayerView; import ru.m.tankz.frame.common.PlayerView;
import ru.m.tankz.game.GameState;
import ru.m.tankz.preset.DotaGame; import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.Type;
@:template class DotaLevelFrame extends LevelFrame { @:template class DotaLevelFrame extends LevelFrame {
public static inline var ID = "dota.level"; public static inline var ID = "dota.level";
@:view var levels(default, null):DataView<Int>; @:view var levels(default, null):DataView<Int, ButtonView>;
@:view var players(default, null):DataView<PlayerId>; @:view var players(default, null):DataView<Array<PlayerState>, PlayerView>;
@:provide var frames:FrameSwitcher; @:provide var frames:FrameSwitcher;
private function onShow():Void { private function onShow():Void {
gameType = DotaGame.TYPE; gameType = DotaGame.TYPE;
levels.data = [for (i in 0...config.game.levels) i]; levels.data = [for (i in 0...config.game.levels) i];
var data = []; players.data = [for (i in 0...2) state.players];
for (team in preset.teams) {
for (p in team.players) {
data.push(new PlayerId(team.id, p.index));
}
}
players.data = data;
} }
private function playerViewFactory(index:Int, player:PlayerId):PlayerView { private function playerViewFactory(index:Int, data:Array<PlayerState>):PlayerView {
var view = new PlayerView(); var view = new PlayerView();
view.item_index = index; view.item_index = index;
view.data = player; view.data = data;
return view; return view;
} }

View File

@@ -1,16 +1,20 @@
--- ---
layout: layout:
$type: haxework.gui.layout.HorizontalLayout $type: haxework.gui.layout.VerticalLayout
hAlign: center
views: views:
- $type: haxework.gui.LabelView
skinId: text.header
text: DotA
- id: players - id: players
$type: haxework.gui.DataView<PlayerId> $type: haxework.gui.DataView
layout: layout:
$type: haxework.gui.layout.VerticalLayout $type: haxework.gui.layout.VerticalLayout
hAlign: center hAlign: center
factory: $this:playerViewFactory factory: $this:playerViewFactory
geometry.padding: 10 geometry.padding: 10
- id: levels - id: levels
$type: haxework.gui.DataView<Int> $type: haxework.gui.DataView
layout: layout:
$type: haxework.gui.layout.TailLayout $type: haxework.gui.layout.TailLayout
rowSize: 5 rowSize: 5

View File

@@ -14,7 +14,7 @@ import ru.m.tankz.storage.SettingsStorage;
public var controlIndex(default, set): Int; public var controlIndex(default, set): Int;
@:view var label:LabelView; @:view var label:LabelView;
@:view var list:DataView<ActionItem>; @:view var list:DataView<ActionItem, ActionView>;
@:view var change:ButtonView; @:view var change:ButtonView;
@:view var clear:ButtonView; @:view var clear:ButtonView;
@:view var reset:ButtonView; @:view var reset:ButtonView;

View File

@@ -23,7 +23,7 @@ views:
skinId: button.simple skinId: button.simple
text: Reset text: Reset
- id: list - id: list
$type: haxework.gui.DataView<ru.m.tankz.control.ActionItem> $type: haxework.gui.DataView
layout: layout:
$type: haxework.gui.layout.VerticalLayout $type: haxework.gui.layout.VerticalLayout
factory: $this:viewFactory factory: $this:viewFactory

View File

@@ -44,7 +44,7 @@ class SoundManager {
play('bullet_hit'); play('bullet_hit');
//case [EntityType.TANK(_), EntityChange.LIVE_UP]: //case [EntityType.TANK(_), EntityChange.LIVE_UP]:
// play('live'); // play('live');
case [EntityType.EAGLE(_), EntityChange.DEATH]: case [EntityType.EAGLE(_), EntityChange.DEATH(_)]:
play('boom_player'); play('boom_player');
case _: case _:
} }

View File

@@ -1,33 +0,0 @@
package ru.m.tankz.storage;
import flash.net.SharedObject;
import ru.m.tankz.game.GameState;
import ru.m.tankz.Type;
class SaveStorage {
private static var TAG(default, never):String = 'SaveStorage';
private var so:SharedObject;
public function new() {
so = SharedObject.getLocal('tankz');
}
public function read(type:GameType):Null<GameState> {
var data:String = Reflect.getProperty(so.data, type);
L.d(TAG, 'read: ${data}');
if (data != null) {
return GameState.fromYaml(data);
}
return null;
}
public function write(save:GameState):Void {
var data:String = save.toYaml();
L.d(TAG, 'write: ${data}');
so.setProperty(save.type, data);
so.flush();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,8 +1,5 @@
package ru.m.tankz; package ru.m.tankz;
import haxe.io.Bytes;
import haxe.crypto.Crc32;
typedef Type = Dynamic; typedef Type = Dynamic;
typedef GameType = String; typedef GameType = String;
@@ -17,20 +14,20 @@ typedef TankType = String;
typedef BonusType = String; typedef BonusType = String;
class PlayerId { abstract PlayerId(Array<Dynamic>) {
public var team(default, null):TeamId; public var team(get, never):TeamId;
public var index(default, null):Int; public var index(get, never):Int;
private var _hashCode(default, null):Int;
public function new(team:TeamId, index:Int) { public function new(team:TeamId, index:Int) {
this.team = team; this = [team, index];
this.index = index;
this._hashCode = Crc32.make(Bytes.ofString('${team}-${index}'));
} }
public function hashCode():Int { private inline function get_team():TeamId return this[0];
return _hashCode;
private inline function get_index():Int return this[1];
@:to public inline function toString():String {
return '${team}:${index}';
} }
} }

View File

@@ -78,9 +78,14 @@ typedef PlayerConfig = {
@:optional var control:ControlType; @:optional var control:ControlType;
} }
typedef EagleConfig = {
@:optional var score:Int;
}
typedef TeamConfig = { typedef TeamConfig = {
var id:TeamId; var id:TeamId;
var players:Array<PlayerConfig>; var players:Array<PlayerConfig>;
@:optional var eagle:EagleConfig;
@:optional var life:Int; @:optional var life:Int;
@:optional var spawnInterval:Int; @:optional var spawnInterval:Int;
@:optional var color:Color; @:optional var color:Color;

View File

@@ -1,19 +1,27 @@
package ru.m.tankz.core; package ru.m.tankz.core;
import ru.m.tankz.config.Config.EagleConfig;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class Eagle extends Entity { class Eagle extends Entity {
public var team(default, null):TeamId; public var team(default, null):TeamId;
public var config(default, null):EagleConfig;
public var death(default, default):Bool; public var death(default, default):Bool;
public var protect(default, null):Modificator; public var protect(default, null):Modificator;
public function new(team:TeamId) { public var score(get, null):Int;
public function new(team:TeamId, config:EagleConfig) {
super(new Rectangle(0, 0, 44, 44)); // ToDo: hardcode size super(new Rectangle(0, 0, 44, 44)); // ToDo: hardcode size
this.team = team; this.team = team;
this.config = config;
this.death = false; this.death = false;
this.protect = new Modificator(); this.protect = new Modificator();
} }
private inline function get_score():Int {
return config != null ? config.score : 0;
}
} }

View File

@@ -17,7 +17,7 @@ import ru.m.tankz.Type;
enum EntityChange { enum EntityChange {
HIT; HIT;
TYPE; TYPE;
DEATH; DEATH(playerId:PlayerId);
PROTECT; PROTECT;
FREEZING; FREEZING;
} }
@@ -74,7 +74,7 @@ class CollisionProcessor {
if (!eagle.protect.active) { if (!eagle.protect.active) {
eagle.death = true; eagle.death = true;
// ToDo: change // ToDo: change
engine.change(eagle, EntityChange.DEATH); engine.change(eagle, EntityChange.DEATH(bullet.playerId));
} }
case _: case _:
} }

View File

@@ -5,7 +5,6 @@ import haxe.Timer;
import haxework.provider.Provider; import haxework.provider.Provider;
import promhx.Deferred; import promhx.Deferred;
import promhx.Stream; import promhx.Stream;
import ru.m.geom.Direction;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.bundle.ILevelBundle;
@@ -22,24 +21,24 @@ import ru.m.tankz.game.GameState;
import ru.m.tankz.game.Spawner; import ru.m.tankz.game.Spawner;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class Game { class Game {
private static var TAG(default, never):String = 'Game'; private static var TAG(default, never):String = 'Game';
public var type(default, null):GameType; public var type(default, null):GameType;
public var state(default, null):GameState;
public var preset(default, null):GamePreset;
public var teams(default, null):Map<TeamId, Team>; public var teams(default, null):Map<TeamId, Team>;
public var config(default, null):Config; public var config(default, null):Config;
public var engine(default, null):Engine; public var engine(default, null):Engine;
public var loser(default, null):Null<TeamId>; public var loser(default, null):Null<TeamId>;
public var state(default, null):GameState;
private var points:Array<SpawnPoint>; private var points:Array<SpawnPoint>;
private var deferred:Deferred<GameState>; private var deferred:Deferred<GameState>;
private var stream:Stream<GameState>; private var stream:Stream<GameState>;
@:provide var configBundle:IConfigBundle; @:provide var configBundle:IConfigBundle;
@:provide var levelBundle:ILevelBundle;
public function new(type:GameType) { public function new(type:GameType) {
this.type = type; this.type = type;
@@ -84,20 +83,25 @@ class Game {
public function start(state:GameState):Stream<GameState> { public function start(state:GameState):Stream<GameState> {
this.state = state; this.state = state;
this.loser = null; this.loser = null;
this.preset = config.getPreset(state.presetId);
this.deferred = new Deferred(); this.deferred = new Deferred();
var level:LevelConfig = Provider.get(ILevelBundle).get(type, config, state.level); var level:LevelConfig = levelBundle.get(type, config, state.level);
points = level.points != null ? level.points : config.points; points = level.points != null ? level.points : config.points;
engine.map.setData(level.data); engine.map.setData(level.data);
teams = new Map<TeamId, Team>(); teams = new Map<TeamId, Team>();
var controlFactory:IControlFactory = Provider.build(IControlFactory); var controlFactory:IControlFactory = Provider.build(IControlFactory);
for (teamConfig in preset.teams) { var players = state.players.slice(0);
for (teamConfig in state.preset.teams) {
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id); var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
var team:Team = new Team(teamConfig, teamPoints, state); var team:Team = new Team(teamConfig, teamPoints);
teams[team.id] = team; teams[team.id] = team;
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
var controlType: ControlType = state.control.get(player.id); var controlType:ControlType = Control.BOT;
if (controlType != null) { var nextPlayer:PlayerState = Lambda.find(players, function(p) return p.id != null && p.id.team == team.id);
if (nextPlayer != null) {
player.state = nextPlayer;
players.remove(nextPlayer);
controlType = nextPlayer.control;
}
var control = controlFactory.build(player.id, controlType); var control = controlFactory.build(player.id, controlType);
L.d(TAG, 'control(${player.id} - ${control})'); L.d(TAG, 'control(${player.id} - ${control})');
if (control != null) { if (control != null) {
@@ -105,19 +109,18 @@ class Game {
player.control.bind(engine); player.control.bind(engine);
} }
} }
}
team.spawner.runner = spawn; team.spawner.runner = spawn;
} }
for (team in teams.iterator()) { for (team in teams.iterator()) {
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
if (team.trySpawn(player.id)) { if (team.tryRespawn(player.id)) {
team.spawner.push(player.id, player.state.tank); team.spawner.push(player.id, player.state.tank);
} }
} }
var eaglePoint = team.spawner.getPoint('eagle'); var eaglePoint = team.spawner.getPoint('eagle');
if (eaglePoint != null) { if (eaglePoint != null) {
var eagle = new Eagle(team.id); var eagle = new Eagle(team.id, team.config.eagle);
team.eagleId = eagle.id; team.eagleId = eagle.id;
applyPoint(eagle, eaglePoint); applyPoint(eagle, eaglePoint);
engine.spawn(eagle); engine.spawn(eagle);
@@ -128,18 +131,14 @@ class Game {
} }
private function spawn(task:SpawnTask):Void { private function spawn(task:SpawnTask):Void {
L.d(TAG, 'spawn(${task}'); L.d(TAG, 'spawn(${task})');
var team = getTeam(task.playerId.team); var team = getTeam(task.playerId.team);
var player = getPlayer(task.playerId); var player = getPlayer(task.playerId);
player.tankId = 0; player.tankId = 0;
if (getTeam(task.playerId.team).trySpawn(task.playerId, true)) {
var tank = buildTank(task); var tank = buildTank(task);
player.tankId = tank.id; player.tankId = tank.id;
player.state.tank = tank.config.type; player.state.tank = tank.config.type;
engine.spawn(tank); engine.spawn(tank);
} else if (!team.isAlive) {
lose(team.id);
}
deferred.resolve(state); deferred.resolve(state);
} }
@@ -160,14 +159,17 @@ class Game {
switch (entity) { switch (entity) {
case EntityType.TANK(tank): case EntityType.TANK(tank):
getPlayer(tank.playerId).control.start(); getPlayer(tank.playerId).control.start();
case EntityType.BULLET(bullet):
getPlayer(bullet.playerId).state.shots++;
case _: case _:
} }
} }
public function onChange(entity:EntityType, change:EntityChange):Void { public function onChange(entity:EntityType, change:EntityChange):Void {
switch [entity, change] { switch [entity, change] {
case [EntityType.EAGLE(eagle), EntityChange.DEATH]: case [EntityType.EAGLE(eagle), EntityChange.DEATH(playerId)]:
if (eagle.death) { if (eagle.death) {
getPlayer(playerId).state.score += eagle.score * (eagle.team == playerId.team ? 0 : 1);
lose(eagle.team); lose(eagle.team);
deferred.resolve(state); deferred.resolve(state);
} }
@@ -192,6 +194,8 @@ class Game {
switch [entity, with] { switch [entity, with] {
case [EntityType.TANK(tank), EntityType.BONUS(bonus)]: case [EntityType.TANK(tank), EntityType.BONUS(bonus)]:
applyBonus(tank, bonus); applyBonus(tank, bonus);
case [EntityType.BULLET(bullet), EntityType.TANK(tank)]:
getPlayer(bullet.playerId).state.hits++;
case _: case _:
} }
} }
@@ -203,7 +207,8 @@ class Game {
var player = getPlayer(tank.playerId); var player = getPlayer(tank.playerId);
player.control.stop(); player.control.stop();
player.tankId = 0; //ToDo: ? player.tankId = 0; //ToDo: ?
var respawn:Bool = team.trySpawn(player.id); team.onDestroy(player.id);
var respawn:Bool = team.tryRespawn(player.id);
if (respawn) { if (respawn) {
team.spawner.push(player.id); team.spawner.push(player.id);
} }
@@ -213,8 +218,9 @@ class Game {
if (tank.bonus) { if (tank.bonus) {
spawnBonus(); spawnBonus();
} }
if (tank.config.score > 0 && playerId != null) { if (playerId != null) {
getPlayer(playerId).state.score += tank.config.score; getPlayer(playerId).state.frags++;
getPlayer(playerId).state.score += tank.config.score * (tank.playerId.team == playerId.team ? 0 : 1);
} }
deferred.resolve(state); deferred.resolve(state);
case EntityType.BONUS(bonus): case EntityType.BONUS(bonus):
@@ -241,9 +247,9 @@ class Game {
return Option.None; return Option.None;
} }
} }
state.level++; var level = this.state.level + 1;
if (state.level >= config.game.levels) state.level = 0; if (level >= config.game.levels) level = 0;
return Option.Some(state); return Option.Some(new GameState(type, state.presetId, level, state.players));
} }
public function dispose():Void { public function dispose():Void {
@@ -298,8 +304,4 @@ class Game {
engine.destroy(tank); // :-D engine.destroy(tank); // :-D
} }
} }
public function save():GameState {
return state;
}
} }

View File

@@ -1,33 +1,52 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.game.Player.PlayerState; import ru.m.tankz.bundle.IConfigBundle;
import haxe.ds.HashMap; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class PlayerState {
public var id:PlayerId;
public var tank:TankType;
public var control:ControlType;
public var life:Int;
public var score:Int;
public var frags:Int;
public var shots:Int;
public var hits:Int;
class GameState { public function new(id:PlayerId, control:ControlType = null, life:Int = 0) {
public var type(default, null):GameType; this.id = id;
public var presetId(default, null):PresetId; this.tank = null;
public var control(default, null):HashMap<PlayerId, ControlType>; this.control = control == null ? Control.BOT : control;
public var players(default, null):HashMap<PlayerId, PlayerState>; this.life = life;
public var level(default, default):Int; this.score = 0;
this.frags = 0;
public function new(type:GameType, presetId:PresetId) { this.shots = 0;
this.type = type; this.hits = 0;
this.presetId = presetId; }
this.control = new HashMap(); }
this.players = new HashMap();
this.level = 0; class GameState {
}
public var type:GameType;
public function toYaml():String { public var presetId:PresetId;
//return Yaml.render(this, Renderer.options().setFlowLevel(0)); public var level:Int;
return ""; public var players:Array<PlayerState>;
} public var preset(get, null):GamePreset;
public static function fromYaml(value:String):GameState { @:provide private var configBundle:IConfigBundle;
//var data:Dynamic = Yaml.parse(value, Parser.options().useObjects());
//return new GameState(); public function new(type:GameType, presetId:PresetId, level:Int = 1, players:Array<PlayerState> = null) {
return null; this.type = type;
this.presetId = presetId;
this.level = level;
this.players = players == null ? [] : players;
}
private function get_preset():GamePreset {
var config = configBundle.get(type);
var preset = config.getPreset(presetId);
return preset;
} }
} }

View File

@@ -1,16 +1,10 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.game.GameState;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.Type; import ru.m.tankz.Type;
typedef PlayerState = {
var tank:TankType;
var life:Int;
var score:Int;
}
class Player { class Player {
public var config(default, null):PlayerConfig; public var config(default, null):PlayerConfig;
public var id(default, null):PlayerId; public var id(default, null):PlayerId;
@@ -19,15 +13,11 @@ class Player {
public var isAlive(get, null):Bool; public var isAlive(get, null):Bool;
public var state(default, default):PlayerState; public var state(default, default):PlayerState;
public function new(teamId:TeamId, config:PlayerConfig) { public function new(teamId:TeamId, config:PlayerConfig, state:PlayerState = null) {
this.config = config; this.config = config;
this.id = new PlayerId(teamId, config.index); this.id = new PlayerId(teamId, config.index);
this.control = null; this.control = null;
this.state = { this.state = state == null ? new PlayerState(id) : state;
life: config.life,
tank: null,
score: 0,
}
} }
private function set_tankId(value:Int):Int { private function set_tankId(value:Int):Int {

View File

@@ -69,7 +69,7 @@ class Spawner {
private function run():Void { private function run():Void {
if (timer == null) { if (timer == null) {
timer = new Timer(config.spawnInterval == null ? 1 : config.spawnInterval); timer = new Timer(config.spawnInterval == null ? 500 : config.spawnInterval);
timer.run = spawn; timer.run = spawn;
} }
} }

View File

@@ -3,7 +3,6 @@ package ru.m.tankz.game;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
class Team { class Team {
public var id(default, null):TeamId; public var id(default, null):TeamId;
@@ -12,35 +11,40 @@ class Team {
public var players(default, null):Map<Int, Player>; public var players(default, null):Map<Int, Player>;
public var life(default, default):Int; public var life(default, default):Int;
public var isAlive(get, null):Bool; public var isAlive(get, null):Bool;
public var score(get, null):Int;
public var eagleId(default, default):Int; public var eagleId(default, default):Int;
public function new(config:TeamConfig, points:Array<SpawnPoint>, ?state:GameState) { private var active(default, default):Int;
public function new(config:TeamConfig, points:Array<SpawnPoint>) {
this.id = config.id; this.id = config.id;
this.config = config; this.config = config;
this.players = new Map(); this.players = new Map();
for (playerConfig in config.players) { for (playerConfig in config.players) {
var player:Player = new Player(id, playerConfig); var player:Player = new Player(id, playerConfig);
var state = state.players.get(player.id);
if (state != null) player.state = state;
this.players[playerConfig.index] = player; this.players[playerConfig.index] = player;
} }
this.life = config.life; this.life = config.life;
this.spawner = new Spawner(config, points); this.spawner = new Spawner(config, points);
} }
public function trySpawn(playerId:PlayerId, spawn:Bool = false):Bool { public function tryRespawn(playerId:PlayerId):Bool {
var player:Player = players[playerId.index]; var player:Player = players[playerId.index];
var result = false; var result = player.state.life > 0 || life > active;
if (player.state.life > 0) { active++;
if (spawn) player.state.life--;
result = true;
} else if (life > 0) {
if (spawn) life--;
result = true;
}
return result; return result;
} }
public function onDestroy(playerId:PlayerId) {
active--;
var player:Player = players[playerId.index];
if (player.state.life > 0) {
player.state.life--;
} else {
life--;
}
}
// ToDo: eagle state? // ToDo: eagle state?
private function get_isAlive():Bool { private function get_isAlive():Bool {
if (life > 0) { if (life > 0) {
@@ -56,4 +60,8 @@ class Team {
} }
return false; return false;
} }
private function get_score():Int {
return Lambda.fold(players, function(p:Player, s:Int) return s + p.state.score, 0);
}
} }

View File

@@ -39,6 +39,8 @@ team:
- {<<: *player-slow, index: 2} - {<<: *player-slow, index: 2}
- {<<: *player-fast, index: 3} - {<<: *player-fast, index: 3}
- {<<: *player-slow, index: 4} - {<<: *player-slow, index: 4}
eagle:
score: 500
radiant: &radiant radiant: &radiant
id: radiant id: radiant
color: 0xff4422 color: 0xff4422
@@ -83,6 +85,7 @@ tanks:
<<: *bullet <<: *bullet
speed: 12.0 speed: 12.0
bullets: 1 bullets: 1
score: 100
skin: bc skin: bc
- type: fast - type: fast
@@ -93,6 +96,7 @@ tanks:
<<: *bullet <<: *bullet
speed: 8.0 speed: 8.0
bullets: 1 bullets: 1
score: 100
skin: bb skin: bb
bonuses: bonuses:

View File

@@ -1,13 +1,13 @@
--- ---
$type: haxework.gui.VGroupView $type: haxework.gui.VGroupView
skin: $r:skin:dark skinId: dark
geometry.size.stretch: true geometry.size.stretch: true
layout.hAlign: center layout.hAlign: center
views: views:
# Tabs # Tabs
- id: tabs - id: tabs
$type: haxework.gui.HGroupView $type: haxework.gui.HGroupView
geometry.margin.bottom: -3 geometry.margin.bottom: -2
views: views:
- id: level - id: level
$type: haxework.gui.ToggleButtonView $type: haxework.gui.ToggleButtonView

View File

@@ -1,57 +1,56 @@
package ru.m.tankz.editor.frame; package ru.m.tankz.editor.frame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.util.LevelUtil;
import ru.m.tankz.bundle.IConfigBundle;
import haxework.gui.ButtonView; import haxework.gui.ButtonView;
import haxework.gui.DataView;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.list.ListView;
import haxework.gui.list.VListView;
import haxework.gui.VGroupView; import haxework.gui.VGroupView;
import haxework.provider.Provider; import haxework.provider.Provider;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.editor.FileUtil; import ru.m.tankz.editor.FileUtil;
import ru.m.tankz.editor.level.BrickView; import ru.m.tankz.editor.level.BrickView;
import ru.m.tankz.editor.level.MapEditView; import ru.m.tankz.editor.level.MapEditView;
import ru.m.tankz.editor.level.SpawnPointView; import ru.m.tankz.editor.level.SpawnPointView;
import ru.m.tankz.preset.ClassicGame;
import ru.m.tankz.preset.DotaGame;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.util.LevelUtil;
@:template class LevelFrame extends VGroupView { @:template class LevelFrame extends VGroupView {
public static inline var ID = 'level'; public static inline var ID = 'level';
public static inline var TAG = 'level'; public static inline var TAG = 'level';
@:view var gameClassicButton(default, null):ButtonView; @:view var gameClassicButton:ButtonView;
@:view var gameDotaButton(default, null):ButtonView; @:view var gameDotaButton:ButtonView;
@:view var openButton(default, null):ButtonView; @:view var openButton:ButtonView;
@:view var saveButton(default, null):ButtonView; @:view var saveButton:ButtonView;
@:view var fileNameLabel(default, null):LabelView; @:view var fileNameLabel:LabelView;
@:view var mapView(default, null):MapEditView; @:view var mapView:MapEditView;
@:view var spawnPointList(default, null):VListView<SpawnPoint>; @:view var spawnPointList:DataView<SpawnPoint, SpawnPointView>;
@:view var brickList(default, null):VListView<BrickConfig>; @:view var brickList:DataView<BrickConfig, BrickView>;
private var config:Config; private var config:Config;
public function init():Void { public function init():Void {
var resetSelected = function() { var resetSelected = function() {
for (v in brickList.items) { for (v in brickList.views) {
cast(v, BrickView).selected = false; cast(v, BrickView).selected = false;
} }
for (v in spawnPointList.items) { for (v in spawnPointList.views) {
cast(v, SpawnPointView).selected = false; cast(v, SpawnPointView).selected = false;
} }
}; };
brickList.onItemSelect.connect(function(item:IListItemView<BrickConfig>) { brickList.onItemSelect.connect(function(index:Int, value:BrickConfig, item:BrickView):Void {
mapView.brush = Brush.BRICK(item.data); mapView.brush = Brush.BRICK(item.data);
resetSelected(); resetSelected();
cast(item, BrickView).selected = true; item.selected = true;
}); });
spawnPointList.onItemSelect.connect(function(item:IListItemView<SpawnPoint>) { spawnPointList.onItemSelect.connect(function(index:Int, value:SpawnPoint, item:SpawnPointView):Void {
mapView.brush = Brush.POINT(item.data); mapView.brush = Brush.POINT(item.data);
resetSelected(); resetSelected();
cast(item, SpawnPointView).selected = true; item.selected = true;
}); });
} }
@@ -70,7 +69,7 @@ import ru.m.tankz.Type;
spawnPointList.data = config.points; spawnPointList.data = config.points;
mapView.brush = Brush.BRICK(brickList.data[0]); mapView.brush = Brush.BRICK(brickList.data[0]);
cast(brickList.items[0], BrickView).selected = true; cast(brickList.views[0], BrickView).selected = true;
} }
public function onPress(v:ButtonView):Void { public function onPress(v:ButtonView):Void {

View File

@@ -31,17 +31,24 @@ views:
+onPress: $this:onPress +onPress: $this:onPress
- id: fileNameLabel - id: fileNameLabel
$type: haxework.gui.LabelView $type: haxework.gui.LabelView
# map
- $type: haxework.gui.HGroupView - $type: haxework.gui.HGroupView
views: views:
- id: spawnPointList - id: spawnPointList
$type: haxework.gui.list.VListView<SpawnPoint> $type: haxework.gui.DataView
factory: $code:function() return new ru.m.tankz.editor.level.SpawnPointView() geometry.padding: 3
geometry.size.width: 56 layout:
geometry.size.height: 100% $type: haxework.gui.layout.VerticalLayout
hAlign: center
margin: 5
factory: $code:ru.m.tankz.editor.level.SpawnPointView.factory
- id: mapView - id: mapView
$type: ru.m.tankz.editor.level.MapEditView $type: ru.m.tankz.editor.level.MapEditView
- id: brickList - id: brickList
$type: haxework.gui.list.VListView<BrickConfig> $type: haxework.gui.DataView
factory: $code:function() return new ru.m.tankz.editor.level.BrickView() geometry.padding: 3
geometry.size.width: 30 layout:
geometry.size.height: 100% $type: haxework.gui.layout.VerticalLayout
hAlign: center
margin: 5
factory: $code:ru.m.tankz.editor.level.BrickView.factory

View File

@@ -1,53 +1,14 @@
package ru.m.tankz.editor.level; package ru.m.tankz.editor.level;
import flash.display.Bitmap;
import flash.display.Shape;
import haxework.gui.list.ListView;
import haxework.gui.SpriteView;
import openfl.utils.Assets;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
class BrickView extends BrushView<BrickConfig> {
class BrickView extends SpriteView implements IListItemView<BrickConfig> { override private function resolveSrc(value:BrickConfig):String {
private static var size = 26; return 'resources/image/map/${value.type}.png';
public var item_index(default, default):Int;
public var data(default, set):BrickConfig;
public var selected(default, set):Bool;
private var imageView:Bitmap;
private var selectView:Shape;
public function new() {
super();
setContentSize(size, size);
selectView = createSelectView(size, size);
selectView.visible = false;
content.addChild(selectView);
imageView = new Bitmap();
content.addChild(imageView);
} }
private static function createSelectView(width:Float, height:Float):Shape { public static inline function factory(index:Int, value:BrickConfig) {
var view = new Shape(); return new BrickView(value);
view.graphics.lineStyle(4, 0x33ff00);
view.graphics.drawRect(0, 0, width, height);
view.graphics.lineStyle();
return view;
}
private function set_data(value:BrickConfig):BrickConfig {
data = value;
var src = 'resources/image/map/${value.type}.png';
imageView.bitmapData = Assets.getBitmapData(src);
imageView.x = (width - imageView.width) / 2;
imageView.y = (height - imageView.height) / 2;
return data;
}
private function set_selected(value:Bool):Bool {
selected = value;
selectView.visible = value;
return selected;
} }
} }

View File

@@ -0,0 +1,48 @@
package ru.m.tankz.editor.level;
import flash.display.Shape;
import haxework.gui.ImageView;
import openfl.utils.Assets;
class BrushView<D> extends ImageView {
public var data(default, set):D;
public var selected(default, set):Bool;
private var selectView:Shape;
public function new(data:D = null) {
super();
selectView = new Shape();
selectView.visible = false;
content.addChild(selectView);
if (data != null) {
this.data = data;
}
}
override public function update():Void {
super.update();
selectView.graphics.clear();
selectView.graphics.lineStyle(4, 0x33ff00);
selectView.graphics.drawRect(0, 0, width, height);
selectView.graphics.lineStyle();
}
private function resolveSrc(value:D):String {
return null;
}
private function set_data(value:D):D {
data = value;
var src = resolveSrc(value);
image = Assets.getBitmapData(src);
return data;
}
private function set_selected(value:Bool):Bool {
selected = value;
selectView.visible = value;
return selected;
}
}

View File

@@ -13,7 +13,6 @@ import ru.m.tankz.map.Brick;
import ru.m.tankz.map.LevelMap; import ru.m.tankz.map.LevelMap;
import ru.m.tankz.render.RenderItem; import ru.m.tankz.render.RenderItem;
class SpawnPointEntity extends Entity { class SpawnPointEntity extends Entity {
public var point(default, null):SpawnPoint; public var point(default, null):SpawnPoint;
@@ -77,13 +76,11 @@ class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
} }
} }
enum Brush { enum Brush {
POINT(point:SpawnPoint); POINT(point:SpawnPoint);
BRICK(brick:BrickConfig); BRICK(brick:BrickConfig);
} }
//ToDo: copy paste from ru.m.tankz.render.Render //ToDo: copy paste from ru.m.tankz.render.Render
class MapEditView extends SpriteView { class MapEditView extends SpriteView {
@@ -213,11 +210,7 @@ class MapEditView extends SpriteView {
private function set_config(value:Config):Config { private function set_config(value:Config):Config {
config = value; config = value;
map = new LevelMap(config.map); map = new LevelMap(config.map);
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight); setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight, "map");
//ToDo:
if (parent != null) {
parent.toUpdateParent();
}
return config; return config;
} }

View File

@@ -1,55 +1,17 @@
package ru.m.tankz.editor.level; package ru.m.tankz.editor.level;
import flash.display.Bitmap;
import flash.display.Shape;
import haxework.gui.list.ListView;
import haxework.gui.SpriteView;
import haxework.provider.Provider; import haxework.provider.Provider;
import openfl.utils.Assets;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.editor.level.MapEditView; import ru.m.tankz.editor.level.MapEditView;
class SpawnPointView extends BrushView<SpawnPoint> {
class SpawnPointView extends SpriteView implements IListItemView<SpawnPoint> { override private function resolveSrc(value:SpawnPoint):String {
private static var size = 52; return SpawnPointItem.getSrc(value, Provider.get(Config));
public var item_index(default, default):Int;
public var data(default, set):SpawnPoint;
public var selected(default, set):Bool;
private var imageView:Bitmap;
private var selectView:Shape;
public function new() {
super();
setContentSize(size, size);
selectView = createSelectView(size, size);
selectView.visible = false;
content.addChild(selectView);
imageView = new Bitmap();
content.addChild(imageView);
} }
private static function createSelectView(width:Float, height:Float):Shape { public static inline function factory(index:Int, value:SpawnPoint) {
var view = new Shape(); return new SpawnPointView(value);
view.graphics.lineStyle(4, 0x33ff00);
view.graphics.drawRect(0, 0, width, height);
view.graphics.lineStyle();
return view;
}
private function set_data(value:SpawnPoint):SpawnPoint {
data = value;
var src = SpawnPointItem.getSrc(value, Provider.get(Config));
imageView.bitmapData = Assets.getBitmapData(src);
imageView.x = (width - imageView.width) / 2;
imageView.y = (height - imageView.height) / 2;
return data;
}
private function set_selected(value:Bool):Bool {
selected = value;
selectView.visible = value;
return selected;
} }
} }

View File

@@ -9,7 +9,7 @@ class DbProvider {
private var orm:Orm; private var orm:Orm;
public function new() { public function new() {
var db = new orm.Db("mysql://shmyga:xkbp8jh9z2@localhost:3306/armageddon"); var db = new orm.Db("mysql://shmyga:password@localhost:3306/armageddon");
orm = new Orm(db); orm = new Orm(db);
} }

View File

@@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tank'z</title>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
ul {
position: absolute;
width: 100%;
margin: 0;
padding: 0;
text-align: center;
}
ul > li {
display: inline-block;
}
</style>
</head>
<body>
<div>
<ul>
<li onclick="content.src='flash/index.html'"><button>Flash</button></li>
<li onclick="content.src='html5/index.html'"><button>Html5</button></li>
</ul>
</div>
<iframe id="content" frameborder="0" width="100%" height="100%" src="flash/index.html"></iframe>
</body>
</html>