[add] GameStorage
This commit is contained in:
@@ -11,8 +11,8 @@ class Game implements IGame {
|
||||
|
||||
private var partsById:Map<Int, Part>;
|
||||
|
||||
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));
|
||||
if (!state.started) {
|
||||
shuffle();
|
||||
state.started = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function shuffle():Void {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ru.m.puzzlez.core;
|
||||
|
||||
typedef GameState = {
|
||||
var started:Bool;
|
||||
var preset:GamePreset;
|
||||
var parts:Array<Part>;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ class GameUtil {
|
||||
}
|
||||
}
|
||||
return {
|
||||
started: false,
|
||||
preset: preset,
|
||||
parts: parts,
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package ru.m.puzzlez.storage;
|
||||
package ru.m.puzzlez.source;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import openfl.Assets;
|
||||
@@ -1,4 +1,4 @@
|
||||
package ru.m.puzzlez.storage;
|
||||
package ru.m.puzzlez.source;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import flash.net.SharedObject;
|
||||
24
src/haxe/ru/m/puzzlez/source/GameStorage.hx
Normal file
24
src/haxe/ru/m/puzzlez/source/GameStorage.hx
Normal file
@@ -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<GameState> {
|
||||
return read(imageId);
|
||||
}
|
||||
|
||||
public function list():Array<ImageId> {
|
||||
return [for (key in Reflect.fields(so.data)) ImageId.fromString(key)];
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package ru.m.puzzlez.storage;
|
||||
package ru.m.puzzlez.source;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import promhx.Promise;
|
||||
@@ -1,4 +1,4 @@
|
||||
package ru.m.puzzlez.storage;
|
||||
package ru.m.puzzlez.source;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import haxework.net.ImageLoader;
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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<GamePreset> {
|
||||
@:template class GameFrame extends FrameView<GameState> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
34
src/haxe/ru/m/puzzlez/view/GameListFrame.hx
Normal file
34
src/haxe/ru/m/puzzlez/view/GameListFrame.hx
Normal file
@@ -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<Dynamic> {
|
||||
|
||||
public static var ID(default, never) = "game_list";
|
||||
|
||||
@:view var images:DataView<ImageId, PuzzleImageView>;
|
||||
|
||||
@: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);
|
||||
}
|
||||
}
|
||||
20
src/haxe/ru/m/puzzlez/view/GameListFrame.yaml
Normal file
20
src/haxe/ru/m/puzzlez/view/GameListFrame.yaml
Normal file
@@ -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()
|
||||
@@ -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<ImageListSource<Dynamic>> {
|
||||
public static var ID = "images";
|
||||
@:template class ImageListFrame extends FrameView<ImageListSource<Dynamic>> {
|
||||
public static var ID = "image_list";
|
||||
|
||||
@:view var images:DataView<ImageId, PuzzleImageView>;
|
||||
@: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;
|
||||
@@ -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
|
||||
@@ -1,6 +1,6 @@
|
||||
package ru.m.puzzlez.view;
|
||||
|
||||
import ru.m.puzzlez.storage.IImageSource;
|
||||
import ru.m.puzzlez.source.IImageSource;
|
||||
|
||||
typedef ImageListSource<T> = {
|
||||
var source:IImageSource<T>;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
41
src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx
Normal file
41
src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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<Dynamic> {
|
||||
public static var ID = "start";
|
||||
@@ -34,6 +34,6 @@ import ru.m.puzzlez.storage.PixabaySource;
|
||||
}
|
||||
|
||||
private function load(source:ImageListSource<Dynamic>):Void {
|
||||
switcher.change(ImagesFrame.ID, source);
|
||||
switcher.change(ImageListFrame.ID, source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user