[common] build tank and bullet with EntityBulder

This commit is contained in:
2019-05-06 17:53:34 +03:00
parent d6b572aead
commit 20b60009e3
11 changed files with 105 additions and 97 deletions

View File

@@ -1,6 +1,5 @@
package ru.m.tankz.render; package ru.m.tankz.render;
import ru.m.tankz.core.EntityType;
import flash.display.DisplayObjectContainer; import flash.display.DisplayObjectContainer;
import flash.display.Graphics; import flash.display.Graphics;
import flash.display.Sprite; import flash.display.Sprite;
@@ -11,6 +10,7 @@ import promhx.Promise;
import ru.m.animate.Animate; import ru.m.animate.Animate;
import ru.m.animate.OnceAnimate; import ru.m.animate.OnceAnimate;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.engine.IEngine; import ru.m.tankz.engine.IEngine;
import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.GameEvent;
import ru.m.tankz.game.IGame; import ru.m.tankz.game.IGame;
@@ -105,6 +105,16 @@ class Render extends SpriteView implements GameListener implements EngineListene
items.set(eagle.key, item); items.set(eagle.key, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
item.update(); item.update();
case TANK(tank):
var item = new TankItem(tank);
items.set(tank.key, item);
entryLayer.addChild(item.view);
item.update();
playAnimate(tank.rect.center, AnimateBundle.tankSpawn());
case BULLET(bullet):
var item = new BulletItem(bullet);
items.set(bullet.key, item);
entryLayer.addChild(item.view);
case _: case _:
} }
} }
@@ -117,17 +127,17 @@ class Render extends SpriteView implements GameListener implements EngineListene
public function onGameEvent(event:GameEvent):Void { public function onGameEvent(event:GameEvent):Void {
switch event { switch event {
case SPAWN(TANK(tank)): /*case SPAWN(TANK(tank)):
var item = new TankItem(tank); var item = new TankItem(tank);
items.set(tank.key, item); items.set(tank.key, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
item.update(); item.update();
playAnimate(tank.rect.center, AnimateBundle.tankSpawn()); playAnimate(tank.rect.center, AnimateBundle.tankSpawn());*/
case SPAWN(BULLET(bullet)): /*case SPAWN(BULLET(bullet)):
var item = new BulletItem(bullet); var item = new BulletItem(bullet);
items.set(bullet.key, item); items.set(bullet.key, item);
entryLayer.addChild(item.view); entryLayer.addChild(item.view);
item.update(); item.update();*/
/*case SPAWN(EAGLE(eagle)): /*case SPAWN(EAGLE(eagle)):
var item = new EagleItem(eagle); var item = new EagleItem(eagle);
items.set(eagle.key, item); items.set(eagle.key, item);

View File

@@ -78,7 +78,7 @@ class SoundManager implements GameListener {
switch event { switch event {
case START(state): case START(state):
play('start'); play('start');
case SPAWN(BULLET(bullet)): case SPAWN(BULLET(_)):
if (false /* ToDo: human tank */) { if (false /* ToDo: human tank */) {
play('shot'); play('shot');
} }

View File

@@ -92,7 +92,8 @@ class GameFrame extends GroupView implements GameListener {
progress.completeLevel(result.levelId, result.presetId); progress.completeLevel(result.levelId, result.presetId);
gameStorage.set(progress); gameStorage.set(progress);
s; s;
case None: null; case None:
new GameState(state.type, state.presetId, 0);
} }
stop(); stop();
switcher.change(ResultFrame.ID); switcher.change(ResultFrame.ID);

View File

@@ -5,19 +5,20 @@ import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class Bullet extends MobileEntity { class Bullet extends MobileEntity {
public var playerId(default, null):PlayerId; public var playerId(default, null):PlayerId;
public var tankId(default, null):Int; public var tankId(get, null):Int;
public var tank(default, null):Tank; public var tank(default, default):Tank;
public var config(default, null):BulletConfig; public var config(default, null):BulletConfig;
public function new(tank:Tank) { public function new(playerId:PlayerId, config:BulletConfig) {
this.playerId = tank.playerId; this.playerId = playerId;
this.tank = tank; this.config = config;
this.config = tank.config.bullet;
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.tankId = tank.id;
this.layer = 2; this.layer = 2;
} }
private inline function get_tankId():Int {
return tank.id;
}
} }

View File

@@ -1,12 +1,9 @@
package ru.m.tankz.core; package ru.m.tankz.core;
import haxe.Timer;
import haxework.color.Color; import haxework.color.Color;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.geom.Point;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.core.Bullet;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class Tank extends MobileEntity { class Tank extends MobileEntity {
@@ -18,9 +15,6 @@ class Tank extends MobileEntity {
public var protect(default, null):Modificator; public var protect(default, null):Modificator;
public var freezing(default, null):Modificator; public var freezing(default, null):Modificator;
private var bulletsCounter:Int = 0;
private var shotDelayTimer:Timer;
public function new(playerId:PlayerId, config:TankConfig) { public function new(playerId:PlayerId, config:TankConfig) {
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.protect = new Modificator(); this.protect = new Modificator();
@@ -45,24 +39,4 @@ class Tank extends MobileEntity {
super.move(direction); super.move(direction);
} }
} }
public function shot():Null<Bullet> {
if (
freezing.active ||
bulletsCounter >= config.bullets ||
shotDelayTimer != null
) {
return null;
}
var bullet = new Bullet(this);
bullet.rect.center = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y));
bullet.move(rect.direction);
bulletsCounter++;
shotDelayTimer = Timer.delay(function() shotDelayTimer = null, 200);
return bullet;
}
public function onDestroyBullet():Void {
bulletsCounter--;
}
} }

