From 2cb38f2681524c2fcd6e15cf13cd6d1ce8e672f7 Mon Sep 17 00:00:00 2001 From: Lang Date: Sat, 19 Nov 2016 12:09:05 +0100 Subject: [PATCH] show left mines after end #2 && reduce network traffic && better active field checking method --- .../public/images/bg-left-mine-outbg.png | Bin 0 -> 18172 bytes .../Resources/public/js/mine-seeker/app.js | 63 +++--- .../js/mine-seeker/grid/grid-control.js | 214 ++++++++++-------- .../public/js/mine-seeker/grid/grid-field.js | 3 +- 4 files changed, 154 insertions(+), 126 deletions(-) create mode 100644 src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png diff --git a/src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png b/src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png new file mode 100644 index 0000000000000000000000000000000000000000..77cc2b5cbb07e496257e3371b2655bd85710079c GIT binary patch literal 18172 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 literal 0 HcmV?d00001 diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js index bcb148e..66261ca 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js @@ -28,19 +28,25 @@ class MineSeeker extends React.Component { return text; } - /** game end control */ + /** THE END */ makeGameEndIfItEnds(bluePoints, redPoints) { var redWins = redPoints > 2, blueWins = bluePoints > 2; if (redWins || blueWins) { + this.refs.gridControl.state.sound.won.play(); + this.refs.gridControl.setState({ overlay: true, overlayTitle: (redWins ? 'Red' : 'Blue') + " wins the game!", overlaySubTitle: "Play again!" }); - this.refs.gridControl.state.sound.won.play(); + this.refs.gridControl.showLeftMines(); + + this.refs.gridControl.refs.userControl.setState({ activePlayer: false}); + this.refs.gridControl.refs.userControl.refs.red.setState({ active: false }); + this.refs.gridControl.refs.userControl.refs.blue.setState({ active: false }); } } @@ -107,7 +113,7 @@ class MineSeeker extends React.Component { this.refs.gridControl.refs.userControl.setState({bombSelected: payload.data.bomb}); this.refs.gridControl.stepEvent(payload.data.coords); - /** End-game control */ + /** THE END */ this.makeGameEndIfItEnds( this.refs.gridControl.refs.userControl.refs.blue.state.mines, this.refs.gridControl.refs.userControl.refs.red.state.mines @@ -159,33 +165,36 @@ class MineSeeker extends React.Component { onClick(coords) { var activePlayer = this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red'; - /** Player step and it is the current player */ - if (activePlayer === this.refs.gridControl.state.webPlayer) { - this.refs.gridControl.stepEvent(coords); + /** if the clicked field is NEVER CLICKED */ + if (this.refs.gridControl.checkFieldHasBeenNeverClicked(coords[0], coords[1])) { + /** Player step and it is the current player */ + if (activePlayer === this.refs.gridControl.state.webPlayer) { + this.refs.gridControl.stepEvent(coords); - var mineCache = this.refs.gridControl.state.foundUserMineCache, - redPoints = this.refs.gridControl.refs.userControl.refs.red.state.mines + ( - this.refs.gridControl.refs.userControl.refs.red.state.active - ? mineCache - : 0 - ), - bluePoints = this.refs.gridControl.refs.userControl.refs.blue.state.mines + ( - this.refs.gridControl.refs.userControl.refs.blue.state.active - ? mineCache - : 0 - ); + var mineCache = this.refs.gridControl.state.foundUserMineCache, + redPoints = this.refs.gridControl.refs.userControl.refs.red.state.mines + ( + this.refs.gridControl.refs.userControl.refs.red.state.active + ? mineCache + : 0 + ), + bluePoints = this.refs.gridControl.refs.userControl.refs.blue.state.mines + ( + this.refs.gridControl.refs.userControl.refs.blue.state.active + ? mineCache + : 0 + ); - /** End-game control */ - this.makeGameEndIfItEnds(bluePoints, redPoints); + /** THE END */ + this.makeGameEndIfItEnds(bluePoints, redPoints); - this.state.session - .publish(this.state.channel, { - 'coords': coords, - 'player': activePlayer, - 'bomb': this.refs.gridControl.refs.userControl.state.bombSelected, - 'redPoints': redPoints, - 'bluePoints': bluePoints - }); + this.state.session + .publish(this.state.channel, { + 'coords': coords, + 'player': activePlayer, + 'bomb': this.refs.gridControl.refs.userControl.state.bombSelected, + 'redPoints': redPoints, + 'bluePoints': bluePoints + }); + } } } diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js index f070877..45e862e 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js @@ -47,6 +47,10 @@ class GridControl extends React.Component { return typeof this.state.grid[row] !== 'undefined' && typeof this.state.grid[row][col] !== 'undefined' && this.state.grid[row][col] !== 'm'; } + checkFieldHasBeenNeverClicked(row, col) { + return this.state.updatedFieldCache.indexOf(this.refString(row, col)) < 0 && !this.refs[this.refString(row, col)].state.active; + } + getBombRadius(row, col) { let isBombTargetCenter = row > 1 && row < this.state.grid.length - 2 && col > 1 && col < this.state.grid[row].length - 2; @@ -146,6 +150,20 @@ class GridControl extends React.Component { } } + showLeftMines() { + for (let i = 0, j = this.state.grid.length; i < j; i++) { + for (let k = 0, l = this.state.grid[i].length; k < l; k++) { + let currentField = this.refs[this.refString(i, k)]; + + if (this.state.grid[i][k] === 'm' && this.checkFieldHasBeenNeverClicked(i, k)) { + currentField.setState({ + currentImage: currentField.state.icons.root + currentField.state.icons.left + }); + } + } + } + } + /** set __ACTIVE__ player in the UserControl !!!! */ changePlayer(idx, max, currentObject) { var userControl = this.refs.userControl, @@ -183,7 +201,7 @@ class GridControl extends React.Component { active: true }); - if (this.state.updatedFieldCache.indexOf(this.refString(row, col)) < 0) { + if (this.checkFieldHasBeenNeverClicked(row, col)) { this.state.updatedFieldCache.push(this.refString(row, col)); } @@ -215,70 +233,67 @@ class GridControl extends React.Component { activePlayer = userControl.state.activePlayer ? 'blue' : 'red', inactivePlayer = userControl.state.activePlayer ? 'red' : 'blue'; - /** if the clicked field is NEVER CLICKED */ - if (!gridFieldControl.state.active) { - /** update LAST CLICKED grid field */ - if (!justOnFirstIteration) { - if (this.state.lastClicked[activePlayer] !== null) { - this.refs[this.refString(this.state.lastClicked[activePlayer][0], this.state.lastClicked[activePlayer][1])].setState({ - lastClickedRed: false, - lastClickedBlue: false - }); - } - } - - this.state.lastClicked[activePlayer] = [x, y]; - - /** if you found mine */ - if (currentObject === 'm') { - this.state.foundUserMineCache++; - - if (!justOnFirstIteration) { - /** set last clicked field w/ color */ - this.state.lastClicked[activePlayer] = [x, y]; - - this.state.sound[ - (userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache) > 20 - ? 'warning' - : 'mine' - ].play(); - } - - /** set current image in field */ - gridFieldControl.setState({ - currentImage: gridFieldControl.state.icons.root + gridFieldControl.state.icons.flag[activePlayer] - }); - } else { - this.state.sound.click.play(); - - /** set current image in field - WHEN it is a number */ - if (!isNaN(currentObject)) { - gridFieldControl.setState({ - currentImage: currentObject - }); - } - } - - /** - * set bombs status - we must add one mine (currentObject === 'm' ? 1 : 0) to current mine - * when it found NOW because the status is not refreshed unless the handleGridField() ends - */ - userControl.refs[activePlayer].setState({ - enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) <= userControl.refs[inactivePlayer].state.mines - }); - - userControl.refs[inactivePlayer].setState({ - enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) >= userControl.refs[inactivePlayer].state.mines - }); - - /** set-up last clicked */ - if (!justOnFirstIteration) { - gridFieldControl.setState({ - lastClickedRed: activePlayer === 'red', - lastClickedBlue: activePlayer === 'blue' + /** update LAST CLICKED grid field */ + if (!justOnFirstIteration) { + if (this.state.lastClicked[activePlayer] !== null) { + this.refs[this.refString(this.state.lastClicked[activePlayer][0], this.state.lastClicked[activePlayer][1])].setState({ + lastClickedRed: false, + lastClickedBlue: false }); } } + + this.state.lastClicked[activePlayer] = [x, y]; + + /** if you found mine */ + if (currentObject === 'm') { + this.state.foundUserMineCache++; + + if (!justOnFirstIteration) { + /** set last clicked field w/ color */ + this.state.lastClicked[activePlayer] = [x, y]; + + this.state.sound[ + (userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache) > 20 + ? 'warning' + : 'mine' + ].play(); + } + + /** set current image in field */ + gridFieldControl.setState({ + currentImage: gridFieldControl.state.icons.root + gridFieldControl.state.icons.flag[activePlayer] + }); + } else { + this.state.sound.click.play(); + + /** set current image in field - WHEN it is a number */ + if (!isNaN(currentObject)) { + gridFieldControl.setState({ + currentImage: currentObject + }); + } + } + + /** + * set bombs status - we must add one mine (currentObject === 'm' ? 1 : 0) to current mine + * when it found NOW because the status is not refreshed unless the handleGridField() ends + */ + userControl.refs[activePlayer].setState({ + enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) <= userControl.refs[inactivePlayer].state.mines + }); + + userControl.refs[inactivePlayer].setState({ + enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) >= userControl.refs[inactivePlayer].state.mines + }); + + /** set-up last clicked */ + if (!justOnFirstIteration) { + gridFieldControl.setState({ + lastClickedRed: activePlayer === 'red', + lastClickedBlue: activePlayer === 'blue' + }); + } } /** @@ -301,51 +316,54 @@ class GridControl extends React.Component { * @param coords */ stepEvent(coords) { - var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red'; + /** if the clicked field is NEVER CLICKED */ + if (this.checkFieldHasBeenNeverClicked(coords[0], coords[1])) { + var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red'; - this.state.foundUserMineCache = 0; - this.state.playBomb = true; + this.state.foundUserMineCache = 0; + this.state.playBomb = true; - /** Show elements */ - if (this.refs.userControl.state.bombSelected) { - this.state.sound.bomb.play(); + /** Show elements */ + if (this.refs.userControl.state.bombSelected) { + this.state.sound.bomb.play(); - var bombRadius = this.getBombRadius(coords[0], coords[1]); - for (var i = 0, j = bombRadius.length; i < j; i++) { - this.show(bombRadius[i][0], bombRadius[i][1], i, j); + var bombRadius = this.getBombRadius(coords[0], coords[1]); + for (var i = 0, j = bombRadius.length; i < j; i++) { + this.show(bombRadius[i][0], bombRadius[i][1], i, j); + } + + /** remove BOMB from activePlayer */ + this.refs.userControl.refs[activePlayer].setState({ + haveBomb: false + }); + } else { + this.show(coords[0], coords[1]); } - /** remove BOMB from activePlayer */ - this.refs.userControl.refs[activePlayer].setState({ - haveBomb: false - }); - } else { - this.show(coords[0], coords[1]); - } + /** Mine score handling */ + if (this.state.foundUserMineCache) { + this.refs.userControl.setState({ + mines: this.refs.userControl.state.mines - this.state.foundUserMineCache, + foundMines: true + }, () => { + /** because of CSS animation in .found-mine */ + setTimeout(() => this.refs.userControl.setState({foundMines: false}), 500); - /** Mine score handling */ - if (this.state.foundUserMineCache) { - this.refs.userControl.setState({ - mines: this.refs.userControl.state.mines - this.state.foundUserMineCache, - foundMines: true - }, () => { - /** because of CSS animation in .found-mine */ - setTimeout(() => this.refs.userControl.setState({foundMines: false}), 500); - - /** add the found mines to the active Player */ - this.refs.userControl.refs[activePlayer].setState({ - mines: this.refs.userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache + /** add the found mines to the active Player */ + this.refs.userControl.refs[activePlayer].setState({ + mines: this.refs.userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache + }); }); - }); - } + } - /** Reset BOMB status */ - if (this.refs.userControl.state.bombSelected) { - /** reset bomb selected status */ - this.refs.userControl.setState({bombSelected: false}); + /** Reset BOMB status */ + if (this.refs.userControl.state.bombSelected) { + /** reset bomb selected status */ + this.refs.userControl.setState({bombSelected: false}); - /** clear cache, reset symbols */ - this.bombClear(); + /** clear cache, reset symbols */ + this.bombClear(); + } } } diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js index ecd0a39..a2bb5db 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js @@ -27,7 +27,8 @@ class GridField extends React.Component { lastRed: 'bg-last-red-outbg.png', crosshair: 'bg-target-outbg.png', crosshairBomb: 'bg-target-bomb-outbg.png' - } + }, + left: 'bg-left-mine-outbg.png' } }; }