[client] update render

This commit is contained in:
2019-05-16 17:13:06 +03:00
parent cd7dd1984b
commit c1ff14111d
24 changed files with 479 additions and 114 deletions

View File

@@ -0,0 +1,7 @@
package ru.m.geom;
typedef Position = {
var x:Float;
var y:Float;
@:optional var direction:Direction;
}

View File

@@ -11,6 +11,7 @@ class Rectangle {
public var right(get, null):Float;
public var top(get, null):Float;
public var bottom(get, null):Float;
public var position(get, null):Position;
public function new(x:Float, y:Float, width:Float, height:Float) {
this.x = x;
@@ -58,7 +59,7 @@ class Rectangle {
}
direction = value;
}
return value;
return direction;
}
public function contain(point:Point):Bool {
@@ -85,6 +86,12 @@ class Rectangle {
}
}
public function clone():Rectangle {
var rect = new Rectangle(x, y, width, height);
rect.direction = direction;
return rect;
}
public function toString():String {
return 'Rectangle{x=$x,y=$y,width=$width,height=$height}';
}
@@ -104,4 +111,8 @@ class Rectangle {
function get_bottom():Float {
return y + height;
}
private function get_position():Position {
return {x:x, y:y, direction:direction};
}
}

View File

@@ -100,7 +100,6 @@ import ru.m.tankz.map.LevelMap;
var collision:Bool = false;
for (cell in cells) {
if (cell.getCollision(entity.layer)) {
entity.rect.lean(cell.rect);
collision = true;
var with = EntityTypeResolver.of(cell);
collisionSignal.emit(entityType, with);

View File

@@ -1,6 +1,7 @@
package ru.m.tankz.game;
import ru.m.geom.Point;
import ru.m.geom.Position;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control;

View File

@@ -1,15 +1,9 @@
package ru.m.tankz.game;
import ru.m.geom.Direction;
import ru.m.geom.Position;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type;
typedef Position = {
var x:Float;
var y:Float;
@:optional var direction:Direction;
}
enum SpawnEvent {
EAGLE(id:Int, position:Position, teamId:TeamId);
TANK(id:Int, position:Position, playerId:PlayerId, type:TankType);
@@ -41,7 +35,12 @@ enum MoveEvent {
BULLET(id:Int, position:Position);
}
enum StopEvent {
TANK(id:Int);
}
enum ChangeEvent {
TANK(id:Int, type:TankType, hits:Int, bonus:Bool);
PLAYER_SCORE(playerId:PlayerId, value:Int);
PLAYER_LIFE(playerId:PlayerId, value:Int);
TEAM_SCORE(teamId:TeamId, value:Int);
@@ -52,6 +51,7 @@ enum GameEvent {
START(state:GameState);
SPAWN(event:SpawnEvent);
MOVE(event:MoveEvent);
STOP(event:StopEvent);
HIT(event:HitEvent);
DESTROY(event:DestroyEvent);
CHANGE(event:ChangeEvent);

View File

@@ -1,10 +1,12 @@
package ru.m.tankz.game;
import ru.m.geom.Direction;
import haxe.ds.Option;
import haxe.Timer;
import haxework.signal.Signal;
import ru.m.geom.Line;
import ru.m.geom.Point;
import ru.m.geom.Position;
import ru.m.tankz.control.Control;
import ru.m.tankz.control.Controller;
import ru.m.tankz.control.IControlFactory;
@@ -55,7 +57,7 @@ class GameRunner implements EngineListener implements GameListener {
return {
x: (point.x + 1) * game.config.map.cellWidth,
y: (point.y + 1) * game.config.map.cellHeight,
direction: point.direction,
direction: Direction.fromString(point.direction),
}
}
@@ -141,6 +143,14 @@ class GameRunner implements EngineListener implements GameListener {
}
}
private inline function emitTankMove(tank:Tank):Void {
gameEventSignal.emit(GameEvent.MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
}
private inline function emitTankChange(tank:Tank):Void {
gameEventSignal.emit(GameEvent.CHANGE(TANK(tank.id, tank.config.type, tank.hits, tank.bonus)));
}
public function onCollision(entity:EntityType, with:EntityType):Void {
switch entity {
case EntityType.TANK(tank):
@@ -151,8 +161,13 @@ class GameRunner implements EngineListener implements GameListener {
switch [entity, with] {
case [TANK(tank), TANK(other_tank)]:
tank.rect.lean(other_tank.rect);
emitTankMove(tank);
case [TANK(tank), EAGLE(eagle)]:
tank.rect.lean(eagle.rect);
emitTankMove(tank);
case [TANK(tank), CELL(cell)]:
tank.rect.lean(cell.rect);
emitTankMove(tank);
case [BULLET(bullet), BULLET(other_bullet)]:
gameEventSignal.emit(GameEvent.DESTROY(BULLET(bullet.id)));
gameEventSignal.emit(GameEvent.DESTROY(BULLET(other_bullet.id)));
@@ -173,9 +188,11 @@ class GameRunner implements EngineListener implements GameListener {
spawnBonus();
}
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
emitTankChange(tank);
} else if (tank.config.downgrade != null) {
tank.config = game.config.getTank(tank.config.downgrade);
gameEventSignal.emit(GameEvent.HIT(TANK(tank.id, buildShot(bullet))));
emitTankChange(tank);
} else {
var score = tank.config.score;
if (tank.playerId.team == bullet.playerId.team) {
@@ -198,7 +215,7 @@ class GameRunner implements EngineListener implements GameListener {
public function onMove(entity:EntityType):Void {
switch entity {
case TANK(tank):
gameEventSignal.emit(GameEvent.MOVE(TANK(tank.id, {x:tank.rect.x, y:tank.rect.y, direction:tank.rect.direction})));
emitTankMove(tank);
case BULLET(bullet):
gameEventSignal.emit(GameEvent.MOVE(BULLET(bullet.id, {x:bullet.rect.x, y:bullet.rect.y, direction:bullet.rect.direction})));
case _:
@@ -237,6 +254,8 @@ class GameRunner implements EngineListener implements GameListener {
case "clock":
for (t in game.engine.iterTanks(alienTank(tank.playerId.team))) {
t.freezing.on(bonus.config.duration);
t.stop();
gameEventSignal.emit(GameEvent.STOP(TANK(t.id)));
}
case "shovel":
// ToDo: protect eagle/area
@@ -260,6 +279,7 @@ class GameRunner implements EngineListener implements GameListener {
} else {
tank.hits++;
}
emitTankChange(tank);
}
private function changeScore(playerId:PlayerId, score:Int):Void {
@@ -305,6 +325,8 @@ class GameRunner implements EngineListener implements GameListener {
}
gameEventSignal.emit(GameEvent.SPAWN(BULLET(++entityId, position, tank.playerId)));
}
case GameEvent.ACTION(tankId, STOP):
gameEventSignal.emit(GameEvent.STOP(TANK(tankId)));
case GameEvent.SPAWN(TANK(_, _, playerId, _)):
game.getPlayer(playerId).control.start();
case GameEvent.SPAWN(BULLET(_, _, playerId)):
@@ -361,7 +383,7 @@ class GameRunner implements EngineListener implements GameListener {
if (cell.armor == bullet.config.piercing) {
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
} else if (cell.armor < bullet.config.piercing) {
var brick = game.engine.map.getBrick(cell);
var brick = game.engine.map.getBrick(cell.position);
for (cell in brick.cells) {
gameEventSignal.emit(GameEvent.DESTROY(CELL(cell.cellX, cell.cellY, buildShot(bullet))));
}

View File

@@ -9,27 +9,33 @@ typedef EventItem = {
event:GameEvent
}
class GameRecord {
class GameRecordInfo {
public var id(default, default):String;
public var date(default, default):Date;
public var type(default, default):GameType;
public var presetId(default, default):PresetId;
public var levelId(default, default):LevelId;
public function new() {}
}
class GameRecord {
public var info(default, null):GameRecordInfo;
public var events(default, default):Array<EventItem>;
public var state(get, null):GameState;
public function new() {
this.id = UUID.generateRandom(new Random()).toString();
this.date = null;
this.info = new GameRecordInfo();
this.info.id = UUID.generateRandom(new Random()).toString();
this.events = [];
}
private inline function get_state():GameState {
return new GameState(type, presetId, levelId);
return new GameState(info.type, info.presetId, info.levelId);
}
public function toString():String {
return 'GameRecord{id=$id,date=$date,type=$type,preset=$presetId,level=$levelId,events=${events.length}}';
return 'GameRecord{id=${info.id},date=${info.date},type=${info.type},preset=${info.presetId},level=${info.levelId},events=${events.length}}';
}
}

View File

@@ -17,9 +17,9 @@ class GameRecorder implements GameListener {
public function onGameEvent(event:GameEvent):Void {
switch event {
case GameEvent.START(state):
record.type = state.type;
record.presetId = state.presetId;
record.levelId = state.levelId;
record.info.type = state.type;
record.info.presetId = state.presetId;
record.info.levelId = state.levelId;
start();
case GameEvent.COMPLETE(_, _):
stop();
@@ -30,7 +30,7 @@ class GameRecorder implements GameListener {
public function start():Void {
frame = 0;
record.date = Date.now();
record.info.date = Date.now();
Lib.current.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

View File

@@ -62,8 +62,8 @@ class LevelMap {
}));
}
public function getBrick(cell:GridCell):Brick {
return bricksMap.get(cell.position);
public function getBrick(position:Point):Brick {
return bricksMap.get(position);
}
public function getPointBrick(point:Point):Brick {

View File

@@ -163,7 +163,7 @@ presets:
- {<<: *team_human}
- id: bot
spawnInterval: 3000
life: 1
life: 10
players:
- {<<: *bot, index: 0, control: bot-stupid}
- {<<: *bot, index: 1, control: bot-stupid}