diff --git a/WORK.md b/WORK.md index 4a7cc72..01f5811 100644 --- a/WORK.md +++ b/WORK.md @@ -4,7 +4,7 @@ * game series * network series * map packs - * import in game + * import in game * save imported in local storage * database * cache @@ -18,3 +18,5 @@ * screen gamepad (button enabled, count label) * ui: * game frame layouts +* fix: + * ice brick fix diff --git a/src/client/haxe/ru/m/Device.hx b/src/client/haxe/ru/m/Device.hx index 3298d2c..99bf839 100644 --- a/src/client/haxe/ru/m/Device.hx +++ b/src/client/haxe/ru/m/Device.hx @@ -36,7 +36,9 @@ class Device { return true; } } - #end return false; + #else + return false; + #end } } diff --git a/src/client/haxe/ru/m/tankz/Client.hx b/src/client/haxe/ru/m/tankz/Client.hx index 316ed1a..eab7a25 100755 --- a/src/client/haxe/ru/m/tankz/Client.hx +++ b/src/client/haxe/ru/m/tankz/Client.hx @@ -4,11 +4,14 @@ import flash.Lib; import haxework.animate.Animate; import haxework.log.TraceLogger; import haxework.view.Root; +import ru.m.tankz.storage.SettingsStorage; import ru.m.tankz.view.ClientView; class Client { private static inline var TAG = "Tankz"; + @:provide private static var settings:SettingsStorage; + public static function main() { L.push(new TraceLogger()); #if flash @@ -30,9 +33,16 @@ class Client { Root.bind(view); view.launch(); - #if debug var fps = new openfl.display.FPS(0, 0, 0x00ff00); + fps.visible = settings.displayFPS; Lib.current.addChild(fps); - #end + + settings.signal.connect(function(setting) { + switch setting { + case DISPLAY_FPS(value): + fps.visible = value; + case _: + } + }); } } diff --git a/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx b/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx index 83becd7..06a518c 100644 --- a/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx +++ b/src/client/haxe/ru/m/tankz/storage/SettingsStorage.hx @@ -1,6 +1,7 @@ package ru.m.tankz.storage; import flash.ui.Keyboard; +import haxework.signal.Signal; import haxework.storage.SharedObjectStorage; import haxework.utils.ObjectUtil; import ru.m.control.DeviceAction; @@ -9,10 +10,30 @@ import ru.m.geom.Direction; import ru.m.tankz.control.Binding; import ru.m.tankz.control.Control; +enum Setting { + CONTROL(index:Int, value:Binding); + DISPLAY_FPS(value:Bool); + ENABLE_NETWORK(value:Bool); +} + class SettingsStorage extends SharedObjectStorage { private static inline var VERSION = 4.1; + public var signal(default, null):Signal = new Signal(); + + public var displayFPS(get, set):Bool; + + private function get_displayFPS():Bool { + return read("setting:display_fps"); + } + + private function set_displayFPS(value:Bool):Bool { + write("setting:display_fps", value); + signal.emit(DISPLAY_FPS(value)); + return get_displayFPS(); + } + public function new() { super('settings_${VERSION}'); } @@ -23,6 +44,7 @@ class SettingsStorage extends SharedObjectStorage { public function saveBinding(index:Int, value:Binding) { write('action:$index', value); + signal.emit(CONTROL(index, value)); } public static function getDefaultBinding(index:Int):Binding { diff --git a/src/client/haxe/ru/m/tankz/view/GameFrame.hx b/src/client/haxe/ru/m/tankz/view/GameFrame.hx index 0df4f29..6bbb1d8 100644 --- a/src/client/haxe/ru/m/tankz/view/GameFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/GameFrame.hx @@ -17,6 +17,7 @@ import ru.m.tankz.network.NetworkGame; import ru.m.tankz.sound.SoundManager; import ru.m.tankz.storage.GameStorage; import ru.m.tankz.storage.SettingsStorage; +import ru.m.tankz.Type; import ru.m.tankz.view.game.GameViewA; import ru.m.tankz.view.game.GameViewB; import ru.m.tankz.view.game.IGameView; @@ -36,6 +37,8 @@ import ru.m.tankz.view.gamepad.GamepadView; @:view("game") private var gameViewContainer(default, null):GroupView; @:view private var gamepad(default, null):GamepadView; + private var gamepadPlayerId:PlayerId; + private var gameView:IGameView; private var game:IGame; @@ -72,6 +75,7 @@ import ru.m.tankz.view.gamepad.GamepadView; for (control in game.controls) { if (Std.is(control, HumanControl)) { if (cast(control, HumanControl).hasDevice(SCREEN)) { + gamepadPlayerId = control.playerId; gamepad.visible = true; break; } @@ -91,6 +95,11 @@ import ru.m.tankz.view.gamepad.GamepadView; public function onGameEvent(event:GameEvent):Void { switch event { + case SPAWN(TANK(id, rect, playerId, info)): + if (gamepadPlayerId != null && playerId == gamepadPlayerId) { + var tankConfig = game.config.getTank(info.type); + gamepad.weapons = tankConfig.weapons; + } case COMPLETE(result): stop(); switcher.change(ResultFrame.ID, result); diff --git a/src/client/haxe/ru/m/tankz/view/SettingsFrame.hx b/src/client/haxe/ru/m/tankz/view/SettingsFrame.hx index b62749e..5ba2639 100644 --- a/src/client/haxe/ru/m/tankz/view/SettingsFrame.hx +++ b/src/client/haxe/ru/m/tankz/view/SettingsFrame.hx @@ -1,14 +1,37 @@ package ru.m.tankz.view; +import haxework.view.form.ToggleButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; +import ru.m.tankz.storage.SettingsStorage; @:template class SettingsFrame extends FrameView { public static var ID(default, never):String = "settings"; + @:view("fps") var fpsButton:ToggleButtonView; + @:provide static var switcher:FrameSwitcher; + @:provide static var settings:SettingsStorage; public function new() { super(ID); } + + override public function onShow(data:Dynamic):Void { + super.onShow(data); + fpsButton.on = settings.displayFPS; + settings.signal.connect(onSettingChange); + } + + override public function onHide():Void { + settings.signal.disconnect(onSettingChange); + } + + private function onSettingChange(setting:Setting):Void { + switch setting { + case DISPLAY_FPS(value): + fpsButton.on = value; + case _: + } + } } diff --git a/src/client/haxe/ru/m/tankz/view/SettingsFrame.yaml b/src/client/haxe/ru/m/tankz/view/SettingsFrame.yaml index 57eb304..e488e3b 100644 --- a/src/client/haxe/ru/m/tankz/view/SettingsFrame.yaml +++ b/src/client/haxe/ru/m/tankz/view/SettingsFrame.yaml @@ -6,21 +6,29 @@ views: - $type: haxework.view.form.LabelView style: text.header text: Settings - - $type: haxework.view.group.GroupView - geometry.width: 100% - geometry.height: 100% + - $type: haxework.view.group.VGroupView + geometry.stretch: true + layout.hAlign: center overflow.y: scroll - layout: - $type: haxework.view.layout.TailLayout - vAlign: top - margin: 20 views: - - id: settings0 - $type: ru.m.tankz.view.settings.SettingsEditor - controlIndex: 0 - - id: settings1 - $type: ru.m.tankz.view.settings.SettingsEditor - controlIndex: 1 + - $type: haxework.view.group.GroupView + geometry.width: 100% + layout: + $type: haxework.view.layout.TailLayout + vAlign: top + margin: 20 + views: + - id: settings0 + $type: ru.m.tankz.view.settings.SettingsEditor + controlIndex: 0 + - id: settings1 + $type: ru.m.tankz.view.settings.SettingsEditor + controlIndex: 1 + - id: fps + $type: haxework.view.form.ToggleButtonView + geometry.margin.top: 20 + text: Display FPS + +onPress: ~function(button) settings.displayFPS = !cast(button,ToggleButtonView).on - $type: haxework.view.group.HGroupView style: panel layout.margin: 10 diff --git a/src/client/haxe/ru/m/tankz/view/game/IGameView.hx b/src/client/haxe/ru/m/tankz/view/game/IGameView.hx index a5fa604..c2d1cef 100644 --- a/src/client/haxe/ru/m/tankz/view/game/IGameView.hx +++ b/src/client/haxe/ru/m/tankz/view/game/IGameView.hx @@ -1,11 +1,11 @@ package ru.m.tankz.view.game; -import ru.m.tankz.render.IRender; import haxework.view.data.DataView; import haxework.view.form.LabelView; import haxework.view.IView; import ru.m.tankz.game.GameState; import ru.m.tankz.game.IGame; +import ru.m.tankz.render.IRender; interface IGameView extends IView extends GameListener { public var render(default, null):IRender; diff --git a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx index b5b0e79..d7b2989 100644 --- a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx +++ b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadSkin.hx @@ -3,6 +3,7 @@ package ru.m.tankz.view.gamepad; import flash.display.Graphics; import haxework.color.Color; import haxework.view.skin.ISkin; +import ru.m.control.DeviceAction; @:style class GamepadSkin implements ISkin { @@ -17,10 +18,14 @@ import haxework.view.skin.ISkin; var actives = [for (item in view.activeAreas.iterator()) item]; var graphics:Graphics = view.content.graphics; graphics.clear(); - graphics.beginFill(0, 0.0); - graphics.drawRect(0, 0, view.width, view.height); - graphics.endFill(); for (area in view.areas) { + switch area.action { + case KEY(code): + if (view.weapons.length < code + 1) { + continue; + } + case _: + } var color = actives.indexOf(area) > -1 ? activeColor : color; graphics.lineStyle(2, color); graphics.beginFill(color, 0.2); diff --git a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx index 132bb3e..610ce9e 100644 --- a/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx +++ b/src/client/haxe/ru/m/tankz/view/gamepad/GamepadView.hx @@ -1,5 +1,6 @@ package ru.m.tankz.view.gamepad; +import flash.display.Sprite; import flash.display.Stage; import flash.events.MouseEvent; import flash.events.TouchEvent; @@ -9,6 +10,7 @@ import ru.m.control.DeviceAction; import ru.m.control.DeviceType; import ru.m.control.IControlDevice; import ru.m.geom.Point; +import ru.m.tankz.config.Config; class GamepadView extends SpriteView implements IControlDevice { @@ -18,9 +20,19 @@ class GamepadView extends SpriteView implements IControlDevice { public var areas(default, null):Array; public var activeAreas(default, null):Map; + public var weapons(default, set):Array; + + private function set_weapons(value:Array):Array { + weapons = value; + toRedraw(); + return weapons; + } + private var builder:IActionAreaBuilder; private var stage:Stage; + private var actionLayer:Sprite; + public function new() { super(); style = "gamepad"; @@ -28,15 +40,18 @@ class GamepadView extends SpriteView implements IControlDevice { builder = new SmartActionAreaBuilder(); signal = new Signal2(); areas = []; + weapons = []; activeAreas = new Map(); skin = new GamepadSkin(); - content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); - content.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); + actionLayer = new Sprite(); + actionLayer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); + actionLayer.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); + content.addChild(actionLayer); } private function onMouseDown(event:MouseEvent):Void { onMouseMove(event); - stage = content.stage; + stage = actionLayer.stage; stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } @@ -54,7 +69,7 @@ class GamepadView extends SpriteView implements IControlDevice { private function onTouchBegin(event:TouchEvent):Void { onTouchMove(event); - stage = content.stage; + stage = actionLayer.stage; stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd); } @@ -103,10 +118,15 @@ class GamepadView extends SpriteView implements IControlDevice { override public function update():Void { super.update(); areas = builder.build(width, height); + actionLayer.graphics.clear(); + actionLayer.graphics.beginFill(0, 0.0); + actionLayer.graphics.drawRect(0, 0, width, height); + actionLayer.graphics.endFill(); } - public function dispose():Void { + actionLayer.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); + actionLayer.removeEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); stage = null; } } diff --git a/src/common/haxe/ru/m/tankz/util/LevelUtil.hx b/src/common/haxe/ru/m/tankz/util/LevelUtil.hx index ee2e928..c8ed405 100644 --- a/src/common/haxe/ru/m/tankz/util/LevelUtil.hx +++ b/src/common/haxe/ru/m/tankz/util/LevelUtil.hx @@ -1,13 +1,11 @@ package ru.m.tankz.util; -import haxe.zip.Tools; -import haxe.io.BytesOutput; -import haxe.zip.Writer; -import flash.utils.ByteArray; import haxe.io.Bytes; import haxe.io.BytesInput; +import haxe.io.BytesOutput; import haxe.zip.Entry; -import haxe.zip.Reader; +import haxe.zip.Tools; +import haxe.zip.Writer; import ru.m.tankz.config.Config; import ru.m.tankz.Type; import yaml.Parser; @@ -29,32 +27,13 @@ class LevelUtil { return result; } - public static function loadsOld(data:String):LevelConfig { - var bricks:Array = []; - for (line in ~/\s+/g.split(data)) { - for (c in line.split('')) { - if (c.length > 0) { - bricks.push(Std.parseInt(c)); - } - } - } - return { - data: bricks - } - } - public static function loads(data:String):LevelConfig { - // If first char is digit load as old format - if (Std.parseInt(data.charAt(0)) != null) { - return loadsOld(data); - } else { - var obj:LevelSource = Yaml.parse(data, Parser.options().useObjects()); - return { - data: obj.data.split('').map(function(c) return Std.parseInt(c)), - points: obj.points, - name: obj.name, - size: obj.size, - } + var obj:LevelSource = Yaml.parse(data, Parser.options().useObjects()); + return { + data: obj.data.split('').map(function(c) return Std.parseInt(c)), + points: obj.points, + name: obj.name, + size: obj.size, } } @@ -96,20 +75,20 @@ class LevelUtil { var bytes = Bytes.ofString(content); var crc = haxe.crypto.Crc32.make(bytes); var result:Entry = { - fileName: '${formatLevel(level.id)}.txt', + fileName: '${formatLevel(level.id)}.yml', fileSize: bytes.length, - fileTime : Date.now(), - compressed : false, - dataSize : bytes.length, - data : bytes, - crc32 : crc, + fileTime: Date.now(), + compressed: false, + dataSize: bytes.length, + data: bytes, + crc32: crc, }; Tools.compress(result, 9); return result; } public static function unpack(bytes:Bytes):Array { - var files = Reader.readZip(new BytesInput(bytes)); + var files = haxe.zip.Reader.readZip(new BytesInput(bytes)); return Lambda.array(files.map(extract)); }