[common] tanks spawn types

This commit is contained in:
2018-02-02 20:53:26 +03:00
parent f9cb985059
commit 59cab68e3e
15 changed files with 202 additions and 52 deletions

View File

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

View File

@@ -26,17 +26,28 @@ class Animate extends Bitmap {
} }
} }
private static var a = new BitmapData(1, 1);
public var playing(default, set):Bool; public var playing(default, set):Bool;
private var frames:Array<BitmapData>; public var frames(default, set):Array<BitmapData>;
private var index:Int; private var index:Int;
public function new(frames:Array<BitmapData>) { public function new(?frames:Array<BitmapData>) {
super(frames[0], PixelSnapping.AUTO, true); super(null, PixelSnapping.AUTO, true);
this.frames = frames; this.frames = frames == null ? [] : frames;
init(); init();
instances.push(this); 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 { public function set_playing(value:Bool):Bool {
if (playing != value) { if (playing != value) {
playing = value; playing = value;

View File

@@ -117,25 +117,34 @@ class BrickItem extends RenderItem<Brick, Shape> {
class TankItem extends RenderItem<Tank, Animate> { class TankItem extends RenderItem<Tank, Animate> {
private var type:String; private var type:String;
private var hits:Int;
public function new(value:Tank) { public function new(value:Tank) {
super(value); super(value);
this.view = new Animate(getFrames().map(function(s) return Assets.getBitmapData(s))); view = new Animate();
redraw();
}
override public function redraw():Void {
view.frames = getFrames().map(function(s) return Assets.getBitmapData(s));
} }
private function getFrames():Array<String> { private function getFrames():Array<String> {
var team = value.playerId.team;
var group = value.config.group; var group = value.config.group;
var index = value.playerId.index; var index = value.playerId.index;
if (group == 'human') group = 'player'; if (team == 'radiant') {
if (group == 'radiant') {
group = 'player';
index = 0; index = 0;
} }
if (group == 'dire') { if (team == 'dire') {
group = 'player';
index = 1; index = 1;
} }
if (group == 'bot') index = 0; if (team == 'human' || team == 'radiant' || team == 'dire') {
group = 'player';
}
if (team == 'bot') {
index = value.hits;
}
return [ 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}-0.png',
'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-1.png', 'resources/images/tank/${group}/tank_${group.charAt(0)}${value.config.type}_${index}-1.png',
@@ -145,8 +154,10 @@ class TankItem extends RenderItem<Tank, Animate> {
override public function update():Void { override public function update():Void {
super.update(); super.update();
var t = value.config.type; var t = value.config.type;
if (t != this.type) { var h = value.hits;
if (t != this.type || h != this.hits) {
this.type = t; this.type = t;
this.hits = h;
redraw(); redraw();
} }
view.playing = (value.mx !=0 || value.my != 0); view.playing = (value.mx !=0 || value.my != 0);

View File

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

View File

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

View File

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

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

View File

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

View File

@@ -1,6 +1,5 @@
package ru.m.tankz.config; package ru.m.tankz.config;
import ru.m.tankz.game.ClassicGame;
import yaml.Parser; import yaml.Parser;
import openfl.Assets; import openfl.Assets;
import yaml.Yaml; import yaml.Yaml;
@@ -8,7 +7,7 @@ import ru.m.tankz.config.Config;
typedef ConfigSource = { typedef ConfigSource = {
var levels:Int; var game:GameConfig;
var map: MapConfig; var map: MapConfig;
var bricks: Array<BrickConfig>; var bricks: Array<BrickConfig>;
var teams: Array<TeamConfig>; var teams: Array<TeamConfig>;
@@ -31,6 +30,6 @@ class ConfigBundle {
tanks.push(item); 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 { class Tank extends MobileEntity {
public var playerId(default, null):PlayerId; public var playerId(default, null):PlayerId;
public var config(default, set):TankConfig; public var config(default, set):TankConfig;
public var hits(default, default):Int;
private var bulletsCounter:Int = 0; 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); super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT);
this.playerId = playerId; this.playerId = playerId;
this.config = config; this.config = config;
this.hits = config.hits;
this.layer = 1; this.layer = 1;
} }

View File

@@ -31,7 +31,16 @@ class CollisionProcessor implements EngineListener {
public function onSpawn(entity:EntityType):Void {} public function onSpawn(entity:EntityType):Void {}
private function checkTankBullet(tank:Tank, bullet:Bullet):Bool { 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 { public function onCollision(entity:EntityType, with:EntityType):Void {
@@ -42,7 +51,7 @@ class CollisionProcessor implements EngineListener {
tank1.rect.lean(tank2.rect); tank1.rect.lean(tank2.rect);
case EntityType.BULLET(bullet2): case EntityType.BULLET(bullet2):
if (checkTankBullet(tank1, bullet2)) { if (checkTankBullet(tank1, bullet2)) {
engine.destroy(tank1); hitTank(tank1);
engine.destroy(bullet2); engine.destroy(bullet2);
} }
case EntityType.EAGLE(eagle): case EntityType.EAGLE(eagle):
@@ -55,7 +64,7 @@ class CollisionProcessor implements EngineListener {
case EntityType.TANK(tank2): case EntityType.TANK(tank2):
if (checkTankBullet(tank2, bullet1)) { if (checkTankBullet(tank2, bullet1)) {
engine.destroy(bullet1); engine.destroy(bullet1);
engine.destroy(tank2); hitTank(tank2);
} }
case EntityType.BULLET(bullet2): case EntityType.BULLET(bullet2):
engine.destroy(bullet1); engine.destroy(bullet1);

View File

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

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import haxe.ds.Option;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
@@ -53,4 +54,10 @@ class DotaGame extends Game {
} }
return state; 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]; return teams.get(playerId.team).players[playerId.index];
} }
private function buildTank(playerId:PlayerId, config:TankConfig, point:SpawnPoint):Tank { private function buildTank(playerId:PlayerId, point:SpawnPoint):Tank {
var tank = new Tank(playerId, config); 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); applyPoint(tank, point);
return tank; return tank;
} }
@@ -114,7 +117,7 @@ class Game implements EngineListener {
private function spawn(task:SpawnTask):Void { private function spawn(task:SpawnTask):Void {
getPlayer(task.playerId).tankId = 0; getPlayer(task.playerId).tankId = 0;
if (trySpawn(task.playerId, true)) { 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); var player:Player = getPlayer(task.playerId);
engine.spawn(tank); engine.spawn(tank);
player.tankId = tank.id; player.tankId = tank.id;