From 14d2b863c53ef6feebec135eae9d025978f872ad Mon Sep 17 00:00:00 2001 From: shmyga Date: Fri, 12 Jan 2018 22:24:27 +0300 Subject: [PATCH] [common] update map --- package.json | 2 +- src/client/haxe/ru/m/tankz/render/Render.hx | 38 ++++-- src/common/haxe/ru/m/geom/Line.hx | 20 +++ src/common/haxe/ru/m/geom/Rectangle.hx | 4 + src/common/haxe/ru/m/tankz/core/Bullet.hx | 1 + .../haxe/ru/m/tankz/core/MobileEntity.hx | 10 +- src/common/haxe/ru/m/tankz/core/Tank.hx | 3 +- src/common/haxe/ru/m/tankz/engine/Engine.hx | 120 ++++-------------- src/common/haxe/ru/m/tankz/map/Brick.hx | 11 +- src/common/haxe/ru/m/tankz/map/Grid.hx | 69 +++++++--- src/common/haxe/ru/m/tankz/map/LevelMap.hx | 44 +++---- 11 files changed, 156 insertions(+), 166 deletions(-) diff --git a/package.json b/package.json index 9fbd005..ada1420 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tankz", - "version": "0.0.3", + "version": "0.0.4", "private": true, "devDependencies": { "ansi-colors": "^1.0.1", diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index fcd26c0..a60c5e2 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -130,7 +130,7 @@ class Render extends SpriteView implements IRender { if (layersForUpdate[groundLayer] || layersForUpdate[upLayer]) { groundLayer.graphics.clear(); upLayer.graphics.clear(); - for (brick in game.map.bricks) { + for (brick in game.map.bricks) if (!brick.destroyed) { var g:Graphics = null; if (brick.config.layer < 3) { g = groundLayer.graphics; @@ -140,37 +140,47 @@ class Render extends SpriteView implements IRender { if (g != null) { g.beginBitmapFill(Assets.getBitmapData('resources/images/map/map_${brick.config.type}.png')); g.drawRect( - brick.cellX * game.map.cellWidth, - brick.cellY * game.map.cellHeight, - game.map.cellWidth, - game.map.cellHeight + brick.rect.x, + brick.rect.y, + brick.rect.width, + brick.rect.height ); - for (point in brick.cells.keys()) { - if (brick.cells.get(point).destroyed) { + for (cell in brick.cells.iterator()) { + if (cell.destroyed) { g.beginFill(0x000000); g.drawRect( - brick.cellX * game.map.cellWidth + point.x * game.map.cellWidth / 2, - brick.cellY * game.map.cellHeight + point.y * game.map.cellHeight / 2, - game.map.cellWidth / 2, - game.map.cellHeight / 2 + cell.rect.x, + cell.rect.y, + cell.rect.width, + cell.rect.height ); } } g.endFill(); } } + + // Debug cells /*var g = groundLayer.graphics; for (c in game.map.grid.cells.iterator()) { var color:Int = 0x000000; - if (c.armor > 0) { + if (c.armor == 1) { + color = 0xffcc00; + } else if (c.armor > 1) { + color = 0x606060; + } else if (c.layer == 0) { + color = 0xffff90; + } else if (c.layer == 1) { + color = 0x0000ff; + }else if (c.layer > 1) { color = 0x00ff00; } g.beginFill(color); g.drawRect(c.rect.x, c.rect.y, c.rect.width, c.rect.height); g.endFill(); - }*/ + } layersForUpdate[groundLayer] = false; - layersForUpdate[upLayer] = false; + layersForUpdate[upLayer] = false;*/ } } diff --git a/src/common/haxe/ru/m/geom/Line.hx b/src/common/haxe/ru/m/geom/Line.hx index c13679c..ae56045 100644 --- a/src/common/haxe/ru/m/geom/Line.hx +++ b/src/common/haxe/ru/m/geom/Line.hx @@ -4,12 +4,32 @@ class Line { public var point1(default, null):Point; public var point2(default, null):Point; + public var center(get, null):Point; public function new(point1:Point, point2:Point) { this.point1 = point1; this.point2 = point2; } + private function get_center():Point { + return new Point( + point1.x + (point2.x - point1.x) / 2, + point1.y + (point2.y - point1.y) / 2 + ); + } + + public function setLength(value:Float):Line { + var center = this.center; + var width = point2.x - point1.x; + var height = point2.y - point1.y; + var kW = width > 0 ? (width + height) / width : 0; + var kH = height > 0 ? (width + height) / height : 0; + return new Line( + center.add(new Point(-kW * value / 2, -kH * value / 2)), + center.add(new Point(kW * value / 2, kH * value / 2)) + ); + } + public function toString():String { return 'Line{point1=$point1,point2=$point2}'; } diff --git a/src/common/haxe/ru/m/geom/Rectangle.hx b/src/common/haxe/ru/m/geom/Rectangle.hx index bd0f195..8f17d5b 100644 --- a/src/common/haxe/ru/m/geom/Rectangle.hx +++ b/src/common/haxe/ru/m/geom/Rectangle.hx @@ -57,6 +57,10 @@ class Rectangle { return value; } + public function contain(point:Point):Bool { + return point.x >= x && point.y >= y && point.x <= width && point.y <= height; + } + public function toString():String { return 'Rectangle{x=$x,y=$y,width=$width,height=$height}'; } diff --git a/src/common/haxe/ru/m/tankz/core/Bullet.hx b/src/common/haxe/ru/m/tankz/core/Bullet.hx index c23f1ec..a8fd582 100644 --- a/src/common/haxe/ru/m/tankz/core/Bullet.hx +++ b/src/common/haxe/ru/m/tankz/core/Bullet.hx @@ -13,5 +13,6 @@ class Bullet extends MobileEntity { super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT); this.tankId = tankId; this.config = config; + this.layer = 2; } } diff --git a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx index 01a3f4a..0d7f963 100755 --- a/src/common/haxe/ru/m/tankz/core/MobileEntity.hx +++ b/src/common/haxe/ru/m/tankz/core/MobileEntity.hx @@ -5,16 +5,20 @@ import ru.m.geom.Rectangle; class MobileEntity extends Entity { - public var mx(default, default):Float = 0; - public var my(default, default):Float = 0; + public var mx(default, default):Float; + public var my(default, default):Float; - public var speed(default, null):Float = 0; + public var layer(default, null):Int; + public var speed(default, null):Float; public var direction(default, default):Direction; public function new(rect:Rectangle, speed:Float, direction:Direction) { super(rect); this.speed = speed; this.direction = direction; + this.layer = 0; + this.mx = 0; + this.my = 0; } public function move(direction:Direction):Void { diff --git a/src/common/haxe/ru/m/tankz/core/Tank.hx b/src/common/haxe/ru/m/tankz/core/Tank.hx index d5711aa..0dfef2a 100755 --- a/src/common/haxe/ru/m/tankz/core/Tank.hx +++ b/src/common/haxe/ru/m/tankz/core/Tank.hx @@ -24,6 +24,7 @@ class Tank extends MobileEntity { super(new Rectangle(0, 0, config.width, config.height), config.speed, Direction.RIGHT); this.index = index; this.config = config; + this.layer = 1; } private function set_config(value:TankConfig):TankConfig { @@ -37,7 +38,7 @@ class Tank extends MobileEntity { public function shot():Null { if (bulletsCounter >= config.bullets) return null; var bullet = new Bullet(id, config.bullet); - bullet.rect.center = rect.center.add(new Point(rect.width / 2 * direction.x, rect.height / 2 * direction.y)); + bullet.rect.center = rect.center.add(new Point(rect.width / 4 * direction.x, rect.height / 4 * direction.y)); bullet.move(direction); bulletsCounter++; return bullet; diff --git a/src/common/haxe/ru/m/tankz/engine/Engine.hx b/src/common/haxe/ru/m/tankz/engine/Engine.hx index 2ec9fa2..f1c3982 100755 --- a/src/common/haxe/ru/m/tankz/engine/Engine.hx +++ b/src/common/haxe/ru/m/tankz/engine/Engine.hx @@ -130,22 +130,6 @@ class Engine { } }*/ - /*private function getBricks(entity:MobileEntity):Array { - var target:Point = entity.rect.getSide(entity.rect.direction); - var cellX:Int = Math.floor(target.x / map.cellWidth); - var cellY:Int = Math.floor(target.y / map.cellHeight); - var brick1 = map.getBrick(cellX, cellY); - var brick2 = map.getBrick(cellX - entity.rect.direction.y * entity.rect.direction.y, cellY - entity.rect.direction.x * entity.rect.direction.x); - return [brick1, brick2]; - } - - public function checkBrick(entity:MobileEntity, brick:Brick):Null { - if (0 < brick.config.layer && brick.config.layer < 3) { - return brick.rect.getSide(entity.rect.direction.reverse()); - } - return null; - }*/ - public function update():Array { var newTime:Float = Date.now().getTime(); var d:Float = newTime - time; @@ -173,22 +157,20 @@ class Engine { entity.rect.x += entity.mx * (d / 30); entity.rect.y += entity.my * (d / 30); - var side:Line = entity.rect.getSide(entity.rect.direction); - L.w('TEST', 'side') - var bricks:Array = [];//getBricks(entity); + var side:Line = entity.rect.getSide(entity.rect.direction.reverse()); + var cells = map.grid.getCells(side); - if (objectType == GameObjectType.TANK) { - for (brick in bricks) { - var point:Point = null;//checkBrick(entity, brick); - if (point != null) { - if (entity.rect.direction.x != 0) { - entity.rect.x = point.x - entity.direction.x * entity.rect.width / 2 - entity.rect.width / 2; - } - if (entity.rect.direction.y != 0) { - entity.rect.y = point.y - entity.direction.y * entity.rect.height / 2 - entity.rect.height / 2; - } - break; + var collision:Bool = false; + for (cell in cells) { + if (cell.layer >= entity.layer && cell.layer < 3) { + var cellSide:Line = cell.rect.getSide(entity.rect.direction); + if (entity.rect.direction.x != 0) { + entity.rect.x = cellSide.point1.x - entity.rect.width * (entity.rect.direction.x + 1) / 2 - entity.direction.x; + } else if (entity.rect.direction.y != 0) { + entity.rect.y = cellSide.point1.y - entity.rect.height * (entity.rect.direction.y + 1) / 2 - entity.direction.y; } + collision = true; + break; } } @@ -202,74 +184,18 @@ class Engine { if (objectType == GameObjectType.BULLET) { var bullet:Bullet = cast ent; - var collision:Bool = false; - for (brick in bricks) { - if (1 < brick.config.layer && brick.config.layer < 3) { - collision = true; - break; - } - } - var d:Direction = ent.rect.direction; - for (i in 0...bricks.length) { - var brick = bricks[i]; - if (brick.config.armor != 0) { - if (brick.config.armor > 0 && brick.config.armor <= bullet.config.piercing) { - brick.config = config.getBrick(0); - } - } - - /*if (brick.config.armor > 0 && brick.config.armor <= bullet.config.piercing) { - if (brick.config.armor == bullet.config.piercing) { - //~~~~~~~~~~ - var p1:Point = new Point(0, 0); - if (d.x > 0 || d.y > 0) { - if (i == 0) { - p1 = p1.add(new Point(0, 0)); - } else { - p1 = p1.add(new Point(d.y, d.x)); - } - } else { - if (i == 0) { - p1 = p1.add(new Point(-d.x, -d.y)); - } else { - p1 = p1.add(new Point(1, 1)); - } - } - //~~~~~~~~~~ - var p2:Point = p1.add(new Point(0, 0)); - if (d.x > 0 || d.y > 0) { - if (i == 0) { - p2 = p2.add(new Point(d.y, d.x)); - } else { - p2 = p2.add(new Point(-d.y, -d.x)); - } - } else { - if (i == 0) { - p2 = p2.add(new Point(-d.y, -d.x)); - } else { - p2 = p2.add(new Point(d.y, d.x)); - } - } - //~~~~~~~~~~ - if (brick.blocks.get(p1)) { - p1 = p1.add(new Point(ent.rect.direction.x, ent.rect.direction.y)); - p2 = p2.add(new Point(ent.rect.direction.x, ent.rect.direction.y)); - } - if (brick.blocks.get(p1)) { - collision = false; - } else { - brick.blocks.set(p1, true); - brick.blocks.set(p2, true); - } - if (brick.destroyed) { - brick.config = config.getBrick(0); - } - } else { - brick.config = config.getBrick(0); - } - }*/ - } if (collision) { + cells = map.grid.getCells(side.setLength(map.grid.cellWidth * 4)); + for (cell in cells) { + if (cell.armor > 0) { + if (cell.armor == bullet.config.piercing) { + cell.destroyed = true; + } else if (cell.armor < bullet.config.piercing) { + var brick = map.getBrick(cell); + brick.destroyed = true; + } + } + } entities.remove(entity.id); var tank:Tank = cast entities.get(bullet.tankId); tank.onDestroyBullet(); diff --git a/src/common/haxe/ru/m/tankz/map/Brick.hx b/src/common/haxe/ru/m/tankz/map/Brick.hx index e2af9ed..5719878 100644 --- a/src/common/haxe/ru/m/tankz/map/Brick.hx +++ b/src/common/haxe/ru/m/tankz/map/Brick.hx @@ -24,7 +24,7 @@ class Brick implements IKey { public var rect(default, null):Rectangle; public var cells(default, null):HashMap; - public var destroyed(get, null):Bool; + public var destroyed(get, set):Bool; public function new(mapConfig:MapConfig, config:BrickConfig, cellX:Int, cellY:Int, cells:HashMap) { this.cellX = cellX; @@ -50,6 +50,15 @@ class Brick implements IKey { return true; } + public function set_destroyed(value:Bool):Bool { + if (value) { + for (c in cells.iterator()) { + c.destroyed = true; + } + } + return value; + } + public function get_key():String { return 'brick:$cellX:$cellY'; } diff --git a/src/common/haxe/ru/m/tankz/map/Grid.hx b/src/common/haxe/ru/m/tankz/map/Grid.hx index cbfdbc0..d7670c4 100644 --- a/src/common/haxe/ru/m/tankz/map/Grid.hx +++ b/src/common/haxe/ru/m/tankz/map/Grid.hx @@ -1,30 +1,49 @@ package ru.m.tankz.map; +import ru.m.geom.Line; import ru.m.geom.Point; -import haxe.ds.HashMap; import ru.m.geom.Rectangle; +import haxe.ds.HashMap; class GridCell { + public var cellX(default, null):Int; + public var cellY(default, null):Int; + + public var position(default, null):Point; public var rect(default, null):Rectangle; public var layer:Int; public var armor:Int; - public var destroyed:Bool; + public var destroyed(default, set):Bool; - public function new(rect:Rectangle, layer:Int, armor:Int) { - this.rect = rect; + public function new(cellX:Int, cellY:Int, width:Int, height:Int, layer:Int, armor:Int) { + this.cellX = cellX; + this.cellY = cellY; + this.position = new Point(cellX, cellY); + this.rect = new Rectangle(cellX * width, cellY * height, width, height); this.layer = layer; this.armor = armor; this.destroyed = false; } + + public function set_destroyed(value:Bool):Bool { + destroyed = value; + if (destroyed) { + this.layer = 0; + this.armor = 0; + } + return destroyed; + } } class Grid { - private var cellWidth:Int; - private var cellHeight:Int; - private var width:Int; - private var height:Int; + public var cellWidth(default, null):Int; + public var cellHeight(default, null):Int; + public var width(default, null):Int; + public var height(default, null):Int; + + private var border:Rectangle; public var cells(default, null):HashMap; @@ -33,21 +52,29 @@ class Grid { this.cellHeight = cellHeight; this.width = width; this.height = height; + border = new Rectangle(0, 0, Math.floor(width / cellWidth) - 1, Math.floor(height / cellHeight) - 1); cells = new HashMap(); - for (x in 0...Math.floor(width / cellWidth)) { - for (y in 0...Math.floor(width / cellWidth)) { - var rect = new Rectangle( - x * cellWidth, - y * cellHeight, - cellWidth, - cellHeight - ); - cells.set(new Point(x, y), new GridCell(rect, 0, 0)); - } - } } - public function getCells(rect:Rectangle):Array { - return []; + private function buildBorderCell(cellX:Int, cellY:Int):GridCell { + return new GridCell(cellX, cellY, cellWidth, cellHeight, 2, -1); + } + + public function getCells(line:Line):Array { + var result:Array = []; + for (x in Math.floor(line.point1.x / cellWidth)...Math.ceil(line.point2.x / cellWidth)) { + for (y in Math.floor(line.point1.y / cellHeight)...Math.ceil(line.point2.y / cellHeight)) { + var point = new Point(x, y); + if (!border.contain(point)) { + var cell = buildBorderCell(Std.int(point.x), Std.int(point.y)); + cells.set(point, cell); + result.push(cell); + } else { + var cell = cells.get(point); + if (cell != null) result.push(cell); + } + } + } + return result; } } \ No newline at end of file diff --git a/src/common/haxe/ru/m/tankz/map/LevelMap.hx b/src/common/haxe/ru/m/tankz/map/LevelMap.hx index 404fa77..554353f 100755 --- a/src/common/haxe/ru/m/tankz/map/LevelMap.hx +++ b/src/common/haxe/ru/m/tankz/map/LevelMap.hx @@ -16,17 +16,18 @@ class LevelMap { public var gridHeight(default, null):Int; public var bricks(default, null):Array; - public var borders(default, null):Array; public var grid(default, null):Grid; + private var bricksMap(default, null):HashMap; + public function new(config:MapConfig) { this.config = config; cellWidth = config.cellWidth; cellHeight = config.cellHeight; gridWidth = config.gridWidth; gridHeight = config.gridHeight; - borders = []; + bricksMap = new HashMap(); grid = new Grid( Std.int(cellWidth / 2), Std.int(cellHeight / 2), @@ -38,35 +39,22 @@ class LevelMap { var cellY = Std.int(Math.floor(i / gridHeight)); var cells:HashMap = new HashMap(); var point:Point = new Point(cellX * 2, cellY * 2); - for (x in 0...2) for (y in 0...2) { - var cell:GridCell = grid.cells.get(point); - cell.layer = brickConfig.layer; - cell.armor = brickConfig.armor; + if (brickConfig.layer > 0 || brickConfig.armor > 0) { + for (x in 0...2) for (y in 0...2) { + var cell:GridCell = new GridCell(Std.int(point.x + x), Std.int(point.y + y), Std.int(cellWidth / 2), Std.int(cellHeight / 2), brickConfig.layer, brickConfig.armor); + grid.cells.set(cell.position, cell); + cells.set(new Point(x, y), cell); + } } - return new Brick(config, brickConfig, cellX, cellY, cells); + var brick = new Brick(config, brickConfig, cellX, cellY, cells); + for (cell in brick.cells.iterator()) { + bricksMap.set(cell.position, brick); + } + return brick; })); - for (brick in bricks) { - var point:Point = new Point(brick.cellX * 2, brick.cellY * 2); - for (x in 0...2) for (y in 0...2) { - var cell:GridCell = grid.cells.get(point); - cell.layer = brick.config.layer; - cell.armor = brick.config.armor; - } - } } - private function getBorderBrick(cellX:Int, cellY:Int):Brick { - var index:Int = cellX + cellY * gridWidth; - if (borders[index] == null) { - borders[index] = new Brick(config, Brick.BORDER, cellX, cellY, null); - } - return borders[index]; - } - - public function getBrick(cellX:Int, cellY:Int):Brick { - if (cellX < 0 || cellX >= gridWidth || cellY < 0 || cellY >= gridHeight) { - return getBorderBrick(cellX, cellY); - } - return bricks[cellY * gridWidth + cellX]; + public function getBrick(cell:GridCell):Brick { + return bricksMap.get(cell.position); } }