20 Commits
0.3.0 ... 0.6.0

Author SHA1 Message Date
a1ed498bf5 [client] render fixes 2018-02-10 15:25:16 +03:00
41c5610f9a [common] added Bonus entity 2018-02-09 16:57:33 +03:00
5c57454998 [common] added Type bundle 2018-02-09 10:59:25 +03:00
a7effef412 [render] tankz colors 2018-02-08 23:12:10 +03:00
dd1014e230 [client] added draw package 2018-02-08 17:57:40 +03:00
89ac9fd225 [resources] added dota maps 2018-02-07 22:49:23 +03:00
3096fba7c5 [editor] update spwan view 2018-02-07 21:47:13 +03:00
baf696a3e1 [editor] game type select 2018-02-07 10:57:23 +03:00
5daf4fafc7 fix 2018-02-06 23:36:40 +03:00
db59377cb2 Merge remote-tracking branch 'origin/editor' 2018-02-06 23:20:20 +03:00
1f6e4fbc3d [common] update level config, spawns points 2018-02-06 17:41:49 +03:00
db5b805276 [editor] ui update 2018-02-06 10:54:48 +03:00
38538b9147 fix 2018-02-05 22:47:46 +03:00
15d830a0d4 [game] added dota maps 2018-02-05 22:24:00 +03:00
feb5bafe72 [editor] update 2018-02-05 20:46:11 +03:00
b36fd77d74 [editor] added save button 2018-02-05 17:54:16 +03:00
421f925a60 [editor] added editor module 2018-02-04 23:32:00 +03:00
ad4744cfef [common] change game team players from array to map 2018-02-04 22:33:50 +03:00
1c9ccf0fb8 [common] humans in DotaGame 2018-02-04 21:02:08 +03:00
e0ceff68f9 update worklist 2018-02-04 14:11:43 +03:00
75 changed files with 1544 additions and 797 deletions

62
WORK.md
View File

@@ -1,46 +1,62 @@
* build
* gulp 100%
* linux 100%
* deb-package 100%
* windows 0%
* exe-package 0% (inno setup)
* deploy
* capistrano 100%
* ui
* login frame
* select person frame (autoselect)
* game mode frame (single, start server, find server)
* game frame
* auth frame 0%
* select game frame 30% (classic 1/2 player, dota singe/coop/vs)
* select level frame 10%
* game frame 50%
* engine
* config 90%
* map 80%
* tanks 30%
* bullets 30%
* boxes 0%
* map changes 50%
* config 100%
* map 100%
* tanks 100%
* bullets 100%
* boxes 100%
* map changes 100%
* bonuses 0%
* eagle 0%
* eagle 100%
* game
* classic
* state 0%
* bot 5%
* state 50%
* bot 50%
* player: 50%
* dota
* state 50%
* bot 10%
* player 0%
* state
* score 0%
* save/load 0%
* export/import 0%
* render
* map 100%
* tanks 100%
* bullet 100%
* calc redraw 20%
* calc redraw 50%
* animations
* tank spawn
* bullet boom
* tank boom
* bonuses
* html5
* tank spawn 0%
* tank move 100%
* map water 0%
* bullet boom 90%
* tank boom 90%
* bonuses 0%
* html5 50%
* proto
...
* webapp
* angular app 0%
* google analytics 0%
* editor
* open 0%
* edit 0%
* save 0%

35
build/editor.js Normal file
View File

@@ -0,0 +1,35 @@
const gulp = require('gulp');
const yargs = require('yargs');
const Haxe = require('../tasks/haxe');
const FlashPlayer = require('../tasks/flashplayer');
const version = require('./version');
const prepare = require('./prepare');
const debug = require('../tasks/debug');
const build = (platform) => function build() {
const argv = yargs.argv;
return gulp.src('.')
.pipe(new Haxe().openfl({
command: 'build',
platform: platform,
version: version,
values: {
build_editor: true
},
debug: argv.dev,
}))
.pipe(gulp.dest(`target/${platform}`));
};
const testFlash = function() {
const argv = yargs.argv;
return build('flash')()
.pipe(new FlashPlayer().run(argv.dev))
.pipe(debug());
};
exports['editor:flash'] = gulp.series(prepare(Haxe.ID), build('flash'));
exports['editor:flash:test'] = gulp.series(prepare(Haxe.ID, FlashPlayer.ID), testFlash);

View File

@@ -29,6 +29,7 @@ const merge = (value) => {
exports.update = prepare.update;
merge('./build/prepare');
merge('./build/client');
merge('./build/editor');
merge('./build/server');

View File

@@ -1,6 +1,6 @@
{
"name": "tankz",
"version": "0.3.0",
"version": "0.6.0",
"private": true,
"devDependencies": {
"ansi-colors": "^1.0.1",
@@ -23,6 +23,7 @@
"plugin-error": "^0.1.2",
"progress": "^2.0.0",
"promise-streams": "^2.1.1",
"rmdir": "^1.2.0",
"tar": "^4.2.0",
"tmp-file": "^2.0.1",
"unzip-stream": "^0.2.1",

View File

@@ -20,4 +20,9 @@
<haxeflag name="-dce" value="no"/>
<haxeflag name="-D" value="dom"/>
<!--<template path="src/client/webapp/index_template.html" rename="index.html"/>-->
<section if="build_editor">
<app main="ru.m.tankz.editor.Editor" path="target" file="editor"/>
<source path="src/editor/haxe"/>
</section>
</project>

View File

@@ -7,21 +7,45 @@
"contentSize": true, "bottomMargin": 15
},
{
"id": "start_1p",
"@type": "haxework.gui.LabelView", "@style": "label",
"fontSize": 20, "topMargin": 15,
"contentSize": true,
"text": "Classic"
},
{
"id": "classic_1p",
"@type": "haxework.gui.ButtonView",
"text": "1 Player",
"@style": "button"
},
{
"id": "start_2p",
"id": "classic_2p",
"@type": "haxework.gui.ButtonView",
"text": "2 Player",
"@style": "button"
},
{
"id": "dota",
"@type": "haxework.gui.LabelView", "@style": "label",
"fontSize": 20, "topMargin": 15,
"contentSize": true,
"text": "DotA"
},
{
"id": "dota_1p",
"@type": "haxework.gui.ButtonView",
"text": "DotA",
"text": "1 Player",
"@style": "button"
},
{
"id": "dota_2p_coop",
"@type": "haxework.gui.ButtonView",
"text": "2 COOP",
"@style": "button"
},
{
"id": "dota_2p_vs",
"@type": "haxework.gui.ButtonView",
"text": "2 VS",
"@style": "button"
}
]

View File

@@ -0,0 +1,17 @@
package ru.m.draw;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
import flash.display.BitmapData;
class BitmapUtil {
public static function colorize(data: BitmapData, color: Color):BitmapData {
if (color.zero) return data;
var result = data.clone();
var transform = new ColorTransform(color.red / 255, color.green / 255, color.blue / 255, 1, 0, 0, 0, 0);
result.colorTransform(new Rectangle(0, 0, result.width, result.height), transform);
return result;
}
}

View File

@@ -0,0 +1,47 @@
package ru.m.draw;
abstract Color(Int) {
public var alpha(get, never):Int;
public var red(get, never):Int;
public var green(get, never):Int;
public var blue(get, never):Int;
public var zero(get, never):Bool;
public inline function new(value:Int) {
this = value;
}
private inline function get_alpha():Int {
return (this >> 24) & 255;
}
private inline function get_red():Int {
return (this >> 16) & 255;
}
private inline function get_green():Int {
return (this >> 8) & 255;
}
private inline function get_blue():Int {
return this & 255;
}
private inline function get_zero():Bool {
return this == 0;
}
@:from
static public inline function fromInt(value:Int):Color {
return new Color(value);
}
@:from
static public inline function fromString(value:String):Color {
return new Color(Std.parseInt('0x${value.split('#').pop()}'));
}
public function toString():String {
return 'Color(${red},${green},${blue})';
}
}

View File

@@ -1,27 +1,26 @@
package ru.m.tankz.control;
import ru.m.tankz.control.Control;
import haxe.Timer;
import ru.m.geom.Direction;
import flash.events.FocusEvent;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.Lib;
import flash.ui.Keyboard;
import haxe.Timer;
import ru.m.geom.Direction;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type;
typedef KeyBinding = Map<Int, TankAction>;
class HumanControl extends Control {
public static var TYPE(default, never):ControlType = 'human';
private var keyBinding:KeyBinding;
private var moveQueue:Array<Int>;
private var shotTimer:Timer;
public function new(index:Int) {
super({type:TYPE, index:index});
this.keyBinding = resolve(index);
public function new(playerId:PlayerId, controlIndex:Int) {
super(playerId);
this.keyBinding = resolve(controlIndex);
moveQueue = new Array<Int>();
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
Lib.current.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
@@ -44,7 +43,7 @@ class HumanControl extends Control {
case _:
}
if (event.keyCode == Keyboard.U) {
action(TankAction.LEVEL_UP(1));
action(TankAction.UPGRADE);
}
}
@@ -83,8 +82,8 @@ class HumanControl extends Control {
action(TankAction.SHOT);
}
private static function resolve(index:Int):KeyBinding {
switch (index) {
private static function resolve(controlIndex:Int):KeyBinding {
switch (controlIndex) {
case 0:
return [
Keyboard.A => TankAction.MOVE(Direction.LEFT),
@@ -101,8 +100,8 @@ class HumanControl extends Control {
Keyboard.RIGHT => TankAction.MOVE(Direction.RIGHT),
Keyboard.NUMPAD_0 => TankAction.SHOT
];
case _:
throw 'Invalid control index ${index}';
case x:
throw 'Invalid control index ${x}';
}
}
}

View File

@@ -5,12 +5,8 @@ import openfl.Assets;
import ru.m.animate.OnceAnimate;
import flash.display.DisplayObjectContainer;
import ru.m.tankz.core.EntityType;
import flash.display.DisplayObject;
import Type.ValueType;
import ru.m.tankz.render.RenderItem;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.core.Bullet;
import ru.m.tankz.core.Tank;
import flash.display.Sprite;
import flash.display.Graphics;
import haxework.gui.SpriteView;
@@ -101,6 +97,7 @@ class Render extends SpriteView implements EngineListener {
items.set(tank.key, item);
entryLayer.addChild(item.view);
item.update();
playTankSpawn(tank.rect.center);
case EntityType.BULLET(bullet):
var item = new BulletItem(bullet);
items.set(bullet.key, item);
@@ -111,6 +108,11 @@ class Render extends SpriteView implements EngineListener {
items.set(eagle.key, item);
entryLayer.addChild(item.view);
item.update();
case EntityType.BONUS(bonus):
var item = new BonusItem(bonus);
items.set(bonus.key, item);
entryLayer.addChild(item.view);
item.update();
case _:
}
}
@@ -139,10 +141,30 @@ class Render extends SpriteView implements EngineListener {
items.get(eagle.key).redraw();
playTankBoom(eagle.rect.center);
}
case EntityType.BONUS(bonus):
if (items.exists(bonus.key)) {
entryLayer.removeChild(items.get(bonus.key).view);
items.remove(bonus.key);
}
case _:
}
}
private function playTankSpawn(point:Point):Void {
var arr = [
0, 1, 2, 3, 3, 4, 5, 5, 6
];
var frames = [for (i in arr) Assets.getBitmapData('resources/images/tank/appear/appear-${i}.png')];
var animate = new OnceAnimate(frames);
animate.x = point.x - animate.width / 2;
animate.y = point.y - animate.height / 2;
upperLayer.addChild(animate);
animate.play().then(function(animate) {
upperLayer.removeChild(animate);
animate.dispose();
});
}
private function playBulletBoom(point:Point):Void {
var arr = [
0, 1, 1, 0, 0, 1

View File

@@ -1,23 +1,27 @@
package ru.m.tankz.render;
import ru.m.animate.Animate;
import ru.m.tankz.core.Eagle;
import openfl.display.BitmapData;
import ru.m.draw.Color;
import ru.m.tankz.core.Bonus;
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import openfl.Assets;
import ru.m.animate.Animate;
import ru.m.draw.BitmapUtil;
import ru.m.geom.Direction;
import ru.m.geom.Rectangle;
import ru.m.tankz.core.Bullet;
import ru.m.tankz.map.Brick;
import openfl.Assets;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Tank;
import flash.display.Bitmap;
import ru.m.tankz.map.Brick;
typedef TRectangle = {
var rect(default, null):Rectangle;
}
class RenderItem<T:TRectangle, D:DisplayObject> {
public var value(default, null):T;
@@ -76,6 +80,7 @@ class BitmapItem<T:TRectangle> extends RenderItem<T, Bitmap> {
class BrickItem extends RenderItem<Brick, Shape> {
private var broken:Int;
private var type:Int;
public function new(value:Brick) {
super(value);
@@ -88,6 +93,7 @@ class BrickItem extends RenderItem<Brick, Shape> {
var g = view.graphics;
g.clear();
if (value.destroyed) return;
if (value.config.type > 0) {
g.beginBitmapFill(image);
g.drawRect(0, 0, value.rect.width, value.rect.height);
for (c in value.cells) {
@@ -98,12 +104,15 @@ class BrickItem extends RenderItem<Brick, Shape> {
}
g.endFill();
}
}
override public function update():Void {
super.update();
var b = value.broken;
if (b != this.broken) {
this.broken = b;
var t = value.config.type;
if (b != broken || t != type) {
broken = b;
type = t;
redraw();
}
}
@@ -114,41 +123,47 @@ class BrickItem extends RenderItem<Brick, Shape> {
}
class TankItem extends RenderItem<Tank, Animate> {
class AnimateItem<T:TRectangle> extends RenderItem<T, Animate> {
public function new(value:T) {
super(value);
view = new Animate();
}
override public function dispose():Void {
view.dispose();
}
}
class TankItem extends RenderItem<Tank, Sprite> {
private var type:String;
private var hits:Int;
private var tankView:Animate;
public function new(value:Tank) {
super(value);
view = new Animate();
view = new Sprite();
tankView = new Animate();
view.addChild(tankView);
redraw();
}
override public function redraw():Void {
view.frames = getFrames().map(function(s) return Assets.getBitmapData(s));
var colors:Array<Color> = [value.color, value.bonus ? 0xff00aa : value.color];
var frames = [for (frame in getFrames()) BitmapUtil.colorize(Assets.getBitmapData(frame), colors.shift())];
tankView.frames = [
frames[0], frames[0], frames[0],
frames[1], frames[1], frames[1],
];
}
private function getFrames():Array<String> {
var team = value.playerId.team;
var group = value.config.group;
var index = value.playerId.index;
if (team == 'radiant') {
index = 0;
}
if (team == 'dire') {
index = 1;
}
if (team == 'human' || team == 'radiant' || team == 'dire') {
group = 'player';
}
if (team == 'bot') {
index = value.hits;
}
return [
'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-0.png',
'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-1.png',
];
var frame0 = 'resources/image/tank/${value.config.skin}-0.png';
var frame1 = 'resources/image/tank/${value.config.skin}-1.png';
return [frame1, frame0];
}
override public function update():Void {
@@ -160,13 +175,13 @@ class TankItem extends RenderItem<Tank, Animate> {
this.hits = h;
redraw();
}
view.playing = (value.mx !=0 || value.my != 0);
tankView.playing = (value.mx !=0 || value.my != 0);
}
override public function dispose():Void {
if (view != null) {
view.dispose();
view = null;
if (tankView != null) {
tankView.dispose();
tankView = null;
}
}
}
@@ -188,3 +203,19 @@ class EagleItem extends BitmapItem<Eagle> {
return 'resources/images/eagle/eagle-${destoyed ? 1 : 0}.png';
}
}
class BonusItem extends AnimateItem<Bonus> {
public function new(value:Bonus) {
super(value);
redraw();
}
override public function redraw():Void {
var image = Assets.getBitmapData('resources/image/bonus/${value.bonusType}.png');
var empty = new BitmapData(image.width, image.height, true, 0x00000000);
view.frames = [for (i in 0...15) image].concat([for (i in 0...15) empty]);
view.playing = true;
}
}

View File

@@ -15,7 +15,7 @@ interface LevelFrameLayout {
@:template("layout/frames/level.json", "layout/styles.json")
class LevelFrame extends VGroupView implements ViewBuilder implements LevelFrameLayout implements ListViewListener<Int> {
class LevelFrame extends VGroupView implements ViewBuilder implements LevelFrameLayout {
public static inline var ID = "level";
public function init():Void {

View File

@@ -1,53 +1,60 @@
package ru.m.tankz.view.frames;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
import haxework.gui.ButtonView;
import haxework.gui.frame.IFrameSwitcher;
import haxework.gui.VGroupView;
import haxework.gui.ViewBuilder;
import haxework.provider.Provider;
import ru.m.tankz.game.ClassicGame;
import ru.m.tankz.game.DotaGame;
import haxework.gui.frame.IFrameSwitcher;
import haxework.provider.Provider;
import haxework.gui.ButtonView;
import haxework.gui.ViewBuilder;
import haxework.gui.VGroupView;
import ru.m.tankz.game.GameState;
import ru.m.tankz.Type;
interface StartFrameLayout {
var start_1p(default, null):ButtonView;
var start_2p(default, null):ButtonView;
var dota(default, null):ButtonView;
var classic_1p(default, null):ButtonView;
var classic_2p(default, null):ButtonView;
var dota_1p(default, null):ButtonView;
var dota_2p_coop(default, null):ButtonView;
var dota_2p_vs(default, null):ButtonView;
}
@:template("layout/frames/start.json", "layout/styles.json")
class StartFrame extends VGroupView implements ViewBuilder implements StartFrameLayout {
public static inline var ID = "start";
public function init() {
start_1p.onPress = this;
start_2p.onPress = this;
dota.onPress = this;
classic_1p.onPress = this;
classic_2p.onPress = this;
dota_1p.onPress = this;
dota_2p_coop.onPress = this;
dota_2p_vs.onPress = this;
}
public function onPress(view:ButtonView):Void {
switch (view.id) {
case 'start_1p':
startGame(ClassicGame.TYPE, 1);
case 'start_2p':
startGame(ClassicGame.TYPE, 2);
case 'dota':
startGame(DotaGame.TYPE, 2);
case 'classic_1p':
startGame(ClassicGame.TYPE, ClassicGame.PLAYER1);
case 'classic_2p':
startGame(ClassicGame.TYPE, ClassicGame.PLAYER2);
case 'dota_1p':
startGame(DotaGame.TYPE, DotaGame.PLAYER1);
case 'dota_2p_coop':
startGame(DotaGame.TYPE, DotaGame.PLAYER2_COOP);
case 'dota_2p_vs':
startGame(DotaGame.TYPE, DotaGame.PLAYER2_VS);
}
}
private function startGame(type:GameType, humans:Int):Void {
private function startGame(type:GameType, mode:GameMode):Void {
switch (type) {
case ClassicGame.TYPE:
Provider.set(GameState, ClassicGame.buildState(0, humans));
Provider.set(GameState, ClassicGame.buildState(0, mode));
Provider.get(IFrameSwitcher).change(LevelFrame.ID);
case DotaGame.TYPE:
Provider.set(GameState, DotaGame.buildState(0, humans));
Provider.get(IFrameSwitcher).change(GameFrame.ID);
Provider.set(GameState, DotaGame.buildState(0, mode));
Provider.get(IFrameSwitcher).change(LevelFrame.ID);
}
}
}

View File

@@ -9,89 +9,33 @@ map:
gridHeight: 26
bricks:
# border
- type: -1
layer: 2
armor: -1
# none
- type: 0
layer: 0
armor: 0
# ace
- type: 1
layer: 0
armor: 0
# bush
- type: 2
layer: 3
armor: 0
# water
- type: 3
layer: 1
armor: 0
# armor
- type: 4
layer: 2
armor: 2
# brick
- type: 5
layer: 2
armor: 1
- {type: -1, layer: 2, armor: -1} # border
- {type: 0, layer: 0, armor: 0} # none
- {type: 1, layer: 0, armor: 0} # ace
- {type: 2, layer: 3, armor: 0} # bush
- {type: 3, layer: 1, armor: 0} # water
- {type: 4, layer: 2, armor: 2} # armor
- {type: 5, layer: 2, armor: 1} # brick
teams:
- id: human
spawnInterval: 0
tanks:
- group: human
type: 0
rate: 1
points:
- type: eagle
index: -1
x: 12
y: 24
direction: right
- type: tank
index: 0
x: 8
y: 24
direction: top
- type: tank
index: 1
x: 16
y: 24
direction: top
- {type: human0, rate: 1}
- id: bot
spawnInterval: 3000
tanks:
- group: bot
type: 0
rate: 0.5
- group: bot
type: 1
rate: 0.5
- group: bot
type: 2
rate: 0.5
- group: bot
type: 3
rate: 0.5
- {type: bot0, rate: 0.25, bonus: 0.25}
- {type: bot1, rate: 0.25, bonus: 0.25}
- {type: bot2, rate: 0.25, bonus: 0.25}
- {type: bot3, rate: 0.25, bonus: 0.25}
points:
- type: tank
index: -1
x: 0
y: 0
direction: bottom
- type: tank
index: -1
x: 12
y: 0
direction: bottom
- type: tank
index: -1
x: 24
y: 0
direction: bottom
- {team: human, type: eagle, index: -1, direction: right, x: 12, y: 24}
- {team: human, type: tank, index: 0, direction: top, x: 8, y: 24}
- {team: human, type: tank, index: 1, direction: top, x: 16, y: 24}
- {team: bot, type: tank, index: -1, direction: bottom, x: 0, y: 0}
- {team: bot, type: tank, index: -2, direction: bottom, x: 12, y: 0}
- {team: bot, type: tank, index: -3, direction: bottom, x: 24, y: 0}
bullet: &bullet
width: 12
@@ -100,8 +44,8 @@ bullet: &bullet
piercing: 1
tanks:
human:
- type: 0
- type: human0
upgrade: human1
width: 36
height: 36
speed: 2.5
@@ -109,8 +53,10 @@ tanks:
<<: *bullet
speed: 8.0
bullets: 1
skin: pa
- type: 1
- type: human1
upgrade: human2
width: 40
height: 36
speed: 3.0
@@ -118,8 +64,10 @@ tanks:
<<: *bullet
speed: 8.5
bullets: 1
skin: pb
- type: 2
- type: human2
upgrade: human3
width: 40
height: 36
speed: 3.0
@@ -127,8 +75,10 @@ tanks:
<<: *bullet
speed: 9.0
bullets: 2
skin: pc
- type: 3
- type: human3
upgrade: human3
width: 42
height: 38
speed: 2.9
@@ -137,9 +87,10 @@ tanks:
speed: 9.0
piercing: 3
bullets: 2
hits: 1
skin: pd
bot:
- type: 0
- type: bot0
width: 38
height: 36
speed: 2.0
@@ -148,8 +99,9 @@ tanks:
speed: 7.0
bullets: 1
score: 100
skin: ba
- type: 1
- type: bot1
width: 40
height: 36
speed: 4.0
@@ -158,8 +110,9 @@ tanks:
speed: 7.0
bullets: 1
score: 200
skin: bb
- type: 2
- type: bot2
width: 38
height: 36
speed: 2.0
@@ -168,8 +121,9 @@ tanks:
speed: 9.0
bullets: 1
score: 300
skin: bc
- type: 3
- type: bot3
width: 40
height: 36
speed: 1.8
@@ -179,3 +133,12 @@ tanks:
bullets: 1
score: 400
hits: 3
skin: bd
bonuses:
- {type: clock}
- {type: grenade}
- {type: helmet}
- {type: life}
- {type: shovel}
- {type: star}

View File

@@ -1,95 +0,0 @@
[keyboard]
reset = 27 ;Escape
pause = 80 ;P
[player0]
key_left = 37 ;Left
key_up = 38 ;Up
key_right = 39 ;Rigth
key_down = 40 ;Down
key_shot = 96 ;Num0
[player1]
key_left = 65 ;A
key_up = 87 ;W
key_right = 68 ;D
key_down = 83 ;S
key_shot = 32 ;Space
[bonus]
score = 500
freeztime = 10
eagletime = 20
protecttime = 15
[bots]
count = 20 ;количество ботов на уровне
respawntime = 2.5 ;задержка между появлением ботов в секундах
shotdelay = 1.0 ;задержка между выстрелами
turndelay = 0.3 ;задержка перед поворотом при столкновении
rndturndelay = 2.0 ;задержка перед случайным поворотом
turntoeagle = 0.75 ;вероятность поворота к Орлу
bonus = 0.25 ;вероятность появления бонусного танка
[tank_p0]
movespeed = 2.5 ;скорость передвижения
bulletspeed = 8.0 ;скорость полёта снаряда
bullettype = 0 ;тип снаряда (0 - обычный, 1 - бронебойный)
bulletcount = 1 ;количество снарядов
hits = 1 ;количество хитпойнтов
[tank_p1]
movespeed = 3.0
bulletspeed = 8.5
bullettype = 0
bulletcount = 1
hits = 1
[tank_p2]
movespeed = 3.0
bulletspeed = 9.0
bullettype = 0
bulletcount = 2
hits = 1
[tank_p3]
movespeed = 2.9
bulletspeed = 9.0
bullettype = 1
bulletcount = 2
hits = 2
[tank_b0]
movespeed = 2.0
bulletspeed = 7.0
bullettype = 0
bulletcount = 1
hits = 1
score = 100
[tank_b1]
movespeed = 4.0
bulletspeed = 7.0
bullettype = 0
bulletcount = 1
hits = 1
score = 200
[tank_b2]
movespeed = 2.0
bulletspeed = 9.0
bullettype = 0
bulletcount = 1
hits = 1
score = 300
[tank_b3]
movespeed = 1.8
bulletspeed = 8.0
bullettype = 0
bulletcount = 1
hits = 4
score = 400

View File

@@ -1,5 +1,5 @@
game:
levels: 2
levels: 7
friendlyFire: true
map:
@@ -9,120 +9,40 @@ map:
gridHeight: 30
bricks:
# border
- type: -1
layer: 2
armor: -1
# none
- type: 0
layer: 0
armor: 0
# ace
- type: 1
layer: 0
armor: 0
# bush
- type: 2
layer: 3
armor: 0
# water
- type: 3
layer: 1
armor: 0
# armor
- type: 4
layer: 2
armor: 2
# brick
- type: 5
layer: 2
armor: 1
- {type: -1, layer: 2, armor: -1} # border
- {type: 0, layer: 0, armor: 0} # none
- {type: 1, layer: 0, armor: 0} # ace
- {type: 2, layer: 3, armor: 0} # bush
- {type: 3, layer: 1, armor: 0} # water
- {type: 4, layer: 2, armor: 2} # armor
- {type: 5, layer: 2, armor: 1} # brick
team_tanks: &team_tanks
tanks:
- group: any
type: 0
rate: 0.25
- group: any
type: 1
rate: 0.25
- group: any
type: 2
rate: 0.25
# - group: any
# type: 3
# rate: 0.25
- {type: slow, rate: 0.5}
- {type: fast, rate: 0.5}
teams:
- <<: *team_tanks
id: radiant
spawnInterval: 0
points:
- type: eagle
index: -1
x: 0
y: 28
direction: right
- type: tank
index: 0
x: 0
y: 0
direction: right
- type: tank
index: 1
x: 6
y: 10
direction: right
- type: tank
index: 2
x: 6
y: 16
direction: right
- type: tank
index: 3
x: 6
y: 22
direction: right
- type: tank
index: 4
x: 10
y: 28
direction: right
color: 0xff5555
- <<: *team_tanks
id: dire
spawnInterval: 0
points:
- type: eagle
index: -1
x: 38
y: 0
direction: right
- type: tank
index: 0
x: 38
y: 28
direction: left
- type: tank
index: 1
x: 32
y: 18
direction: left
- type: tank
index: 2
x: 32
y: 12
direction: left
- type: tank
index: 3
x: 32
y: 6
direction: left
- type: tank
index: 4
x: 28
y: 0
direction: left
color: 0x5555ff
points:
- {team: radiant, type: eagle, index: -1, direction: right, x: 0, y: 28}
- {team: radiant, type: tank, index: 0, direction: right, x: 0, y: 0}
- {team: radiant, type: tank, index: 1, direction: right, x: 6, y: 10}
- {team: radiant, type: tank, index: 2, direction: right, x: 6, y: 16}
- {team: radiant, type: tank, index: 3, direction: right, x: 6, y: 22}
- {team: radiant, type: tank, index: 4, direction: right, x: 10, y: 28}
- {team: dire, type: eagle, index: -1, direction: right, x: 38, y: 0}
- {team: dire, type: tank, index: 0, direction: left, x: 38, y: 28}
- {team: dire, type: tank, index: 1, direction: left, x: 32, y: 18}
- {team: dire, type: tank, index: 2, direction: left, x: 32, y: 12}
- {team: dire, type: tank, index: 3, direction: left, x: 32, y: 6}
- {team: dire, type: tank, index: 4, direction: left, x: 28, y: 0}
bullet: &bullet
width: 12
@@ -131,40 +51,30 @@ bullet: &bullet
piercing: 1
tanks:
any:
- type: 0
width: 36
- type: slow
width: 38
height: 36
speed: 2.5
speed: 2.3
bullet:
<<: *bullet
speed: 12.0
bullets: 1
skin: bc
- type: fast
width: 40
height: 36
speed: 4.0
bullet:
<<: *bullet
speed: 8.0
bullets: 1
skin: bb
- type: 1
width: 40
height: 36
speed: 3.0
bullet:
<<: *bullet
speed: 8.5
bullets: 1
- type: 2
width: 40
height: 36
speed: 3.0
bullet:
<<: *bullet
speed: 9.0
bullets: 2
- type: 3
width: 42
height: 38
speed: 2.9
bullet:
<<: *bullet
speed: 9.0
piercing: 3
bullets: 2
bonuses:
- {type: clock}
- {type: grenade}
- {type: helmet}
- {type: life}
- {type: shovel}
- {type: star}

View File

@@ -1,30 +1,2 @@
0000000000000000000000000000000000005500
0000000000000000000000000000000000005500
0000000000000000000000000000000000005555
0000000000000000000000000000000000005555
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
5555000000000000000000000000000000000000
5555000000000000000000000000000000000000
0055000000000000000000000000000000000000
0055000000000000000000000000000000000000
points: [{index: -1, team: radiant, x: 0, direction: right, type: eagle, y: 28}, {index: 0, team: radiant, x: 0, direction: right, type: tank, y: 0}, {index: 1, team: radiant, x: 6, direction: right, type: tank, y: 10}, {index: 2, team: radiant, x: 6, direction: right, type: tank, y: 16}, {index: 3, team: radiant, x: 6, direction: right, type: tank, y: 22}, {index: 4, team: radiant, x: 10, direction: right, type: tank, y: 28}, {index: -1, team: dire, x: 38, direction: right, type: eagle, y: 0}, {index: 0, team: dire, x: 38, direction: left, type: tank, y: 28}, {index: 1, team: dire, x: 32, direction: left, type: tank, y: 18}, {index: 2, team: dire, x: 32, direction: left, type: tank, y: 12}, {index: 3, team: dire, x: 32, direction: left, type: tank, y: 6}, {index: 4, team: dire, x: 28, direction: left, type: tank, y: 0}]
data: "000044000000000000000000005500004400550000004400000000000000000000550000440055000000440000004400003333000055000044005555000044000000440000333300005500004400555500004422442244000000000000550000440000000000442244224400000000000055000044000000000000000000444444555544444400442200330000000000000044444455554444440044220033005555333333554422220000222244000022003300555533333355442222000022224400002200330000000000000044220000000022440000440033000000000000004422000000002244000044003300000000000000550000555500005500002200000000000000000055000055550000550000220000004444444400005500445555440055000044444444444444440000550044555544005500004444444400000022000055000055550000550000000000000000002200005500005555000055000000000000003300440000442200000000224400000000000000330044000044220000000022440000000000000033002200004422220000222244553333335555003300220000442222000022224455333333555500330022440044444455554444440000000000000033002244004444445555444444000000000000000000440000550000000000004422442244000000000044000055000000000000442244224400005555004400005500003333000044000000440000555500440000550000333300004400000044000000550044000055000000000000000000004400000055004400005500000000000000000000440000"

View File

@@ -1,30 +1,2 @@
0000000000000000000000000000000000004400
0000000000000000000000000000000000004400
0000000000000000000000000000000000004444
0000000000000000000000000000000000004444
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
4444000000000000000000000000000000000000
4444000000000000000000000000000000000000
0044000000000000000000000000000000000000
0044000000000000000000000000000000000000
points: [{index: -1, direction: right, team: radiant, type: eagle, y: 28, x: 0}, {index: 0, direction: right, team: radiant, type: tank, y: 2, x: 2}, {index: 1, direction: right, team: radiant, type: tank, y: 6, x: 2}, {index: 2, direction: right, team: radiant, type: tank, y: 10, x: 2}, {index: 3, direction: right, team: radiant, type: tank, y: 14, x: 2}, {index: 4, direction: right, team: radiant, type: tank, y: 18, x: 2}, {index: -1, direction: right, team: dire, type: eagle, y: 28, x: 38}, {index: 0, direction: left, team: dire, type: tank, y: 2, x: 36}, {index: 1, direction: left, team: dire, type: tank, y: 6, x: 36}, {index: 2, direction: left, team: dire, type: tank, y: 10, x: 36}, {index: 3, direction: left, team: dire, type: tank, y: 14, x: 36}, {index: 4, direction: left, team: dire, type: tank, y: 18, x: 36}]
data: "005500330033003300333300330033003300550000550033003300330033330033003300330055000000000000330033000000003300330000000000000000000033003300000000330033000000000000550033000000330000000033000000330055000055003300000033000000003300000033005500000000330000003300333300330000003300000000000033000000330033330033000000330000000055000000330033003333003300330000005500005500000033003300333300330033000000550000000033003300330033330033003300330000000000003300330033003333003300330033000000005500330000003300333300330000003300550000550033000000330033330033000000330055000000000000330033003333003300330000000000000000000033003300333300330033000000000000550033003300330033330033003300330055000055003300330033003333003300330033005500000000330033003300333300330033003300000000000033003300330033330033003300330000005555553300330033003333003300330033555555555555330033003300333300330033003355555555555533003300330033330033003300335555555555553300330033003333003300330033555555440000330033000000333300000033000000004444000033003300000033330000003300000000440000443300330000003333000000330033440000000044330033000000333300000033003344000000440033003300330033330033003300330044000044003300330033003333003300330033004400"

View File

@@ -0,0 +1,2 @@
data: "000000000000000000000000000000440000000000000000000000000000000000000044000000000044003300005500440000440055000000000000004400330000550044000044005500000000000000000000440000000000000000000055004400000000000044000000000000000000005500440000003300000000330044003300440000000000000000330000000033004400330044000000000000000000440055000000000000000000005500003300000044005500000000000000000000550000330000000000000055000044005500440000004400000000000000005500004400550044000000440000555500003300000000000000000000000000555555550000330000000000000000000000000055550055440000004400330000000000003300445500005544000000440033000000000000330044550055550000440000000044004400550000000055555555000044000000004400440055000000005555000000000000000000000000000044000044000000000000000000000000000000004400004400000044000044000044005500004400000000000000004400004400004400550000440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003300000000550000330055003300005500440000330000000055000033005500330000550044000000440033000000440000000000440000000000000044003300000044000000000044000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
points: [{direction: right, team: radiant, x: 0, type: eagle, y: 14, index: -1}, {direction: right, team: radiant, x: 0, type: tank, y: 0, index: 0}, {direction: right, team: radiant, x: 6, type: tank, y: 10, index: 1}, {direction: right, team: radiant, x: 6, type: tank, y: 16, index: 2}, {direction: right, team: radiant, x: 6, type: tank, y: 22, index: 3}, {direction: right, team: radiant, x: 10, type: tank, y: 28, index: 4}, {direction: right, team: dire, x: 38, type: eagle, y: 14, index: -1}, {direction: left, team: dire, x: 38, type: tank, y: 28, index: 0}, {direction: left, team: dire, x: 32, type: tank, y: 18, index: 1}, {direction: left, team: dire, x: 32, type: tank, y: 12, index: 2}, {direction: left, team: dire, x: 32, type: tank, y: 6, index: 3}, {direction: left, team: dire, x: 28, type: tank, y: 0, index: 4}]

View File

@@ -0,0 +1,2 @@
points: [{index: -1, direction: right, team: radiant, x: 24, type: eagle, y: 26}, {index: 0, direction: right, team: radiant, x: 14, type: tank, y: 26}, {index: 1, direction: right, team: radiant, x: 20, type: tank, y: 20}, {index: 2, direction: right, team: radiant, x: 26, type: tank, y: 20}, {index: 3, direction: right, team: radiant, x: 34, type: tank, y: 24}, {index: 4, direction: right, team: radiant, x: 38, type: tank, y: 22}, {index: -1, direction: right, team: dire, x: 22, type: eagle, y: 2}, {index: 0, direction: left, team: dire, x: 8, type: tank, y: 2}, {index: 1, direction: left, team: dire, x: 12, type: tank, y: 6}, {index: 2, direction: left, team: dire, x: 20, type: tank, y: 6}, {index: 3, direction: left, team: dire, x: 21, type: tank, y: 10}, {index: 4, direction: left, team: dire, x: 28, type: tank, y: 4}]
data: "444444444400000000440000004444000000000044444444440000000044000000444400000000004444440000004444004400000044440033444400444444000000444400440000004444003344440000000000440000440044000000000000000000000000000044000044004400000000000000000000003344004400000000000044004444440000444400334400440000000000004400444444000044440000000000004400444444440033440000005544000000000000440044444444003344000000554444004433440044444400000000004400440000004400443344004444440000000000440044000000440000000000004444004444440044004444440044000000000000444400444444004400444444000000440055440044440044440000000055444400000044005544004444004444000000005544440000444400444400000000000000443300000000000044440044440000000000000044330000000000000044004444003300444444004444004433004400004400444400330044444400444400443300444400000000000033000000000000000044000000440000000000003300000000000000004400000044440044004444444400444444440000440044004444004400444444440044444444000044004400000000000000440000000000000000000000440000000000000044000000000000000000000044004455003344000000440044000000440033444400445500334400000044004400000044003344440044440000000044000000440000004400000000004444000000004400000044000000440000000000"

View File

@@ -0,0 +1,2 @@
points: [{index: -1, direction: right, team: radiant, x: 12, type: eagle, y: 2}, {index: 0, direction: right, team: radiant, x: 6, type: tank, y: 6}, {index: 1, direction: right, team: radiant, x: 10, type: tank, y: 10}, {index: 2, direction: right, team: radiant, x: 14, type: tank, y: 10}, {index: 3, direction: right, team: radiant, x: 18, type: tank, y: 6}, {index: 4, direction: right, team: radiant, x: 20, type: tank, y: 2}, {index: -1, direction: right, team: dire, x: 22, type: eagle, y: 26}, {index: 0, direction: left, team: dire, x: 12, type: tank, y: 26}, {index: 1, direction: left, team: dire, x: 18, type: tank, y: 22}, {index: 2, direction: left, team: dire, x: 24, type: tank, y: 22}, {index: 3, direction: left, team: dire, x: 28, type: tank, y: 18}, {index: 4, direction: left, team: dire, x: 30, type: tank, y: 10}]
data: "000000000033333300000000000000000000000000000000003333330000000000000000000000000000004400330033004400000000003300000044000000440033003300440000000000330000004400000000003333330000000044440000000000000000000000333333000000004444000000000000000000000000000000003300000000004444000000000000000000000000330000000000444400000044000000004400000000004400000044000000004400000000440000000000440000004400000000000033000000000000004444000000000000000000003300000000000000444400000000000000000000000000330000440000000033000000000000000000000033000044000000003300000000000000000000000000444400004400000000000000000000000000000044440000440000000000000000000000334444004444000000000044000000000000000033444400444400000000004400000000004400000044000000000000330000440000000000440000004400000000000033000044000000000000440000000000330000440000000000000033000044000000000033000044000000000000003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000003333330000000033000000000000004400000000333333000000003300000000000000000000440033003300440000000000000000000000000044003300330044000000000000000000000000000000333333000000000000000000000000000000000033333300000000000000"

View File

@@ -0,0 +1,2 @@
points: [{index: -1, direction: right, team: radiant, x: 19, type: eagle, y: 28}, {index: 0, direction: right, team: radiant, x: 0, type: tank, y: 28}, {index: 1, direction: right, team: radiant, x: 10, type: tank, y: 22}, {index: 2, direction: right, team: radiant, x: 19, type: tank, y: 18}, {index: 3, direction: right, team: radiant, x: 28, type: tank, y: 22}, {index: 4, direction: right, team: radiant, x: 38, type: tank, y: 28}, {index: -1, direction: right, team: dire, x: 19, type: eagle, y: 0}, {index: 0, direction: left, team: dire, x: 0, type: tank, y: 0}, {index: 1, direction: left, team: dire, x: 10, type: tank, y: 6}, {index: 2, direction: left, team: dire, x: 19, type: tank, y: 10}, {index: 3, direction: left, team: dire, x: 28, type: tank, y: 6}, {index: 4, direction: left, team: dire, x: 38, type: tank, y: 0}]
data: "000000000000440000000000004400000000000000000000000044000000000000440000000000004400000000000000000440000000000000000044440000000000000000044000000000000000004400000000005555555555555555555500000000000000000000555555555555555555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000440000000000000000440000000000000000000044000000005555555544333333333553333333334455555555555555554433333333355333333333445555555500000000440000000000000000000044000000000000000044000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055555555555555555555000000000000000000005555555555555555555500000000004400000000000000000440000000000000000044440000000000000000044000000000000000004400000000000044000000000000440000000000000000000000004400000000000044000000000000"

View File

@@ -0,0 +1,2 @@
points: [{index: -1, direction: right, team: radiant, x: 19, type: eagle, y: 28}, {index: 0, direction: right, team: radiant, x: 2, type: tank, y: 22}, {index: 1, direction: right, team: radiant, x: 9, type: tank, y: 20}, {index: 2, direction: right, team: radiant, x: 19, type: tank, y: 24}, {index: 3, direction: right, team: radiant, x: 29, type: tank, y: 20}, {index: 4, direction: right, team: radiant, x: 36, type: tank, y: 22}, {index: -1, direction: right, team: dire, x: 19, type: eagle, y: 0}, {index: 0, direction: left, team: dire, x: 2, type: tank, y: 6}, {index: 1, direction: left, team: dire, x: 9, type: tank, y: 8}, {index: 2, direction: left, team: dire, x: 19, type: tank, y: 4}, {index: 3, direction: left, team: dire, x: 29, type: tank, y: 8}, {index: 4, direction: left, team: dire, x: 36, type: tank, y: 6}]
data: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005555555544444455555555000000000000000000555555554444445555555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005500000000000000550000000000000000000000550000000000000055000000000000000000000055000000000000005500000000000000000000005500000000000000550000000000000000000000000044000000440000000000000000000000000000004400000044000000000000000333333333333333445500004433333333333333333333333333333344550000443333333333333333333333333333334400440044333333333333333333333333333333440044004433333333333333333333333333333344000055443333333333333333333333333333334400005544333333333333333000000000000000440000004400000000000000000000000000000044000000440000000000000000000000000055000000000000005500000000000000000000005500000000000000550000000000000000000000550000000000000055000000000000000000000055000000000000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005555555544444455555555000000000000000000555555554444445555555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

View File

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

View File

Before

Width:  |  Height:  |  Size: 541 B

After

Width:  |  Height:  |  Size: 541 B

View File

Before

Width:  |  Height:  |  Size: 455 B

After

Width:  |  Height:  |  Size: 455 B

View File

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

View File

@@ -1,20 +1,22 @@
package ru.m.tankz;
import ru.m.tankz.proto.pack.LeaveGameRequest;
import ru.m.tankz.proto.pack.LeaveGameResponse;
import ru.m.tankz.proto.pack.GameUpdateResponse;
import ru.m.tankz.proto.pack.GameActionRequest;
import ru.m.connect.IConnection;
import protohx.Message;
import ru.m.tankz.proto.pack.ErrorResponse;
import ru.m.tankz.proto.pack.GameListRequest;
import ru.m.tankz.proto.pack.GameListResponse;
import ru.m.connect.IConnection;
import ru.m.tankz.proto.pack.CreateGameRequest;
import ru.m.tankz.proto.pack.CreateGameResponse;
import ru.m.tankz.proto.pack.ErrorResponse;
import ru.m.tankz.proto.pack.GameActionRequest;
import ru.m.tankz.proto.pack.GameListRequest;
import ru.m.tankz.proto.pack.GameListResponse;
import ru.m.tankz.proto.pack.GameUpdateResponse;
import ru.m.tankz.proto.pack.JoinGameRequest;
import ru.m.tankz.proto.pack.JoinGameResponse;
import ru.m.tankz.proto.pack.LeaveGameRequest;
import ru.m.tankz.proto.pack.LeaveGameResponse;
import ru.m.tankz.proto.pack.StartGameRequest;
import ru.m.tankz.proto.pack.StartGameResponse;
import Type;
class PacketBuilder implements IPacketBuilder {

View File

@@ -0,0 +1,26 @@
package ru.m.tankz;
import ru.m.draw.Color;
typedef Type = Dynamic;
typedef GameType = String;
typedef TeamId = String;
typedef ControlType = String;
typedef BrickType = Int;
typedef TankType = String;
typedef BonusType = String;
typedef PlayerId = {
var team:TeamId;
var type:ControlType;
var index:Int;
@:optional var color:Color;
}
typedef GameMode = Array<PlayerId>;

View File

@@ -1,20 +1,59 @@
package ru.m.tankz.bot;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.control.Control;
import ru.m.geom.Direction;
import haxe.Timer;
import ru.m.geom.Direction;
import ru.m.tankz.control.Control;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank;
import ru.m.tankz.Type;
class BotHelper {
public static function findEagle(team:TeamId, handler:ControlHandler):Null<Eagle> {
for (entity in handler.entities) {
switch (EntityTypeResolver.of(entity)) {
case EntityType.EAGLE(eagle):
if (eagle.team != team) {
return eagle;
}
case x:
}
}
return null;
}
public static function getDirectionTo(entity:Entity, target:Entity):Direction {
var x:Float = target.rect.x - entity.rect.x;
var y:Float = target.rect.y - entity.rect.y;
var xD:Direction = Direction.from(Std.int(x / Math.abs(x)), 0);
var yD:Direction = Direction.from(0, Std.int(y / Math.abs(y)));
if (entity.rect.direction == xD) return yD;
if (entity.rect.direction == yD) return xD;
return Math.abs(x) > Math.abs(y) ? xD : yD;
}
public static function randomDirection():Direction {
return [
Direction.TOP,
Direction.BOTTOM,
Direction.LEFT,
Direction.RIGHT,
][Math.floor(Math.random() * 4)];
}
}
class BotControl extends Control {
public static var TYPE(default, never):ControlType = 'bot';
private var shotTimer:Timer;
private var turnRandomTimer:Timer;
private var turnTimer:Timer;
private var turnDelayTimer:Timer;
private var tank(get, null):Tank;
public function new(index:Int) {
super({type:TYPE, index:index});
public function new(playerId:PlayerId) {
super(playerId);
}
override public function onCollision(with:EntityType):Void {
@@ -27,15 +66,14 @@ class BotControl extends Control {
override public function start():Void {
if (handler == null) return;
var tank = handler.entities.get(tankId);
action(TankAction.MOVE(tank.rect.direction));
if (shotTimer == null) {
shotTimer = new Timer(1000);
shotTimer.run = shot;
}
if (turnTimer == null) {
turnTimer = new Timer(2000);
turnTimer.run = turn;
if (turnRandomTimer == null) {
turnRandomTimer = new Timer(2000);
turnRandomTimer.run = turn;
}
}
@@ -44,9 +82,9 @@ class BotControl extends Control {
shotTimer.stop();
shotTimer = null;
}
if (turnTimer != null) {
turnTimer.stop();
turnTimer = null;
if (turnRandomTimer != null) {
turnRandomTimer.stop();
turnRandomTimer = null;
}
}
@@ -55,26 +93,27 @@ class BotControl extends Control {
}
public function turnAfter(delay:Int):Void {
if (turnDelayTimer == null) {
turnDelayTimer = new Timer(delay);
turnDelayTimer.run = function() {
turnDelayTimer.stop();
turnDelayTimer = null;
turn();
}
if (turnTimer == null) {
turnTimer = Timer.delay(turn, delay);
}
}
public function turn():Void {
action(TankAction.MOVE(randomDirection()));
if (turnTimer != null) {
turnTimer.stop();
turnTimer = null;
}
// ToDo:
if (handler == null || tank == null) return;
var eagle:Eagle = BotHelper.findEagle(playerId.team, handler);
if (eagle != null && Math.random() > 0.25) {
action(TankAction.MOVE(BotHelper.getDirectionTo(tank, eagle)));
} else {
action(TankAction.MOVE(BotHelper.randomDirection()));
}
}
private function randomDirection():Direction {
return [
Direction.TOP,
Direction.BOTTOM,
Direction.LEFT,
Direction.RIGHT,
][Math.floor(Math.random() * 4)];
private function get_tank():Tank {
return cast handler.entities[tankId];
}
}

View File

@@ -1,5 +1,8 @@
package ru.m.tankz.config;
import ru.m.draw.Color;
import ru.m.tankz.Type;
typedef GameConfig = {
var levels: Int;
@@ -7,6 +10,7 @@ typedef GameConfig = {
}
typedef SpawnPoint = {
var team:TeamId;
var type:String;
var index:Int;
var x:Int;
@@ -22,7 +26,7 @@ typedef MapConfig = {
}
typedef BrickConfig = {
var type:Int;
var type:BrickType;
var layer:Int;
var armor:Int;
}
@@ -34,32 +38,41 @@ typedef BulletConfig = {
var piercing:Int;
}
typedef TankType = {
var group:String;
var type:String;
}
typedef TankConfig = { > TankType,
typedef TankConfig = {
var type:TankType;
var width:Float;
var height:Float;
var speed:Float;
var bullet:BulletConfig;
var bullets:Int;
var hits:Int;
var skin:String;
@:optinal var upgrade:TankType;
}
typedef TankSpawn = { > TankType,
typedef BonusConfig = {
var type:BonusType;
}
typedef TankSpawn = {
var type:TankType;
var rate:Float;
@:optional var bonus:Float;
}
typedef TeamConfig = {
var id:String;
var id:TeamId;
var size:Int;
var spawnInterval:Int;
var tanks:Array<TankSpawn>;
var points:Array<SpawnPoint>;
@:optional var spawnInterval:Int;
@:optional var color:Color;
}
typedef LevelConfig = {
var data:Array<BrickConfig>;
@:optional var points:Array<SpawnPoint>;
}
@@ -70,18 +83,32 @@ class Config {
public var bricks(default, null):Array<BrickConfig>;
public var tanks(default, null):Array<TankConfig>;
public var teams(default, null):Array<TeamConfig>;
public var points(default, null):Array<SpawnPoint>;
public var bonuses(default, null):Array<BonusConfig>;
private var brickMap:Map<Int, BrickConfig>;
private var tankMap:Map<String, Map<String, TankConfig>>;
private var teamMap:Map<String, TeamConfig>;
private var tankMap:Map<TankType, TankConfig>;
private var teamMap:Map<TeamId, TeamConfig>;
private var bonusMap:Map<BonusType, BonusConfig>;
public function new(type:String, game:GameConfig, map:MapConfig, bricks:Array<BrickConfig>, teams:Array<TeamConfig>, tanks:Array<TankConfig>) {
public function new(
type:String,
game:GameConfig,
map:MapConfig,
bricks:Array<BrickConfig>,
teams:Array<TeamConfig>,
points:Array<SpawnPoint>,
tanks:Array<TankConfig>,
bonuses:Array<BonusConfig>
) {
this.type = type;
this.game = game;
this.map = map;
this.bricks = bricks;
this.teams = teams;
this.points = points;
this.tanks = tanks;
this.bonuses = bonuses;
init();
}
@@ -96,8 +123,11 @@ class Config {
}
tankMap = new Map();
for (item in tanks) {
if (!tankMap.exists(item.group)) tankMap.set(item.group, new Map<String, TankConfig>());
tankMap.get(item.group).set(item.type, item);
tankMap.set(item.type, item);
}
bonusMap = new Map();
for (item in bonuses) {
bonusMap.set(item.type, item);
}
}
@@ -109,7 +139,11 @@ class Config {
return teamMap.get(id);
}
public function getTank(group:String, type:String):TankConfig {
return tankMap.get(group).get(type);
public function getTank(type:TankType):TankConfig {
return tankMap.get(type);
}
public function getBonus(type:BonusType):BonusConfig {
return bonusMap.get(type);
}
}

View File

@@ -11,7 +11,9 @@ typedef ConfigSource = {
var map: MapConfig;
var bricks: Array<BrickConfig>;
var teams: Array<TeamConfig>;
var tanks: Dynamic<Array<TankConfig>>;
var points: Array<SpawnPoint>;
var tanks: Array<TankConfig>;
var bonuses: Array<BonusConfig>;
}
class ConfigBundle {
@@ -21,15 +23,7 @@ class ConfigBundle {
}
public static function get(type:String):Config {
var source:ConfigSource = convert(Yaml.parse(Assets.getText('resources/${type}/config.yaml'), Parser.options().useObjects()));
var tanks:Array<TankConfig> = [];
for (group in Reflect.fields(source.tanks)) {
var data:Array<TankConfig> = Reflect.field(source.tanks, group);
for (item in data) {
item.group = group;
tanks.push(item);
}
}
return new Config(type, source.game, source.map, source.bricks, source.teams, tanks);
var source = convert(Yaml.parse(Assets.getText('resources/${type}/config.yaml'), Parser.options().useObjects()));
return new Config(type, source.game, source.map, source.bricks, source.teams, source.points, source.tanks, source.bonuses);
}
}

View File

@@ -1,10 +1,18 @@
package ru.m.tankz.config;
import openfl.Assets;
import ru.m.tankz.game.Game;
import ru.m.tankz.config.Config;
import ru.m.tankz.Type;
import yaml.Parser;
import yaml.Renderer;
import yaml.Yaml;
typedef LevelSource = {
var data:String;
@:optional var points:Array<SpawnPoint>;
}
class LevelBundle {
private static function formatLevel(level:Int):String {
@@ -13,16 +21,48 @@ class LevelBundle {
return result;
}
public static function get(type:GameType, config:Config, level:Int):Array<BrickConfig> {
var bricksData:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
public static function loadsOld(config:Config, data:String):LevelConfig {
var bricks:Array<BrickConfig> = [];
for (line in ~/\s+/g.split(bricksData)) {
for (line in ~/\s+/g.split(data)) {
for (c in line.split('')) {
if (c.length > 0) {
bricks.push(config.bricks[Std.parseInt(c) + 1]);
bricks.push(config.getBrick(Std.parseInt(c)));
}
}
}
return bricks;
return {
data: bricks
}
}
public static function loads(config:Config, data:String):LevelConfig {
if (config.type == 'classic') {
return loadsOld(config, data);
} else {
var obj:LevelSource = Yaml.parse(data, Parser.options().useObjects());
return {
data: obj.data.split('').map(function(c) return config.getBrick(Std.parseInt(c))),
points: obj.points,
}
}
}
public static function dumps(config:Config, level:LevelConfig):String {
var bricksStr = level.data.map(function(brick:BrickConfig) return Std.string(brick.type)).join('');
return Yaml.render({
data: bricksStr,
points: level.points,
}, Renderer.options().setFlowLevel(1));
}
public static function empty(config:Config):LevelConfig {
return {
data: [for (i in 0...config.map.gridWidth * config.map.gridHeight) config.bricks[1]]
}
}
public static function get(type:GameType, config:Config, level:Int):LevelConfig {
var data:String = Assets.getText('resources/${type}/levels/level${formatLevel(level)}.txt');
return loads(config, data);
}
}

View File

@@ -1,34 +1,30 @@
package ru.m.tankz.control;
import ru.m.geom.Direction;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType;
import ru.m.geom.Direction;
import ru.m.tankz.Type;
enum TankAction {
MOVE(direction:Direction);
LEVEL_UP(level:Int);
UPGRADE;
STOP;
SHOT;
}
typedef ControlType = String;
typedef ControlId = {
var type:ControlType;
var index:Int;
}
class Control {
public var id:ControlId;
public static var NONE(default, never):ControlType = 'none';
public static var HUMAN(default, never):ControlType = 'human';
public static var BOT(default, never):ControlType = 'bot';
public var playerId(default, null):PlayerId;
public var tankId(default, default):Int;
private var handler:ControlHandler;
public function new(id:ControlId) {
this.id = id;
public function new(playerId:PlayerId) {
this.playerId = playerId;
}
public function bind(handler:ControlHandler):Void {

View File

@@ -0,0 +1,15 @@
package ru.m.tankz.core;
import ru.m.geom.Rectangle;
import ru.m.tankz.Type;
class Bonus extends Entity {
public var bonusType(default, null):BonusType;
public function new(bonusType:BonusType) {
super(new Rectangle(0, 0, 44, 44));
this.bonusType = bonusType;
}
}

View File

@@ -1,9 +1,9 @@
package ru.m.tankz.core;
import ru.m.tankz.game.Game;
import ru.m.tankz.config.Config;
import ru.m.geom.Rectangle;
import ru.m.geom.Direction;
import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config;
import ru.m.tankz.Type;
class Bullet extends MobileEntity {

View File

@@ -1,7 +1,7 @@
package ru.m.tankz.core;
import ru.m.tankz.game.Game;
import ru.m.geom.Rectangle;
import ru.m.tankz.Type;
class Eagle extends Entity {

View File

@@ -1,6 +1,7 @@
package ru.m.tankz.core;
import ru.m.geom.Rectangle;
import Type;
class Entity implements IKey {

View File

@@ -1,7 +1,7 @@
package ru.m.tankz.core;
import Type.ValueType;
import ru.m.tankz.map.Grid.GridCell;
import Type;
import ru.m.tankz.map.Grid;
enum EntityType {
@@ -9,6 +9,7 @@ enum EntityType {
TANK(tank:Tank);
BULLET(bullet:Bullet);
CELL(cell:GridCell);
BONUS(bonus:Bonus);
}
@@ -20,6 +21,7 @@ class EntityTypeResolver {
case ValueType.TClass(Tank): EntityType.TANK(cast entity);
case ValueType.TClass(Bullet): EntityType.BULLET(cast entity);
case ValueType.TClass(GridCell): EntityType.CELL(cast entity);
case ValueType.TClass(Bonus): EntityType.BONUS(cast entity);
case x: null;
}
}

View File

@@ -1,17 +1,20 @@
package ru.m.tankz.core;
import ru.m.tankz.game.Game;
import ru.m.draw.Color;
import ru.m.geom.Direction;
import ru.m.geom.Point;
import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config;
import ru.m.tankz.core.Bullet;
import ru.m.geom.Rectangle;
import ru.m.geom.Direction;
import ru.m.tankz.Type;
class Tank extends MobileEntity {
public var playerId(default, null):PlayerId;
public var config(default, set):TankConfig;
public var color(default, default):Color;
public var hits(default, default):Int;
public var bonus(default, default):Bool;
private var bulletsCounter:Int = 0;

View File

@@ -58,6 +58,8 @@ class CollisionProcessor implements EngineListener {
tank1.rect.lean(eagle.rect);
case EntityType.CELL(cell):
tank1.rect.lean(cell.rect);
case EntityType.BONUS(bonus):
engine.destroy(bonus);
}
case EntityType.BULLET(bullet1):
switch (with) {
@@ -74,6 +76,7 @@ class CollisionProcessor implements EngineListener {
engine.destroy(eagle);
case EntityType.CELL(cell):
engine.destroy(bullet1);
case EntityType.BONUS(bonus):
}
case _:
}
@@ -131,9 +134,10 @@ class Engine implements ControlHandler {
switch (action) {
case TankAction.MOVE(direction):
tank.move(direction);
case TankAction.LEVEL_UP(level):
// ToDo:
tank.config = config.getTank('human', Std.string(Std.int(Math.min(Std.parseInt(tank.config.type) + level, 3))));
case TankAction.UPGRADE:
if (tank.config.upgrade != null) {
tank.config = config.getTank(tank.config.upgrade);
}
case TankAction.STOP:
tank.stop();
case TankAction.SHOT:

View File

@@ -1,8 +1,11 @@
package ru.m.tankz.game;
import haxe.ds.Option;
import ru.m.tankz.game.GameState.PlayerState;
import ru.m.draw.Color;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState.PlayerState;
import ru.m.tankz.Type;
class ClassicGame extends Game {
@@ -12,6 +15,17 @@ class ClassicGame extends Game {
public static var HUMAN(default, never):TeamId = 'human';
public static var BOT(default, never):TeamId = 'bot';
private static var PLAYER1_COLOR:Color = 0xFC9838;
private static var PLAYER2_COLOR:Color = 0x159D49;
public static var PLAYER1(default, never):GameMode = [
{team:HUMAN, type:Control.HUMAN, color: PLAYER1_COLOR, index:0}
];
public static var PLAYER2(default, never):GameMode = [
{team:HUMAN, type:Control.HUMAN, color: PLAYER1_COLOR, index:0},
{team:HUMAN, type:Control.HUMAN, color: PLAYER2_COLOR, index:1}
];
private static var HUMAN_LIFE(default, never):Int = 3;
private static var BOT_LIFE(default, never):Int = 20;
@@ -19,37 +33,22 @@ class ClassicGame extends Game {
super(TYPE);
}
public static function buildState(level:Int, humans:Int):GameState {
public static function buildState(level:Int, mode:GameMode):GameState {
var state = new GameState();
state.type = TYPE;
state.mode = mode;
state.level = level;
state.teams[HUMAN] = {life: -1, players: new Map(), lose: false};
state.teams[BOT] = {life: BOT_LIFE, players: new Map(), lose: false};
for (i in 0...humans) {
state.teams[HUMAN].players[i] = {
index:i,
tank:{
group: HUMAN,
type: '1'
},
control:{
type: 'human',
index: i
},
for (human in mode) {
state.teams[HUMAN].players[human.index] = {
id:human,
life:HUMAN_LIFE,
};
}
for (i in 0...humans*2+2) {
for (i in 0...mode.length * 2 + 2) {
state.teams[BOT].players[i] = {
index:i,
tank:{
group: BOT,
type: '1'
},
control:{
type: 'bot',
index: i
},
id:{team:BOT, index:i, type:Control.BOT},
life:-1,
};
}

View File

@@ -1,8 +1,11 @@
package ru.m.tankz.game;
import haxe.ds.Option;
import ru.m.draw.Color;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
import ru.m.tankz.Type;
class DotaGame extends Game {
@@ -12,52 +15,57 @@ class DotaGame extends Game {
public static var RADIANT(default, never):TeamId = 'radiant';
public static var DIRE(default, never):TeamId = 'dire';
public static var PLAYER1(default, never):GameMode = [
{team:RADIANT, type:Control.HUMAN, index:0}
];
private static var PLAYER1_COLOR:Color = 0xff7777;
private static var PLAYER2_COLOR:Color = 0x7777ff;
public static var PLAYER2_COOP(default, never):GameMode = [
{team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:0},
{team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:1}
];
public static var PLAYER2_VS(default, never):GameMode = [
{team:RADIANT, type:Control.HUMAN, color: PLAYER1_COLOR, index:0},
{team:DIRE, type:Control.HUMAN, color: PLAYER2_COLOR, index:0}
];
private static var TEAM_SIZE(default, never):Int = 5;
public function new() {
super(TYPE);
}
public static function buildState(level:Int, humans:Int):GameState {
public static function buildState(level:Int, mode:GameMode):GameState {
var state = new GameState();
state.type = TYPE;
state.mode = mode;
state.level = level;
state.teams[RADIANT] = {life: 20, players: new Map(), lose: false};
state.teams[DIRE] = {life: 20, players: new Map(), lose: false};
for (i in 0...TEAM_SIZE) {
state.teams[RADIANT].players[i] = {
index:i,
tank:{
group: RADIANT,
type: '1'
},
control:{
type: 'bot',
index: i
},
id: {team:RADIANT, index:i, type:Control.BOT},
life: -1,
};
}
for (i in 0...TEAM_SIZE) {
state.teams[DIRE].players[i] = {
index:i,
tank:{
group: DIRE,
type: '1'
},
control:{
type: 'bot',
index: i
},
id: {team:DIRE, index:i, type:Control.BOT},
life: -1,
};
}
for (human in mode) {
state.teams[human.team].players[human.index].id = human;
}
return state;
}
override public function next():Option<GameState> {
state.level++;
if (state.level >= config.game.levels) state.level = 0;
return Option.Some(buildState(state.level, 0));
return Option.Some(buildState(state.level, state.mode));
}
}

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game;
import ru.m.tankz.core.Bonus;
import haxe.ds.Option;
import haxe.Timer;
import promhx.Deferred;
@@ -19,26 +20,20 @@ import ru.m.tankz.core.Tank;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.game.GameState;
import ru.m.tankz.game.Spawner;
typedef GameType = String;
typedef TeamId = String;
typedef PlayerId = {
var team:TeamId;
var index:Int;
}
import ru.m.tankz.Type;
class Game implements EngineListener {
private static var TAG(default, never):String = 'Game';
public var type(default, null):GameType;
public var state(default, null):GameState;
public var teams(default, null):Map<TeamId, Team>;
public var config(default, null):Config;
public var engine(default, null):Engine;
private var points:Array<SpawnPoint>;
private var spawners:Map<TeamId, Spawner>;
private var deferred:Deferred<GameState>;
private var stream:Stream<GameState>;
@@ -51,14 +46,16 @@ class Game implements EngineListener {
}
public function getPlayer(playerId:PlayerId):Player {
return teams.get(playerId.team).players[playerId.index];
return teams[playerId.team].players[playerId.index];
}
private function buildTank(playerId:PlayerId, point:SpawnPoint):Tank {
var types:Array<TankSpawn> = teams[playerId.team].config.tanks;
var type:TankSpawn = types[Math.floor(Math.random() * types.length)];
var tankConfig:TankConfig = config.getTank(type.group, type.type);
var spawns:Array<TankSpawn> = teams[playerId.team].config.tanks;
var spawn:TankSpawn = spawns[Math.floor(Math.random() * spawns.length)];
var tankConfig:TankConfig = config.getTank(spawn.type);
var tank = new Tank(playerId, tankConfig);
tank.color = playerId.color.zero ? teams[playerId.team].config.color : playerId.color;
tank.bonus = Math.random() < spawn.bonus;
applyPoint(tank, point);
return tank;
}
@@ -71,39 +68,43 @@ class Game implements EngineListener {
public function start(state:GameState):Stream<GameState> {
this.deferred = new Deferred();
this.state = state;
var bricks = LevelBundle.get(type, config, state.level);
engine.map.setData(bricks);
var level = LevelBundle.get(type, config, state.level);
points = level.points != null ? level.points : config.points;
engine.map.setData(level.data);
teams = new Map<TeamId, Team>();
spawners = new Map<TeamId, Spawner>();
var humanControlIndex = 0;
for (teamConfig in config.teams) {
var team = new Team(teamConfig);
for (playerState in state.teams.get(team.id).players) {
var player = new Player({team:team.id, index:playerState.index});
team.players.push(player);
teams.set(team.id, team);
if (playerState.control != null) {
var control = switch (playerState.control.type) {
case HumanControl.TYPE: new HumanControl(playerState.control.index);
case BotControl.TYPE: new BotControl(playerState.control.index);
case 'none': null;
case _: throw 'Unsupported control type: "${playerState.control.type}"';
for (playerState in state.teams[team.id].players) {
var player = new Player(playerState.id);
team.players[player.id.index] = player;
teams[team.id] = team;
if (player.id.type != null) {
var control = switch (player.id.type) {
case Control.HUMAN: new HumanControl(player.id, humanControlIndex++);
case Control.BOT: new BotControl(player.id);
case Control.NONE: null;
case _: throw 'Unsupported control type: "${player.id.type}"';
}
L.d(TAG, 'control(${player.id} - ${control})');
if (control != null) {
player.control = control;
player.control.bind(engine);
}
}
}
spawners.set(team.id, new Spawner(team.config, spawn));
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == team.id);
spawners[team.id] = new Spawner(team.config, teamPoints, spawn);
}
for (team in teams) {
for (player in team.players) {
if (trySpawn(player.id)) {
spawners.get(team.id).push(player.id);
spawners[team.id].push(player.id);
}
}
var eaglePoint = spawners.get(team.id).getPoint('eagle');
var eaglePoint = spawners[team.id].getPoint('eagle');
if (eaglePoint != null) {
var eagle = new Eagle(team.id);
applyPoint(eagle, eaglePoint);
@@ -115,12 +116,13 @@ class Game implements EngineListener {
}
private function spawn(task:SpawnTask):Void {
L.d(TAG, 'spawn(${task}');
getPlayer(task.playerId).tankId = 0;
if (trySpawn(task.playerId, true)) {
var tank = buildTank(task.playerId, task.point);
var player:Player = getPlayer(task.playerId);
engine.spawn(tank);
player.tankId = tank.id;
Timer.delay(function() engine.spawn(tank), 1500);
} else if (!isTeamAlive(task.playerId.team)) {
state.teams[task.playerId.team].lose = true;
complete();
@@ -135,31 +137,18 @@ class Game implements EngineListener {
player.control.dispose();
}
}
var timer = new Timer(5000);
timer.run = function() {
timer.stop();
Timer.delay(function() {
deferred.resolve(state);
stream.end();
}, 5000);
}
}
public function setControl(playerId:PlayerId, control:Control):Void {
for (team in teams.iterator()) {
if (team.id == playerId.team) {
var player = team.players[playerId.index];
if (player.control != null) {
player.control.dispose();
}
player.control = control;
player.control.bind(engine);
break;
}
}
}
public function onSpawn(entity:EntityType):Void {
switch (entity) {
case EntityType.TANK(tank):
getPlayer(tank.playerId).control.start();
case x:
}
}
public function onCollision(entity:EntityType, with:EntityType):Void {
@@ -167,6 +156,11 @@ class Game implements EngineListener {
case EntityType.TANK(tank):
var control = getPlayer(tank.playerId).control;
if (control != null) control.onCollision(with);
switch (with) {
case EntityType.BONUS(bonus):
applyBonus(tank, bonus);
case x:
}
case x:
}
}
@@ -210,15 +204,17 @@ class Game implements EngineListener {
public function onDestroy(entity:EntityType):Void {
switch (entity) {
case EntityType.TANK(tank):
getPlayer(tank.playerId).tankId = 0;
getPlayer(tank.playerId).control.stop();
getPlayer(tank.playerId).tankId = 0; //ToDo: ?
var respawn:Bool = trySpawn(tank.playerId);
if (respawn) {
spawners.get(tank.playerId.team).push(tank.playerId);
spawners[tank.playerId.team].push(tank.playerId);
}
if (!isTeamAlive(tank.playerId.team)) {
state.teams[tank.playerId.team].lose = true;
complete();
}
if (tank.bonus) spawnBonus();
deferred.resolve(state);
case EntityType.EAGLE(eagle):
state.teams[eagle.team].lose = true;
@@ -228,18 +224,53 @@ class Game implements EngineListener {
}
}
public function onAction(tankId:Int, action:TankAction):Void {
engine.action(tankId, action);
}
public function next():Option<GameState> {
return Option.None;
}
public function dispose():Void {
engine.dispose();
}
private function spawnBonus():Void {
var bonusConfig = config.bonuses[Math.floor(Math.random() * config.bonuses.length)];
L.d(TAG, 'Spawn Bonus(${bonusConfig}');
var bonus = new Bonus(bonusConfig.type);
bonus.rect.x = Math.random() * engine.map.width;
bonus.rect.y = Math.random() * engine.map.height;
engine.spawn(bonus);
}
private function applyBonus(tank:Tank, bonus:Bonus):Void {
switch (bonus.bonusType) {
case 'life':
state.teams[tank.playerId.team].players[tank.playerId.index].life++;
case 'star':
if (tank.config.upgrade != null) {
tank.config = config.getTank(tank.config.upgrade);
} else {
tank.hits++;
}
case 'grenade':
for (entity in engine.entities.iterator()) {
switch (EntityTypeResolver.of(entity)) {
case EntityType.TANK(t):
if (t.playerId.team != tank.playerId.team) {
engine.destroy(t);
}
case x:
}
}
case 'helmet':
case 'clock':
case 'shovel':
case x:
engine.destroy(tank); // :-D
}
}
}

View File

@@ -1,35 +1,22 @@
package ru.m.tankz.game;
import ru.m.tankz.game.Game;
import ru.m.tankz.config.Config;
typedef ControlType = String;
typedef ControId = {
var type:ControlType;
var index:Int;
}
import ru.m.tankz.Type;
typedef PlayerState = {
var index:Int;
var tank:TankType;
var id:PlayerId;
var life:Int;
var control:ControId;
}
typedef TeamState = {
var players:Map<Int, PlayerState>;
var life:Int;
var lose:Bool;
}
class GameState {
public var type:GameType;
public var mode:GameMode;
public var level:Int;
public var teams:Map<TeamId, TeamState>;

View File

@@ -1,7 +1,7 @@
package ru.m.tankz.game;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.Game;
import ru.m.tankz.Type;
class Player {
@@ -19,11 +19,6 @@ class Player {
tankId = value;
if (control != null) {
control.tankId = tankId;
if (tankId != 0) {
control.start();
} else {
control.stop();
}
}
return tankId;
}
@@ -33,9 +28,6 @@ class Player {
control = value;
if (control != null) {
control.tankId = tankId;
if (tankId != 0) {
control.start();
}
}
return control;
}

View File

@@ -1,9 +1,8 @@
package ru.m.tankz.game;
import haxe.Timer;
import ru.m.tankz.game.Game;
import ru.m.tankz.config.Config;
import ru.m.tankz.Type;
typedef SpawnTask = {
@@ -11,12 +10,12 @@ typedef SpawnTask = {
var playerId:PlayerId;
}
class Spawner {
public var active(get, never):Bool;
private var config:TeamConfig;
private var points:Array<SpawnPoint>;
private var runner:SpawnTask -> Void;
private var queue:Array<SpawnTask>;
private var timer:Timer;
@@ -25,13 +24,14 @@ class Spawner {
private var anyPoints:Array<SpawnPoint>;
private var index:Int;
public function new(config:TeamConfig, runner:SpawnTask -> Void) {
public function new(config:TeamConfig, points:Array<SpawnPoint>, runner:SpawnTask -> Void) {
this.config = config;
this.points = points;
this.runner = runner;
queue = [];
indexedPoints = new Map();
anyPoints = [];
for (point in config.points) {
for (point in points) {
if (point.type == 'tank') {
if (point.index > -1) {
indexedPoints.set(point.index, point);
@@ -43,7 +43,7 @@ class Spawner {
}
public function getPoint(type:String, index:Int=-1):Null<SpawnPoint> {
for (point in config.points) {
for (point in points) {
if (point.type == type && point.index == index) {
return point;
}

View File

@@ -1,21 +1,21 @@
package ru.m.tankz.game;
import ru.m.tankz.config.Config.TeamConfig;
import ru.m.tankz.config.Config;
import ru.m.tankz.game.Player;
import ru.m.tankz.game.Game;
import ru.m.tankz.Type;
class Team {
public var id(default, null):TeamId;
public var config(default, null):TeamConfig;
public var players(default, null):Array<Player>;
public var players(default, null):Map<Int, Player>;
private static var i:Int = 0;
public function new(config:TeamConfig) {
this.id = config.id;
this.config = config;
this.players = [];
this.players = new Map();
}
}

View File

@@ -15,6 +15,9 @@ class LevelMap {
public var gridWidth(default, null):Int;
public var gridHeight(default, null):Int;
public var width(get, null):Float;
public var height(get, null):Float;
public var bricks(default, null):Array<Brick>;
public var grid(default, null):Grid;
@@ -62,4 +65,18 @@ class LevelMap {
public function getBrick(cell:GridCell):Brick {
return bricksMap.get(cell.position);
}
public function getPointBrick(point:Point):Brick {
var cellX:Int = Math.floor(point.x / config.cellWidth);
var cellY:Int = Math.floor(point.y / config.cellHeight);
return bricks[cellX + cellY * config.gridWidth];
}
private inline function get_width():Float {
return config.cellWidth * config.gridWidth;
}
private inline function get_height():Float {
return config.cellHeight * config.gridHeight;
}
}

View File

@@ -0,0 +1,53 @@
package ru.m.tankz.editor;
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 SpriteView implements IListItemView<BrickConfig> {
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();
width = 26;
height = 26;
selectView = createSelectView(width, height);
selectView.visible = false;
contentAsSprite.addChild(selectView);
imageView = new Bitmap();
contentAsSprite.addChild(imageView);
}
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/images/map/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,143 @@
package ru.m.tankz.editor;
import ru.m.tankz.game.Game;
import ru.m.tankz.editor.MapEditView;
import ru.m.tankz.game.DotaGame;
import haxework.gui.list.ListView;
import haxework.gui.list.VListView;
import ru.m.tankz.editor.FileUtil;
import haxework.gui.LabelView;
import ru.m.tankz.config.Config;
import ru.m.tankz.config.LevelBundle;
import ru.m.tankz.game.ClassicGame;
import ru.m.tankz.config.ConfigBundle;
import haxework.gui.ButtonView;
import haxework.gui.Root;
import flash.text.Font;
import haxework.resources.Resources;
import haxework.resources.IResources;
import haxework.provider.Provider;
import haxework.log.TraceLogger;
import haxework.gui.ViewBuilder;
import haxework.gui.GroupView;
import haxework.log.JSLogger;
import haxework.log.SocketLogger;
interface EditorViewLayout {
var gameClassicButton(default, null):ButtonView;
var gameDotaButton(default, null):ButtonView;
var openButton(default, null):ButtonView;
var saveButton(default, null):ButtonView;
var fileNameLabel(default, null):LabelView;
var mapView(default, null):MapEditView;
var spawnPointList(default, null):VListView<SpawnPoint>;
var brickList(default, null):VListView<BrickConfig>;
}
@:template("ru/m/tankz/editor/Editor.yaml")
class EditorView extends GroupView implements ViewBuilder implements EditorViewLayout {}
class Editor {
private static inline var TAG = "Tankz.Editor";
public static function main() {
L.push(new TraceLogger());
#if flash
L.push(new JSLogger());
#end
#if debug
L.push(new SocketLogger());
#end
Const.init();
L.d(TAG, "Debug: " + Const.DEBUG);
L.i(TAG, "Version: " + Const.VERSION);
L.i(TAG, "Build: " + Const.BUILD);
new Editor();
}
private var view:EditorView;
private var config:Config;
public function new() {
Provider.setFactory(IResources, Resources);
var font:Font = Font.enumerateFonts()[0];
Provider.get(IResources).text.put("font", "Bookman Old Style");
Provider.get(IResources).text.put("version", 'v${Const.VERSION} b${Const.BUILD}');
view = new EditorView();
Root.bind(view);
view.content.stage.stageFocusRect = false;
view.gameClassicButton.onPress = this;
view.gameDotaButton.onPress = this;
view.openButton.onPress = this;
view.saveButton.onPress = this;
var resetSelected = function() {
for (v in view.brickList.items) {
cast(v, BrickView).selected = false;
}
for (v in view.spawnPointList.items) {
cast(v, SpawnPointView).selected = false;
}
};
view.brickList.dispatcher.addListener({
onListItemClick: function(item:IListItemView<BrickConfig>) {
view.mapView.brush = Brush.BRICK(item.data);
resetSelected();
cast(item, BrickView).selected = true; }
});
view.spawnPointList.dispatcher.addListener({
onListItemClick: function(item:IListItemView<SpawnPoint>) {
view.mapView.brush = Brush.POINT(item.data);
resetSelected();
cast(item, SpawnPointView).selected = true;
}
});
setGameType(ClassicGame.TYPE);
}
private function setGameType(type:GameType):Void {
config = ConfigBundle.get(type);
Provider.set(Config, config);
view.mapView.config = config;
view.mapView.data = LevelBundle.empty(config);
view.brickList.data = config.bricks.filter(function(brick) return brick.type > -1);
view.spawnPointList.data = config.points;
view.mapView.brush = Brush.BRICK(view.brickList.data[0]);
cast(view.brickList.items[0], BrickView).selected = true;
}
public function onPress(v:ButtonView):Void {
switch (v.id) {
case 'gameClassicButton':
setGameType(ClassicGame.TYPE);
case 'gameDotaButton':
setGameType(DotaGame.TYPE);
case 'openButton':
L.d(TAG, 'OPEN');
FileUtil.browse().then(function(content:FileContent) {
view.fileNameLabel.text = content.name;
view.mapView.data = LevelBundle.loads(config, content.content);
});
case 'saveButton':
L.d(TAG, 'SAVE');
FileUtil.save({
name: view.fileNameLabel.text,
content: LevelBundle.dumps(config, view.mapView.data),
});
case _:
}
}
}

View File

@@ -0,0 +1,89 @@
$type: haxework.gui.GroupView
pWidth: 100
pHeight: 100
views:
- $type: haxework.gui.VGroupView
pWidth: 100
pHeight: 100
views:
- $type: haxework.gui.HGroupView
pWidth: 100
height: 20
views:
- id: gameClassicButton
$type: haxework.gui.ButtonView
text: Classic
contentSize: true
skin:
$type: haxework.gui.skin.ButtonColorSkin
color: 0xaaff00
- id: gameDotaButton
$type: haxework.gui.ButtonView
text: DotA
contentSize: true
skin:
$type: haxework.gui.skin.ButtonColorSkin
color: 0xaaff00
- $type: haxework.gui.HGroupView
pWidth: 100
height: 20
views:
- id: openButton
$type: haxework.gui.ButtonView
text: Open
contentSize: true
skin:
$type: haxework.gui.skin.ButtonColorSkin
color: 0xaaff00
- id: saveButton
$type: haxework.gui.ButtonView
text: Save
contentSize: true
skin:
$type: haxework.gui.skin.ButtonColorSkin
color: 0xaaff00
- id: fileNameLabel
$type: haxework.gui.LabelView
contentSize: true
- $type: haxework.gui.HGroupView
contentSize: true
views:
- id: spawnPointList
$type: haxework.gui.list.VListView<SpawnPoint>
factory: '@class:ru.m.tankz.editor.SpawnPointView'
width: 56
pHeight: 100
scroll:
$type: haxework.gui.list.VScrollView
width: 0
pHeight: 100
skin:
$type: haxework.gui.list.VScrollSkin
skin:
$type: haxework.gui.skin.ColorSkin
color: 0x000000
alpha: 0.0
- id: mapView
$type: ru.m.tankz.editor.MapEditView
contentSize: true
- id: brickList
$type: haxework.gui.list.VListView<BrickConfig>
factory: '@class:ru.m.tankz.editor.BrickView'
width: 30
pHeight: 100
scroll:
$type: haxework.gui.list.VScrollView
width: 0
pHeight: 100
skin:
$type: haxework.gui.list.VScrollSkin
skin:
$type: haxework.gui.skin.ColorSkin
color: 0x000000
alpha: 0.0
- $type: haxework.gui.LabelView
inLayout: false
contentSize: true
vAlign: BOTTOM
hAlign: RIGHT
text: '@res:text:version'

View File

@@ -0,0 +1,48 @@
package ru.m.tankz.editor;
import promhx.Deferred;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.net.FileReference;
import promhx.Promise;
typedef FileContent = {
var name:String;
var content:String;
}
class FileUtil {
public static function browse():Promise<FileContent> {
var d = new Deferred<FileContent>();
var file = new FileReference();
file.addEventListener(Event.SELECT, function(event:Event) {
cast(event.target, FileReference).load();
});
file.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent) {
d.throwError(event);
});
file.addEventListener(ProgressEvent.PROGRESS, function(event:ProgressEvent) {
trace('progress', '${event}');
});
file.addEventListener(Event.COMPLETE, function(event:Event) {
var f:FileReference = cast event.target;
var data = f.data.readUTFBytes(f.data.length);
d.resolve({
name: f.name,
content: data
});
});
file.browse();
return d.promise();
}
public static function save(content:FileContent):Void {
var file = new FileReference();
file.save(content.content, content.name);
}
}

View File

@@ -0,0 +1,234 @@
package ru.m.tankz.editor;
import ru.m.geom.Rectangle;
import ru.m.tankz.core.Entity;
import ru.m.geom.Point;
import flash.events.MouseEvent;
import ru.m.tankz.map.Brick;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Sprite;
import ru.m.tankz.render.RenderItem;
import ru.m.tankz.config.Config;
import ru.m.tankz.map.LevelMap;
import haxework.gui.SpriteView;
class SpawnPointEntity extends Entity {
public var point(default, null):SpawnPoint;
public function new(point:SpawnPoint, rect:Rectangle) {
super(rect);
this.point = point;
}
}
class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
private var cellX:Int;
private var cellY:Int;
private var src:String;
public function new(value:SpawnPoint, config:Config) {
src = getSrc(value, config);
super(new SpawnPointEntity(value, new Rectangle(
value.x * config.map.cellWidth,
value.y * config.map.cellHeight,
config.map.cellWidth * 2,
config.map.cellHeight * 2
)));
}
public static function getSrc(value:SpawnPoint, config:Config):String {
var tankType = config.getTeam(value.team).tanks[0];
return switch(value.type) {
case 'eagle': 'resources/images/eagle/eagle-0.png';
case 'tank': TankItem.getTankFrames(value.team, value.index, tankType)[0];
case x: 'resources/images/eagle/eagle-1.png';
}
}
override public function update():Void {
super.update();
if (cellX != value.point.x || cellY != value.point.y) {
cellX = value.point.x;
cellY = value.point.y;
value.rect.x = cellX * (value.rect.width / 2);
value.rect.y = cellY * (value.rect.height / 2);
redraw();
}
}
override private function getImage():String {
return src;
}
}
enum Brush {
POINT(point:SpawnPoint);
BRICK(brick:BrickConfig);
}
//ToDo: copy paste from ru.m.tankz.render.Render
class MapEditView extends SpriteView {
public var config(default, set):Config;
public var data(get, set):LevelConfig;
public var map(default, null):LevelMap;
public var brush(default, default):Brush;
private var items:Map<String, RenderItem<Dynamic, Dynamic>>;
private var backgroundLayer:Sprite;
private var upLayer:Sprite;
private var groundLayer:Sprite;
private var spawnLayer:Sprite;
public function new() {
super();
items = new Map();
map = null;
backgroundLayer = new Sprite();
upLayer = new Sprite();
groundLayer = new Sprite();
spawnLayer = new Sprite();
contentAsSprite.addChild(backgroundLayer);
contentAsSprite.addChild(groundLayer);
contentAsSprite.addChild(upLayer);
contentAsSprite.addChild(spawnLayer);
contentAsSprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
reset();
}
private function onMouseDown(event:MouseEvent):Void {
contentAsSprite.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
contentAsSprite.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
onMouseMove(event);
}
private function onMouseUp(event:MouseEvent):Void {
contentAsSprite.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
contentAsSprite.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseMove(event:MouseEvent):Void {
var b = map.getPointBrick(new Point(event.localX, event.localY));
if (b != null) {
switch (brush) {
case Brush.POINT(point):
for (p in config.points) {
if (p.team == point.team && p.type == point.type && p.index == point.index) {
p.x = b.cellX;
p.y = b.cellY;
drawMap();
break;
}
}
case Brush.BRICK(brick):
b.config = brick;
drawMap();
}
}
}
private function clearLayer(layer:DisplayObjectContainer) {
while (layer.numChildren > 0) layer.removeChildAt(0);
}
public function reset():Void {
for (item in items.iterator()) {
item.dispose();
}
items = new Map();
clearLayer(groundLayer);
clearLayer(upLayer);
clearLayer(spawnLayer);
}
private function drawBackground():Void {
var mapWidth = map.gridWidth * map.cellWidth;
var mapHeight = map.gridHeight * map.cellHeight;
var g:Graphics = backgroundLayer.graphics;
g.clear();
g.beginFill(0x000000);
g.drawRect(0, 0, mapWidth, mapHeight);
g.endFill();
if (contentSize) {
width = mapWidth;
height = mapHeight;
}
g.lineStyle(1, 0x007700);
for (x in 0...map.gridWidth) {
g.moveTo(x * map.cellWidth, 0);
g.lineTo(x * map.cellWidth, mapHeight);
}
for (y in 0...map.gridHeight) {
g.moveTo(0, y * map.cellHeight);
g.lineTo(mapWidth, y * map.cellHeight);
}
}
override public function update():Void {
if (this.map != null) {
drawBackground();
drawMap();
}
super.update();
}
private function drawMap() {
for (brick in map.bricks) if (brick.config.type > 0) {
if (!items.exists(brick.key)) {
items[brick.key] = new BrickItem(brick);
if (brick.config.layer > 2) {
upLayer.addChild(items[brick.key].view);
} else {
groundLayer.addChild(items[brick.key].view);
}
}
}
for (point in config.points) {
var key = '${point.team}:${point.type}:${point.index}';
if (!items.exists(key)) {
items[key] = new SpawnPointItem(point, config);
spawnLayer.addChild(items[key].view);
}
}
for (item in items) {
item.update();
}
}
private function set_config(value:Config):Config {
config = value;
map = new LevelMap(config.map);
invalidate();
return config;
}
private function get_data():LevelConfig {
return {
data: map.bricks.map(function(brick:Brick) return brick.config),
points: config.points,
}
}
private function set_data(value:LevelConfig):LevelConfig {
reset();
map.setData(value.data);
if (value.points != null) for (point in value.points) {
for (p in config.points) {
if (p.team == point.team && p.type == point.type && p.index == point.index) {
p.x = point.x;
p.y = point.y;
break;
}
}
}
invalidate();
return value;
}
}

View File

@@ -0,0 +1,55 @@
package ru.m.tankz.editor;
import haxework.provider.Provider;
import ru.m.tankz.editor.MapEditView.SpawnPointItem;
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 SpawnPointView extends SpriteView implements IListItemView<SpawnPoint> {
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();
width = 52;
height = 52;
selectView = createSelectView(width, height);
selectView.visible = false;
contentAsSprite.addChild(selectView);
imageView = new Bitmap();
contentAsSprite.addChild(imageView);
}
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;
}
}

View File

@@ -11,6 +11,7 @@ const PluginError = require('plugin-error');
const colors = require('ansi-colors');
const log = require('fancy-log');
const vfs = require('vinyl-fs');
const rmdir = require('rmdir');
class Haxe extends Sdk {
@@ -179,13 +180,10 @@ class Haxe extends Sdk {
args.push('-debug');
}
//console.log('haxelib', args.join(' '));
const target = `${buildDir}/${params.platform}/bin`;
rmdir(target);
this.haxelib(args).then(() => {
const result = {
'flash': `${buildDir}/flash/bin/*.swf`,
'html5': `${buildDir}/html5/bin/**/*`,
'linux': `${buildDir}/linux/bin/**/*`,
}[params.platform];
vfs.src(result).pipe(through.obj((file, enc, cb) => {
vfs.src(`${target}/**/*`).pipe(through.obj((file, enc, cb) => {
file.debug = debug;
stream.push(file);
cb();