diff --git a/src/haxe/ru/m/puzzlez/core/Game.hx b/src/haxe/ru/m/puzzlez/core/Game.hx index a1bd3af..adbac12 100644 --- a/src/haxe/ru/m/puzzlez/core/Game.hx +++ b/src/haxe/ru/m/puzzlez/core/Game.hx @@ -11,8 +11,8 @@ class Game implements IGame { private var partsById:Map; - public function new(preset:GamePreset) { - state = GameUtil.buildState(preset); + public function new(state:GameState) { + this.state = state; partsById = new Map(); for (part in state.parts) { partsById[part.id] = part; @@ -23,7 +23,10 @@ class Game implements IGame { public function start():Void { signal.emit(GameEvent.START(state)); - shuffle(); + if (!state.started) { + shuffle(); + state.started = true; + } } public function shuffle():Void { diff --git a/src/haxe/ru/m/puzzlez/core/GameState.hx b/src/haxe/ru/m/puzzlez/core/GameState.hx index 9b58af3..d6cf599 100644 --- a/src/haxe/ru/m/puzzlez/core/GameState.hx +++ b/src/haxe/ru/m/puzzlez/core/GameState.hx @@ -1,6 +1,7 @@ package ru.m.puzzlez.core; typedef GameState = { + var started:Bool; var preset:GamePreset; var parts:Array; } diff --git a/src/haxe/ru/m/puzzlez/core/GameUtil.hx b/src/haxe/ru/m/puzzlez/core/GameUtil.hx index 3037fdf..39fdd8c 100644 --- a/src/haxe/ru/m/puzzlez/core/GameUtil.hx +++ b/src/haxe/ru/m/puzzlez/core/GameUtil.hx @@ -125,6 +125,7 @@ class GameUtil { } } return { + started: false, preset: preset, parts: parts, } diff --git a/src/haxe/ru/m/puzzlez/render/Render.hx b/src/haxe/ru/m/puzzlez/render/Render.hx index e28779d..d1c26c6 100644 --- a/src/haxe/ru/m/puzzlez/render/Render.hx +++ b/src/haxe/ru/m/puzzlez/render/Render.hx @@ -78,9 +78,16 @@ class Render extends SpriteView implements IRender { this.state = state; for (part in state.parts) { var partView = PartView.factory(part); - partView.position = part.rect.topLeft; parts.set(part.id, partView); - tableView.addChild(partView); + switch part.location { + case TABLE(point): + partView.position = point; + tableView.addChild(partView); + case IMAGE: + partView.complete(); + imageView.addChild(partView); + case _: + } } imageView.x = state.preset.imageRect.x; @@ -105,7 +112,9 @@ class Render extends SpriteView implements IRender { parts[result.part.id].image = result.image; progress.setProgress(++i, state.parts.length); }).endThen(function(_) { - content.removeChild(progress.content); + if (progress.content.parent != null) { + progress.content.parent.removeChild(progress.content); + } }); } diff --git a/src/haxe/ru/m/puzzlez/storage/AssetSource.hx b/src/haxe/ru/m/puzzlez/source/AssetSource.hx similarity index 96% rename from src/haxe/ru/m/puzzlez/storage/AssetSource.hx rename to src/haxe/ru/m/puzzlez/source/AssetSource.hx index 4b09f4b..35bd4d2 100644 --- a/src/haxe/ru/m/puzzlez/storage/AssetSource.hx +++ b/src/haxe/ru/m/puzzlez/source/AssetSource.hx @@ -1,4 +1,4 @@ -package ru.m.puzzlez.storage; +package ru.m.puzzlez.source; import flash.display.BitmapData; import openfl.Assets; diff --git a/src/haxe/ru/m/puzzlez/storage/FileSource.hx b/src/haxe/ru/m/puzzlez/source/FileSource.hx similarity index 98% rename from src/haxe/ru/m/puzzlez/storage/FileSource.hx rename to src/haxe/ru/m/puzzlez/source/FileSource.hx index df8480a..839929c 100644 --- a/src/haxe/ru/m/puzzlez/storage/FileSource.hx +++ b/src/haxe/ru/m/puzzlez/source/FileSource.hx @@ -1,4 +1,4 @@ -package ru.m.puzzlez.storage; +package ru.m.puzzlez.source; import flash.display.BitmapData; import flash.net.SharedObject; diff --git a/src/haxe/ru/m/puzzlez/source/GameStorage.hx b/src/haxe/ru/m/puzzlez/source/GameStorage.hx new file mode 100644 index 0000000..581c397 --- /dev/null +++ b/src/haxe/ru/m/puzzlez/source/GameStorage.hx @@ -0,0 +1,24 @@ +package ru.m.puzzlez.source; + +import haxework.storage.SharedObjectStorage; +import ru.m.puzzlez.core.GameState; +import ru.m.puzzlez.core.Id.ImageId; + +@:provide class GameStorage extends SharedObjectStorage { + + public function new() { + super('game_1'); + } + + public function save(state:GameState):Void { + write(state.preset.image, state); + } + + public function load(imageId:ImageId):Null { + return read(imageId); + } + + public function list():Array { + return [for (key in Reflect.fields(so.data)) ImageId.fromString(key)]; + } +} diff --git a/src/haxe/ru/m/puzzlez/storage/IImageSource.hx b/src/haxe/ru/m/puzzlez/source/IImageSource.hx similarity index 91% rename from src/haxe/ru/m/puzzlez/storage/IImageSource.hx rename to src/haxe/ru/m/puzzlez/source/IImageSource.hx index 4c6a7f0..a87fe9e 100644 --- a/src/haxe/ru/m/puzzlez/storage/IImageSource.hx +++ b/src/haxe/ru/m/puzzlez/source/IImageSource.hx @@ -1,4 +1,4 @@ -package ru.m.puzzlez.storage; +package ru.m.puzzlez.source; import flash.display.BitmapData; import promhx.Promise; diff --git a/src/haxe/ru/m/puzzlez/storage/PixabaySource.hx b/src/haxe/ru/m/puzzlez/source/PixabaySource.hx similarity index 98% rename from src/haxe/ru/m/puzzlez/storage/PixabaySource.hx rename to src/haxe/ru/m/puzzlez/source/PixabaySource.hx index 15ee880..99849f9 100644 --- a/src/haxe/ru/m/puzzlez/storage/PixabaySource.hx +++ b/src/haxe/ru/m/puzzlez/source/PixabaySource.hx @@ -1,4 +1,4 @@ -package ru.m.puzzlez.storage; +package ru.m.puzzlez.source; import flash.display.BitmapData; import haxework.net.ImageLoader; diff --git a/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx b/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx index 5583d87..db9a598 100644 --- a/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx +++ b/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx @@ -13,6 +13,10 @@ import promhx.Deferred; import promhx.Promise; import Reflect; import ru.m.puzzlez.core.Id; +import ru.m.puzzlez.source.AssetSource; +import ru.m.puzzlez.source.FileSource; +import ru.m.puzzlez.source.IImageSource; +import ru.m.puzzlez.source.PixabaySource; @:provide class ImageStorage { diff --git a/src/haxe/ru/m/puzzlez/view/GameFrame.hx b/src/haxe/ru/m/puzzlez/view/GameFrame.hx index f7ec076..1fb7c2d 100644 --- a/src/haxe/ru/m/puzzlez/view/GameFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/GameFrame.hx @@ -3,25 +3,30 @@ package ru.m.puzzlez.view; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; import ru.m.puzzlez.core.Game; -import ru.m.puzzlez.core.GamePreset; +import ru.m.puzzlez.core.GameEvent; +import ru.m.puzzlez.core.GameState; import ru.m.puzzlez.core.IGame; +import ru.m.puzzlez.core.PartLocation; import ru.m.puzzlez.render.IRender; +import ru.m.puzzlez.source.GameStorage; -@:template class GameFrame extends FrameView { +@:template class GameFrame extends FrameView { public static var ID = "game"; @:view private var render:IRender; private var game:IGame; @:provide var switcher:FrameSwitcher; + @:provide var storage:GameStorage; public function new() { super(ID); } - override public function onShow(preset:GamePreset):Void { + override public function onShow(state:GameState):Void { onHide(); - game = new Game(preset); + game = new Game(state); game.signal.connect(render.onGameEvent); + game.signal.connect(onGameEvent); render.signal.connect(game.signal.emit); game.start(); } @@ -35,7 +40,15 @@ import ru.m.puzzlez.render.IRender; } } + private function onGameEvent(event:GameEvent):Void { + switch event { + case CHANGE(PART_UPDATE(_, IMAGE)): + storage.save(game.state); + case _: + } + } + private function back():Void { - switcher.change(ImagesFrame.ID); + switcher.change(ImageListFrame.ID); } } diff --git a/src/haxe/ru/m/puzzlez/view/GameListFrame.hx b/src/haxe/ru/m/puzzlez/view/GameListFrame.hx new file mode 100644 index 0000000..29df85e --- /dev/null +++ b/src/haxe/ru/m/puzzlez/view/GameListFrame.hx @@ -0,0 +1,34 @@ +package ru.m.puzzlez.view; + +import haxework.view.data.DataView; +import haxework.view.frame.FrameSwitcher; +import haxework.view.frame.FrameView; +import ru.m.puzzlez.core.Id; +import ru.m.puzzlez.source.GameStorage; + +@:template class GameListFrame extends FrameView { + + public static var ID(default, never) = "game_list"; + + @:view var images:DataView; + + @:provide var switcher:FrameSwitcher; + @:provide var storage:GameStorage; + + public function new() { + super(ID); + } + + override public function onShow(data:Dynamic):Void { + images.data = storage.list(); + } + + private function start(image:ImageId):Void { + var state = storage.load(image); + switcher.change(GameFrame.ID, state); + } + + private function back():Void { + switcher.change(StartFrame.ID); + } +} diff --git a/src/haxe/ru/m/puzzlez/view/GameListFrame.yaml b/src/haxe/ru/m/puzzlez/view/GameListFrame.yaml new file mode 100644 index 0000000..345d1ea --- /dev/null +++ b/src/haxe/ru/m/puzzlez/view/GameListFrame.yaml @@ -0,0 +1,20 @@ +--- +style: frame +views: + - id: images + $type: haxework.view.data.DataView + layout: + $type: haxework.view.layout.TailLayout + margin: 5 + vAlign: middle + geometry.stretch: true + factory: ~ru.m.puzzlez.view.PuzzleImageView.factory + +onDataSelect: ~start + geometry.margin: 5 + overflow.y: scroll + - $type: haxework.view.form.ButtonView + text: Back + geometry.position: absolute + geometry.hAlign: right + geometry.vAlign: top + +onPress: ~back() diff --git a/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx similarity index 56% rename from src/haxe/ru/m/puzzlez/view/ImagesFrame.hx rename to src/haxe/ru/m/puzzlez/view/ImageListFrame.hx index 29bcef6..751b462 100644 --- a/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx @@ -1,49 +1,16 @@ package ru.m.puzzlez.view; -import haxework.view.group.GroupView; import haxework.view.data.DataView; import haxework.view.form.ButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; -import haxework.view.ImageView; -import haxework.view.utils.DrawUtil; import ru.m.puzzlez.core.Id; import ru.m.puzzlez.FileUtil; -import ru.m.puzzlez.storage.FileSource; +import ru.m.puzzlez.source.FileSource; import ru.m.puzzlez.storage.ImageStorage; - -class PuzzleImageView extends GroupView { - - public var imageId(null, set):ImageId; - - private function set_imageId(value:ImageId):ImageId { - if (imageId != value) { - imageId = value; - loading.promise = imageStorage.resolve(imageId, true).then(function(data) image.image = data); - } - return imageId; - } - - private var image:ImageView; - private var loading:LoadingWrapper; - @:provide var imageStorage:ImageStorage; - - public function new() { - super(); - style = "view"; - image = new ImageView(); - image.geometry.stretch = true; - image.stretch = false; - image.fillType = COVER; - addView(image); - loading = new LoadingWrapper(this); - } -} - - -@:template class ImagesFrame extends FrameView> { - public static var ID = "images"; +@:template class ImageListFrame extends FrameView> { + public static var ID = "image_list"; @:view var images:DataView; @:view var select:ButtonView; @@ -71,12 +38,6 @@ class PuzzleImageView extends GroupView { //images.data = []; } - private function imageViewFactory(index:Int, imageId:ImageId):PuzzleImageView { - var result = new PuzzleImageView(); - result.imageId = imageId; - return result; - } - private function selectFile():Void { FileUtil.browse().then(function(data:FileContent) { var fileSource:FileSource = cast source.source; diff --git a/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml b/src/haxe/ru/m/puzzlez/view/ImageListFrame.yaml similarity index 90% rename from src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml rename to src/haxe/ru/m/puzzlez/view/ImageListFrame.yaml index dfad8a4..689db5c 100644 --- a/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml +++ b/src/haxe/ru/m/puzzlez/view/ImageListFrame.yaml @@ -8,7 +8,7 @@ views: margin: 5 vAlign: middle geometry.stretch: true - factory: ~imageViewFactory + factory: ~ru.m.puzzlez.view.PuzzleImageView.factory +onDataSelect: ~start geometry.margin: 5 overflow.y: scroll diff --git a/src/haxe/ru/m/puzzlez/view/ImageListSource.hx b/src/haxe/ru/m/puzzlez/view/ImageListSource.hx index 4c7a6ff..5f8cee2 100644 --- a/src/haxe/ru/m/puzzlez/view/ImageListSource.hx +++ b/src/haxe/ru/m/puzzlez/view/ImageListSource.hx @@ -1,6 +1,6 @@ package ru.m.puzzlez.view; -import ru.m.puzzlez.storage.IImageSource; +import ru.m.puzzlez.source.IImageSource; typedef ImageListSource = { var source:IImageSource; diff --git a/src/haxe/ru/m/puzzlez/view/PresetFrame.hx b/src/haxe/ru/m/puzzlez/view/PresetFrame.hx index 0a7e3e1..e77e6ca 100644 --- a/src/haxe/ru/m/puzzlez/view/PresetFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/PresetFrame.hx @@ -47,10 +47,10 @@ import ru.m.puzzlez.storage.ImageStorage; } private function start():Void { - switcher.change(GameFrame.ID, imageView.preset); + switcher.change(GameFrame.ID, GameUtil.buildState(imageView.preset)); } private function back():Void { - switcher.change(ImagesFrame.ID); + switcher.change(ImageListFrame.ID); } } diff --git a/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx b/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx new file mode 100644 index 0000000..5faa4c1 --- /dev/null +++ b/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx @@ -0,0 +1,41 @@ +package ru.m.puzzlez.view; + +import haxework.view.group.GroupView; +import haxework.view.ImageView; +import haxework.view.utils.DrawUtil; +import ru.m.puzzlez.core.Id; +import ru.m.puzzlez.storage.ImageStorage; + +class PuzzleImageView extends GroupView { + + public var imageId(null, set):ImageId; + + private function set_imageId(value:ImageId):ImageId { + if (imageId != value) { + imageId = value; + loading.promise = imageStorage.resolve(imageId, true).then(function(data) image.image = data); + } + return imageId; + } + + private var image:ImageView; + private var loading:LoadingWrapper; + @:provide var imageStorage:ImageStorage; + + public function new() { + super(); + style = "view"; + image = new ImageView(); + image.geometry.stretch = true; + image.stretch = false; + image.fillType = COVER; + addView(image); + loading = new LoadingWrapper(this); + } + + public static function factory(index:Int, imageId:ImageId):PuzzleImageView { + var result = new PuzzleImageView(); + result.imageId = imageId; + return result; + } +} diff --git a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml index c2ef373..a05d4b9 100644 --- a/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml +++ b/src/haxe/ru/m/puzzlez/view/PuzzlezAppView.yaml @@ -6,6 +6,7 @@ views: style: dark factory: _start_: {$class: ru.m.puzzlez.view.StartFrame} - _images_: {$class: ru.m.puzzlez.view.ImagesFrame} + _game_list_: {$class: ru.m.puzzlez.view.GameListFrame} + _image_list_: {$class: ru.m.puzzlez.view.ImageListFrame} _preset_: {$class: ru.m.puzzlez.view.PresetFrame} _game_: {$class: ru.m.puzzlez.view.GameFrame} diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.hx b/src/haxe/ru/m/puzzlez/view/StartFrame.hx index 7b71469..54b46fc 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.hx @@ -4,10 +4,10 @@ import haxework.view.data.DataView; import haxework.view.form.ButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; -import ru.m.puzzlez.storage.AssetSource; -import ru.m.puzzlez.storage.FileSource; +import ru.m.puzzlez.source.AssetSource; +import ru.m.puzzlez.source.FileSource; import ru.m.puzzlez.storage.ImageStorage; -import ru.m.puzzlez.storage.PixabaySource; +import ru.m.puzzlez.source.PixabaySource; @:template class StartFrame extends FrameView { public static var ID = "start"; @@ -34,6 +34,6 @@ import ru.m.puzzlez.storage.PixabaySource; } private function load(source:ImageListSource):Void { - switcher.change(ImagesFrame.ID, source); + switcher.change(ImageListFrame.ID, source); } } diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml index 3ee14d9..0380261 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml @@ -18,3 +18,6 @@ views: +onDataSelect: ~load geometry.margin: 5 overflow.y: scroll + - $type: haxework.view.form.ButtonView + text: Load + +onPress: ~switcher.change('game_list')