Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f5cf7fdc5 | |||
| 426b2718bb | |||
| 8ea862a118 | |||
| 1f87a71833 | |||
| 56c2cd9437 | |||
| 85e5f9a553 | |||
| d9915120d4 |
2
gen.sh
2
gen.sh
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
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 \
|
||||
-c ru.m.tankz.db \
|
||||
-a ru.m.tankz.db
|
||||
17
gulpfile.js
17
gulpfile.js
@@ -34,7 +34,7 @@ const config = new Project.Config({
|
||||
meta: {
|
||||
title: 'Tank\'z',
|
||||
filename: 'tankz',
|
||||
icon: 'src/client/resources/image/tank/pd-0.png',
|
||||
icon: 'src/client/resources/icon.png',
|
||||
pack: 'ru.m.tankz',
|
||||
author: 'shmyga <shmyga.z@gmail.com>',
|
||||
company: 'MegaLoMania',
|
||||
@@ -70,6 +70,10 @@ const client = new Project(
|
||||
sources: ['src/client/haxe'],
|
||||
main: 'ru.m.tankz.Client',
|
||||
assets: ['src/client/resources'],
|
||||
meta: {
|
||||
width: 1024,
|
||||
height: 768,
|
||||
},
|
||||
flags: [
|
||||
//'dom',
|
||||
//'dev_layout',
|
||||
@@ -90,7 +94,14 @@ const editor = new Project(
|
||||
sources: ['src/client/haxe', 'src/editor/haxe'],
|
||||
main: 'ru.m.tankz.editor.Editor',
|
||||
assets: ['src/client/resources'],
|
||||
meta: {filename: 'editor'}
|
||||
meta: {
|
||||
filename: 'editor',
|
||||
width: 1024,
|
||||
height: 800,
|
||||
},
|
||||
flags: [
|
||||
//'dev_layout',
|
||||
]
|
||||
})
|
||||
).bind(module, gulp);
|
||||
|
||||
@@ -117,7 +128,7 @@ module.exports.default = gulp.series(
|
||||
module.exports['client:linux:build'],
|
||||
//module.exports['client:android:build'],
|
||||
module.exports['editor:flash:build'],
|
||||
module.exports['server:neko:build'],
|
||||
//module.exports['server:neko:build'],
|
||||
module.exports['client:flash:html'],
|
||||
module.exports['client:linux:deb'],
|
||||
);
|
||||
|
||||
6518
package-lock.json
generated
6518
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "tankz",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.3",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"dateformat": "^3.0.3",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-add": "0.0.2",
|
||||
"gulp-clean": "^0.4.0",
|
||||
"gulp-haxetool": "^0.0.14"
|
||||
"gulp-haxetool": "^0.0.16"
|
||||
},
|
||||
"haxeDependencies": {
|
||||
"haxework": "git@bitbucket.org:shmyga/haxework.git",
|
||||
|
||||
@@ -48,7 +48,7 @@ class Client {
|
||||
public function init():Void {
|
||||
var font:Font = Font.enumerateFonts()[0];
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import ru.m.tankz.network.NetworkManager;
|
||||
import ru.m.tankz.proto.pack.Request;
|
||||
import ru.m.tankz.proto.pack.Response;
|
||||
import ru.m.tankz.sound.SoundManager;
|
||||
import ru.m.tankz.storage.SaveStorage;
|
||||
import ru.m.tankz.storage.UserStorage;
|
||||
#if flash
|
||||
import flash.Lib;
|
||||
@@ -46,7 +45,6 @@ class Init {
|
||||
Provider.setFactory(IResources, Resources);
|
||||
Provider.setFactory(ILevelBundle, LevelBundle);
|
||||
Provider.setFactory(IConfigBundle, ConfigBundle);
|
||||
Provider.setFactory(SaveStorage, SaveStorage);
|
||||
Provider.setFactory(UserStorage, UserStorage);
|
||||
Provider.setFactory(SettingsStorage, SettingsStorage);
|
||||
Provider.setFactory(SoundManager, SoundManager);
|
||||
|
||||
@@ -16,9 +16,20 @@ class Style {
|
||||
private static var fontFamily = "Courirer New";
|
||||
|
||||
public static function register() {
|
||||
resources.skin.put("light", [Skin.color(lightColor)]);
|
||||
resources.skin.put("dark", [Skin.color(darkColor)]);
|
||||
resources.skin.put("text", [Skin.text(textColor, 16, fontFamily)]);
|
||||
resources.skin.put("light", [
|
||||
Skin.color(lightColor),
|
||||
]);
|
||||
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", [
|
||||
Skin.buttonColor(lightColor),
|
||||
Skin.text(textColor, 18, fontFamily),
|
||||
|
||||
@@ -4,26 +4,20 @@ layout.hAlign: center
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- $type: haxework.gui.LabelView
|
||||
skinId: text
|
||||
geometry.size.fixed.height: 20
|
||||
skinId: text.header
|
||||
text: Settings
|
||||
- $type: haxework.gui.HGroupView
|
||||
geometry.size.width: 100%
|
||||
layout.margin: 20
|
||||
views:
|
||||
- $type: ru.m.tankz.frame.settings.SettingsEditor
|
||||
geometry.size.percent.width: 50
|
||||
#geometry.size.percent.height: 100
|
||||
controlIndex: 0
|
||||
- $type: ru.m.tankz.frame.settings.SettingsEditor
|
||||
geometry.size.percent.width: 50
|
||||
#geometry.size.percent.height: 100
|
||||
controlIndex: 1
|
||||
- id: close
|
||||
$type: haxework.gui.ButtonView
|
||||
skinId: button.close
|
||||
+onPress: $this:onPress
|
||||
geometry.position: absolute
|
||||
geometry.margin.left: 10
|
||||
geometry.margin.bottom: 10
|
||||
geometry.margin: 10
|
||||
geometry.vAlign: bottom
|
||||
geometry.hAlign: left
|
||||
|
||||
@@ -5,14 +5,12 @@ import ru.m.tankz.frame.dota.DotaLevelFrame;
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.frame.FrameSwitcher;
|
||||
import haxework.gui.VGroupView;
|
||||
import ru.m.tankz.storage.SaveStorage;
|
||||
|
||||
@:template class StartFrame extends VGroupView {
|
||||
|
||||
public static var ID(default, never):String = "start";
|
||||
|
||||
@:provide var frameSwitcher:FrameSwitcher;
|
||||
@:provide var storage:SaveStorage;
|
||||
|
||||
public function onPress(view:ButtonView):Void {
|
||||
switch (view.id) {
|
||||
|
||||
@@ -3,10 +3,10 @@ geometry.size.stretch: true
|
||||
layout.hAlign: center
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- $type: haxework.gui.ImageView
|
||||
- $type: haxework.gui.ImageView
|
||||
image: $asset:image:resources/image/ui/logo.png
|
||||
geometry.margin.bottom: 15
|
||||
- $type: haxework.gui.VGroupView
|
||||
- $type: haxework.gui.VGroupView
|
||||
layout.margin: 3
|
||||
views:
|
||||
- id: classic
|
||||
@@ -26,19 +26,17 @@ views:
|
||||
text: Network (in developing)
|
||||
fontColor: 0xff0000
|
||||
visible: false
|
||||
- $type: haxework.gui.LabelView
|
||||
- $type: haxework.gui.LabelView
|
||||
skinId: text
|
||||
geometry.position: absolute
|
||||
geometry.margin.right: 10
|
||||
geometry.margin.bottom: 10
|
||||
geometry.margin: 10
|
||||
geometry.vAlign: bottom
|
||||
geometry.hAlign: right
|
||||
text: $r:text:version
|
||||
- id: settings
|
||||
- id: settings
|
||||
$type: haxework.gui.ButtonView
|
||||
geometry.position: absolute
|
||||
geometry.margin.left: 10
|
||||
geometry.margin.bottom: 10
|
||||
geometry.margin: 10
|
||||
geometry.vAlign: bottom
|
||||
geometry.hAlign: left
|
||||
skinId: button.settings
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.frame.classic;
|
||||
|
||||
import haxework.gui.LabelView;
|
||||
import haxework.gui.VGroupView;
|
||||
import ru.m.tankz.frame.common.IGamePanel;
|
||||
import ru.m.tankz.frame.common.LifeView;
|
||||
@@ -11,16 +12,21 @@ import ru.m.tankz.preset.ClassicGame;
|
||||
@:view var bot:LifeView;
|
||||
@:view var player1:LifeView;
|
||||
@:view var player2:LifeView;
|
||||
@:view var level:LabelView;
|
||||
|
||||
public var game:Game;
|
||||
|
||||
private function updateViews():Void {
|
||||
bot.count.text = '${game.teams[ClassicGame.BOT].life}';
|
||||
player1.count.text = '${game.teams[ClassicGame.HUMAN].players[0].state.life}';
|
||||
level.text = 'Level: ${game.state.level}';
|
||||
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) {
|
||||
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 {
|
||||
player2.count.text = "";
|
||||
player2.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
---
|
||||
geometry.padding: 5
|
||||
geometry.size.height: 100%
|
||||
layout.margin: 5
|
||||
layout.hAlign: right
|
||||
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
|
||||
$type: ru.m.tankz.frame.common.LifeView
|
||||
image.image: $asset:image:resources/image/tank/ba-0.png
|
||||
tank: ba
|
||||
scoreLabel.visible: false
|
||||
- id: player1
|
||||
$type: ru.m.tankz.frame.common.LifeView
|
||||
image.image: $asset:image:resources/image/tank/pa-0.png
|
||||
image.color: 0xFFFF00
|
||||
tank: pa
|
||||
color: 0xFFFF00
|
||||
- id: player2
|
||||
$type: ru.m.tankz.frame.common.LifeView
|
||||
image.image: $asset:image:resources/image/tank/pa-0.png
|
||||
image.color: 0x15C040
|
||||
tank: pa
|
||||
color: 0x15C040
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package ru.m.tankz.frame.classic;
|
||||
|
||||
import haxework.gui.frame.FrameSwitcher;
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.DataView;
|
||||
import haxework.gui.frame.FrameSwitcher;
|
||||
import haxework.gui.ToggleButtonView;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.frame.common.LevelFrame;
|
||||
@@ -10,8 +11,8 @@ import ru.m.tankz.preset.ClassicGame;
|
||||
@:template class ClassicLevelFrame extends LevelFrame {
|
||||
public static inline var ID = "classic.level";
|
||||
|
||||
@:view var presets(default, null):DataView<GamePreset>;
|
||||
@:view var levels(default, null):DataView<Int>;
|
||||
@:view var presets(default, null):DataView<GamePreset, ToggleButtonView>;
|
||||
@:view var levels(default, null):DataView<Int, ButtonView>;
|
||||
|
||||
@:provide var frames:FrameSwitcher;
|
||||
|
||||
|
||||
@@ -3,8 +3,11 @@ layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
hAlign: center
|
||||
views:
|
||||
- $type: haxework.gui.LabelView
|
||||
skinId: text.header
|
||||
text: Classic
|
||||
- id: presets
|
||||
$type: haxework.gui.DataView<GamePreset>
|
||||
$type: haxework.gui.DataView
|
||||
layout:
|
||||
$type: haxework.gui.layout.HorizontalLayout
|
||||
hAlign: center
|
||||
@@ -13,7 +16,7 @@ views:
|
||||
+onDataSelect: $code:function(value) preset = value
|
||||
geometry.padding: 10
|
||||
- id: levels
|
||||
$type: haxework.gui.DataView<Int>
|
||||
$type: haxework.gui.DataView
|
||||
layout:
|
||||
$type: haxework.gui.layout.TailLayout
|
||||
rowSize: 10
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.m.tankz.frame.common;
|
||||
|
||||
import ru.m.tankz.game.GameState;
|
||||
import flash.events.Event;
|
||||
import haxe.ds.Option;
|
||||
import haxe.Timer;
|
||||
@@ -7,11 +8,9 @@ import haxework.gui.frame.FrameSwitcher;
|
||||
import haxework.gui.GroupView;
|
||||
import ru.m.tankz.frame.common.IGamePanel;
|
||||
import ru.m.tankz.game.Game;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.network.NetworkManager;
|
||||
import ru.m.tankz.render.Render;
|
||||
import ru.m.tankz.sound.SoundManager;
|
||||
import ru.m.tankz.storage.SaveStorage;
|
||||
|
||||
class GameFrame extends GroupView {
|
||||
|
||||
@@ -23,7 +22,6 @@ class GameFrame extends GroupView {
|
||||
@:provide var network:NetworkManager;
|
||||
@:provide var sound:SoundManager;
|
||||
@:provide var state:GameState;
|
||||
@:provide var storage:SaveStorage;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
|
||||
private var game:Game;
|
||||
@@ -67,24 +65,15 @@ class GameFrame extends GroupView {
|
||||
render.reset();
|
||||
}
|
||||
|
||||
private function onGameStateChange(s:GameState):GameState {
|
||||
private function onGameStateChange(_):Void {
|
||||
panel.toUpdate();
|
||||
return s;
|
||||
}
|
||||
|
||||
private function onGameComplete(result:Option<GameState>):Void {
|
||||
switch (result) {
|
||||
case Option.Some(s):
|
||||
panel.toUpdate();
|
||||
case Option.None:
|
||||
}
|
||||
private function onGameComplete(_):Void {
|
||||
switch (game.next()) {
|
||||
case Option.Some(s):
|
||||
var state = game.save();
|
||||
this.state = state;
|
||||
storage.write(state);
|
||||
stop();
|
||||
start(state);
|
||||
start(s);
|
||||
case Option.None:
|
||||
switcher.change(StartFrame.ID);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@ import haxework.gui.GroupView;
|
||||
import haxework.resources.IResources;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.storage.SaveStorage;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
class LevelFrame extends GroupView {
|
||||
@@ -19,11 +17,10 @@ class LevelFrame extends GroupView {
|
||||
|
||||
@:provide var configBundle:IConfigBundle;
|
||||
@:provide var state:GameState;
|
||||
@:provide var storage:SaveStorage;
|
||||
@:provide var resources:IResources;
|
||||
|
||||
private function set_gameType(value:GameType):GameType {
|
||||
if (gameType != value) {
|
||||
if (gameType != value || true) { // ToDo:
|
||||
gameType = value;
|
||||
config = configBundle.get(gameType);
|
||||
preset = config.presets[0];
|
||||
@@ -32,13 +29,13 @@ class LevelFrame extends GroupView {
|
||||
}
|
||||
|
||||
private function set_preset(value:GamePreset):GamePreset {
|
||||
if (preset != value) {
|
||||
if (preset != value || true) { // ToDo:
|
||||
preset = value;
|
||||
state = new GameState(gameType, preset.id);
|
||||
for (team in value.teams) {
|
||||
for (player in team.players) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,10 +1,37 @@
|
||||
package ru.m.tankz.frame.common;
|
||||
|
||||
import openfl.Assets;
|
||||
import haxework.gui.LabelView;
|
||||
import haxework.gui.ImageView;
|
||||
import haxework.gui.HGroupView;
|
||||
|
||||
@:template class LifeView extends HGroupView {
|
||||
@:view public var image:ImageView;
|
||||
@:view public var count:LabelView;
|
||||
@:view("tank") public var tankImage:ImageView;
|
||||
@: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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
---
|
||||
layout.margin: 5
|
||||
views:
|
||||
- id: image
|
||||
- id: tank
|
||||
$type: haxework.gui.ImageView
|
||||
- id: count
|
||||
- id: live
|
||||
$type: haxework.gui.LabelView
|
||||
skinId: text.box
|
||||
geometry.size.fixed: [50, 38]
|
||||
- id: score
|
||||
$type: haxework.gui.LabelView
|
||||
skinId: text.box
|
||||
geometry.size.fixed: [100, 38]
|
||||
|
||||
@@ -1,65 +1,105 @@
|
||||
package ru.m.tankz.frame.common;
|
||||
|
||||
import haxework.color.Color;
|
||||
import haxework.gui.ButtonView;
|
||||
import ru.m.tankz.control.Control;
|
||||
import haxework.gui.DataView;
|
||||
import haxework.gui.HGroupView;
|
||||
import haxework.gui.LabelView;
|
||||
import haxework.gui.list.ListView;
|
||||
import haxework.gui.skin.Skin;
|
||||
import openfl.Assets;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.control.Control;
|
||||
import haxework.gui.skin.ISkin;
|
||||
import haxework.gui.ToggleButtonView;
|
||||
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;
|
||||
public var data(default, set):PlayerId;
|
||||
private function set_team(value:TeamId):TeamId {
|
||||
if (team != value) {
|
||||
team = value;
|
||||
text = team.substr(0, 1).toUpperCase() + team.substr(1);
|
||||
}
|
||||
return team;
|
||||
}
|
||||
}
|
||||
|
||||
@:view("index") var indexLabel(default, null):LabelView;
|
||||
@:view var control(default, null):ButtonView;
|
||||
class TeamSkin implements ISkin<TeamButton> {
|
||||
|
||||
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 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;
|
||||
indexLabel.text = '${value.team} ${Std.string(data.index + 1)}';
|
||||
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();
|
||||
teams.data = [NONE].concat([for (team in state.preset.teams) team.id]);
|
||||
return data;
|
||||
}
|
||||
|
||||
public function toggleControl():Void {
|
||||
if (data != null && data.index > -1) {
|
||||
var controlType = switch state.control.get(data) {
|
||||
case Control.BOT: Control.HUMAN;
|
||||
case Control.HUMAN: Control.BOT;
|
||||
case _: Control.BOT;
|
||||
private function getTeamColor(teamId:TeamId):Int {
|
||||
var color = 0xcccccc;
|
||||
for (team in state.preset.teams) {
|
||||
if (team.id == teamId) {
|
||||
if (!team.color.zero) color = team.color;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
---
|
||||
geometry.size.width: 200
|
||||
geometry.size.height: 44
|
||||
geometry.margin: 5
|
||||
layout.margin: 10
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- id: index
|
||||
- id: label
|
||||
$type: haxework.gui.LabelView
|
||||
geometry.size.stretch: true
|
||||
skin:
|
||||
- $type: haxework.gui.skin.ColorSkin
|
||||
color: 0x000000
|
||||
alpha: 0.2
|
||||
shadow: true
|
||||
shadowColor: 0x000000
|
||||
- id: control
|
||||
$type: haxework.gui.ButtonView
|
||||
+onPress: $code:toggleControl()
|
||||
skinId: text
|
||||
- id: teams
|
||||
$type: haxework.gui.DataView
|
||||
factory: $this:teamViewFactory
|
||||
layout:
|
||||
$type: haxework.gui.layout.HorizontalLayout
|
||||
margin: 3
|
||||
+onDataSelect: $this:onTeamSelect
|
||||
|
||||
@@ -1,43 +1,26 @@
|
||||
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.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.preset.DotaGame;
|
||||
|
||||
@:template class DotaGamePanel extends HGroupView implements IGamePanel {
|
||||
|
||||
@:view var radiant:LifeView;
|
||||
@:view var dire:LifeView;
|
||||
@:view var level:LabelView;
|
||||
|
||||
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 {
|
||||
radiant.count.text = '${game.teams[DotaGame.RADIANT].life}';
|
||||
dire.count.text = '${game.teams[DotaGame.DIRE].life}';
|
||||
level.text = 'Level: ${game.state.level}';
|
||||
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 {
|
||||
|
||||
@@ -4,11 +4,18 @@ layout.margin: 20
|
||||
views:
|
||||
- id: radiant
|
||||
$type: ru.m.tankz.frame.common.LifeView
|
||||
image.image: $asset:image:resources/image/tank/bc-0.png
|
||||
image.color: 0xff4422
|
||||
tank: bc
|
||||
color: 0xff4422
|
||||
- $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
|
||||
$type: ru.m.tankz.frame.common.LifeView
|
||||
image.image: $asset:image:resources/image/tank/bc-0.png
|
||||
image.color: 0x3284ff
|
||||
tank: bc
|
||||
color: 0x3284ff
|
||||
|
||||
@@ -1,36 +1,31 @@
|
||||
package ru.m.tankz.frame.dota;
|
||||
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.DataView;
|
||||
import haxework.gui.frame.FrameSwitcher;
|
||||
import ru.m.tankz.frame.common.LevelFrame;
|
||||
import ru.m.tankz.frame.common.PlayerView;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.preset.DotaGame;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
@:template class DotaLevelFrame extends LevelFrame {
|
||||
public static inline var ID = "dota.level";
|
||||
|
||||
@:view var levels(default, null):DataView<Int>;
|
||||
@:view var players(default, null):DataView<PlayerId>;
|
||||
@:view var levels(default, null):DataView<Int, ButtonView>;
|
||||
@:view var players(default, null):DataView<Array<PlayerState>, PlayerView>;
|
||||
|
||||
@:provide var frames:FrameSwitcher;
|
||||
|
||||
private function onShow():Void {
|
||||
gameType = DotaGame.TYPE;
|
||||
levels.data = [for (i in 0...config.game.levels) i];
|
||||
var data = [];
|
||||
for (team in preset.teams) {
|
||||
for (p in team.players) {
|
||||
data.push(new PlayerId(team.id, p.index));
|
||||
}
|
||||
}
|
||||
players.data = data;
|
||||
players.data = [for (i in 0...2) state.players];
|
||||
}
|
||||
|
||||
private function playerViewFactory(index:Int, player:PlayerId):PlayerView {
|
||||
private function playerViewFactory(index:Int, data:Array<PlayerState>):PlayerView {
|
||||
var view = new PlayerView();
|
||||
view.item_index = index;
|
||||
view.data = player;
|
||||
view.data = data;
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
---
|
||||
layout:
|
||||
$type: haxework.gui.layout.HorizontalLayout
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
hAlign: center
|
||||
views:
|
||||
- $type: haxework.gui.LabelView
|
||||
skinId: text.header
|
||||
text: DotA
|
||||
- id: players
|
||||
$type: haxework.gui.DataView<PlayerId>
|
||||
$type: haxework.gui.DataView
|
||||
layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
hAlign: center
|
||||
factory: $this:playerViewFactory
|
||||
geometry.padding: 10
|
||||
- id: levels
|
||||
$type: haxework.gui.DataView<Int>
|
||||
$type: haxework.gui.DataView
|
||||
layout:
|
||||
$type: haxework.gui.layout.TailLayout
|
||||
rowSize: 5
|
||||
|
||||
@@ -14,7 +14,7 @@ import ru.m.tankz.storage.SettingsStorage;
|
||||
public var controlIndex(default, set): Int;
|
||||
|
||||
@:view var label:LabelView;
|
||||
@:view var list:DataView<ActionItem>;
|
||||
@:view var list:DataView<ActionItem, ActionView>;
|
||||
@:view var change:ButtonView;
|
||||
@:view var clear:ButtonView;
|
||||
@:view var reset:ButtonView;
|
||||
|
||||
@@ -23,7 +23,7 @@ views:
|
||||
skinId: button.simple
|
||||
text: Reset
|
||||
- id: list
|
||||
$type: haxework.gui.DataView<ru.m.tankz.control.ActionItem>
|
||||
$type: haxework.gui.DataView
|
||||
layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
factory: $this:viewFactory
|
||||
|
||||
@@ -44,7 +44,7 @@ class SoundManager {
|
||||
play('bullet_hit');
|
||||
//case [EntityType.TANK(_), EntityChange.LIVE_UP]:
|
||||
// play('live');
|
||||
case [EntityType.EAGLE(_), EntityChange.DEATH]:
|
||||
case [EntityType.EAGLE(_), EntityChange.DEATH(_)]:
|
||||
play('boom_player');
|
||||
case _:
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
BIN
src/client/resources/icon.png
Normal file
BIN
src/client/resources/icon.png
Normal file
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 |
@@ -1,8 +1,5 @@
|
||||
package ru.m.tankz;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.crypto.Crc32;
|
||||
|
||||
typedef Type = Dynamic;
|
||||
|
||||
typedef GameType = String;
|
||||
@@ -17,20 +14,20 @@ typedef TankType = String;
|
||||
|
||||
typedef BonusType = String;
|
||||
|
||||
class PlayerId {
|
||||
public var team(default, null):TeamId;
|
||||
public var index(default, null):Int;
|
||||
|
||||
private var _hashCode(default, null):Int;
|
||||
abstract PlayerId(Array<Dynamic>) {
|
||||
public var team(get, never):TeamId;
|
||||
public var index(get, never):Int;
|
||||
|
||||
public function new(team:TeamId, index:Int) {
|
||||
this.team = team;
|
||||
this.index = index;
|
||||
this._hashCode = Crc32.make(Bytes.ofString('${team}-${index}'));
|
||||
this = [team, index];
|
||||
}
|
||||
|
||||
public function hashCode():Int {
|
||||
return _hashCode;
|
||||
private inline function get_team():TeamId return this[0];
|
||||
|
||||
private inline function get_index():Int return this[1];
|
||||
|
||||
@:to public inline function toString():String {
|
||||
return '${team}:${index}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,14 @@ typedef PlayerConfig = {
|
||||
@:optional var control:ControlType;
|
||||
}
|
||||
|
||||
typedef EagleConfig = {
|
||||
@:optional var score:Int;
|
||||
}
|
||||
|
||||
typedef TeamConfig = {
|
||||
var id:TeamId;
|
||||
var players:Array<PlayerConfig>;
|
||||
@:optional var eagle:EagleConfig;
|
||||
@:optional var life:Int;
|
||||
@:optional var spawnInterval:Int;
|
||||
@:optional var color:Color;
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
package ru.m.tankz.core;
|
||||
|
||||
import ru.m.tankz.config.Config.EagleConfig;
|
||||
import ru.m.geom.Rectangle;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
class Eagle extends Entity {
|
||||
|
||||
public var team(default, null):TeamId;
|
||||
public var config(default, null):EagleConfig;
|
||||
public var death(default, default):Bool;
|
||||
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
|
||||
this.team = team;
|
||||
this.config = config;
|
||||
this.death = false;
|
||||
this.protect = new Modificator();
|
||||
}
|
||||
|
||||
private inline function get_score():Int {
|
||||
return config != null ? config.score : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import ru.m.tankz.Type;
|
||||
enum EntityChange {
|
||||
HIT;
|
||||
TYPE;
|
||||
DEATH;
|
||||
DEATH(playerId:PlayerId);
|
||||
PROTECT;
|
||||
FREEZING;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class CollisionProcessor {
|
||||
if (!eagle.protect.active) {
|
||||
eagle.death = true;
|
||||
// ToDo: change
|
||||
engine.change(eagle, EntityChange.DEATH);
|
||||
engine.change(eagle, EntityChange.DEATH(bullet.playerId));
|
||||
}
|
||||
case _:
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import haxe.Timer;
|
||||
import haxework.provider.Provider;
|
||||
import promhx.Deferred;
|
||||
import promhx.Stream;
|
||||
import ru.m.geom.Direction;
|
||||
import ru.m.geom.Point;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
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.Type;
|
||||
|
||||
|
||||
class Game {
|
||||
|
||||
private static var TAG(default, never):String = 'Game';
|
||||
|
||||
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 config(default, null):Config;
|
||||
public var engine(default, null):Engine;
|
||||
public var loser(default, null):Null<TeamId>;
|
||||
|
||||
public var state(default, null):GameState;
|
||||
|
||||
private var points:Array<SpawnPoint>;
|
||||
private var deferred:Deferred<GameState>;
|
||||
private var stream:Stream<GameState>;
|
||||
|
||||
@:provide var configBundle:IConfigBundle;
|
||||
@:provide var levelBundle:ILevelBundle;
|
||||
|
||||
public function new(type:GameType) {
|
||||
this.type = type;
|
||||
@@ -84,20 +83,25 @@ class Game {
|
||||
public function start(state:GameState):Stream<GameState> {
|
||||
this.state = state;
|
||||
this.loser = null;
|
||||
this.preset = config.getPreset(state.presetId);
|
||||
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;
|
||||
engine.map.setData(level.data);
|
||||
teams = new Map<TeamId, Team>();
|
||||
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 team:Team = new Team(teamConfig, teamPoints, state);
|
||||
var team:Team = new Team(teamConfig, teamPoints);
|
||||
teams[team.id] = team;
|
||||
for (player in team.players.iterator()) {
|
||||
var controlType: ControlType = state.control.get(player.id);
|
||||
if (controlType != null) {
|
||||
var controlType:ControlType = Control.BOT;
|
||||
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);
|
||||
L.d(TAG, 'control(${player.id} - ${control})');
|
||||
if (control != null) {
|
||||
@@ -105,19 +109,18 @@ class Game {
|
||||
player.control.bind(engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
team.spawner.runner = spawn;
|
||||
}
|
||||
|
||||
for (team in teams.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);
|
||||
}
|
||||
}
|
||||
var eaglePoint = team.spawner.getPoint('eagle');
|
||||
if (eaglePoint != null) {
|
||||
var eagle = new Eagle(team.id);
|
||||
var eagle = new Eagle(team.id, team.config.eagle);
|
||||
team.eagleId = eagle.id;
|
||||
applyPoint(eagle, eaglePoint);
|
||||
engine.spawn(eagle);
|
||||
@@ -128,18 +131,14 @@ class Game {
|
||||
}
|
||||
|
||||
private function spawn(task:SpawnTask):Void {
|
||||
L.d(TAG, 'spawn(${task}');
|
||||
L.d(TAG, 'spawn(${task})');
|
||||
var team = getTeam(task.playerId.team);
|
||||
var player = getPlayer(task.playerId);
|
||||
player.tankId = 0;
|
||||
if (getTeam(task.playerId.team).trySpawn(task.playerId, true)) {
|
||||
var tank = buildTank(task);
|
||||
player.tankId = tank.id;
|
||||
player.state.tank = tank.config.type;
|
||||
engine.spawn(tank);
|
||||
} else if (!team.isAlive) {
|
||||
lose(team.id);
|
||||
}
|
||||
deferred.resolve(state);
|
||||
}
|
||||
|
||||
@@ -160,14 +159,17 @@ class Game {
|
||||
switch (entity) {
|
||||
case EntityType.TANK(tank):
|
||||
getPlayer(tank.playerId).control.start();
|
||||
case EntityType.BULLET(bullet):
|
||||
getPlayer(bullet.playerId).state.shots++;
|
||||
case _:
|
||||
}
|
||||
}
|
||||
|
||||
public function onChange(entity:EntityType, change:EntityChange):Void {
|
||||
switch [entity, change] {
|
||||
case [EntityType.EAGLE(eagle), EntityChange.DEATH]:
|
||||
case [EntityType.EAGLE(eagle), EntityChange.DEATH(playerId)]:
|
||||
if (eagle.death) {
|
||||
getPlayer(playerId).state.score += eagle.score * (eagle.team == playerId.team ? 0 : 1);
|
||||
lose(eagle.team);
|
||||
deferred.resolve(state);
|
||||
}
|
||||
@@ -192,6 +194,8 @@ class Game {
|
||||
switch [entity, with] {
|
||||
case [EntityType.TANK(tank), EntityType.BONUS(bonus)]:
|
||||
applyBonus(tank, bonus);
|
||||
case [EntityType.BULLET(bullet), EntityType.TANK(tank)]:
|
||||
getPlayer(bullet.playerId).state.hits++;
|
||||
case _:
|
||||
}
|
||||
}
|
||||
@@ -203,7 +207,8 @@ class Game {
|
||||
var player = getPlayer(tank.playerId);
|
||||
player.control.stop();
|
||||
player.tankId = 0; //ToDo: ?
|
||||
var respawn:Bool = team.trySpawn(player.id);
|
||||
team.onDestroy(player.id);
|
||||
var respawn:Bool = team.tryRespawn(player.id);
|
||||
if (respawn) {
|
||||
team.spawner.push(player.id);
|
||||
}
|
||||
@@ -213,8 +218,9 @@ class Game {
|
||||
if (tank.bonus) {
|
||||
spawnBonus();
|
||||
}
|
||||
if (tank.config.score > 0 && playerId != null) {
|
||||
getPlayer(playerId).state.score += tank.config.score;
|
||||
if (playerId != null) {
|
||||
getPlayer(playerId).state.frags++;
|
||||
getPlayer(playerId).state.score += tank.config.score * (tank.playerId.team == playerId.team ? 0 : 1);
|
||||
}
|
||||
deferred.resolve(state);
|
||||
case EntityType.BONUS(bonus):
|
||||
@@ -241,9 +247,9 @@ class Game {
|
||||
return Option.None;
|
||||
}
|
||||
}
|
||||
state.level++;
|
||||
if (state.level >= config.game.levels) state.level = 0;
|
||||
return Option.Some(state);
|
||||
var level = this.state.level + 1;
|
||||
if (level >= config.game.levels) level = 0;
|
||||
return Option.Some(new GameState(type, state.presetId, level, state.players));
|
||||
}
|
||||
|
||||
public function dispose():Void {
|
||||
@@ -298,8 +304,4 @@ class Game {
|
||||
engine.destroy(tank); // :-D
|
||||
}
|
||||
}
|
||||
|
||||
public function save():GameState {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,52 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.game.Player.PlayerState;
|
||||
import haxe.ds.HashMap;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.control.Control;
|
||||
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 var type(default, null):GameType;
|
||||
public var presetId(default, null):PresetId;
|
||||
public var control(default, null):HashMap<PlayerId, ControlType>;
|
||||
public var players(default, null):HashMap<PlayerId, PlayerState>;
|
||||
public var level(default, default):Int;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId) {
|
||||
this.type = type;
|
||||
this.presetId = presetId;
|
||||
this.control = new HashMap();
|
||||
this.players = new HashMap();
|
||||
this.level = 0;
|
||||
}
|
||||
|
||||
public function toYaml():String {
|
||||
//return Yaml.render(this, Renderer.options().setFlowLevel(0));
|
||||
return "";
|
||||
}
|
||||
|
||||
public static function fromYaml(value:String):GameState {
|
||||
//var data:Dynamic = Yaml.parse(value, Parser.options().useObjects());
|
||||
//return new GameState();
|
||||
return null;
|
||||
public function new(id:PlayerId, control:ControlType = null, life:Int = 0) {
|
||||
this.id = id;
|
||||
this.tank = null;
|
||||
this.control = control == null ? Control.BOT : control;
|
||||
this.life = life;
|
||||
this.score = 0;
|
||||
this.frags = 0;
|
||||
this.shots = 0;
|
||||
this.hits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class GameState {
|
||||
|
||||
public var type:GameType;
|
||||
public var presetId:PresetId;
|
||||
public var level:Int;
|
||||
public var players:Array<PlayerState>;
|
||||
public var preset(get, null):GamePreset;
|
||||
|
||||
@:provide private var configBundle:IConfigBundle;
|
||||
|
||||
public function new(type:GameType, presetId:PresetId, level:Int = 1, players:Array<PlayerState> = 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;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,10 @@
|
||||
package ru.m.tankz.game;
|
||||
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.Type;
|
||||
|
||||
|
||||
typedef PlayerState = {
|
||||
var tank:TankType;
|
||||
var life:Int;
|
||||
var score:Int;
|
||||
}
|
||||
|
||||
class Player {
|
||||
public var config(default, null):PlayerConfig;
|
||||
public var id(default, null):PlayerId;
|
||||
@@ -19,15 +13,11 @@ class Player {
|
||||
public var isAlive(get, null):Bool;
|
||||
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.id = new PlayerId(teamId, config.index);
|
||||
this.control = null;
|
||||
this.state = {
|
||||
life: config.life,
|
||||
tank: null,
|
||||
score: 0,
|
||||
}
|
||||
this.state = state == null ? new PlayerState(id) : state;
|
||||
}
|
||||
|
||||
private function set_tankId(value:Int):Int {
|
||||
|
||||
@@ -69,7 +69,7 @@ class Spawner {
|
||||
|
||||
private function run():Void {
|
||||
if (timer == null) {
|
||||
timer = new Timer(config.spawnInterval == null ? 1 : config.spawnInterval);
|
||||
timer = new Timer(config.spawnInterval == null ? 500 : config.spawnInterval);
|
||||
timer.run = spawn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package ru.m.tankz.game;
|
||||
import ru.m.tankz.Type;
|
||||
import ru.m.tankz.config.Config;
|
||||
|
||||
|
||||
class Team {
|
||||
|
||||
public var id(default, null):TeamId;
|
||||
@@ -12,35 +11,40 @@ class Team {
|
||||
public var players(default, null):Map<Int, Player>;
|
||||
public var life(default, default):Int;
|
||||
public var isAlive(get, null):Bool;
|
||||
public var score(get, null):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.config = config;
|
||||
this.players = new Map();
|
||||
for (playerConfig in config.players) {
|
||||
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.life = config.life;
|
||||
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 result = false;
|
||||
if (player.state.life > 0) {
|
||||
if (spawn) player.state.life--;
|
||||
result = true;
|
||||
} else if (life > 0) {
|
||||
if (spawn) life--;
|
||||
result = true;
|
||||
}
|
||||
var result = player.state.life > 0 || life > active;
|
||||
active++;
|
||||
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?
|
||||
private function get_isAlive():Bool {
|
||||
if (life > 0) {
|
||||
@@ -56,4 +60,8 @@ class Team {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function get_score():Int {
|
||||
return Lambda.fold(players, function(p:Player, s:Int) return s + p.state.score, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ team:
|
||||
- {<<: *player-slow, index: 2}
|
||||
- {<<: *player-fast, index: 3}
|
||||
- {<<: *player-slow, index: 4}
|
||||
eagle:
|
||||
score: 500
|
||||
radiant: &radiant
|
||||
id: radiant
|
||||
color: 0xff4422
|
||||
@@ -83,6 +85,7 @@ tanks:
|
||||
<<: *bullet
|
||||
speed: 12.0
|
||||
bullets: 1
|
||||
score: 100
|
||||
skin: bc
|
||||
|
||||
- type: fast
|
||||
@@ -93,6 +96,7 @@ tanks:
|
||||
<<: *bullet
|
||||
speed: 8.0
|
||||
bullets: 1
|
||||
score: 100
|
||||
skin: bb
|
||||
|
||||
bonuses:
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
$type: haxework.gui.VGroupView
|
||||
skin: $r:skin:dark
|
||||
skinId: dark
|
||||
geometry.size.stretch: true
|
||||
layout.hAlign: center
|
||||
views:
|
||||
# Tabs
|
||||
- id: tabs
|
||||
$type: haxework.gui.HGroupView
|
||||
geometry.margin.bottom: -3
|
||||
geometry.margin.bottom: -2
|
||||
views:
|
||||
- id: level
|
||||
$type: haxework.gui.ToggleButtonView
|
||||
|
||||
@@ -1,57 +1,56 @@
|
||||
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.DataView;
|
||||
import haxework.gui.LabelView;
|
||||
import haxework.gui.list.ListView;
|
||||
import haxework.gui.list.VListView;
|
||||
import haxework.gui.VGroupView;
|
||||
import haxework.provider.Provider;
|
||||
import ru.m.tankz.bundle.IConfigBundle;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.editor.FileUtil;
|
||||
import ru.m.tankz.editor.level.BrickView;
|
||||
import ru.m.tankz.editor.level.MapEditView;
|
||||
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.util.LevelUtil;
|
||||
|
||||
@:template class LevelFrame extends VGroupView {
|
||||
public static inline var ID = 'level';
|
||||
public static inline var TAG = 'level';
|
||||
|
||||
@:view var gameClassicButton(default, null):ButtonView;
|
||||
@:view var gameDotaButton(default, null):ButtonView;
|
||||
@:view var openButton(default, null):ButtonView;
|
||||
@:view var saveButton(default, null):ButtonView;
|
||||
@:view var fileNameLabel(default, null):LabelView;
|
||||
@:view var mapView(default, null):MapEditView;
|
||||
@:view var spawnPointList(default, null):VListView<SpawnPoint>;
|
||||
@:view var brickList(default, null):VListView<BrickConfig>;
|
||||
@:view var gameClassicButton:ButtonView;
|
||||
@:view var gameDotaButton:ButtonView;
|
||||
@:view var openButton:ButtonView;
|
||||
@:view var saveButton:ButtonView;
|
||||
@:view var fileNameLabel:LabelView;
|
||||
@:view var mapView:MapEditView;
|
||||
@:view var spawnPointList:DataView<SpawnPoint, SpawnPointView>;
|
||||
@:view var brickList:DataView<BrickConfig, BrickView>;
|
||||
|
||||
private var config:Config;
|
||||
|
||||
public function init():Void {
|
||||
var resetSelected = function() {
|
||||
for (v in brickList.items) {
|
||||
for (v in brickList.views) {
|
||||
cast(v, BrickView).selected = false;
|
||||
}
|
||||
for (v in spawnPointList.items) {
|
||||
for (v in spawnPointList.views) {
|
||||
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);
|
||||
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);
|
||||
resetSelected();
|
||||
cast(item, SpawnPointView).selected = true;
|
||||
item.selected = true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,7 +69,7 @@ import ru.m.tankz.Type;
|
||||
spawnPointList.data = config.points;
|
||||
|
||||
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 {
|
||||
|
||||
@@ -31,17 +31,24 @@ views:
|
||||
+onPress: $this:onPress
|
||||
- id: fileNameLabel
|
||||
$type: haxework.gui.LabelView
|
||||
# map
|
||||
- $type: haxework.gui.HGroupView
|
||||
views:
|
||||
- id: spawnPointList
|
||||
$type: haxework.gui.list.VListView<SpawnPoint>
|
||||
factory: $code:function() return new ru.m.tankz.editor.level.SpawnPointView()
|
||||
geometry.size.width: 56
|
||||
geometry.size.height: 100%
|
||||
$type: haxework.gui.DataView
|
||||
geometry.padding: 3
|
||||
layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
hAlign: center
|
||||
margin: 5
|
||||
factory: $code:ru.m.tankz.editor.level.SpawnPointView.factory
|
||||
- id: mapView
|
||||
$type: ru.m.tankz.editor.level.MapEditView
|
||||
- id: brickList
|
||||
$type: haxework.gui.list.VListView<BrickConfig>
|
||||
factory: $code:function() return new ru.m.tankz.editor.level.BrickView()
|
||||
geometry.size.width: 30
|
||||
geometry.size.height: 100%
|
||||
$type: haxework.gui.DataView
|
||||
geometry.padding: 3
|
||||
layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
hAlign: center
|
||||
margin: 5
|
||||
factory: $code:ru.m.tankz.editor.level.BrickView.factory
|
||||
|
||||
@@ -1,53 +1,14 @@
|
||||
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;
|
||||
|
||||
class BrickView extends BrushView<BrickConfig> {
|
||||
|
||||
class BrickView extends SpriteView implements IListItemView<BrickConfig> {
|
||||
private static var size = 26;
|
||||
|
||||
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);
|
||||
override private function resolveSrc(value:BrickConfig):String {
|
||||
return 'resources/image/map/${value.type}.png';
|
||||
}
|
||||
|
||||
private static function createSelectView(width:Float, height:Float):Shape {
|
||||
var view = new Shape();
|
||||
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;
|
||||
public static inline function factory(index:Int, value:BrickConfig) {
|
||||
return new BrickView(value);
|
||||
}
|
||||
}
|
||||
|
||||
48
src/editor/haxe/ru/m/tankz/editor/level/BrushView.hx
Normal file
48
src/editor/haxe/ru/m/tankz/editor/level/BrushView.hx
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import ru.m.tankz.map.Brick;
|
||||
import ru.m.tankz.map.LevelMap;
|
||||
import ru.m.tankz.render.RenderItem;
|
||||
|
||||
|
||||
class SpawnPointEntity extends Entity {
|
||||
|
||||
public var point(default, null):SpawnPoint;
|
||||
@@ -77,13 +76,11 @@ class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum Brush {
|
||||
POINT(point:SpawnPoint);
|
||||
BRICK(brick:BrickConfig);
|
||||
}
|
||||
|
||||
|
||||
//ToDo: copy paste from ru.m.tankz.render.Render
|
||||
class MapEditView extends SpriteView {
|
||||
|
||||
@@ -213,11 +210,7 @@ class MapEditView extends SpriteView {
|
||||
private function set_config(value:Config):Config {
|
||||
config = value;
|
||||
map = new LevelMap(config.map);
|
||||
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight);
|
||||
//ToDo:
|
||||
if (parent != null) {
|
||||
parent.toUpdateParent();
|
||||
}
|
||||
setContentSize(map.gridWidth * map.cellWidth, map.gridHeight * map.cellHeight, "map");
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +1,17 @@
|
||||
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 openfl.utils.Assets;
|
||||
import ru.m.tankz.config.Config;
|
||||
import ru.m.tankz.editor.level.MapEditView;
|
||||
|
||||
class SpawnPointView extends BrushView<SpawnPoint> {
|
||||
|
||||
class SpawnPointView extends SpriteView implements IListItemView<SpawnPoint> {
|
||||
private static var size = 52;
|
||||
|
||||
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);
|
||||
override private function resolveSrc(value:SpawnPoint):String {
|
||||
return SpawnPointItem.getSrc(value, Provider.get(Config));
|
||||
}
|
||||
|
||||
private static function createSelectView(width:Float, height:Float):Shape {
|
||||
var view = new Shape();
|
||||
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;
|
||||
public static inline function factory(index:Int, value:SpawnPoint) {
|
||||
return new SpawnPointView(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class DbProvider {
|
||||
private var orm:Orm;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user