[map] load
This commit is contained in:
14
WORK.md
14
WORK.md
@@ -1,8 +1,8 @@
|
|||||||
* build
|
* build
|
||||||
* gulp
|
* gulp 100%
|
||||||
|
|
||||||
* deploy
|
* deploy
|
||||||
* capistrano
|
* capistrano 100%
|
||||||
|
|
||||||
* ui
|
* ui
|
||||||
* login frame
|
* login frame
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
* game frame
|
* game frame
|
||||||
|
|
||||||
* engine
|
* engine
|
||||||
* config
|
* config 50%
|
||||||
* map
|
* map 50%
|
||||||
* tanks
|
* tanks 2%
|
||||||
* bullets
|
* bullets 2%
|
||||||
* boxes
|
* boxes
|
||||||
* map changes
|
* map changes
|
||||||
* bonuses
|
* bonuses
|
||||||
@@ -22,4 +22,4 @@
|
|||||||
* proto
|
* proto
|
||||||
|
|
||||||
* common
|
* common
|
||||||
* single game
|
* single game 2%
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.m.tankz;
|
package ru.m.tankz;
|
||||||
|
|
||||||
|
import flash.ui.Keyboard;
|
||||||
|
import flash.events.KeyboardEvent;
|
||||||
import flash.text.Font;
|
import flash.text.Font;
|
||||||
import ru.m.tankz.view.frames.StartFrame;
|
import ru.m.tankz.view.frames.StartFrame;
|
||||||
import haxework.log.SocketLogger;
|
import haxework.log.SocketLogger;
|
||||||
@@ -66,6 +68,12 @@ class Client implements IConnectionHandler {
|
|||||||
Root.bind(view);
|
Root.bind(view);
|
||||||
//view.logout.onPress = this;
|
//view.logout.onPress = this;
|
||||||
view.switcher.change(StartFrame.ID);
|
view.switcher.change(StartFrame.ID);
|
||||||
|
|
||||||
|
view.content.stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):Void {
|
||||||
|
if (event.keyCode == Keyboard.ESCAPE) {
|
||||||
|
view.switcher.change(StartFrame.ID);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPress(view:ButtonView):Void {
|
public function onPress(view:ButtonView):Void {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class PlayerControl {
|
|||||||
moveQueue = new Array<Int>();
|
moveQueue = new Array<Int>();
|
||||||
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
Lib.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
||||||
Lib.current.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
|
Lib.current.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
|
||||||
Lib.current.stage.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
|
//Lib.current.stage.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function onKeyDown(event:KeyboardEvent):Void {
|
private function onKeyDown(event:KeyboardEvent):Void {
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ import ru.m.tankz.engine.IEngine;
|
|||||||
|
|
||||||
interface IRender extends IView {
|
interface IRender extends IView {
|
||||||
public function draw(game:IEngine):Void;
|
public function draw(game:IEngine):Void;
|
||||||
|
public function reset():Void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.m.tankz.render;
|
package ru.m.tankz.render;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.Entity;
|
||||||
|
import ru.m.tankz.map.Brick;
|
||||||
import ru.m.tankz.core.Direction;
|
import ru.m.tankz.core.Direction;
|
||||||
import flash.geom.Matrix;
|
import flash.geom.Matrix;
|
||||||
import openfl.Assets;
|
import openfl.Assets;
|
||||||
@@ -10,48 +12,144 @@ import flash.display.Graphics;
|
|||||||
import haxework.gui.SpriteView;
|
import haxework.gui.SpriteView;
|
||||||
import ru.m.tankz.engine.IEngine;
|
import ru.m.tankz.engine.IEngine;
|
||||||
|
|
||||||
|
|
||||||
|
interface IState<T> {
|
||||||
|
public function update(object:T):Bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BrickState implements IState<Brick> {
|
||||||
|
private var type:BrickType;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
|
||||||
|
public function update(object:Brick):Bool {
|
||||||
|
if (type != object.type) {
|
||||||
|
type = object.type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EntityState implements IState<Entity> {
|
||||||
|
private var x:Float;
|
||||||
|
private var y:Float;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
|
||||||
|
public function update(object:Entity):Bool {
|
||||||
|
if (x != object.x || y != object.y) {
|
||||||
|
x = object.x;
|
||||||
|
y = object.y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Render extends SpriteView implements IRender {
|
class Render extends SpriteView implements IRender {
|
||||||
|
|
||||||
private var mapLayer:Sprite;
|
private static var GROUND_BRICKS:Array<BrickType> = [
|
||||||
private var tankLayer:Sprite;
|
BrickType.BRICK, BrickType.ARMOR, BrickType.WATER, BrickType.ACE
|
||||||
|
];
|
||||||
|
|
||||||
|
private static var UP_BRICKS:Array<BrickType> = [
|
||||||
|
BrickType.BUSH
|
||||||
|
];
|
||||||
|
|
||||||
|
private var backgroundLayer:Sprite;
|
||||||
|
private var groundLayer:Sprite;
|
||||||
|
private var entryLayer:Sprite;
|
||||||
|
private var upLayer:Sprite;
|
||||||
|
|
||||||
|
private var layersForUpdate:Map<Sprite, Bool>;
|
||||||
|
private var states:Map<String, IState<Dynamic>>;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
mapLayer = new Sprite();
|
layersForUpdate = new Map();
|
||||||
tankLayer = new Sprite();
|
backgroundLayer = new Sprite();
|
||||||
contentAsSprite.addChild(mapLayer);
|
groundLayer = new Sprite();
|
||||||
contentAsSprite.addChild(tankLayer);
|
entryLayer = new Sprite();
|
||||||
|
upLayer = new Sprite();
|
||||||
|
contentAsSprite.addChild(backgroundLayer);
|
||||||
|
contentAsSprite.addChild(groundLayer);
|
||||||
|
contentAsSprite.addChild(entryLayer);
|
||||||
|
contentAsSprite.addChild(upLayer);
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function draw(game:IEngine):Void {
|
private function invalidateLayers(game:IEngine):Void {
|
||||||
|
for (brick in game.map.bricks) {
|
||||||
|
if (!states.exists(brick.key)) {
|
||||||
|
states[brick.key] = new BrickState();
|
||||||
|
}
|
||||||
|
if (states.get(brick.key).update(brick)) {
|
||||||
|
layersForUpdate[groundLayer] = true;
|
||||||
|
layersForUpdate[upLayer] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (entry in game.mobileEntities) {
|
||||||
|
if (!states.exists(entry.key)) {
|
||||||
|
states[entry.key] = new EntityState();
|
||||||
|
}
|
||||||
|
if (states.get(entry.key).update(entry)) {
|
||||||
|
layersForUpdate[entryLayer] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function drawBackground(game:IEngine):Void {
|
||||||
var mapWidth = game.map.gridWidth * game.map.cellWidth;
|
var mapWidth = game.map.gridWidth * game.map.cellWidth;
|
||||||
var mapHeight = game.map.gridHeight * game.map.cellHeight;
|
var mapHeight = game.map.gridHeight * game.map.cellHeight;
|
||||||
|
|
||||||
|
if (layersForUpdate[backgroundLayer]) {
|
||||||
|
var g:Graphics = backgroundLayer.graphics;
|
||||||
|
g.clear();
|
||||||
|
g.beginFill(0x000000);
|
||||||
|
g.drawRect(0, 0, mapWidth, mapHeight);
|
||||||
|
g.endFill();
|
||||||
if (contentSize) {
|
if (contentSize) {
|
||||||
width = mapWidth;
|
width = mapWidth;
|
||||||
height = mapHeight;
|
height = mapHeight;
|
||||||
}
|
}
|
||||||
|
layersForUpdate[backgroundLayer] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var g:Graphics = mapLayer.graphics;
|
private function drawMap(game:IEngine):Void {
|
||||||
g.clear();
|
if (layersForUpdate[groundLayer] || layersForUpdate[upLayer]) {
|
||||||
|
groundLayer.graphics.clear();
|
||||||
|
upLayer.graphics.clear();
|
||||||
|
for (brick in game.map.bricks) {
|
||||||
|
var g:Graphics = null;
|
||||||
|
if (GROUND_BRICKS.indexOf(brick.type) > -1) {
|
||||||
|
g = groundLayer.graphics;
|
||||||
|
} else if (UP_BRICKS.indexOf(brick.type) > -1) {
|
||||||
|
g = upLayer.graphics;
|
||||||
|
}
|
||||||
|
if (g != null) {
|
||||||
g.beginFill(0x00ff00);
|
g.beginFill(0x00ff00);
|
||||||
g.drawRect(0, 0, mapWidth, mapHeight);
|
g.beginBitmapFill(Assets.getBitmapData('resources/images/map/map_${brick.type}.png'));
|
||||||
|
g.drawRect(
|
||||||
|
brick.cellX * game.map.cellWidth,
|
||||||
|
brick.cellY * game.map.cellHeight,
|
||||||
|
game.map.cellWidth,
|
||||||
|
game.map.cellHeight
|
||||||
|
);
|
||||||
g.endFill();
|
g.endFill();
|
||||||
|
|
||||||
g.lineStyle(1, 0x000000);
|
|
||||||
for (i in 0...game.map.gridWidth + 1) {
|
|
||||||
g.moveTo(i * game.map.cellWidth, 0);
|
|
||||||
g.lineTo(i * game.map.cellWidth, mapHeight);
|
|
||||||
}
|
}
|
||||||
for (i in 0...game.map.gridHeight + 1) {
|
|
||||||
g.moveTo(0, i * game.map.cellHeight);
|
|
||||||
g.lineTo(mapWidth, i * game.map.cellHeight);
|
|
||||||
}
|
}
|
||||||
g.lineStyle();
|
layersForUpdate[groundLayer] = false;
|
||||||
|
layersForUpdate[upLayer] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var g:Graphics = tankLayer.graphics;
|
public function drawEntries(game:IEngine):Void {
|
||||||
|
if (layersForUpdate[entryLayer]) {
|
||||||
|
var g:Graphics = entryLayer.graphics;
|
||||||
g.clear();
|
g.clear();
|
||||||
|
|
||||||
for (e in game.mobileEntities) {
|
for (e in game.mobileEntities) {
|
||||||
if (Std.is(e, Tank)) {
|
if (Std.is(e, Tank)) {
|
||||||
var m = new Matrix();
|
var m = new Matrix();
|
||||||
@@ -69,6 +167,20 @@ class Render extends SpriteView implements IRender {
|
|||||||
g.endFill();
|
g.endFill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
layersForUpdate[entryLayer] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function draw(game:IEngine):Void {
|
||||||
|
invalidateLayers(game);
|
||||||
|
drawBackground(game);
|
||||||
|
drawMap(game);
|
||||||
|
drawEntries(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reset():Void {
|
||||||
|
states = new Map<String, IState<Dynamic>>();
|
||||||
|
layersForUpdate[backgroundLayer] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function calcRotate(direction:Direction):Float {
|
private function calcRotate(direction:Direction):Float {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
|
|
||||||
public function onShow():Void {
|
public function onShow():Void {
|
||||||
var game:Game = Provider.get(Game);
|
var game:Game = Provider.get(Game);
|
||||||
engine.init(ConfigBundle.get(GameType.CLASSIC));
|
engine.init(ConfigBundle.get(GameType.CLASSIC, 0));
|
||||||
engine.initTanks(game.players);
|
engine.initTanks(game.players);
|
||||||
content.addEventListener(Event.ENTER_FRAME, updateGame);
|
content.addEventListener(Event.ENTER_FRAME, updateGame);
|
||||||
for (index in 0...game.players.length) {
|
for (index in 0...game.players.length) {
|
||||||
@@ -46,6 +46,7 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
Provider.get(IConnection).packetHandler.removeListener(this);
|
Provider.get(IConnection).packetHandler.removeListener(this);
|
||||||
content.removeEventListener(Event.ENTER_FRAME, updateGame);
|
content.removeEventListener(Event.ENTER_FRAME, updateGame);
|
||||||
engine.clear();
|
engine.clear();
|
||||||
|
render.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateGame(_):Void {
|
private function updateGame(_):Void {
|
||||||
|
|||||||
BIN
src/client/resources/images/map/map_3.png
Normal file
BIN
src/client/resources/images/map/map_3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 598 B |
@@ -1,27 +1 @@
|
|||||||
00000000000000000000000000
|
00000000000000000000000000
|
||||||
|
|
||||||
00000000000000000000000000
|
|
||||||
|
|
||||||
00055500055500005000555000
|
|
||||||
|
|
||||||
00550550550550055005505500
|
|
||||||
|
|
||||||
00000050500050555005000500
|
|
||||||
|
|
||||||
00000550500050505005000500
|
|
||||||
|
|
||||||
00055500500050005005000500
|
|
||||||
|
|
||||||
00550000550550055005505500
|
|
||||||
|
|
||||||
00555550055500555500555000
|
|
||||||
|
|
||||||
00000000000000000000000000
|
|
||||||
|
|
||||||
22222222222222222222222222
|
|
||||||
|
|
||||||
22222222222222222222222222
|
|
||||||
|
|
||||||
44111111111144111111111144
|
|
||||||
|
|
||||||
44111111111144111111111144
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.m.tankz.config;
|
package ru.m.tankz.config;
|
||||||
|
|
||||||
|
import openfl.utils.Assets;
|
||||||
|
import ru.m.tankz.map.Brick.BrickType;
|
||||||
import ru.m.tankz.proto.core.GameType;
|
import ru.m.tankz.proto.core.GameType;
|
||||||
import ru.m.tankz.core.Direction;
|
import ru.m.tankz.core.Direction;
|
||||||
|
|
||||||
@@ -8,6 +10,8 @@ typedef MapConfig = {
|
|||||||
var cellHeight:Float;
|
var cellHeight:Float;
|
||||||
var gridWidth:Int;
|
var gridWidth:Int;
|
||||||
var gridHeight:Int;
|
var gridHeight:Int;
|
||||||
|
|
||||||
|
var bricks:Array<BrickType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpawnPointType {
|
enum SpawnPointType {
|
||||||
@@ -53,7 +57,8 @@ class ConfigBundle {
|
|||||||
cellWidth: 22,
|
cellWidth: 22,
|
||||||
cellHeight: 22,
|
cellHeight: 22,
|
||||||
gridWidth: 26,
|
gridWidth: 26,
|
||||||
gridHeight: 26
|
gridHeight: 26,
|
||||||
|
bricks: null
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -73,9 +78,17 @@ class ConfigBundle {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
public static function get(type:Int):Config {
|
public static function get(type:Int, level:Int):Config {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GameType.CLASSIC:
|
case GameType.CLASSIC:
|
||||||
|
var bricksData:String = Assets.getText('resources/levels/level00${level}.txt');
|
||||||
|
var bricks:Array<BrickType> = [];
|
||||||
|
for (line in ~/\s+/g.split(bricksData)) {
|
||||||
|
for (c in line.split('')) {
|
||||||
|
bricks.push(Std.parseInt(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CLASSIC.map.bricks = bricks; // ToDo:
|
||||||
return CLASSIC;
|
return CLASSIC;
|
||||||
case _:
|
case _:
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -7,9 +7,14 @@ class Entity implements IEntity {
|
|||||||
|
|
||||||
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 key(get, null):String;
|
||||||
|
|
||||||
public function new(x:Float, y:Float) {
|
public function new(x:Float, y:Float) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function get_key():String {
|
||||||
|
return '${Type.getClassName(Type.getClass(this))}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package ru.m.tankz.core;
|
package ru.m.tankz.core;
|
||||||
|
|
||||||
interface IEntity {
|
interface IEntity extends IKey {
|
||||||
public var x(default, default):Float;
|
public var x(default, default):Float;
|
||||||
public var y(default, default):Float;
|
public var y(default, default):Float;
|
||||||
|
|
||||||
|
|||||||
5
src/common/haxe/ru/m/tankz/core/IKey.hx
Normal file
5
src/common/haxe/ru/m/tankz/core/IKey.hx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package ru.m.tankz.core;
|
||||||
|
|
||||||
|
interface IKey {
|
||||||
|
public var key(get, null):String;
|
||||||
|
}
|
||||||
@@ -28,4 +28,8 @@ class MobileEntity extends Entity implements IMobileEntity {
|
|||||||
mx = 0;
|
mx = 0;
|
||||||
my = 0;
|
my = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override private function get_key():String {
|
||||||
|
return '${super.get_key()}:${id}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/common/haxe/ru/m/tankz/map/Brick.hx
Normal file
31
src/common/haxe/ru/m/tankz/map/Brick.hx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package ru.m.tankz.map;
|
||||||
|
|
||||||
|
import ru.m.tankz.core.IKey;
|
||||||
|
|
||||||
|
|
||||||
|
@:enum abstract BrickType(Int) from Int to Int {
|
||||||
|
var NONE = 0;
|
||||||
|
var ACE = 1;
|
||||||
|
var BUSH = 2;
|
||||||
|
var WATER = 3;
|
||||||
|
var ARMOR = 4;
|
||||||
|
var BRICK = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Brick implements IKey {
|
||||||
|
public var cellX(default, null):Int;
|
||||||
|
public var cellY(default, null):Int;
|
||||||
|
public var type(default, null):BrickType;
|
||||||
|
public var key(get, null):String;
|
||||||
|
|
||||||
|
public function new(type:BrickType, cellX:Int, cellY:Int) {
|
||||||
|
this.cellX = cellX;
|
||||||
|
this.cellY = cellY;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_key():String {
|
||||||
|
return 'brick:${cellX}:${cellY}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package ru.m.tankz.map;
|
package ru.m.tankz.map;
|
||||||
|
|
||||||
|
|
||||||
interface ILevelMap {
|
interface ILevelMap {
|
||||||
public var cellWidth(default, null):Float;
|
public var cellWidth(default, null):Float;
|
||||||
public var cellHeight(default, null):Float;
|
public var cellHeight(default, null):Float;
|
||||||
public var gridWidth(default, null):Int;
|
public var gridWidth(default, null):Int;
|
||||||
public var gridHeight(default, null):Int;
|
public var gridHeight(default, null):Int;
|
||||||
|
|
||||||
|
public var bricks(default, null):Array<Brick>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,13 @@ class LevelMap implements ILevelMap {
|
|||||||
public var gridWidth(default, null):Int;
|
public var gridWidth(default, null):Int;
|
||||||
public var gridHeight(default, null):Int;
|
public var gridHeight(default, null):Int;
|
||||||
|
|
||||||
|
public var bricks(default, null):Array<Brick>;
|
||||||
|
|
||||||
public function new(config:MapConfig) {
|
public function new(config:MapConfig) {
|
||||||
cellWidth = config.cellWidth;
|
cellWidth = config.cellWidth;
|
||||||
cellHeight = config.cellHeight;
|
cellHeight = config.cellHeight;
|
||||||
gridWidth = config.gridWidth;
|
gridWidth = config.gridWidth;
|
||||||
gridHeight = config.gridHeight;
|
gridHeight = config.gridHeight;
|
||||||
|
bricks = Lambda.array(Lambda.mapi(config.bricks, function(i, type):Brick return new Brick(type, Std.int(i % gridWidth), Std.int(Math.floor(i / gridHeight)))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user