Nikatlas 6 tahun lalu
induk
melakukan
f7a65803ff

+ 38 - 0
package-lock.json

@@ -1619,6 +1619,39 @@
       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
       "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
     },
+    "chart.js": {
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.2.tgz",
+      "integrity": "sha512-90wl3V9xRZ8tnMvMlpcW+0Yg13BelsGS9P9t0ClaDxv/hdypHDr/YAGf+728m11P5ljwyB0ZHfPKCapZFqSqYA==",
+      "requires": {
+        "chartjs-color": "2.2.0",
+        "moment": "2.22.1"
+      }
+    },
+    "chartjs-color": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.2.0.tgz",
+      "integrity": "sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=",
+      "requires": {
+        "chartjs-color-string": "0.5.0",
+        "color-convert": "0.5.3"
+      },
+      "dependencies": {
+        "color-convert": {
+          "version": "0.5.3",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+          "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+        }
+      }
+    },
+    "chartjs-color-string": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz",
+      "integrity": "sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
     "chokidar": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -6330,6 +6363,11 @@
         "minimist": "0.0.8"
       }
     },
+    "moment": {
+      "version": "2.22.1",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
+      "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ=="
+    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

+ 20 - 0
src/Game/game/machine/GameMachine.js

@@ -18,6 +18,16 @@ class GameMachine {
         this.state = { ...this.state, board};
     }
 
+    save() {
+        let temp = { ...this.state, board: this.state.board.save() };
+        return temp;
+    }
+
+    load(state) {
+        this.state.board.load(state.board);
+        this.state = { ...state, board: this.state.board };
+    }
+
     setPlayers(players) {
         this.state = { ...this.state, players};
     }
@@ -203,6 +213,16 @@ class Board {
         return !!this.data[position];
     }
 
+    save() {
+        return {
+            data: this.data,
+            owners: this.owners
+        }
+    }
+    load(state) {
+        this.data = state.data;
+        this.owners = state.owners;
+    }
 }
 // START From top left goin row row  
 Board.ATTACK_VECTORS = [

+ 21 - 9
src/Game/views/base/Card.js

@@ -160,6 +160,9 @@ class Card extends GuiableContainer{
         return this;
     }
 
+    lock() { return this.unsetEvents(); }
+    unlock() { return this.setEvents(); }
+
     setEvents() {
         dragAndDrop(this);
         return this;
@@ -168,8 +171,9 @@ class Card extends GuiableContainer{
 
     // Animate to Position
     moveTo(point, milliseconds=1000) {
-        if(!point)
-            debugger; // error with x undefined...
+        if(typeof point === "undefined") {
+            return; // Some times this happens...
+        }
         let path = new PIXI.tween.TweenPath();
         path.moveTo(this.position.x, this.position.y).lineTo(point.x, point.y);
 
@@ -183,20 +187,28 @@ class Card extends GuiableContainer{
     }
     // Animate Scale
     scaleTo(newscale, milliseconds=1000) {
-        this._tween = PIXI.tweenManager.createTween(this);
-        this._tween.easing = PIXI.tween.Easing.outQuart();
-        this._tween.loop = false;
-        this._tween.from({
+        this._stween = PIXI.tweenManager.createTween(this);
+        this._stween.easing = PIXI.tween.Easing.outQuart();
+        this._stween.loop = false;
+        this._stween.from({
             scale: { x: this.scale.x, y: this.scale.y }
         });
-        this._tween.to({
+        this._stween.to({
             scale: { x: newscale, y: newscale }
         });
-        this._tween.time = milliseconds;
-        this._tween.start();
+        this._stween.time = milliseconds;
+        this._stween.start();
         return this;
     }
 
+    destroy() {
+        if(this._tween)
+            this._tween.stop();
+        if(this._stween)
+            this._stween.stop();
+        super.destroy();
+    }
+
     _kill() {
         super._kill();
     }

+ 10 - 0
src/Game/views/base/CardHolder.js

@@ -112,6 +112,16 @@ class CardHolder extends GuiableContainer {
         }
     }
 
+    discard() {
+        if(!this.isEmpty()) {
+            if(this._card.parent)
+                this._card.parent.removeChild(this._card);
+            this._card.destroy();
+        }
+        if(this._locked)this.setEvents();
+        this._locked = false;
+    }
+
     unlock() {
         this.setEvents();
         this._locked = false;

+ 23 - 1
src/Game/views/buildings/Board.js

@@ -6,6 +6,7 @@ import GuiableContainer from '../../../helpers/Guiable';
 import CardHolder from '../base/CardHolder';
 // import CollectionHolder from '../base/CollectionHolder';
 import Injector from '../../services/Injector';
+import Text from '../misc/Text';
 
 class BoardHandler extends GuiableContainer{
     constructor(props) {
@@ -62,6 +63,21 @@ class BoardHandler extends GuiableContainer{
         this.holders.forEach((item) => item.parentLayer = Injector.getByName('TopLayer'));
         this.holders.forEach((item) => item.lockable());
         this.holders.forEach((item) => this.addChild(item));
+
+        this.score = new Text({GameLayer, x: 350, y: 0, text: '0 - 0'});
+        this.addChild(this.score);
+    }
+
+    updateScore() {
+        let score = this.holders.reduce((a,b) => {
+            if(!b.isEmpty()){
+                let card = b.getCard();
+                a[card.team]++;
+            }
+            return a;
+        }, ([0,0]) );
+        this.score.setText(`${score[0]} - ${score[1]}`);
+
     }
 
     updateTeam(position, team) {
@@ -70,7 +86,7 @@ class BoardHandler extends GuiableContainer{
         }
     }
 
-    isEmpty(x) { return !this.holders[x]._locked; }
+    isEmpty(x) { return this.holders[x].isEmpty(); }
 
     getCard(x,y) {
         return this.holders[3*y+x].getCard();
@@ -82,6 +98,12 @@ class BoardHandler extends GuiableContainer{
         }
     }
 
+    clear() {
+        this.holders.forEach((h) => {
+            h.discard();
+        })
+    }
+
     onClick(fn) {
         this.sprite.on('pointerdown', (e) => fn(e));
     }

+ 31 - 0
src/Game/views/buildings/Deck.js

@@ -4,6 +4,7 @@
 import GuiableContainer from '../../../helpers/Guiable';
 // import Deck from '../../assets/deck';
 import CardHolder from '../base/CardHolder';
+import Card from '../base/Card';
 
 class DeckHandler extends GuiableContainer{
     constructor(props) {
@@ -35,6 +36,8 @@ class DeckHandler extends GuiableContainer{
             GameLayer
         } = props;
         
+        this.GameLayer = GameLayer;
+
         let DeckScale = 0.35;
         this.cards = [];
 
@@ -47,6 +50,34 @@ class DeckHandler extends GuiableContainer{
         this.cards.forEach((c) => this.addChild(c));
     }
 
+    draw() {
+        for(var i=0;i<5;i++) {
+            if(!this.getHolder(i).isEmpty())continue;
+            let rn = parseInt((Math.random()*1000) % 6, 10);
+            let card = new Card({GameLayer: this.GameLayer, id:rn});
+            let t = i;
+            this.getHolder(t).occupy(card);
+            // setTimeout(() => ) , 100);
+            this.addChild(card);
+        }
+    }
+
+    lock() {
+        this.cards.forEach((c,i) => {
+            if(!c.isEmpty()){
+                c.getCard().lock();
+            }
+        });
+    }
+    
+    unlock() {
+        this.cards.forEach((c,i) => {
+            if(!c.isEmpty()){
+                c.getCard().unlock();
+            }
+        });
+    }
+
     getHolder(x) {
         return this.cards[x];
     }

+ 72 - 13
src/Game/views/demo/BoardPlay.js

@@ -1,16 +1,20 @@
-import * as PIXI from 'pixi.js';
+// import * as PIXI from 'pixi.js';
 
 import Card from '../base/Card';
+import Button from '../misc/Button';
 // import Injector from '../../services/Injector';
 import BoardStage from './Board';
+import GuiableContainer from '../../../helpers/Guiable';
 
 import * as Machine from '../../game';
 console.log(Machine);
 let GameMachine = new Machine.GameMachine();
 
-class BoardPlayDemo extends PIXI.Container{
+const TURN_TIME = 2000;// ms delay for NPC 
+
+class BoardPlayDemo extends GuiableContainer{
     constructor(props) {
-        super();
+        super(props);
 
         let {GameLayer} = props;
         this.GameLayer = GameLayer;
@@ -18,26 +22,36 @@ class BoardPlayDemo extends PIXI.Container{
         this.stage = new BoardStage(props);
         this.addChild(this.stage);
 
-        for(var i=0;i<5;i++) {
-            let rn = parseInt((Math.random()*1000) % 6, 10);
-            let card = new Card({GameLayer, id:rn});
-            let t = i;
-            this.stage.deck.getHolder(t).occupy(card);
-            // setTimeout(() => ) , 100);
-            this.addChild(card);
-        }
+        this.stage.deck.draw();
 
         this.stage.board.onCardPlaced = (p,c) => this.moveOnMachine(p,c);
 
         document.onkeypress = (e) => {
             e = e || window.event;
-            if (e.keyCode === '80') {
+            if (e.keyCode === 80 || e.keyCode === 112) {
                 if(this.freeSlots.includes(1))
                     this.NPCMove();
             }
+            if (e.keyCode === 99) {
+                this.stage.board.clear();
+                this.freeSlots = [1,1,1, 1,1,1 ,1,1,1];
+            }
+            if (e.keyCode === 100) {
+                this.stage.deck.draw();
+            }
         };
 
         this.freeSlots = [1,1,1, 1,1,1 ,1,1,1];
+
+
+        this.addUI(props);
+
+        // Gui ///////////////////////////
+
+        this.addFolder('BoardPlayDemo');
+        this.addToFolder('BoardPlayDemo', this, 'saveState');
+        this.addToFolder('BoardPlayDemo', this, 'loadState');
+        /////////////////////////////////
     }
 
     moveOnMachine(position, card) {
@@ -52,9 +66,12 @@ class BoardPlayDemo extends PIXI.Container{
 
         // Play NPC
         if( card.team === 0 ) {
+            this.stage.deck.lock();
             if(this.freeSlots.includes(1))
-                    this.NPCMove();
+                    setTimeout( () => this.NPCMove(), TURN_TIME);
         }
+
+        this.stage.board.updateScore();
     }
 
     NPCMove() {
@@ -68,6 +85,48 @@ class BoardPlayDemo extends PIXI.Container{
         let cc = new Card({GameLayer:this.GameLayer, id:cid, team: 1});
         this.addChild(cc);
         this.stage.board.holders[pos].occupy(cc);
+
+        this.stage.deck.unlock();
+    }
+
+    addUI(props) {
+        let clearButton = new Button({GameLayer: this.GameLayer, Text: { text: 'Clear Board'}, x: 150, y: 200});
+        clearButton.scale.set(0.6);
+        this.addChild(clearButton.onClick(() => {
+                this.stage.board.clear();
+                this.freeSlots = [1,1,1, 1,1,1 ,1,1,1];
+        }));
+        let drawButton = new Button({GameLayer: this.GameLayer, Text: { text: 'Draw Cards'}, x: 150, y: 300});
+        drawButton.scale.set(0.6);
+        this.addChild(drawButton.onClick(() => {
+                this.stage.deck.draw();
+        }));
+    }
+
+
+
+    saveState = () => {
+        let state = GameMachine.save();
+        alert(JSON.stringify({ state: state, freeSlots: this.freeSlots}));
+    }
+
+    loadState = () => {
+        var loadJSON = prompt("Enter load info...", "");
+        
+        let jsonData = null;
+        try { 
+            jsonData = JSON.parse(loadJSON);
+        } catch (e) {
+            alert("Error parsing input data!");
+        }
+        let {freeSlots, ...restState} = jsonData;
+        this.freeSlots = freeSlots;
+        GameMachine.load(restState);
+        this.sync();
+    }
+
+    sync() {
+
     }
 
     _kill = () => {}

+ 1 - 0
src/Game/views/misc/Button.js

@@ -59,6 +59,7 @@ class Button extends GuiableContainer{
 
     onClick(fn) {
         this.sprite.on('pointerdown', (e) => fn(e));
+        return this;
     }