[common] update GameEvent
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package ru.m.tankz.render;
|
package ru.m.tankz.render;
|
||||||
|
|
||||||
|
import ru.m.geom.Rectangle;
|
||||||
import flash.display.DisplayObjectContainer;
|
import flash.display.DisplayObjectContainer;
|
||||||
import flash.display.Graphics;
|
import flash.display.Graphics;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
@@ -24,7 +25,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
private var upperLayer:Sprite;
|
private var upperLayer:Sprite;
|
||||||
|
|
||||||
private var background:Sprite;
|
private var background:Sprite;
|
||||||
private var items:Map<String, RenderItem<Dynamic, Dynamic>>;
|
private var items:Map<Int, RenderItem<Dynamic, Dynamic>>;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
@@ -53,7 +54,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
|
|
||||||
public function draw(game:IEngine):Void {
|
public function draw(game:IEngine):Void {
|
||||||
for (brick in game.map.bricks) if (brick.config.index > 0) {
|
for (brick in game.map.bricks) if (brick.config.index > 0) {
|
||||||
if (!items.exists(brick.key)) {
|
if (!items.exists(brick.id)) {
|
||||||
var item:RenderItem<Dynamic, Dynamic> = switch(brick.config.type) {
|
var item:RenderItem<Dynamic, Dynamic> = switch(brick.config.type) {
|
||||||
case 'ace' | 'bush': new BrickItem(brick);
|
case 'ace' | 'bush': new BrickItem(brick);
|
||||||
case 'water': new BrickAnimateItem(brick);
|
case 'water': new BrickAnimateItem(brick);
|
||||||
@@ -61,7 +62,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
case x: null;
|
case x: null;
|
||||||
};
|
};
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
items[brick.key] = item;
|
items[brick.id] = item;
|
||||||
if (brick.config.layer > 2) {
|
if (brick.config.layer > 2) {
|
||||||
upLayer.addChild(item.view);
|
upLayer.addChild(item.view);
|
||||||
} else {
|
} else {
|
||||||
@@ -101,23 +102,23 @@ class Render extends SpriteView implements IRender {
|
|||||||
switch entity {
|
switch entity {
|
||||||
case EAGLE(eagle):
|
case EAGLE(eagle):
|
||||||
var item = new EagleItem(eagle);
|
var item = new EagleItem(eagle);
|
||||||
items.set(eagle.key, item);
|
items.set(eagle.id, item);
|
||||||
entryLayer.addChild(item.view);
|
entryLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
case TANK(tank):
|
case TANK(tank):
|
||||||
var item = new TankItem(tank);
|
var item = new TankItem(tank);
|
||||||
items.set(tank.key, item);
|
items.set(tank.id, 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 BULLET(bullet):
|
case BULLET(bullet):
|
||||||
var item = new BulletItem(bullet);
|
var item = new BulletItem(bullet);
|
||||||
items.set(bullet.key, item);
|
items.set(bullet.id, item);
|
||||||
entryLayer.addChild(item.view);
|
entryLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
case BONUS(bonus):
|
case BONUS(bonus):
|
||||||
var item = new BonusItem(bonus);
|
var item = new BonusItem(bonus);
|
||||||
items.set(bonus.key, item);
|
items.set(bonus.id, item);
|
||||||
upperLayer.addChild(item.view);
|
upperLayer.addChild(item.view);
|
||||||
item.update();
|
item.update();
|
||||||
case _:
|
case _:
|
||||||
@@ -135,34 +136,44 @@ class Render extends SpriteView implements IRender {
|
|||||||
|
|
||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
switch event {
|
switch event {
|
||||||
case DESTROY(TANK(tank, who, wherewith, score)):
|
case DESTROY(TANK(id, shot)):
|
||||||
if (items.exists(tank.key)) {
|
if (items.exists(id)) {
|
||||||
entryLayer.removeChild(items.get(tank.key).view);
|
var item = items[id];
|
||||||
items.remove(tank.key);
|
entryLayer.removeChild(item.view);
|
||||||
playAnimate(tank.rect.center, AnimateBundle.tankBoom());
|
var rect:Rectangle = item.value.rect;
|
||||||
if (score != 0) {
|
playAnimate(rect.center, AnimateBundle.tankBoom());
|
||||||
showScore(tank.rect.center, score);
|
if (shot.score != 0) {
|
||||||
|
showScore(rect.center, shot.score);
|
||||||
}
|
}
|
||||||
|
items.remove(id);
|
||||||
}
|
}
|
||||||
case DESTROY(BULLET(bullet)):
|
case DESTROY(BULLET(id)):
|
||||||
if (items.exists(bullet.key)) {
|
if (items.exists(id)) {
|
||||||
entryLayer.removeChild(items.get(bullet.key).view);
|
var item = items[id];
|
||||||
items.remove(bullet.key);
|
entryLayer.removeChild(item.view);
|
||||||
var point = bullet.rect.center.add(new Point(bullet.rect.width * bullet.rect.direction.x, bullet.rect.height * bullet.rect.direction.y));
|
var rect:Rectangle = item.value.rect;
|
||||||
|
var point = rect.center.add(new Point(rect.width * rect.direction.x, rect.height * rect.direction.y));
|
||||||
playAnimate(point, AnimateBundle.bulletBoom());
|
playAnimate(point, AnimateBundle.bulletBoom());
|
||||||
|
items.remove(id);
|
||||||
}
|
}
|
||||||
case DESTROY(BONUS(bonus, who, score)):
|
case DESTROY(BONUS(id, shot)):
|
||||||
if (items.exists(bonus.key)) {
|
if (items.exists(id)) {
|
||||||
upperLayer.removeChild(items.get(bonus.key).view);
|
var item = items[id];
|
||||||
items.remove(bonus.key);
|
upperLayer.removeChild(item.view);
|
||||||
if (score != 0) {
|
var rect:Rectangle = item.value.rect;
|
||||||
showScore(bonus.rect.center, score);
|
if (shot.score != 0) {
|
||||||
|
showScore(rect.center, shot.score);
|
||||||
}
|
}
|
||||||
|
items.remove(id);
|
||||||
|
}
|
||||||
|
case DESTROY(EAGLE(id, shot)):
|
||||||
|
if (items.exists(id)) {
|
||||||
|
var item = items[id];
|
||||||
|
var rect:Rectangle = item.value.rect;
|
||||||
|
playAnimate(rect.center, AnimateBundle.tankBoom());
|
||||||
|
if (shot.score != 0) {
|
||||||
|
showScore(rect.center, shot.score);
|
||||||
}
|
}
|
||||||
case DESTROY(EAGLE(eagle, who, wherewith, score)):
|
|
||||||
playAnimate(eagle.rect.center, AnimateBundle.tankBoom());
|
|
||||||
if (score != 0) {
|
|
||||||
showScore(eagle.rect.center, score);
|
|
||||||
}
|
}
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,26 +76,28 @@ class SoundManager implements GameListener {
|
|||||||
|
|
||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
switch event {
|
switch event {
|
||||||
case START(state):
|
case START(_):
|
||||||
play('start');
|
play('start');
|
||||||
case SPAWN(_, BULLET(_)):
|
case SPAWN(BULLET(_)):
|
||||||
if (false /* ToDo: human tank */) {
|
if (false /*ToDo: human tank*/) {
|
||||||
play('shot');
|
play('shot');
|
||||||
}
|
}
|
||||||
case SPAWN(_, BONUS(_, _)):
|
case SPAWN(BONUS(_, _)):
|
||||||
play('bonus_add');
|
play('bonus_add');
|
||||||
case HIT(TANK(tank, who, wherewith)):
|
case HIT(TANK(_, _)):
|
||||||
play('bullet_hit');
|
play('bullet_hit');
|
||||||
case DESTROY(TANK(tank, who, wherewith, score)):
|
case DESTROY(TANK(_, _)):
|
||||||
if (true /* ToDo: human tank */) {
|
if (true /*ToDo: human tank*/) {
|
||||||
play('boom_player');
|
play('boom_player');
|
||||||
} else {
|
} else {
|
||||||
play('boom_bot');
|
play('boom_bot');
|
||||||
}
|
}
|
||||||
case DESTROY(EAGLE(eagle, who, wherewith, score)):
|
case DESTROY(EAGLE(_, _)):
|
||||||
play('boom_player');
|
play('boom_player');
|
||||||
case DESTROY(BONUS(bonus, who, score)):
|
case DESTROY(BONUS(_, _)):
|
||||||
if (bonus.type == 'life') {
|
// ToDo: bonus type
|
||||||
|
play('bonus_get');
|
||||||
|
if (false /*ToDo: bonus.type == 'life'*/) {
|
||||||
play('live');
|
play('live');
|
||||||
} else {
|
} else {
|
||||||
play('bonus_get');
|
play('bonus_get');
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ import ru.m.tankz.game.record.GameRecord;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function save(record:GameRecord):Void {
|
public function save(record:GameRecord):Void {
|
||||||
trace(record.id);
|
|
||||||
trace(record.date);
|
|
||||||
trace(record.events);
|
|
||||||
write(record.id, record);
|
write(record.id, record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ import ru.m.tankz.view.game.GameView;
|
|||||||
|
|
||||||
public function onGameEvent(event:GameEvent):Void {
|
public function onGameEvent(event:GameEvent):Void {
|
||||||
switch event {
|
switch event {
|
||||||
case GameEvent.COMPLETE(state, winner):
|
case GameEvent.COMPLETE(state, _):
|
||||||
// ToDo:
|
// ToDo:
|
||||||
recordStorage.save(recorder.record);
|
recordStorage.save(recorder.record);
|
||||||
result = state;
|
result = state;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class BotControl extends Control {
|
|||||||
private var tank(get, null):Tank;
|
private var tank(get, null):Tank;
|
||||||
|
|
||||||
private inline function get_tank():Tank {
|
private inline function get_tank():Tank {
|
||||||
return handler == null ? null : cast handler.engine.entities[tankId];
|
return handler == null ? null : handler.engine.getEntity(tankId);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function stop():Void {
|
override public function stop():Void {
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package ru.m.tankz.core;
|
|||||||
import ru.m.geom.Rectangle;
|
import ru.m.geom.Rectangle;
|
||||||
import Type;
|
import Type;
|
||||||
|
|
||||||
|
class Entity {
|
||||||
class Entity implements IKey {
|
|
||||||
|
|
||||||
public var id(default, null):Int;
|
public var id(default, null):Int;
|
||||||
public var type(default, null):String;
|
public var type(default, null):String;
|
||||||
public var key(get, null):String;
|
|
||||||
public var rect(default, null):Rectangle;
|
public var rect(default, null):Rectangle;
|
||||||
|
|
||||||
public function new(id:Int, rect:Rectangle) {
|
public function new(id:Int, rect:Rectangle) {
|
||||||
@@ -17,11 +15,7 @@ class Entity implements IKey {
|
|||||||
this.rect = rect;
|
this.rect = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function get_key():String {
|
|
||||||
return '$type:$id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toString():String {
|
public function toString():String {
|
||||||
return key;
|
return '$type($id)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package ru.m.tankz.core;
|
|
||||||
|
|
||||||
interface IKey {
|
|
||||||
public var key(get, null):String;
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@ import ru.m.tankz.map.LevelMap;
|
|||||||
public var config(default, default):Config;
|
public var config(default, default):Config;
|
||||||
public var map(default, null):LevelMap;
|
public var map(default, null):LevelMap;
|
||||||
|
|
||||||
|
public var allEntities(default, null):Map<Int, Entity>;
|
||||||
public var entities(default, null):Map<Int, Entity>;
|
public var entities(default, null):Map<Int, Entity>;
|
||||||
|
|
||||||
private var time:Float;
|
private var time:Float;
|
||||||
@@ -25,19 +26,26 @@ import ru.m.tankz.map.LevelMap;
|
|||||||
public function new(config:Config) {
|
public function new(config:Config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
map = new LevelMap(config.map);
|
map = new LevelMap(config.map);
|
||||||
|
allEntities = new Map();
|
||||||
entities = new Map();
|
entities = new Map();
|
||||||
time = Date.now().getTime();
|
time = Date.now().getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEntity<T:Entity>(entityId:Int):T {
|
||||||
|
return cast allEntities.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
public function spawn(entity:Entity):Void {
|
public function spawn(entity:Entity):Void {
|
||||||
|
allEntities.set(entity.id, entity);
|
||||||
entities.set(entity.id, entity);
|
entities.set(entity.id, entity);
|
||||||
spawnSignal.emit(EntityTypeResolver.of(entity));
|
spawnSignal.emit(EntityTypeResolver.of(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(entityId:Int):Void {
|
public function destroy(entityId:Int):Void {
|
||||||
if (entities.exists(entityId)) {
|
if (entities.exists(entityId)) {
|
||||||
var entity = entities.remove(entityId);
|
var entity = entities[entityId];
|
||||||
destroySignal.emit(EntityTypeResolver.of(entity));
|
destroySignal.emit(EntityTypeResolver.of(entity));
|
||||||
|
entities.remove(entityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ interface IEngine {
|
|||||||
public var moveSignal(default, null):Signal1<EntityType>;
|
public var moveSignal(default, null):Signal1<EntityType>;
|
||||||
public var destroySignal(default, null):Signal1<EntityType>;
|
public var destroySignal(default, null):Signal1<EntityType>;
|
||||||
|
|
||||||
|
public function getEntity<T:Entity>(entityId:Int):T;
|
||||||
|
|
||||||
public function spawn(entity:Entity):Void;
|
public function spawn(entity:Entity):Void;
|
||||||
|
|
||||||
public function move(entityId:Int, direction:Direction):Void;
|
public function move(entityId:Int, direction:Direction):Void;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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;
|
||||||
import ru.m.tankz.engine.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
|
import ru.m.tankz.game.GameEvent;
|
||||||
import ru.m.tankz.game.GameState;
|
import ru.m.tankz.game.GameState;
|
||||||
import ru.m.tankz.game.IGame;
|
import ru.m.tankz.game.IGame;
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
@@ -56,9 +57,11 @@ import ru.m.tankz.Type;
|
|||||||
engine.update();
|
engine.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
|
private function applyPosition(entity:Entity, position:Position):Void {
|
||||||
entity.rect.center = new Point((point.x + 1) * config.map.cellWidth, (point.y + 1) * config.map.cellHeight);
|
entity.rect.center = new Point(position.x, position.y);
|
||||||
entity.rect.direction = point.direction;
|
if (position.direction != null) {
|
||||||
|
entity.rect.direction = position.direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function getTeam(teamId:TeamId):Team {
|
public inline function getTeam(teamId:TeamId):Team {
|
||||||
@@ -75,22 +78,22 @@ import ru.m.tankz.Type;
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
timer = new Timer(10);
|
timer = new Timer(10);
|
||||||
timer.run = update;
|
timer.run = update;
|
||||||
case GameEvent.COMPLETE(state, team):
|
case GameEvent.COMPLETE(state, winnerId):
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.winner = team.id;
|
this.winner = winnerId;
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
timer = null;
|
timer = null;
|
||||||
}
|
}
|
||||||
case GameEvent.SPAWN(entityId, EAGLE(teamId, point)):
|
case GameEvent.SPAWN(EAGLE(id, position, teamId)):
|
||||||
var eagle = builder.buildEagle(entityId, teamId);
|
var eagle = builder.buildEagle(id, teamId);
|
||||||
applyPoint(eagle, point);
|
applyPosition(eagle, position);
|
||||||
var team = getTeam(teamId);
|
var team = getTeam(teamId);
|
||||||
team.eagleId = eagle.id;
|
team.eagleId = eagle.id;
|
||||||
engine.spawn(eagle);
|
engine.spawn(eagle);
|
||||||
case GameEvent.SPAWN(entityId, TANK(playerId, type, point)):
|
case GameEvent.SPAWN(TANK(id, position, playerId, type)):
|
||||||
var tank = builder.buildTank(entityId, playerId, type);
|
var tank = builder.buildTank(id, playerId, type);
|
||||||
applyPoint(tank, point);
|
applyPosition(tank, position);
|
||||||
var player = getPlayer(playerId);
|
var player = getPlayer(playerId);
|
||||||
player.tankId = tank.id;
|
player.tankId = tank.id;
|
||||||
player.state.tank = tank.config.type;
|
player.state.tank = tank.config.type;
|
||||||
@@ -101,28 +104,26 @@ import ru.m.tankz.Type;
|
|||||||
tank.bonus = Math.random() < player.config.bonus;
|
tank.bonus = Math.random() < player.config.bonus;
|
||||||
//
|
//
|
||||||
engine.spawn(tank);
|
engine.spawn(tank);
|
||||||
case GameEvent.SPAWN(entityId, BULLET(playerId)):
|
case GameEvent.SPAWN(BULLET(id, position, playerId)):
|
||||||
var player = getPlayer(playerId);
|
var player = getPlayer(playerId);
|
||||||
var tank:Tank = cast engine.entities.get(player.tankId);
|
var tank:Tank = cast engine.entities.get(player.tankId);
|
||||||
var bullet = builder.buildBullet(entityId, playerId, tank.config.type);
|
var bullet = builder.buildBullet(id, playerId, tank.config.type);
|
||||||
|
applyPosition(bullet, position);
|
||||||
bullet.tank = tank;
|
bullet.tank = tank;
|
||||||
var rect = tank.rect;
|
bullet.move(bullet.rect.direction);
|
||||||
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(entityId, BONUS(type, point)):
|
case GameEvent.SPAWN(BONUS(id, position, type)):
|
||||||
var bonus = builder.buildBonus(entityId, type);
|
var bonus = builder.buildBonus(id, type);
|
||||||
bonus.rect.x = point.x * config.map.cellWidth;
|
applyPosition(bonus, position);
|
||||||
bonus.rect.y = point.y * config.map.cellHeight;
|
|
||||||
engine.spawn(bonus);
|
engine.spawn(bonus);
|
||||||
case GameEvent.DESTROY(TANK(tank, who, wherewith, score)):
|
case GameEvent.DESTROY(TANK(id, _)):
|
||||||
engine.destroy(tank.id);
|
engine.destroy(id);
|
||||||
case GameEvent.DESTROY(BONUS(bonus, who, score)):
|
case GameEvent.DESTROY(BONUS(id, _)):
|
||||||
engine.destroy(bonus.id);
|
engine.destroy(id);
|
||||||
case GameEvent.DESTROY(BULLET(bullet)):
|
case GameEvent.DESTROY(BULLET(id)):
|
||||||
engine.destroy(bullet.id);
|
engine.destroy(id);
|
||||||
case GameEvent.DESTROY(CELL(cell, tank, bullet)):
|
case GameEvent.DESTROY(CELL(cellX, cellY, _)):
|
||||||
engine.destroyCell(cell.cellX, cell.cellY);
|
engine.destroyCell(cellX, cellY);
|
||||||
case GameEvent.ACTION(tankId, MOVE(direction)):
|
case GameEvent.ACTION(tankId, MOVE(direction)):
|
||||||
engine.move(tankId, direction);
|
engine.move(tankId, direction);
|
||||||
case GameEvent.ACTION(tankId, STOP):
|
case GameEvent.ACTION(tankId, STOP):
|
||||||
|
|||||||
@@ -1,32 +1,39 @@
|
|||||||
package ru.m.tankz.game;
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
import ru.m.tankz.config.Config;
|
import ru.m.geom.Direction;
|
||||||
import ru.m.tankz.control.Control;
|
import ru.m.tankz.control.Control;
|
||||||
import ru.m.tankz.core.Bonus;
|
|
||||||
import ru.m.tankz.core.Bullet;
|
|
||||||
import ru.m.tankz.core.Eagle;
|
|
||||||
import ru.m.tankz.core.Tank;
|
|
||||||
import ru.m.tankz.map.Grid;
|
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
|
|
||||||
|
typedef Position = {
|
||||||
|
var x:Float;
|
||||||
|
var y:Float;
|
||||||
|
@:optional var direction:Direction;
|
||||||
|
}
|
||||||
|
|
||||||
enum SpawnEvent {
|
enum SpawnEvent {
|
||||||
EAGLE(teamId:TeamId, point:SpawnPoint);
|
EAGLE(id:Int, position:Position, teamId:TeamId);
|
||||||
TANK(playerId:PlayerId, type:TankType, point:SpawnPoint);
|
TANK(id:Int, position:Position, playerId:PlayerId, type:TankType);
|
||||||
BULLET(playerId:PlayerId);
|
BULLET(id:Int, position:Position, playerId:PlayerId);
|
||||||
BONUS(type:BonusType, point:{x:Int, y:Int});
|
BONUS(id:Int, position:Position, type:BonusType);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Shot = {
|
||||||
|
var tankId:Int;
|
||||||
|
@:optional var bulletId:Int;
|
||||||
|
@:optional var score:Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HitEvent {
|
enum HitEvent {
|
||||||
TANK(tank:Tank, who:Tank, wherewith:Bullet);
|
TANK(id:Int, shot:Shot);
|
||||||
CELL(cell:GridCell, who:Tank, wherewith:Bullet);
|
CELL(cellX:Int, cellY:Int, shot:Shot);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DestroyEvent {
|
enum DestroyEvent {
|
||||||
EAGLE(eagle:Eagle, who:Tank, wherewith:Bullet, score:Int);
|
EAGLE(id:Int, shot:Shot);
|
||||||
TANK(tank:Tank, who:Tank, wherewith:Bullet, score:Int);
|
TANK(id:Int, shot:Shot);
|
||||||
CELL(cell:GridCell, who:Tank, wherewith:Bullet);
|
BONUS(id:Int, shot:Shot);
|
||||||
BONUS(bonus:Bonus, who:Tank, score:Int);
|
BULLET(id:Int);
|
||||||
BULLET(bullet:Bullet);
|
CELL(cellX:Int, cellY:Int, shot:Shot);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ChangeEvent {
|
enum ChangeEvent {
|
||||||
@@ -38,10 +45,10 @@ enum ChangeEvent {
|
|||||||
|
|
||||||
enum GameEvent {
|
enum GameEvent {
|
||||||
START(state:GameState);
|
START(state:GameState);
|
||||||
SPAWN(entityId:Int, event:SpawnEvent);
|
SPAWN(event:SpawnEvent);
|
||||||
HIT(event:HitEvent);
|
HIT(event:HitEvent);
|
||||||
DESTROY(event:DestroyEvent);
|
DESTROY(event:DestroyEvent);
|
||||||
CHANGE(event:ChangeEvent);
|
CHANGE(event:ChangeEvent);
|
||||||
COMPLETE(state:GameState, winner:Team);
|
COMPLETE(state:GameState, winnerId:TeamId);
|
||||||
ACTION(tankId:Int, action:TankAction);
|
ACTION(tankId:Int, action:TankAction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package ru.m.tankz.game;
|
package ru.m.tankz.game;
|
||||||
|
|
||||||
import haxe.Timer;
|
|
||||||
import haxe.ds.Option;
|
import haxe.ds.Option;
|
||||||
|
import haxe.Timer;
|
||||||
import haxework.signal.Signal;
|
import haxework.signal.Signal;
|
||||||
import ru.m.geom.Line;
|
import ru.m.geom.Line;
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
@@ -10,11 +10,12 @@ import ru.m.tankz.control.Control;
|
|||||||
import ru.m.tankz.control.Controller;
|
import ru.m.tankz.control.Controller;
|
||||||
import ru.m.tankz.control.IControlFactory;
|
import ru.m.tankz.control.IControlFactory;
|
||||||
import ru.m.tankz.core.Bonus;
|
import ru.m.tankz.core.Bonus;
|
||||||
|
import ru.m.tankz.core.Bullet;
|
||||||
import ru.m.tankz.core.Eagle;
|
import ru.m.tankz.core.Eagle;
|
||||||
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.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
|
import ru.m.tankz.game.GameEvent;
|
||||||
import ru.m.tankz.game.IGame;
|
import ru.m.tankz.game.IGame;
|
||||||
import ru.m.tankz.game.Spawner;
|
import ru.m.tankz.game.Spawner;
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
@@ -42,9 +43,12 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
game.engine.disconnect(this);
|
game.engine.disconnect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function applyPoint(entity:Entity, point:SpawnPoint):Void {
|
private function pointToPosition(point:{x:Int, y:Int, direction:String}):Position {
|
||||||
entity.rect.center = new Point((point.x + 1) * game.engine.map.cellWidth, (point.y + 1) * game.engine.map.cellHeight);
|
return {
|
||||||
entity.rect.direction = point.direction;
|
x: (point.x + 1) * game.config.map.cellWidth,
|
||||||
|
y: (point.y + 1) * game.config.map.cellHeight,
|
||||||
|
direction: point.direction,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function start(state:GameState):Void {
|
public function start(state:GameState):Void {
|
||||||
@@ -64,7 +68,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
}
|
}
|
||||||
if (team.config.eagle != null) {
|
if (team.config.eagle != null) {
|
||||||
var point = game.config.getPoint(team.id, "eagle");
|
var point = game.config.getPoint(team.id, "eagle");
|
||||||
gameEventSignal.emit(GameEvent.SPAWN(++entityId, EAGLE(team.id, point)));
|
gameEventSignal.emit(GameEvent.SPAWN(EAGLE(++entityId, pointToPosition(point), team.id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.START(state));
|
gameEventSignal.emit(GameEvent.START(state));
|
||||||
@@ -82,7 +86,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function spawn(task:SpawnTask):Void {
|
private function spawn(task:SpawnTask):Void {
|
||||||
gameEventSignal.emit(GameEvent.SPAWN(++entityId, TANK(task.playerId, task.tankType, task.point)));
|
gameEventSignal.emit(GameEvent.SPAWN(TANK(++entityId, pointToPosition(task.point), task.playerId, task.tankType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkComplete():Void {
|
private function checkComplete():Void {
|
||||||
@@ -114,13 +118,21 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timer.delay(function() {
|
Timer.delay(function() {
|
||||||
gameEventSignal.emit(GameEvent.COMPLETE(game.state, game.getTeam(winner)));
|
gameEventSignal.emit(GameEvent.COMPLETE(game.state, winner));
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSpawn(entity:EntityType):Void {
|
public function onSpawn(entity:EntityType):Void {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function buildShot(bullet:Bullet, score:Int = 0):Shot {
|
||||||
|
return {
|
||||||
|
tankId: bullet.tank.id,
|
||||||
|
bulletId: bullet.id,
|
||||||
|
score: score,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function onCollision(entity:EntityType, with:EntityType):Void {
|
public function onCollision(entity:EntityType, with:EntityType):Void {
|
||||||
switch entity {
|
switch entity {
|
||||||
case EntityType.TANK(tank):
|
case EntityType.TANK(tank):
|
||||||
@@ -134,13 +146,13 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
case [TANK(tank), EAGLE(eagle)]:
|
case [TANK(tank), EAGLE(eagle)]:
|
||||||
tank.rect.lean(eagle.rect);
|
tank.rect.lean(eagle.rect);
|
||||||
case [BULLET(bullet), BULLET(other_bullet)]:
|
case [BULLET(bullet), BULLET(other_bullet)]:
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet.id)));
|
||||||
case [BULLET(bullet), CELL(cell)]:
|
case [BULLET(bullet), CELL(cell)]:
|
||||||
gameEventSignal.emit(GameEvent.HIT(CELL(cell, bullet.tank, bullet)));
|
gameEventSignal.emit(GameEvent.HIT(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||||
case [TANK(tank), BONUS(bonus)]:
|
case [TANK(tank), BONUS(bonus)]:
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BONUS(bonus, tank, bonus.config.score)));
|
gameEventSignal.emit(GameEvent.DESTROY(BONUS(bonus.id, {tankId: tank.id, score: bonus.config.score})));
|
||||||
case [BULLET(bullet), TANK(tank)]/* | [TANK(tank), BULLET(bullet)]*/:
|
case [BULLET(bullet), TANK(tank)]/* | [TANK(tank), BULLET(bullet)]*/:
|
||||||
if (bullet.tankId == tank.id || (!game.config.game.friendlyFire && tank.playerId.team == bullet.playerId.team)) {
|
if (bullet.tankId == tank.id || (!game.config.game.friendlyFire && tank.playerId.team == bullet.playerId.team)) {
|
||||||
// Nothing
|
// Nothing
|
||||||
@@ -152,25 +164,25 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
tank.bonus = false;
|
tank.bonus = false;
|
||||||
spawnBonus();
|
spawnBonus();
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank, bullet.tank, bullet)));
|
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||||
} else if (tank.config.downgrade != null) {
|
} else if (tank.config.downgrade != null) {
|
||||||
tank.config = game.config.getTank(tank.config.downgrade);
|
tank.config = game.config.getTank(tank.config.downgrade);
|
||||||
gameEventSignal.emit(GameEvent.HIT(TANK(tank, bullet.tank, bullet)));
|
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
|
||||||
} else {
|
} else {
|
||||||
var score = tank.config.score;
|
var score = tank.config.score;
|
||||||
if (tank.playerId.team == bullet.playerId.team) {
|
if (tank.playerId.team == bullet.playerId.team) {
|
||||||
score = Math.round(score * -0.5);
|
score = Math.round(score * -0.5);
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank, bullet.tank, bullet, score)));
|
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank.id, buildShot(bullet, score))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||||
}
|
}
|
||||||
case [BULLET(bullet), EAGLE(eagle)]:
|
case [BULLET(bullet), EAGLE(eagle)]:
|
||||||
if (!eagle.protect.active) {
|
if (!eagle.protect.active) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(EAGLE(eagle, bullet.tank, bullet, eagle.score)));
|
gameEventSignal.emit(GameEvent.DESTROY(EAGLE(eagle.id, buildShot(bullet, eagle.score))));
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
|
||||||
case _:
|
case _:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,8 +198,9 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
var point = {
|
var point = {
|
||||||
x: Math.floor(Math.random() * (game.engine.map.gridWidth - 1)),
|
x: Math.floor(Math.random() * (game.engine.map.gridWidth - 1)),
|
||||||
y: Math.floor(Math.random() * (game.engine.map.gridHeight - 1)),
|
y: Math.floor(Math.random() * (game.engine.map.gridHeight - 1)),
|
||||||
|
direction: "right",
|
||||||
}
|
}
|
||||||
gameEventSignal.emit(GameEvent.SPAWN(++entityId, BONUS(type, point)));
|
gameEventSignal.emit(GameEvent.SPAWN(BONUS(++entityId, pointToPosition(point), type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline function alienTank(team:TeamId):Tank->Bool {
|
private inline function alienTank(team:TeamId):Tank->Bool {
|
||||||
@@ -202,7 +215,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
upgradeTank(tank);
|
upgradeTank(tank);
|
||||||
case "grenade":
|
case "grenade":
|
||||||
for (t in game.engine.iterTanks(alienTank(tank.playerId.team))) {
|
for (t in game.engine.iterTanks(alienTank(tank.playerId.team))) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(t, tank, null, 0)));
|
gameEventSignal.emit(GameEvent.DESTROY(TANK(t.id, {tankId: tank.id})));
|
||||||
}
|
}
|
||||||
case "helmet":
|
case "helmet":
|
||||||
tank.protect.on(bonus.config.duration);
|
tank.protect.on(bonus.config.duration);
|
||||||
@@ -220,7 +233,7 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
case "gun":
|
case "gun":
|
||||||
upgradeTank(tank, 5);
|
upgradeTank(tank, 5);
|
||||||
case _:
|
case _:
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank, null, null, 0))); // :-D
|
gameEventSignal.emit(GameEvent.DESTROY(TANK(tank.id, {tankId: tank.id}))); // :-D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,19 +277,29 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
var tank:Tank = cast game.engine.entities.get(tankId);
|
var tank:Tank = cast game.engine.entities.get(tankId);
|
||||||
var player = game.getPlayer(tank.playerId);
|
var player = game.getPlayer(tank.playerId);
|
||||||
if (!tank.freezing.active && player.bullets < tank.config.bullets) {
|
if (!tank.freezing.active && player.bullets < tank.config.bullets) {
|
||||||
gameEventSignal.emit(GameEvent.SPAWN(++entityId, BULLET(tank.playerId)));
|
var rect = tank.rect;
|
||||||
|
var point = rect.center.add(new Point(rect.width / 4 * rect.direction.x, rect.height / 4 * rect.direction.y));
|
||||||
|
var position = {
|
||||||
|
x: point.x,
|
||||||
|
y: point.y,
|
||||||
|
direction: rect.direction,
|
||||||
}
|
}
|
||||||
case GameEvent.SPAWN(entityId, TANK(playerId, _)):
|
gameEventSignal.emit(GameEvent.SPAWN(BULLET(++entityId, position, tank.playerId)));
|
||||||
|
}
|
||||||
|
case GameEvent.SPAWN(TANK(_, _, playerId, _)):
|
||||||
game.getPlayer(playerId).control.start();
|
game.getPlayer(playerId).control.start();
|
||||||
case GameEvent.SPAWN(entityId, BULLET(playerId)):
|
case GameEvent.SPAWN(BULLET(_, _, playerId)):
|
||||||
game.getPlayer(playerId).bullets++;
|
game.getPlayer(playerId).bullets++;
|
||||||
case GameEvent.DESTROY(EAGLE(eagle, who, wherewith, score)):
|
case GameEvent.DESTROY(EAGLE(id, shot)):
|
||||||
|
var eagle:Eagle = game.engine.getEntity(id);
|
||||||
eagle.death = true;
|
eagle.death = true;
|
||||||
if (score != 0) {
|
if (shot.score != 0) {
|
||||||
changeScore(who.playerId, score);
|
var tank:Tank = game.engine.getEntity(shot.tankId);
|
||||||
|
changeScore(tank.playerId, shot.score);
|
||||||
}
|
}
|
||||||
checkComplete();
|
checkComplete();
|
||||||
case GameEvent.DESTROY(TANK(tank, who, wherewith, score)):
|
case GameEvent.DESTROY(TANK(id, shot)):
|
||||||
|
var tank:Tank = game.engine.getEntity(id);
|
||||||
var team = game.getTeam(tank.playerId.team);
|
var team = game.getTeam(tank.playerId.team);
|
||||||
var player = game.getPlayer(tank.playerId);
|
var player = game.getPlayer(tank.playerId);
|
||||||
player.control.stop();
|
player.control.stop();
|
||||||
@@ -294,18 +317,22 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
if (!team.isAlive) {
|
if (!team.isAlive) {
|
||||||
checkComplete();
|
checkComplete();
|
||||||
}
|
}
|
||||||
if (tank.bonus && wherewith != null) {
|
if (tank.bonus && shot.bulletId != null) {
|
||||||
spawnBonus();
|
spawnBonus();
|
||||||
}
|
}
|
||||||
if (score != 0) {
|
if (shot.score != 0) {
|
||||||
changeScore(who.playerId, score);
|
var shooterTank:Tank = game.engine.getEntity(shot.tankId);
|
||||||
|
changeScore(shooterTank.playerId, shot.score);
|
||||||
}
|
}
|
||||||
case GameEvent.DESTROY(BONUS(bonus, who, score)):
|
case GameEvent.DESTROY(BONUS(id, shot)):
|
||||||
applyBonus(who, bonus);
|
var bonus:Bonus = game.engine.getEntity(id);
|
||||||
if (score != 0) {
|
var tank:Tank = game.engine.getEntity(shot.tankId);
|
||||||
changeScore(who.playerId, score);
|
applyBonus(tank, bonus);
|
||||||
|
if (shot.score != 0) {
|
||||||
|
changeScore(tank.playerId, shot.score);
|
||||||
}
|
}
|
||||||
case GameEvent.DESTROY(BULLET(bullet)):
|
case GameEvent.DESTROY(BULLET(id)):
|
||||||
|
var bullet:Bullet = game.engine.getEntity(id);
|
||||||
var player = game.getPlayer(bullet.playerId);
|
var player = game.getPlayer(bullet.playerId);
|
||||||
player.bullets--;
|
player.bullets--;
|
||||||
var side:Line = bullet.rect.getSide(bullet.rect.direction.reverse()).move(new Point(bullet.mx, bullet.my));
|
var side:Line = bullet.rect.getSide(bullet.rect.direction.reverse()).move(new Point(bullet.mx, bullet.my));
|
||||||
@@ -313,11 +340,11 @@ class GameRunner implements EngineListener implements GameListener {
|
|||||||
for (cell in cells) {
|
for (cell in cells) {
|
||||||
if (cell.armor > 0) {
|
if (cell.armor > 0) {
|
||||||
if (cell.armor == bullet.config.piercing) {
|
if (cell.armor == bullet.config.piercing) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell, bullet.tank, bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||||
} else if (cell.armor < bullet.config.piercing) {
|
} else if (cell.armor < bullet.config.piercing) {
|
||||||
var brick = game.engine.map.getBrick(cell);
|
var brick = game.engine.map.getBrick(cell);
|
||||||
for (cell in brick.cells) {
|
for (cell in brick.cells) {
|
||||||
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell, bullet.tank, bullet)));
|
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import ru.m.tankz.config.Config;
|
|||||||
import ru.m.tankz.engine.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
import ru.m.tankz.Type;
|
import ru.m.tankz.Type;
|
||||||
|
|
||||||
interface IGame {
|
interface IGame extends GameListener {
|
||||||
public var type(default, null):GameType;
|
public var type(default, null):GameType;
|
||||||
public var teams(default, null):Map<TeamId, Team>;
|
public var teams(default, null):Map<TeamId, Team>;
|
||||||
public var config(default, null):Config;
|
public var config(default, null):Config;
|
||||||
|
|||||||
@@ -5,13 +5,12 @@ import ru.m.geom.Rectangle;
|
|||||||
import haxe.ds.HashMap;
|
import haxe.ds.HashMap;
|
||||||
import ru.m.geom.Point;
|
import ru.m.geom.Point;
|
||||||
import ru.m.tankz.config.Config;
|
import ru.m.tankz.config.Config;
|
||||||
import ru.m.tankz.core.IKey;
|
|
||||||
|
|
||||||
|
class Brick {
|
||||||
|
public var id(get, null):Int;
|
||||||
|
|
||||||
class Brick implements IKey {
|
|
||||||
public var cellX(default, null):Int;
|
public var cellX(default, null):Int;
|
||||||
public var cellY(default, null):Int;
|
public var cellY(default, null):Int;
|
||||||
public var key(get, null):String;
|
|
||||||
|
|
||||||
public var mapConfig(default, null):MapConfig;
|
public var mapConfig(default, null):MapConfig;
|
||||||
public var config(default, default):BrickConfig;
|
public var config(default, default):BrickConfig;
|
||||||
@@ -67,11 +66,11 @@ class Brick implements IKey {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_key():String {
|
public function get_id():Int {
|
||||||
return 'brick:$cellX:$cellY';
|
return -((cellX * 1000) + cellY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toString() {
|
public function toString() {
|
||||||
return 'Brick{${config.type},$cellX:$cellY}';
|
return 'Brick(${config.type},$cellX:$cellY)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user