View File

@@ -1,9 +1,9 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.geom.Point; import ru.m.tankz.core.Bullet;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.core.Eagle; import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Entity; import ru.m.tankz.core.Tank;
import ru.m.tankz.Type; import ru.m.tankz.Type;
class EntityBuilder { class EntityBuilder {
@@ -14,18 +14,26 @@ class EntityBuilder {
this.config = config; this.config = config;
} }
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
entity.rect.center = new Point((point.x + 1) * config.map.cellWidth, (point.y + 1) * config.map.cellHeight);
entity.rect.direction = point.direction;
}
public function buildEagle(teamId:TeamId):Eagle { public function buildEagle(teamId:TeamId):Eagle {
var eageleConfig = config.getTeam(teamId).eagle; var eageleConfig = config.getTeam(teamId).eagle;
var eaglePoint = config.getPoint(teamId, "eagle"); var eaglePoint = config.getPoint(teamId, "eagle");
var eagle = new Eagle(teamId, eageleConfig); var eagle = new Eagle(teamId, eageleConfig);
eagle.color = config.getColor(new PlayerId(teamId, -1)); eagle.color = config.getColor(new PlayerId(teamId, -1));
applyPoint(eagle, eaglePoint);
return eagle; return eagle;
} }
public function buildTank(playerId:PlayerId, type:TankType):Tank {
var playerConfig = config.getPlayer(playerId);
var tankConfig = config.getTank(type);
var tank = new Tank(playerId, tankConfig);
tank.color = config.getColor(playerId);
return tank;
}
public function buildBullet(playerId:PlayerId, type:TankType):Bullet {
var tankConfig = config.getTank(type);
var bullet = new Bullet(playerId, tankConfig.bullet);
return bullet;
}
} }

View File

@@ -1,8 +1,10 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.geom.Point;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
import ru.m.tankz.engine.Engine; import ru.m.tankz.engine.Engine;
@@ -36,6 +38,11 @@ import ru.m.tankz.Type;
connect(this); connect(this);
} }
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
entity.rect.center = new Point((point.x + 1) * config.map.cellWidth, (point.y + 1) * config.map.cellHeight);
entity.rect.direction = point.direction;
}
public inline function getTeam(teamId:TeamId):Team { public inline function getTeam(teamId:TeamId):Team {
return teams[teamId]; return teams[teamId];
} }
@@ -51,13 +58,33 @@ import ru.m.tankz.Type;
case GameEvent.COMPLETE(state, team): case GameEvent.COMPLETE(state, team):
this.state = state; this.state = state;
this.winner = team.id; this.winner = team.id;
case GameEvent.SPAWN(EAGLE(teamId)): case GameEvent.SPAWN(EAGLE(teamId, point)):
var eagle = builder.buildEagle(teamId); var eagle = builder.buildEagle(teamId);
getTeam(teamId).eagleId = eagle.id; applyPoint(eagle, point);
var team = getTeam(teamId);
team.eagleId = eagle.id;
engine.spawn(eagle); engine.spawn(eagle);
case GameEvent.SPAWN(TANK(tank)): case GameEvent.SPAWN(TANK(playerId, type, point)):
var tank = builder.buildTank(playerId, type);
applyPoint(tank, point);
var player = getPlayer(playerId);
player.tankId = tank.id;
player.state.tank = tank.config.type;
// ToDo: in GameRunner?
if (player.config.protect > 0) {
tank.protect.on(player.config.protect);
}
tank.bonus = Math.random() < player.config.bonus;
//
engine.spawn(tank); engine.spawn(tank);
case GameEvent.SPAWN(BULLET(bullet)): case GameEvent.SPAWN(BULLET(playerId)):
var player = getPlayer(playerId);
var tank:Tank = cast engine.entities.get(player.tankId);
var bullet = builder.buildBullet(playerId, tank.config.type);
bullet.tank = tank;
var rect = tank.rect;
bullet.rect.center = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y));
bullet.move(rect.direction);
engine.spawn(bullet); engine.spawn(bullet);
case GameEvent.SPAWN(BONUS(bonus)): case GameEvent.SPAWN(BONUS(bonus)):
engine.spawn(bonus); engine.spawn(bonus);

