Nikatlas 6 tahun lalu
induk
melakukan
2d120cfdfc

+ 1 - 0
.gitignore

@@ -15,6 +15,7 @@
 .env.development.local
 .env.test.local
 .env.production.local
+.idea
 
 npm-debug.log*
 yarn-debug.log*

File diff ditekan karena terlalu besar
+ 343 - 233
package-lock.json


+ 2 - 1
package.json

@@ -13,8 +13,9 @@
     "pixi.js": "^4.6.2",
     "react": "^16.2.0",
     "react-dom": "^16.2.0",
-    "react-scripts": "1.0.17",
+    "react-scripts": "^1.1.4",
     "reactstrap": "^5.0.0-alpha.4",
+    "socket.io-client": "^2.1.1",
     "wolfy87-eventemitter": "^5.2.4"
   },
   "scripts": {

+ 1 - 0
src/Game/game/machine/Card.js

@@ -6,6 +6,7 @@ let deck = dg();
 class Card {
     constructor(id = 0) {
         this.attack = deck[id];
+        this.id = id;
     }
 
     setAttack(attack) {

+ 1 - 1
src/Game/game/machine/GameMachine.js

@@ -210,7 +210,7 @@ class Board {
     }
 
     isEmpty(position) {
-        return !!this.data[position];
+        return !this.data[position];
     }
 
     save() {

+ 3 - 1
src/Game/game/machine/GameMachine.test.js

@@ -1,7 +1,8 @@
-let GameMachine = require('./GameMachine').GameMachine;
+let GameMachine = require('./GameMachine');
 let Moves = require('./GameMoves');
 let Card = require('./Card');
 
+console.log(GameMachine);
 var mac = new GameMachine();
 
 
@@ -37,4 +38,5 @@ mac.runMove(nnmove);
 mac.state.board.debug();
 mac.runMove(nnnmove);
 mac.state.board.debug();
+console.log(mac.state.board.data);
 

+ 35 - 27
src/Game/game/machine/GameMoves.js

@@ -1,38 +1,46 @@
-class GameMove {	
-	constructor(type, data) {
-		this.type = type;
-		this.data = data;
-	}
-	verify() {}
-	performMove() {}
-};
+class GameMove {    
+    constructor(type, data) {
+        this.type = type;
+        this.data = data;
+    }
+    verify() {}
+    performMove() {}
+}
 GameMove.TYPES = {
-	PLACE: 1,
-	PLACE_AND_REVEAL: 2,
-	SELECT_CARDS: 0
+    PLACE: 1,
+    PLACE_AND_REVEAL: 2,
+    SELECT_CARDS: 0
 };
 
 
 class PlaceMove extends GameMove {
-	constructor(card, position, player) {
-		super(GameMove.TYPES.PLACE, {});
-		this.position = position;
-		this.card = card;
-		this.player = player;
-	}
-	verify(state) {
-		if (state.board.isEmpty(this.position)) {
-			throw Error('Not a valid move, there is already a card there!');
-		}
+    constructor(card, position, player) {
+        super(GameMove.TYPES.PLACE, {});
+        this.position = position;
+        this.card = card;
+        this.player = player;
+    }
+    verify(state) {
+        if (state.board.isEmpty(this.position)) {
+            throw Error('Not a valid move, there is already a card there!');
+        }
+
+        return true;
+    }
 
-		return true;
-	}
+    performMove(board) {
+        if(!board.isEmpty(this.position)) {
+            console.log(this.position);
+            console.log('Board');
+            console.log(board);
+            
 
-	performMove(board) {
-		board.putCard(this.card, this.position, this.player);
-	}
+            throw ('Tried to place a card on occupied holder!');
+        }
+        board.putCard(this.card, this.position, this.player);
+    }
 }
 
 module.exports = {
-	PlaceMove
+    PlaceMove
 };

+ 54 - 0
src/Game/services/GameService.js

@@ -0,0 +1,54 @@
+import Game from '../game/';
+import SocketService from '../services/SocketService';
+
+class GameService {
+    constructor() {
+        this.state = {
+            cards: [],
+            salts: [],
+            setup: {}
+        };
+        this.stack = [];
+
+        this.__enablePersistence = true;
+    }
+
+    init(game) {
+        this.GameMachine = new Game.GameMachine();
+        this.stack = [];
+        this.state.cards = game.cards.playerCardsArray;
+        this.state.salts = game.cards.saltArray;
+        this.state.setup = game.setup;
+
+        if(this.onInit) this.onInit();
+        SocketService.on('move', (data) => this.move(data));
+        SocketService.on('result', (data) => this.end(data));
+    }
+
+    move(data) {
+        // Game Machine perform internal Move
+
+        let {cardid, position, player} = data;
+
+        const card = new Game.Card(cardid);
+        const move = new Game.GameMoves.PlaceMove(card, position, player);
+        try{
+            this.GameMachine.runMove(move);
+        } catch(e) {
+            console.log(e);
+            throw e;
+        }
+        // require UI Update where a card is placed and Board updated
+        if(this.onUpdate) this.onUpdate(1);
+    }
+
+    end(data) {
+
+
+
+        SocketService.close();
+    }
+
+}
+
+export default new GameService();

+ 27 - 27
src/Game/services/Net.js

@@ -2,41 +2,41 @@ import UserService from './UserService';
 
 function checkIt(resp) {
     if ( Math.parseInt(resp.status / 100, 10) === 2) {
-	    return resp;
-	} else {
-  		throw resp;
-	}
+        return resp;
+    } else {
+        throw resp;
+    }
 }
 
 function catchIt(err) {
-	if ( Math.parseInt(err.status / 500, 10) === 5 ){
-		return err;
-	} else {
-		throw err;
-	}
+    if ( Math.parseInt(err.status / 500, 10) === 5 ){
+        return err;
+    } else {
+        throw err;
+    }
 }
 
 class Net {
-	constructor(baseURL) {
-		this.baseURL = baseURL;
-	}
+    constructor(baseURL) {
+        this.baseURL = baseURL;
+    }
 
-	get(url) {
-		url = this.baseURL + url;
-		return window.fetch(url, {method: 'GET'}).then(checkIt).catch(catchIt);
-	}
+    get(url) {
+        url = this.baseURL + url;
+        return window.fetch(url, {method: 'GET'}).then(checkIt).catch(catchIt);
+    }
 
-	post(url, body) {
-		let urb = this.baseURL + url;
-		return window.fetch(urb, {
-			method: 'POST',
-			headers: {
-				'Content-Type':'application/json',
-				'Token' : UserService.getToken() || ''
-			},
-			body: JSON.stringify(body)
-		});
-	}
+    post(url, body) {
+        let urb = this.baseURL + url;
+        return window.fetch(urb, {
+            method: 'POST',
+            headers: {
+                'Content-Type':'application/json',
+                'Token' : UserService.getToken() || ''
+            },
+            body: JSON.stringify(body)
+        });
+    }
 }
 
 export default new Net('/api/');

+ 19 - 0
src/Game/services/SocketService.js

@@ -0,0 +1,19 @@
+import Net from './Net.js';
+import openSocket from 'socket.io-client';
+class SocketService {
+
+    constructor() {
+    }
+    openSocket(channel) {
+        if(this.socket)
+            this.socket.disconnect();
+        this.socket = openSocket('http://localhost:3555/' + channel);
+        this.on = this.socket.on.bind(this.socket);
+        this.emit = this.socket.emit.bind(this.socket);
+        this.close = this.socket.close.bind(this.socket);
+    }
+
+
+}
+
+export default new SocketService();

+ 82 - 63
src/Game/services/UserService.js

@@ -2,80 +2,99 @@ import Net from './Net.js';
 
 
 class UserService {
+    constructor() {
+        this.__enablePeristence = true;
+        this.__load();
+    }
 
-	constructor() {
-		this.__enablePeristence = true;
-		let data = JSON.parse(localStorage.getItem('user') || {});
-		let { 
-			username,
-			token
-		} = data;
-		this.username = username;
-		this.token = token;
-	}
+    register(username, password) {
+        let data = {
+            username,
+            password
+        };
+        return Net.post('users/register', data)
+            .then((res) => res.json());
+    }
 
-	login(username, password) {
-		let data = {
-			username,
-			password
-		};
-		return Net.post('users/login', data)
-				  .then((res) => res.json())
-				  .then((response) => {
-				  	return this._setUser(response);
-				  });
-	}
+    login(username, password) {
+        let data = {
+            username,
+            password
+        };
+        return Net.post('users/login', data)
+            .then((res) => res.json())
+            .then((response) => {
+                return this._setUser(response);
+            });
+    }
 
-	logout() {
-		// To request Token removal
-		this._unsetUser();
-	}
+    logout() {
+        // To request Token removal
+        this._unsetUser();
+    }
 
-	getUsername() {
-		return this.username;
-	}
+    getUsername() {
+        return this.username;
+    }
 
-	getToken() {
-		return this.token;
-	}
+    getToken() {
+        return this.token;
+    }
 
-	_unsetUser() {
-		// clear this singleton
-		this.username = null;
-		this.token = null;
-		this.__persistence();
-	}
-	
-	_setUser(data) {
-		if(!this._checkDataIntegrity(data)) {
-			throw data;
-		}
+    _unsetUser() {
+        // clear this singleton
+        this.username = null;
+        this.token = null;
+        this.__persistence();
+    }
+    
+    _setUser(data) {
+        if(!this._checkDataIntegrity(data)) {
+            throw data;
+        }
 
-		let {
-			username,
-			token
-		} = data;
+        let {
+            username,
+            token
+        } = data;
 
-		this.username = username;
-		this.token = token;
+        this.username = username;
+        this.token = token;
 
-		this.__persistence();
-		return data;
-	}
+        this.__persistence();
+        return data;
+    }
 
-	__persistence() {
-		if(!this.__enablePeristence)return;
-		localStorage.setItem('user', JSON.stringify({
-			username: this.username,
-			token   : this.token
-		}));
-	}
+    __persistence() {
+        if(!this.__enablePeristence)return;
+        localStorage.setItem('user', JSON.stringify({
+            username: this.username,
+            token   : this.token
+        }));
+    }
+    
+    __load() {
+        if(!this.__enablePeristence)return;
+        let user = localStorage.getItem('user');
+        try { 
+            let json = JSON.parse(user);
+            this.username = json.username;
+            this.token = json.token;
+        } catch (e) {
+            this._unsetUser();
+            console.log(e);
+        }
+    }
 
-	_checkDataIntegrity(data) {
-		let tkn = data.token && data.token.length;
-		let username = data.username && data.username.length;
-		return tkn && username;
-	}
+    isLogged() {
+        return this.username && this.username.length && this.token && this.token.length;
+    }
+
+    _checkDataIntegrity(data) {
+        let tkn = data.token && data.token.length;
+        let username = data.username && data.username.length;
+        return tkn && username;
+    }
 }
 
 export default new UserService();

+ 3 - 2
src/Game/views/base/Card.js

@@ -127,10 +127,11 @@ class Card extends GuiableContainer{
     }
 
     loadCard(number) {
+        const mod = 4;
         number = parseInt(number+0.5, 10);
         this.card = number;
-        this.imageURL = Deck.Filenames[number];
-        this.sprite.texture = Deck.Textures[number];
+        this.imageURL = Deck.Filenames[number%mod];
+        this.sprite.texture = Deck.Textures[number%mod];
 
         this.machineCard = new Machine.Card(number);
         this.machineCard.attack.forEach((a,i) => this.numbers[i].setText(a));

+ 17 - 2
src/Game/views/buildings/Board.js

@@ -7,6 +7,7 @@ import CardHolder from '../base/CardHolder';
 // import CollectionHolder from '../base/CollectionHolder';
 import Injector from '../../services/Injector';
 import Text from '../misc/Text';
+import Card from '../base/Card';
 
 class BoardHandler extends GuiableContainer{
     constructor(props) {
@@ -47,8 +48,6 @@ class BoardHandler extends GuiableContainer{
         bg.scale.set(1.75);
         this.addChild(bg);
 
-
-
         this.holders = [];
         this.holders.push(new CardHolder({GameLayer, 'x': -220, 'y': -230, team: 0, id: 4}).scaleTo(BoardScale).onDrop((c) => this.placeCard(0, c)));
         this.holders.push(new CardHolder({GameLayer, 'x': -50, 'y': -230, team: 1, id: 5}).scaleTo(BoardScale).onDrop((c) => this.placeCard(1, c)));
@@ -68,6 +67,22 @@ class BoardHandler extends GuiableContainer{
         this.addChild(this.score);
     }
 
+    sync = (board) => {
+        const owners = board.owners;
+        const data = board.data;
+
+        this.holders.forEach((holder, index) => {
+            if ( data[index] && !holder.isEmpty() ) {
+                holder.getCard().setTeam(owners[index]);
+            } else if ( data[index] ) {
+                const card = new Card({id: data[index].id});
+                this.addChild(card);
+                card.attach(holder);
+                card.setTeam(owners[index]);
+            }
+        })
+    }
+
     updateScore() {
         let score = this.holders.reduce((a,b) => {
             if(!b.isEmpty()){

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

@@ -65,6 +65,15 @@ class DeckHandler extends GuiableContainer{
         }
     }
 
+    sync(cards) {
+        if(!cards)return;
+        this.cards.forEach((holder, index) => {
+            const card = new Card({id: cards[index]});
+            this.addChild(card);
+            card.attach(holder);
+        });
+    }
+
     lock() {
         this.cards.forEach((c,i) => {
             if(!c.isEmpty()){

+ 99 - 0
src/Game/views/buildings/Menu.js

@@ -0,0 +1,99 @@
+import * as PIXI from 'pixi.js';
+import dragAndDrop from '../../../helpers/dragAndDrop';
+import GuiableContainer from '../../../helpers/Guiable';
+import Injector from '../../services/Injector';
+
+import UserService from '../../services/UserService';
+
+import Text from '../misc/Text';
+import Button from '../misc/Button';
+
+import SocketService from '../../services/SocketService';
+import GameService from '../../services/GameService';
+
+const BlueURL = '/files/assets/cards/frame_blue.png';
+const BlueImage = PIXI.Texture.fromImage(BlueURL);
+
+class Menu extends GuiableContainer{
+    constructor(props) {
+        super(props);
+        let {
+            x,
+            y
+        } = props;
+
+        // Properties Component 
+        //this.imageURL = image || getParam('imageURL');
+        this.position.set(x,y);
+
+        this.options = {
+            x: x || 0,
+            y: y || 0
+        };
+
+
+        // GUI
+        this.addFolder('Menu');
+        this.addToFolder('Menu', this.options, 'x').onFinishChange((v) => this.position.x = v);
+        this.addToFolder('Menu', this.options, 'y').onFinishChange((v) => this.position.y = v);
+        //
+        this.construct(props);
+    }
+
+    construct(props) {
+        this.parentLayer = Injector.getByName('MainLayer');
+
+        this.textSprite = new Text({text: "123", y: -345});
+        this.textSprite.setText(UserService.getUsername() + ':' + UserService.getToken());
+            
+        let play = new Button({  y:-100 , Text: {text: "Play"}});
+        play.onClick((e) => {
+            SocketService.openSocket('randomFree');
+            SocketService.on('test', () => {
+                console.log("TESTING");
+            });
+            SocketService.on('joinGame', (game) => {
+                console.log('Joining Game...');
+                console.log(game);
+                Injector.getByName('Navigator').goToGame();
+                GameService.init(game);
+            });
+        });
+
+        let collection = new Button({  y:50 , Text: {text: "Collection"}});
+        collection.onClick((e) => alert(e));
+        let logout = new Button({  y:200 , Text: {text: "Logout"}});
+        logout.onClick((e) => {
+            let nav = Injector.getByName('Navigator');
+            UserService.logout();
+            nav.go('Login');
+        });
+
+
+
+        this.addChild(play);
+        this.addChild(collection);
+        this.addChild(logout);
+        this.addChild(this.textSprite);
+    }
+
+    update = () => {
+        this.textSprite.setText(UserService.getUsername() + ':' + UserService.getToken());
+    }
+
+    _kill() {
+        super._kill();
+    }
+
+    getAsJSON() {
+        return {
+            component: 'base/Menu',
+            x:  this.position.x,
+            y:  this.position.y,
+            id: this.options.id,
+            team: this.options.team
+        };
+    }
+}
+
+export default Menu;

+ 21 - 11
src/Game/views/demo/Board.js

@@ -1,34 +1,44 @@
 import * as PIXI from 'pixi.js';
 
-// import Card from '../base/Card';
-// import CardHolder from '../base/CardHolder';
 import BoardHandler from '../buildings/Board';
 import DeckHandler from '../buildings/Deck';
-// import Injector from '../../services/Injector';
+import GameService from '../../services/GameService';
+import UserService from '../../services/UserService';
+import SocketService from '../../services/SocketService';
 
 class BoardDemo extends PIXI.Container{
     constructor(props) {
         super();
 
         let {GameLayer} = props;
-
-
-        // let card = new Card({GameLayer, 'x': 100, 'y': -230, team: 0, id: 4}).scaleTo(0.27);
-        // card.parentLayer = Injector.getByName('MainLayer');
-        // this.addChild(card);
         
         let board = new BoardHandler({GameLayer, 'x': -250, 'y': 0 });
         this.addChild(board);
 
-        // let holder2 = new Card({'x':200,'y':100, 's': 0.7, id: 3});
-        // this.addChild(holder2);
-
         let deck = new DeckHandler({GameLayer, 'x': 380, 'y': 0});
         this.addChild(deck);
 
         this.board = board;
         this.deck = deck;
+
+        this.board.onCardPlaced = (position, card) => {
+            const move = {
+                cardid: card.id,
+                position: position,
+                player: UserService.getUsername()
+            };
+            SocketService.emit('broadcast', move);
+        }
+
+        GameService.onInit = () => {
+            this.deck.sync(GameService.state.cards);
+        }
+
+        GameService.onUpdate = () => {
+            this.board.sync(GameService.GameMachine.state.board);
+        }
     }
+    update() {}
 
     _kill = () => {
 

+ 1 - 0
src/Game/views/demo/BoardPlay.js

@@ -125,6 +125,7 @@ class BoardPlayDemo extends GuiableContainer{
         this.sync();
     }
 
+
     sync() {
 
     }

+ 38 - 2
src/Game/views/demo/Login.js

@@ -25,11 +25,16 @@ class Login extends PIXI.Container{
         let loginBtn = new Button({GameLayer, width: 100});
         this.addChild(loginBtn);
 
+        let registerBtn = new Button({GameLayer, width: 100});
+        this.addChild(registerBtn);
+
         // Set Properties
         emailText.setText("Username/Email");
         passwordText.setText("Password");
         loginBtn.setText("Login");
         loginBtn.scaleTo(0.75);
+        registerBtn.setText("Register");
+        registerBtn.scaleTo(0.5);
 
         // Position It
         emailText.position.set	(0, -150);
@@ -37,6 +42,7 @@ class Login extends PIXI.Container{
         passwordText.position.set(0,-50);
         password.position.set 	(0,0);
         loginBtn.position.set	(0,	100);
+        registerBtn.position.set(0,	220);
 
         email.setText(UserService.username || '');
 
@@ -45,6 +51,7 @@ class Login extends PIXI.Container{
         this.password = password;
         loginBtn.onClick((e) => this.login(e));
         this.onLogin(() => alert("Logged in succesfully ! ! !"));
+        registerBtn.onClick((e) => this.register(e));
     }
 
     login() {
@@ -55,11 +62,14 @@ class Login extends PIXI.Container{
     	UserService.login(e,p)
     	.then((data) => {
             console.log(data);
-            this._onLogin();
+            if(this._onLogin)
+            	this._onLogin();
     		return true;
     	})
     	.catch((err) => {
-    		throw err;
+    		console.log(err);
+    		alert(JSON.stringify(err));
+    		//throw err;
     	});
     }
 
@@ -71,6 +81,32 @@ class Login extends PIXI.Container{
         this._onLoginFn = fn;
     }
 
+    register() {
+		let e = this.email.getValue();
+    	let p = this.password.getValue();
+
+    	// UserService Singleton to be called
+    	UserService.register(e,p)
+    	.then((data) => {
+            console.log(data);
+            this.login();
+            return true;
+    	})
+    	.catch((err) => {
+    		console.log(err);
+    		alert(JSON.stringify(err));
+    		//throw err;
+    	});
+    }
+
+
+    update = () => {
+    	if(UserService.isLogged()) {
+    		if( this._onLogin )
+    			this._onLogin();
+    	}
+    }
+
     _kill = () => {
 
     }

+ 55 - 0
src/Game/views/demo/Navigation.js

@@ -0,0 +1,55 @@
+import * as PIXI from 'pixi.js';
+import Injector from '../../services/Injector';
+
+import UserService from '../../services/UserService';
+
+import TextInput from '../misc/TextInput';
+import Text from '../misc/Text';
+import Button from '../misc/Button';
+
+import Login from './Login';
+import BoardPlay from './Board';
+import Menu from '../buildings/Menu';
+
+
+class Navigation extends PIXI.Container{
+    constructor(props) {
+        super();
+        this.props = props;
+        let {GameLayer, Gui} = props;
+
+        Injector.saveAs('Navigator',this);
+        this.routes = {
+            Login:   new Login({}),
+            Menu:    new Menu({})
+        }
+
+        this.addChild(this.routes.Login);
+
+        this.routes.Login.onLogin(() => this.go('Menu'));
+        this.current = this.routes.Login;
+        this.current.update();
+    }
+
+    go = (link) => {
+        if(!this.routes[link])return;
+        this.removeChild(this.current);
+        this.addChild(this.routes[link]);
+        this.current = this.routes[link];
+        this.current.update();
+    }
+
+    goToGame = () => {
+        console.log(this.props);
+        this.routes.Board = new BoardPlay(this.props);
+        this.go('Board');
+    }
+
+    _kill = () => {
+
+    }
+
+    getAsJSON = () => {return {component: 'demo/Navigation'}}
+}
+
+export default Navigation;

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

@@ -4,6 +4,8 @@ import { getParam } from '../../../helpers/url';
 
 import GuiableContainer from '../../../helpers/Guiable';
 
+
+
 const DefaultImageUrl = '/files/assets/ui/woodenbutton.png';
 const DefaultImage = PIXI.Texture.fromImage(DefaultImageUrl);
 
@@ -66,7 +68,7 @@ class Button extends GuiableContainer{
 
     onClick(fn) {
         this.sprite.on('pointerdown', (e) => fn(e));
-        this.sprite.on('mouseup', (e) => fn(e));
+        //this.sprite.on('mouseup', (e) => fn(e));
         return this;
     }
 

+ 8 - 0
src/Playground/Loader.js

@@ -23,6 +23,14 @@ class Loader extends PIXI.Container{
         this.gui.add(this, 'loadJSON');
 
         this.load();
+
+        document.onkeydown = (e) => {
+          var tabKey = 9;
+          if(e.keyCode == tabKey) {
+            e.preventDefault();
+            return false;
+          }
+        };
     }
 
     destroy() {

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini