5 Commits
0.2.1 ... 0.3.0

Author SHA1 Message Date
59cab68e3e [common] tanks spawn types 2018-02-02 20:53:26 +03:00
f9cb985059 [engine] update collision detect 2018-02-02 17:30:50 +03:00
6f338584eb [render] added animates 2018-02-01 00:05:14 +03:00
f2f860fc9d Merge branch 'develop' 2018-01-31 23:04:38 +03:00
3e65a5ba5d [cap] use master branch in production 2018-01-17 09:16:17 +03:00
21 changed files with 441 additions and 107 deletions

View File

@@ -10,4 +10,4 @@ user = fetch(:user)
server host, ssh_options: { port: 22, user: user, forward_agent: true }
set :tmp_dir, "/home/#{user}/tmp"
set :branch, 'develop'
set :branch, 'master'

View File

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

View File

@@ -12,6 +12,7 @@
<haxelib name="protohx" version="0.4.6"/>
<haxelib name="haxework" version="git"/>
<haxelib name="yaml" version="1.3.0"/>
<window fps="30"/>
<window width="1024" height="768" unless="html5"/>
<haxeflag name="-D" value="swf-gpu"/>
<haxeflag name="-D" value="native-trace"/>

View File

@@ -0,0 +1,73 @@
package ru.m.animate;
import flash.display.PixelSnapping;
import haxe.Timer;
import flash.display.Bitmap;
import flash.display.BitmapData;
class Animate extends Bitmap {
private static var timer:Timer;
private static var instances:Array<Animate> = [];
private static function init():Void {
if (timer == null) {
timer = new Timer(30);
timer.run = updateAll;
}
}
private static function updateAll():Void {
for (instance in instances) {
if (instance.playing) {
instance.update();
}
}
}
private static var a = new BitmapData(1, 1);
public var playing(default, set):Bool;
public var frames(default, set):Array<BitmapData>;
private var index:Int;
public function new(?frames:Array<BitmapData>) {
super(null, PixelSnapping.AUTO, true);
this.frames = frames == null ? [] : frames;
init();
instances.push(this);
}
public function set_frames(value:Array<BitmapData>):Array<BitmapData> {
if (value != null) {
frames = value;
bitmapData = frames[0];
index = 0;
}
return frames;
}
public function set_playing(value:Bool):Bool {
if (playing != value) {
playing = value;
}
return playing;
}
private function update():Void {
if (++index >= frames.length) {
index = 0;
}
var nextBitmapData = frames[index];
x -= (nextBitmapData.width - bitmapData.width) / 2;
y -= (nextBitmapData.height - bitmapData.height) / 2;
bitmapData = nextBitmapData;
}
public function dispose():Void {
if (instances.indexOf(this) > -1) {
instances.remove(this);
}
}
}

View File

@@ -0,0 +1,31 @@
package ru.m.animate;
import promhx.Deferred;
import flash.display.BitmapData;
import promhx.Promise;
class OnceAnimate extends Animate {
private var deferred:Deferred<Animate>;
public function new(frames:Array<BitmapData>) {
super(frames);
}
public function play():Promise<Animate> {
deferred = new Deferred();
playing = true;
return deferred.promise();
}
override private function update():Void {
super.update();
if (index == 0) {
playing = false;
if (deferred != null) {
deferred.resolve(this);
}
}
}
}

View File

@@ -1,5 +1,8 @@
package ru.m.tankz.render;
import ru.m.geom.Point;
import openfl.Assets;
import ru.m.animate.OnceAnimate;
import flash.display.DisplayObjectContainer;
import ru.m.tankz.core.EntityType;
import flash.display.DisplayObject;
@@ -19,20 +22,24 @@ class Render extends SpriteView implements EngineListener {
private var groundLayer:Sprite;
private var entryLayer:Sprite;
private var upLayer:Sprite;
private var upperLayer:Sprite;
private var background:Sprite;
private var items:Map<String, RenderItem<Dynamic>>;
private var items:Map<String, RenderItem<Dynamic, Dynamic>>;
public function new() {
super();
items = new Map();
backgroundLayer = new Sprite();
groundLayer = new Sprite();
entryLayer = new Sprite();
upLayer = new Sprite();
upperLayer = new Sprite();
contentAsSprite.addChild(backgroundLayer);
contentAsSprite.addChild(groundLayer);
contentAsSprite.addChild(entryLayer);
contentAsSprite.addChild(upLayer);
contentAsSprite.addChild(upperLayer);
reset();
}
@@ -74,7 +81,10 @@ class Render extends SpriteView implements EngineListener {
}
public function reset():Void {
items = new Map<String, RenderItem<Dynamic>>();
for (item in items.iterator()) {
item.dispose();
}
items = new Map();
if (background != null) {
backgroundLayer.removeChild(background);
background = null;
@@ -115,18 +125,51 @@ class Render extends SpriteView implements EngineListener {
if (items.exists(tank.key)) {
entryLayer.removeChild(items.get(tank.key).view);
items.remove(tank.key);
playTankBoom(tank.rect.center);
}
case EntityType.BULLET(bullet):
if (items.exists(bullet.key)) {
entryLayer.removeChild(items.get(bullet.key).view);
items.remove(bullet.key);
playBulletBoom(bullet.rect.center.add(new Point(bullet.rect.width * bullet.rect.direction.x, bullet.rect.height * bullet.rect.direction.y)));
}
case EntityType.EAGLE(eagle):
if (items.exists(eagle.key)) {
cast(items.get(eagle.key), EagleItem).destoyed = true;
items.get(eagle.key).redraw();
playTankBoom(eagle.rect.center);
}
case _:
}
}
private function playBulletBoom(point:Point):Void {
var arr = [
0, 1, 1, 0, 0, 1
];
var frames = [for (i in arr) Assets.getBitmapData('resources/images/bullet/boom/boom-${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 playTankBoom(point:Point):Void {
var arr = [
0, 1, 2, 3, 4, 4, 4, 1, 4, 4, 7, 7, 8, 9, 9
];
var frames = [for (i in arr) Assets.getBitmapData('resources/images/tank/kaboom/kaboom-${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();
});
}
}

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.render;
import ru.m.animate.Animate;
import ru.m.tankz.core.Eagle;
import flash.display.DisplayObject;
import flash.display.Shape;
@@ -17,23 +18,17 @@ typedef TRectangle = {
}
class RenderItem<T:TRectangle> {
class RenderItem<T:TRectangle, D:DisplayObject> {
public var value(default, null):T;
public var view(default, null):DisplayObject;
private var bitmap:Bitmap;
public var view(default, null):D;
public function new(value:T) {
this.value = value;
this.bitmap = new Bitmap();
this.view = bitmap;
redraw();
this.view = null;
}
public function redraw():Void {
bitmap.bitmapData = Assets.getBitmapData(getImage());
}
public function redraw():Void {}
public function update():Void {
var rect = value.rect;
@@ -42,10 +37,6 @@ class RenderItem<T:TRectangle> {
view.y = rect.y - rect.height * (rect.direction.x + 1) / 2 - rect.height * (rect.direction.y + 1) / 2 + 1.5 * rect.height;
}
private function getImage():String {
return 'ERROR';
}
private static function calcRotate(direction:Direction):Float {
return (if (direction == Direction.RIGHT) {
0;
@@ -59,23 +50,42 @@ class RenderItem<T:TRectangle> {
0;
});
}
public function dispose():Void {}
}
class BrickItem extends RenderItem<Brick> {
class BitmapItem<T:TRectangle> extends RenderItem<T, Bitmap> {
public function new(value:T) {
super(value);
this.view = new Bitmap();
redraw();
}
override public function redraw():Void {
view.bitmapData = Assets.getBitmapData(getImage());
}
private function getImage():String {
return 'ERROR';
}
}
class BrickItem extends RenderItem<Brick, Shape> {
private var shape:Shape;
private var broken:Int;
public function new(value:Brick) {
this.shape = new Shape();
super(value);
this.view = shape;
this.view = new Shape();
redraw();
}
override public function redraw():Void {
var image = Assets.getBitmapData(getImage());
var g = shape.graphics;
var g = view.graphics;
g.clear();
if (value.destroyed) return;
g.beginBitmapFill(image);
@@ -98,45 +108,71 @@ class BrickItem extends RenderItem<Brick> {
}
}
override private function getImage():String {
private function getImage():String {
return 'resources/images/map/map_${value.config.type}.png';
}
}
class TankItem extends RenderItem<Tank> {
class TankItem extends RenderItem<Tank, Animate> {
private var type:String;
private var hits:Int;
override private function getImage():String {
public function new(value:Tank) {
super(value);
view = new Animate();
redraw();
}
override public function redraw():Void {
view.frames = getFrames().map(function(s) return Assets.getBitmapData(s));
}
private function getFrames():Array<String> {
var team = value.playerId.team;
var group = value.config.group;
var index = value.playerId.index;
if (group == 'human') group = 'player';
if (group == 'radiant') {
group = 'player';
if (team == 'radiant') {
index = 0;
}
if (group == 'dire') {
group = 'player';
if (team == 'dire') {
index = 1;
}
if (group == 'bot') index = 0;
return 'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-0.png';
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',
];
}
override public function update():Void {
super.update();
var t = value.config.type;
if (t != this.type) {
var h = value.hits;
if (t != this.type || h != this.hits) {
this.type = t;
this.hits = h;
redraw();
}
view.playing = (value.mx !=0 || value.my != 0);
}
override public function dispose():Void {
if (view != null) {
view.dispose();
view = null;
}
}
}
class BulletItem extends RenderItem<Bullet> {
class BulletItem extends BitmapItem<Bullet> {
override private function getImage():String {
return 'resources/images/bullet/bullet_${value.config.piercing > 1 ? 1 : 0}.png';
@@ -144,7 +180,7 @@ class BulletItem extends RenderItem<Bullet> {
}
class EagleItem extends RenderItem<Eagle> {
class EagleItem extends BitmapItem<Eagle> {
public var destoyed(default, default):Bool;

View File

@@ -24,7 +24,7 @@ class LevelFrame extends VGroupView implements ViewBuilder implements LevelFrame
public function onShow():Void {
var state = Provider.get(GameState);
var c = ConfigBundle.get(state.type).levels;
var c = ConfigBundle.get(state.type).game.levels;
levels.data = [for (i in 0...c) i];
}

View File

@@ -1,4 +1,6 @@
game:
levels: 36
friendlyFire: false
map:
cellWidth: 22
@@ -39,6 +41,10 @@ bricks:
teams:
- id: human
spawnInterval: 0
tanks:
- group: human
type: 0
rate: 1
points:
- type: eagle
index: -1
@@ -57,6 +63,19 @@ teams:
direction: top
- 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
points:
- type: tank
index: -1
@@ -107,7 +126,7 @@ tanks:
bullet:
<<: *bullet
speed: 9.0
bullets: 3
bullets: 2
- type: 3
width: 42
@@ -159,4 +178,4 @@ tanks:
speed: 8.0
bullets: 1
score: 400
hits: 4
hits: 3

View File

@@ -1,4 +1,6 @@
levels: 36
game:
levels: 2
friendlyFire: true
map:
cellWidth: 22
@@ -36,8 +38,24 @@ bricks:
layer: 2
armor: 1
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
teams:
- id: radiant
- <<: *team_tanks
id: radiant
spawnInterval: 0
points:
- type: eagle
@@ -49,28 +67,29 @@ teams:
index: 0
x: 0
y: 0
direction: top
direction: right
- type: tank
index: 1
x: 6
y: 10
direction: top
direction: right
- type: tank
index: 2
x: 6
y: 16
direction: top
direction: right
- type: tank
index: 3
x: 6
y: 22
direction: top
direction: right
- type: tank
index: 4
x: 10
y: 28
direction: top
- id: dire
direction: right
- <<: *team_tanks
id: dire
spawnInterval: 0
points:
- type: eagle
@@ -82,27 +101,27 @@ teams:
index: 0
x: 38
y: 28
direction: bottom
direction: left
- type: tank
index: 1
x: 32
y: 18
direction: bottom
direction: left
- type: tank
index: 2
x: 32
y: 12
direction: bottom
direction: left
- type: tank
index: 3
x: 32
y: 6
direction: bottom
direction: left
- type: tank
index: 4
x: 28
y: 0
direction: bottom
direction: left
bullet: &bullet
@@ -112,7 +131,7 @@ bullet: &bullet
piercing: 1
tanks:
radiant: &tanks
any:
- type: 0
width: 36
height: 36
@@ -130,5 +149,22 @@ tanks:
<<: *bullet
speed: 8.5
bullets: 1
dire:
- <<: *tanks
- 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

View File

@@ -0,0 +1,30 @@
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

View File

@@ -18,6 +18,10 @@ class Line {
);
}
public function move(point:Point):Line {
return new Line(point1.add(point), point2.add(point));
}
public function setLength(value:Float):Line {
var center = this.center;
var width = point2.x - point1.x;

View File

@@ -18,6 +18,6 @@ class Point {
}
public function toString():String {
return 'Point{x=$x,y=$y}';
return 'Point{x=${Math.round(x * 100) / 100},y=${Math.round(y * 100) / 100}}';
}
}

View File

@@ -11,6 +11,7 @@ class BotControl extends Control {
private var shotTimer:Timer;
private var turnTimer:Timer;
private var turnDelayTimer:Timer;
public function new(index:Int) {
super({type:TYPE, index:index});
@@ -18,22 +19,22 @@ class BotControl extends Control {
override public function onCollision(with:EntityType):Void {
switch (with) {
case EntityType.TANK(_): turn();
case EntityType.CELL(_): turn();
case EntityType.TANK(_): turnAfter(300);
case EntityType.CELL(_): turnAfter(300);
case _:
}
}
override public function start():Void {
//var tank = handler.entities.get(tankId);
//action(TankAction.MOVE(tank.rect.direction));
action(TankAction.MOVE(Direction.BOTTOM)); // ToDo: hardcode bot start direction
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(3000);
turnTimer = new Timer(2000);
turnTimer.run = turn;
}
}
@@ -53,6 +54,17 @@ class BotControl extends Control {
action(TankAction.SHOT);
}
public function turnAfter(delay:Int):Void {
if (turnDelayTimer == null) {
turnDelayTimer = new Timer(delay);
turnDelayTimer.run = function() {
turnDelayTimer.stop();
turnDelayTimer = null;
turn();
}
}
}
public function turn():Void {
action(TankAction.MOVE(randomDirection()));
}

View File

@@ -1,6 +1,11 @@
package ru.m.tankz.config;
typedef GameConfig = {
var levels: Int;
var friendlyFire:Bool;
}
typedef SpawnPoint = {
var type:String;
var index:Int;
@@ -41,6 +46,11 @@ typedef TankConfig = { > TankType,
var speed:Float;
var bullet:BulletConfig;
var bullets:Int;
var hits:Int;
}
typedef TankSpawn = { > TankType,
var rate: Float;
}
@@ -48,13 +58,14 @@ typedef TeamConfig = {
var id:String;
var size:Int;
var spawnInterval:Int;
var tanks:Array<TankSpawn>;
var points:Array<SpawnPoint>;
}
class Config {
public var type(default, null):String;
public var levels(default, null):Int;
public var game(default, null):GameConfig;
public var map(default, null):MapConfig;
public var bricks(default, null):Array<BrickConfig>;
public var tanks(default, null):Array<TankConfig>;
@@ -64,9 +75,9 @@ class Config {
private var tankMap:Map<String, Map<String, TankConfig>>;
private var teamMap:Map<String, TeamConfig>;
public function new(type:String, levels:Int, 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>, tanks:Array<TankConfig>) {
this.type = type;
this.levels = levels;
this.game = game;
this.map = map;
this.bricks = bricks;
this.teams = teams;

View File

@@ -1,6 +1,5 @@
package ru.m.tankz.config;
import ru.m.tankz.game.ClassicGame;
import yaml.Parser;
import openfl.Assets;
import yaml.Yaml;
@@ -8,7 +7,7 @@ import ru.m.tankz.config.Config;
typedef ConfigSource = {
var levels:Int;
var game:GameConfig;
var map: MapConfig;
var bricks: Array<BrickConfig>;
var teams: Array<TeamConfig>;
@@ -31,6 +30,6 @@ class ConfigBundle {
tanks.push(item);
}
}
return new Config(type, source.levels, source.map, source.bricks, source.teams, tanks);
return new Config(type, source.game, source.map, source.bricks, source.teams, tanks);
}
}

View File

@@ -11,6 +11,7 @@ import ru.m.geom.Direction;
class Tank extends MobileEntity {
public var playerId(default, null):PlayerId;
public var config(default, set):TankConfig;
public var hits(default, default):Int;
private var bulletsCounter:Int = 0;
@@ -18,6 +19,7 @@ class Tank extends MobileEntity {
super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT);
this.playerId = playerId;
this.config = config;
this.hits = config.hits;
this.layer = 1;
}

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.engine;
import ru.m.geom.Point;
import ru.m.geom.Line;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;
@@ -30,7 +31,16 @@ class CollisionProcessor implements EngineListener {
public function onSpawn(entity:EntityType):Void {}
private function checkTankBullet(tank:Tank, bullet:Bullet):Bool {
return tank.playerId.team != bullet.playerId.team;
if (bullet.tankId == tank.id) return false;
return engine.config.game.friendlyFire || tank.playerId.team != bullet.playerId.team;
}
private function hitTank(tank:Tank):Void {
if (tank.hits > 0) {
tank.hits--;
} else {
engine.destroy(tank);
}
}
public function onCollision(entity:EntityType, with:EntityType):Void {
@@ -41,7 +51,7 @@ class CollisionProcessor implements EngineListener {
tank1.rect.lean(tank2.rect);
case EntityType.BULLET(bullet2):
if (checkTankBullet(tank1, bullet2)) {
engine.destroy(tank1);
hitTank(tank1);
engine.destroy(bullet2);
}
case EntityType.EAGLE(eagle):
@@ -54,7 +64,7 @@ class CollisionProcessor implements EngineListener {
case EntityType.TANK(tank2):
if (checkTankBullet(tank2, bullet1)) {
engine.destroy(bullet1);
engine.destroy(tank2);
hitTank(tank2);
}
case EntityType.BULLET(bullet2):
engine.destroy(bullet1);
@@ -134,6 +144,8 @@ class Engine implements ControlHandler {
}
}
public function update():Void {
var newTime:Float = Date.now().getTime();
var d:Float = newTime - time;
@@ -153,10 +165,15 @@ class Engine implements ControlHandler {
}*/
if (entity.mx != 0 || entity.my != 0) {
entity.rect.x += entity.mx * (d / 30);
entity.rect.y += entity.my * (d / 30);
var side:Line = entity.rect.getSide(entity.rect.direction.reverse());
var step:Point = new Point(entity.rect.direction.x * map.cellWidth / 4, entity.rect.direction.y * map.cellHeight / 4);
var end:Point = side.center.add(new Point(entity.mx * (d / 30), entity.my * (d / 30)));
var c:Int = Math.floor(Math.abs(((end.x - side.center.x) / (map.cellWidth / 4) + (end.y - side.center.y) / (map.cellHeight / 4))));
var isStop:Bool = false;
while (c-- >= 0) {
side = side.move(step);
var cells = map.grid.getCells(side);
var collision:Bool = false;
@@ -166,6 +183,7 @@ class Engine implements ControlHandler {
collision = true;
var with = EntityTypeResolver.of(cell);
for (l in listeners) l.onCollision(entityType, with);
isStop = true;
break;
}
}
@@ -175,6 +193,7 @@ class Engine implements ControlHandler {
if (other.rect.intersection2(side)) {
var with = EntityTypeResolver.of(other);
for (l in listeners) l.onCollision(entityType, with);
isStop = true;
}
}
}
@@ -195,6 +214,14 @@ class Engine implements ControlHandler {
}
}
}
if (isStop) break;
}
if (!isStop || Std.is(entity, Bullet)) {
entity.rect.x += entity.mx * (d / 30);
entity.rect.y += entity.my * (d / 30);
}
}
}
}

View File

@@ -59,7 +59,7 @@ class ClassicGame extends Game {
override public function next():Option<GameState> {
if (!state.teams[HUMAN].lose) {
state.level++;
if (state.level >= config.levels) state.level = 0;
if (state.level >= config.game.levels) state.level = 0;
state.teams[BOT].lose = false;
state.teams[BOT].life = BOT_LIFE;
for (ps in state.teams[HUMAN].players) {

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game;
import haxe.ds.Option;
import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState;
@@ -53,4 +54,10 @@ class DotaGame extends Game {
}
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));
}
}

View File

@@ -54,8 +54,11 @@ class Game implements EngineListener {
return teams.get(playerId.team).players[playerId.index];
}
private function buildTank(playerId:PlayerId, config:TankConfig, point:SpawnPoint):Tank {
var tank = new Tank(playerId, config);
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 tank = new Tank(playerId, tankConfig);
applyPoint(tank, point);
return tank;
}
@@ -114,7 +117,7 @@ class Game implements EngineListener {
private function spawn(task:SpawnTask):Void {
getPlayer(task.playerId).tankId = 0;
if (trySpawn(task.playerId, true)) {
var tank = buildTank(task.playerId, config.getTank(task.playerId.team, '0'), task.point);
var tank = buildTank(task.playerId, task.point);
var player:Player = getPlayer(task.playerId);
engine.spawn(tank);
player.tankId = tank.id;