View File

@@ -1,17 +1,18 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.core.Bonus; import ru.m.tankz.core.Bonus;
import ru.m.tankz.core.Bullet; import ru.m.tankz.core.Bullet;
import ru.m.tankz.core.Eagle; import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
import ru.m.tankz.map.Grid; import ru.m.tankz.map.Grid;
import ru.m.tankz.Type.TeamId; import ru.m.tankz.Type;
enum SpawnEvent { enum SpawnEvent {
EAGLE(teamId:TeamId); EAGLE(teamId:TeamId, point:SpawnPoint);
TANK(tank:Tank); TANK(playerId:PlayerId, type:TankType, point:SpawnPoint);
BULLET(bullet:Bullet); BULLET(playerId:PlayerId);
BONUS(bonus:Bonus); BONUS(bonus:Bonus);
} }

View File

@@ -46,26 +46,6 @@ class GameRunner implements EngineListener implements GameListener {
game.engine.update(); game.engine.update();
} }
private function buildTank(task:SpawnTask):Tank {
var player = game.getPlayer(task.playerId);
var tankType:TankType = if (task.tankType != null) {
task.tankType;
} else {
var spawns:Array<TankSpawn> = player.config.tanks;
var spawn:TankSpawn = spawns[Math.floor(Math.random() * spawns.length)];
spawn.type;
}
var tankConfig:TankConfig = game.config.getTank(tankType);
var tank = new Tank(task.playerId, tankConfig);
tank.color = game.state.getPlayerColor(player.id);
tank.bonus = Math.random() < player.config.bonus;
applyPoint(tank, task.point);
if (player.config.protect > 0) {
tank.protect.on(player.config.protect);
}
return tank;
}
private function applyPoint(entity:Entity, point:SpawnPoint):Void { private function applyPoint(entity:Entity, point:SpawnPoint):Void {
entity.rect.center = new Point((point.x + 1) * game.engine.map.cellWidth, (point.y + 1) * game.engine.map.cellHeight); entity.rect.center = new Point((point.x + 1) * game.engine.map.cellWidth, (point.y + 1) * game.engine.map.cellHeight);
entity.rect.direction = point.direction; entity.rect.direction = point.direction;
@@ -91,11 +71,12 @@ class GameRunner implements EngineListener implements GameListener {
for (team in game.teams.iterator()) { for (team in game.teams.iterator()) {
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
if (team.tryRespawn(player.id)) { if (team.tryRespawn(player.id)) {
team.spawner.push(player.id, player.state.tank); team.spawner.push(player.id);
} }
} }
if (team.config.eagle != null) { if (team.config.eagle != null) {
gameEventSignal.emit(GameEvent.SPAWN(EAGLE(team.id))); var point = game.config.getPoint(team.id, "eagle");
gameEventSignal.emit(GameEvent.SPAWN(EAGLE(team.id, point)));
} }
} }
gameEventSignal.emit(GameEvent.START(state)); gameEventSignal.emit(GameEvent.START(state));
@@ -115,13 +96,7 @@ class GameRunner implements EngineListener implements GameListener {
} }
private function spawn(task:SpawnTask):Void { private function spawn(task:SpawnTask):Void {
var team = game.getTeam(task.playerId.team); gameEventSignal.emit(GameEvent.SPAWN(TANK(task.playerId, task.tankType, task.point)));
var player = game.getPlayer(task.playerId);
player.tankId = 0;
var tank = buildTank(task);
player.tankId = tank.id;
player.state.tank = tank.config.type;
gameEventSignal.emit(GameEvent.SPAWN(TANK(tank)));
} }
private function checkComplete():Void { private function checkComplete():Void {
@@ -301,12 +276,14 @@ class GameRunner implements EngineListener implements GameListener {
} }
case GameEvent.ACTION(tankId, SHOT): case GameEvent.ACTION(tankId, SHOT):
var tank:Tank = cast game.engine.entities.get(tankId); var tank:Tank = cast game.engine.entities.get(tankId);
var bullet = tank.shot(); var player = game.getPlayer(tank.playerId);
if (bullet != null) { if (!tank.freezing.active && player.bullets < tank.config.bullets) {
gameEventSignal.emit(GameEvent.SPAWN(BULLET(bullet))); gameEventSignal.emit(GameEvent.SPAWN(BULLET(tank.playerId)));
} }
case GameEvent.SPAWN(TANK(tank)): case GameEvent.SPAWN(TANK(playerId, _)):
game.getPlayer(tank.playerId).control.start(); game.getPlayer(playerId).control.start();
case GameEvent.SPAWN(BULLET(playerId)):
game.getPlayer(playerId).bullets++;
case GameEvent.DESTROY(EAGLE(eagle, who, wherewith, score)): case GameEvent.DESTROY(EAGLE(eagle, who, wherewith, score)):
eagle.death = true; eagle.death = true;
if (score != 0) { if (score != 0) {
@@ -343,10 +320,8 @@ class GameRunner implements EngineListener implements GameListener {
changeScore(who.playerId, score); changeScore(who.playerId, score);
} }
case GameEvent.DESTROY(BULLET(bullet)): case GameEvent.DESTROY(BULLET(bullet)):
var tank:Tank = bullet.tank; var player = game.getPlayer(bullet.playerId);
if (tank != null) { player.bullets--;
tank.onDestroyBullet();
}
case _: case _:
} }
} }

