[common] player tank levels

This commit is contained in:
2018-01-08 22:28:35 +03:00
parent 3061a4088c
commit d3294a04f5
8 changed files with 125 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.core; package ru.m.tankz.core;
import haxe.Timer;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import flash.events.FocusEvent; import flash.events.FocusEvent;
import flash.ui.Keyboard; import flash.ui.Keyboard;
@@ -15,6 +16,7 @@ class PlayerControl {
private var keyBinding:Map<Int, TankAction>; private var keyBinding:Map<Int, TankAction>;
private var moveQueue:Array<Int>; private var moveQueue:Array<Int>;
private var shotTimer:Timer;
public function new(id:Int, engine:IEngine, keyBinding:Map<Int, TankAction>) { public function new(id:Int, engine:IEngine, keyBinding:Map<Int, TankAction>) {
this.id = id; this.id = id;
@@ -34,9 +36,16 @@ class PlayerControl {
updateMove(); updateMove();
} }
case TankAction.SHOT: case TankAction.SHOT:
engine.action(id, TankAction.SHOT); if (shotTimer == null) {
shotTimer = new Timer(300);
shotTimer.run = shot;
shot();
}
case _: case _:
} }
if (event.keyCode == Keyboard.U) {
engine.action(id, TankAction.LEVEL_UP(1));
}
} }
private function onKeyUp(event:KeyboardEvent):Void { private function onKeyUp(event:KeyboardEvent):Void {
@@ -44,6 +53,11 @@ class PlayerControl {
case TankAction.MOVE(direction): case TankAction.MOVE(direction):
moveQueue.remove(event.keyCode); moveQueue.remove(event.keyCode);
updateMove(); updateMove();
case TankAction.SHOT:
if (shotTimer != null) {
shotTimer.stop();
shotTimer = null;
}
case _: case _:
} }
} }
@@ -65,6 +79,10 @@ class PlayerControl {
} }
} }
private function shot():Void {
engine.action(id, TankAction.SHOT);
}
public static function forPlayer(index:Int, tankId:Int, engine:IEngine):PlayerControl { public static function forPlayer(index:Int, tankId:Int, engine:IEngine):PlayerControl {
switch (index) { switch (index) {
case 0: case 0:

View File

@@ -35,6 +35,7 @@ class BrickState implements IState<Brick> {
class EntityState implements IState<Entity> { class EntityState implements IState<Entity> {
private var x:Float; private var x:Float;
private var y:Float; private var y:Float;
private var level:Int;
public function new() {} public function new() {}
@@ -44,6 +45,13 @@ class EntityState implements IState<Entity> {
y = object.rect.y; y = object.rect.y;
return true; return true;
} }
if (Std.is(object, Tank)) {
var tank:Tank = cast object;
if (tank.config.level != level) {
level = tank.config.level;
return true;
}
}
return false; return false;
} }
} }
@@ -153,17 +161,18 @@ class Render extends SpriteView implements IRender {
} }
} }
public function drawEntries(game:IEngine):Void { public function drawEntities(game:IEngine):Void {
if (layersForUpdate[entryLayer]) { if (layersForUpdate[entryLayer]) {
var g:Graphics = entryLayer.graphics; var g:Graphics = entryLayer.graphics;
g.clear(); g.clear();
for (ent in game.entities) { for (ent in game.entities) {
var image:String = null; var image:String = null;
if (Std.is(ent, Tank)) { if (Std.is(ent, Tank)) {
image = 'resources/images/tank/player/tank_p0_${cast(ent, Tank).index}-0.png'; var tank:Tank = cast ent;
image = 'resources/images/tank/player/tank_p${tank.config.level}_${tank.index}-0.png';
} else if (Std.is(ent, Bullet)) { } else if (Std.is(ent, Bullet)) {
var m = new Matrix(); var bullet:Bullet = cast ent;
image = 'resources/images/bullet/bullet_0.png'; image = 'resources/images/bullet/bullet_${bullet.config.type}.png';
} else { } else {
image = 'ERROR'; // ToDo: image = 'ERROR'; // ToDo:
} }
@@ -172,7 +181,7 @@ class Render extends SpriteView implements IRender {
m.rotate(calcRotate(cast(ent, IMobileEntity).direction)); m.rotate(calcRotate(cast(ent, IMobileEntity).direction));
} }
m.translate(ent.rect.x, ent.rect.y); m.translate(ent.rect.x, ent.rect.y);
g.beginBitmapFill(Assets.getBitmapData(image), m); g.beginBitmapFill(Assets.getBitmapData(image), m, true, true);
g.drawRect(ent.rect.x, ent.rect.y, ent.rect.width, ent.rect.height); g.drawRect(ent.rect.x, ent.rect.y, ent.rect.width, ent.rect.height);
g.endFill(); g.endFill();
} }
@@ -184,7 +193,7 @@ class Render extends SpriteView implements IRender {
invalidateLayers(game); invalidateLayers(game);
drawBackground(game); drawBackground(game);
drawMap(game); drawMap(game);
drawEntries(game); drawEntities(game);
} }
public function reset():Void { public function reset():Void {

View File

@@ -6,12 +6,14 @@ class Rectangle {
public var width(default, default):Float; public var width(default, default):Float;
public var height(default, default):Float; public var height(default, default):Float;
public var center(get, set):Point; public var center(get, set):Point;
public var direction(default, set):Direction;
public function new(x:Float, y:Float, width:Float, height:Float) { public function new(x:Float, y:Float, width:Float, height:Float) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.direction = Direction.RIGHT;
} }
private function get_center():Point { private function get_center():Point {
@@ -28,4 +30,17 @@ class Rectangle {
return center.add(new Point(direction.x * width / 2, direction.y * height / 2)); return center.add(new Point(direction.x * width / 2, direction.y * height / 2));
} }
public function set_direction(value:Direction):Direction {
if (direction != value) {
if (direction != null && direction.x * value.x == 0 && direction.y * value.y == 0) {
var w = width;
var h = height;
width = h;
height = w;
}
direction = value;
}
return value;
}
} }

View File

@@ -24,6 +24,7 @@ typedef BulletConfig = {
} }
typedef TankConfig = { typedef TankConfig = {
var level:Int;
var width:Float; var width:Float;
var height:Float; var height:Float;
var speed:Float; var speed:Float;
@@ -94,19 +95,53 @@ class ConfigBundle {
] ]
); );
public static var BULLET_A:BulletConfig = { private static function bulletConfig(speed:Float, type:BulletType):BulletConfig {
width: 12, return {
height: 12, width: 12,
speed: 5, height: 12,
type: BulletType.NORMAL speed: speed,
type: type
}
} }
public static var PLAYER_TANK_A:TankConfig = { public static var PLAYER_TANKS:Array<TankConfig> = [
width: 36, {
height: 36, level: 0,
speed: 3, width: 36,
bullet: BULLET_A, height: 36,
bullets: 1 speed: 3,
bullet: bulletConfig(5, BulletType.NORMAL),
bullets: 1
},
{
level: 1,
width: 40,
height: 36,
speed: 3.5,
bullet: bulletConfig(5.5, BulletType.NORMAL),
bullets: 1
},
{
level: 2,
width: 40,
height: 36,
speed: 3.5,
bullet: bulletConfig(5.5, BulletType.NORMAL),
bullets: 2
},
{
level: 3,
width: 42,
height: 38,
speed: 3.5,
bullet: bulletConfig(6, BulletType.PIERCING),
bullets: 2
}
];
public static function getPlayerTank(level:Int):TankConfig {
return PLAYER_TANKS[level];
} }
public static function get(type:Int, level:Int):Config { public static function get(type:Int, level:Int):Config {

View File

@@ -6,18 +6,17 @@ import ru.m.geom.Direction;
@:enum abstract BulletType(Int) from Int to Int { @:enum abstract BulletType(Int) from Int to Int {
var NORMAL = 1; var NORMAL = 0;
var PIERCING = 2; var PIERCING = 1;
} }
class Bullet extends MobileEntity { class Bullet extends MobileEntity {
public var tankId(default, null):Int; public var tankId(default, null):Int;
public var config(default, null):BulletConfig;
private var config:BulletConfig;
public function new(tankId:Int, config:BulletConfig) { public function new(tankId:Int, config:BulletConfig) {
super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.TOP); super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT);
this.tankId = tankId; this.tankId = tankId;
this.config = config; this.config = config;
} }

View File

@@ -18,7 +18,10 @@ class MobileEntity extends Entity implements IMobileEntity {
} }
public function move(direction:Direction):Void { public function move(direction:Direction):Void {
this.direction = direction; if (this.direction != direction) {
this.rect.direction = direction;
this.direction = direction;
}
mx = direction.x * speed; mx = direction.x * speed;
my = direction.y * speed; my = direction.y * speed;
} }

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.core; package ru.m.tankz.core;
import ru.m.geom.Point;
import ru.m.tankz.config.Config.TankConfig; import ru.m.tankz.config.Config.TankConfig;
import ru.m.tankz.core.Bullet; import ru.m.tankz.core.Bullet;
import ru.m.geom.Rectangle; import ru.m.geom.Rectangle;
@@ -8,26 +9,35 @@ import ru.m.geom.Direction;
enum TankAction { enum TankAction {
MOVE(direction:Direction); MOVE(direction:Direction);
LEVEL_UP(level:Int);
STOP; STOP;
SHOT; SHOT;
} }
class Tank extends MobileEntity { class Tank extends MobileEntity {
public var index(default, null):Int; public var index(default, null):Int;
public var config(default, set):TankConfig;
private var bulletsCounter:Int = 0; private var bulletsCounter:Int = 0;
private var config:TankConfig;
public function new(index:Int, config: TankConfig) { public function new(index:Int, config: TankConfig) {
super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.TOP); super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT);
this.index = index; this.index = index;
this.config = config; this.config = config;
} }
private function set_config(value:TankConfig):TankConfig {
rect = new Rectangle(rect.x, rect.y, value.width, value.height);
rect.direction = direction;
speed = value.speed;
config = value;
return value;
}
public function shot():Null<Bullet> { public function shot():Null<Bullet> {
if (bulletsCounter >= config.bullets) return null; if (bulletsCounter >= config.bullets) return null;
var bullet = new Bullet(id, config.bullet); var bullet = new Bullet(id, config.bullet);
bullet.rect.center = rect.center; bullet.rect.center = rect.center.add(new Point(rect.width / 2 * direction.x, rect.height / 2 * direction.y));
bullet.move(direction); bullet.move(direction);
bulletsCounter++; bulletsCounter++;
return bullet; return bullet;

View File

@@ -63,7 +63,7 @@ class Engine implements IEngine {
for (index in 0...players.length) { for (index in 0...players.length) {
var player:Player = players[index]; var player:Player = players[index];
var point:SpawnPoint = config.getSpawnPoint(SpawnPointType.PLAYER, index); var point:SpawnPoint = config.getSpawnPoint(SpawnPointType.PLAYER, index);
var tank = buildTank(index, ConfigBundle.PLAYER_TANK_A, point); var tank = buildTank(index, ConfigBundle.getPlayerTank(0), point);
playerTanks.set(player.id, tank); playerTanks.set(player.id, tank);
entities.set(tank.id, tank); entities.set(tank.id, tank);
changes.push(new GameChange() changes.push(new GameChange()
@@ -90,6 +90,8 @@ class Engine implements IEngine {
.setDirectionX(direction.x) .setDirectionX(direction.x)
.setDirectionY(direction.y) .setDirectionY(direction.y)
);*/ );*/
case TankAction.LEVEL_UP(level):
tank.config = ConfigBundle.getPlayerTank(Std.int(Math.min(tank.config.level + level, 3)));
case TankAction.STOP: case TankAction.STOP:
tank.stop(); tank.stop();
/*Provider.get(IConnection).send( /*Provider.get(IConnection).send(
@@ -196,10 +198,11 @@ class Engine implements IEngine {
); );
if (objectType == GameObjectType.BULLET) { if (objectType == GameObjectType.BULLET) {
var bullet:Bullet = cast ent;
for (brick in bricks) { for (brick in bricks) {
if (BULLET_BRICKS.indexOf(brick.type) > -1) { if (BULLET_BRICKS.indexOf(brick.type) > -1) {
entities.remove(entity.id); entities.remove(entity.id);
var tank:Tank = cast entities.get(cast(entity, Bullet).tankId); var tank:Tank = cast entities.get(bullet.tankId);
tank.onDestroyBullet(); tank.onDestroyBullet();
changes.push(new GameChange() changes.push(new GameChange()
.setType(GameChangeType.DESTROED) .setType(GameChangeType.DESTROED)
@@ -211,7 +214,10 @@ class Engine implements IEngine {
} }
} }
for (brick in bricks) { for (brick in bricks) {
if (brick.type == BrickType.BRICK || brick.type == BrickType.BUSH) { if (brick.type == BrickType.BRICK) {
brick.type = BrickType.NONE;
}
if (bullet.config.type == BulletType.PIERCING && brick.type == BrickType.ARMOR) {
brick.type = BrickType.NONE; brick.type = BrickType.NONE;
} }
} }