View File

@@ -12,6 +12,7 @@ class Player {
public var control(default, set):Control; public var control(default, set):Control;
public var isAlive(get, null):Bool; public var isAlive(get, null):Bool;
public var state(default, default):PlayerState; public var state(default, default):PlayerState;
public var bullets(default, default):Int;
public function new(teamId:TeamId, config:PlayerConfig, state:PlayerState = null) { public function new(teamId:TeamId, config:PlayerConfig, state:PlayerState = null) {
this.config = config; this.config = config;
@@ -20,6 +21,7 @@ class Player {
this.state = state == null ? new PlayerState(id) : state; this.state = state == null ? new PlayerState(id) : state;
this.state.reset(); this.state.reset();
this.state.life = Math.isNaN(config.life) ? 0 : config.life; this.state.life = Math.isNaN(config.life) ? 0 : config.life;
this.bullets = 0;
} }
private function set_tankId(value:Int):Int { private function set_tankId(value:Int):Int {

View File

@@ -53,7 +53,16 @@ class Spawner {
return null; return null;
} }
public function push(playerId:PlayerId, ?tankType:TankType):Void { private function getPlayerTank(playerId:PlayerId):TankType {
for (player in config.players) if (player.index == playerId.index) {
var spawns:Array<TankSpawn> = player.tanks;
var spawn:TankSpawn = spawns[Math.floor(Math.random() * spawns.length)];
return spawn.type;
}
return null;
}
public function push(playerId:PlayerId):Void {
var point:SpawnPoint = null; var point:SpawnPoint = null;
if (indexedPoints.exists(playerId.index)) { if (indexedPoints.exists(playerId.index)) {
point = indexedPoints.get(playerId.index); point = indexedPoints.get(playerId.index);
@@ -62,7 +71,7 @@ class Spawner {
if (index >= anyPoints.length) index = 0; if (index >= anyPoints.length) index = 0;
} }
if (point != null) { if (point != null) {
queue.push({playerId:playerId, point:point, tankType:tankType}); queue.push({playerId:playerId, point:point, tankType:getPlayerTank(playerId)});
run(); run();
} }
} }