From c34013313efce85fbfb5b0f9d90963ea661fcd82 Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sat, 16 Apr 2016 08:05:45 -0700 Subject: [PATCH] Movement and munching updated to use redux. --- js/app/Constants.js | 21 +++++++++++-- js/app/Creators.js | 29 ++++++++++++++++-- js/app/Reducers.js | 54 +++++++++++++++++++++++++++++++--- js/app/Settings.js | 4 +++ js/board/Board.js | 17 +++-------- js/board/Grid.js | 49 ++++++++++++------------------- js/board/Message.js | 21 ++++++------- js/board/Muncher.js | 68 ++++++++++++++++++++++++++++++++++++------- js/board/Scorebar.js | 17 +++++------ js/board/Values.js | 2 +- js/index.js | 5 +++- js/welcome/NewGame.js | 26 ++++++++++++----- js/welcome/Welcome.js | 9 +++--- 13 files changed, 224 insertions(+), 98 deletions(-) create mode 100644 js/app/Settings.js diff --git a/js/app/Constants.js b/js/app/Constants.js index ddecf67..34a2744 100644 --- a/js/app/Constants.js +++ b/js/app/Constants.js @@ -1,8 +1,23 @@ export const MODE = { WELCOME: 'WELCOME', - BOARD: 'BOARD' + BOARD: 'BOARD', + NEXT: 'NEXT' }; -export const ACTIONS = { - NEXT: 'NEXT' +export const BLINK = { + TOGGLE: 'TOGGLE' +}; + +export const VALUES = { + FOO: 'FOO', + GENERATE: 'GENERATE', + UPDATE: 'UPDATE' +}; + +export const MUNCHER = { + MOVE: 'MOVE', + LEFT: 'LEFT', + RIGHT: 'RIGHT', + UP: 'UP', + DOWN: 'DOWN' }; diff --git a/js/app/Creators.js b/js/app/Creators.js index cf1f0d0..ee73a7e 100644 --- a/js/app/Creators.js +++ b/js/app/Creators.js @@ -1,4 +1,29 @@ -import { ACTIONS } from './Constants'; +import { MODE, BLINK, VALUES, MUNCHER } from './Constants'; export const nextMode = - () => ({ type: ACTIONS.NEXT }); + () => ({ type: MODE.NEXT }); + +export const toggleBlink = + () => ({ type: BLINK.TOGGLE }); + +export const generateValues = + (count, level) => ({ + type: VALUES.FOO, + action: VALUES.GENERATE, + count: count, + level: level + }); + +export const updateValues = + (i, level) => ({ + type: VALUES.FOO, + action: VALUES.UPDATE, + index: i, + level: level + }); + +export const moveMuncher = + (direction) => ({ + type: MUNCHER.MOVE, + direction: direction + }); diff --git a/js/app/Reducers.js b/js/app/Reducers.js index f7fc38d..0230129 100644 --- a/js/app/Reducers.js +++ b/js/app/Reducers.js @@ -1,7 +1,10 @@ -import { MODE, ACTIONS } from './Constants.js'; +import { MODE, VALUES, BLINK, MUNCHER } from './Constants.js'; + +import { Values } from '../board/Values'; +import { GRID } from './Settings'; export const modeReducer = (state = MODE.WELCOME, action) => { - if (action.type === ACTIONS.NEXT) { + if (action.type === MODE.NEXT) { switch (state) { case MODE.BOARD: return MODE.WELCOME; @@ -9,7 +12,50 @@ export const modeReducer = (state = MODE.WELCOME, action) => { return MODE.BOARD; }; } - else { - return MODE.WELCOME; + + return MODE.BOARD; +}; + +export const blinkReducer = (state = false, action) => { + if (action.type === BLINK.TOGGLE) { + return (state ? false : true); } + + return state; }; + +export const valuesReducer = (state = [], action) => { + if (action.type === VALUES.FOO) { + switch (action.action) { + case VALUES.GENERATE: + return Values.generate(action.count, action.level); + case VALUES.UPDATE: + const valid = Values.validate(state[action.index], action.level); + const results = state.slice(0); + if (valid) { + results[action.index] = ""; + } + return results; + } + } + + return state; +}; + +const muncherInitialState = { x: 0, y: 0 }; +export const muncherReducer = (state = muncherInitialState, action) => { + if (action.type === MUNCHER.MOVE) { + switch (action.direction) { + case MUNCHER.LEFT: + return (state.x > 0 ? { x: state.x - 1, y: state.y } : state); + case MUNCHER.RIGHT: + return (state.x < GRID.W - 1 ? { x: state.x + 1, y: state.y } : state); + case MUNCHER.UP: + return (state.y > 0 ? { x: state.x, y: state.y - 1 } : state); + case MUNCHER.DOWN: + return (state.y < GRID.H - 1 ? { x: state.x, y: state.y + 1 } : state); + }; + } + + return state; + }; diff --git a/js/app/Settings.js b/js/app/Settings.js new file mode 100644 index 0000000..d9e8fb5 --- /dev/null +++ b/js/app/Settings.js @@ -0,0 +1,4 @@ +export const GRID = { + W: 3, + H: 3 +} diff --git a/js/board/Board.js b/js/board/Board.js index f0ebc2c..5afd137 100644 --- a/js/board/Board.js +++ b/js/board/Board.js @@ -6,24 +6,15 @@ import Titlebar from './Titlebar'; import Grid from './Grid'; import Message from './Message'; import Muncher from './Muncher'; -import Input from './Input'; - -module.exports = React.createClass({ - componentDidMount() { - window.addEventListener('keydown', Input.keydown.bind(this)); - }, - - componentWillUnmount() { - window.removeEventListener('keydown', Input.keydown.bind(this)); - }, +export default class Board extends Component { render() { return (
- - + +
); } -}); +}; diff --git a/js/board/Grid.js b/js/board/Grid.js index 7560431..25eb60f 100644 --- a/js/board/Grid.js +++ b/js/board/Grid.js @@ -1,19 +1,14 @@ require('../../sass/board/grid.scss'); import { Component } from 'react'; +import { connect } from 'react-redux'; import GridCell from './GridCell'; -// var Values = require('./Values'); +import * as creators from '../app/Creators'; +import { GRID } from '../app/Settings'; export default class Grid extends Component { - generateValues() { - // return Values.generate(this.props.width * this.props.height, State.level); - }; - - // getInitialState() { - // return { values: this.generateValues() }; - // }, - - componentDidMount() { + componentDidMount(n) { + this.props.dispatch(creators.generateValues(GRID.W * GRID.H, 1)); // State.subscribe('level/next', this.levelNext); }; @@ -27,34 +22,26 @@ export default class Grid extends Component { // this.setState({ values: this.generateValues() }); }; - munch(x, y) { - // var i = y * this.props.width + x; - // - // if (this.state.values[i] === "") { - // return; - // } - // - // if (Values.validate(this.state.values[i], State.level)) { - // this.state.values[i] = ""; - // this.setState({ values: this.state.values }, this.checkComplete); - // State.publish('munch/successful'); - // } - // else { - // State.publish('munch/failed', this.state.values[i]); - // } - }; - render() { + const { values, dispatch } = this.props; const cells = []; let i; - for (let x = 0; x < this.props.width; x++) { - for (let y = 0; y < this.props.height; y++) { - i = y * this.props.width + x; - // cells.push(); + for (let x = 0; x < GRID.W; x++) { + for (let y = 0; y < GRID.H; y++) { + i = y * GRID.W + x; + cells.push(); } } return (
{cells}
); }; }; + +const select = (state) => { + return { + values: state.values + } +}; + +export default connect(select)(Grid); diff --git a/js/board/Message.js b/js/board/Message.js index b4c22fe..0891e50 100644 --- a/js/board/Message.js +++ b/js/board/Message.js @@ -62,21 +62,18 @@ export default class Message extends Component { }; render() { - var classname = ['message']; - + var classname = ['message', 'hidden']; + const state = { message1: 'foo', message2: 'bar' }; // if (this.state.hidden === true) { // classname.push('hidden'); // } - return (
message
); - - - // return ( - //
- // {this.state.message1} - //
- // {this.state.message2} - //
- // ); + return ( +
+ {state.message1} +
+ {state.message2} +
+ ); }; }; diff --git a/js/board/Muncher.js b/js/board/Muncher.js index a26cbbc..e794ff7 100644 --- a/js/board/Muncher.js +++ b/js/board/Muncher.js @@ -1,21 +1,69 @@ require('../../sass/board/muncher.scss'); import { Component } from 'react'; +import { connect } from 'react-redux'; +import { MUNCHER } from '../app/Constants'; +import * as creators from '../app/Creators'; -export default class Muncher extends Component{ - // getInitialState() { - // return { - // x: 0, - // y: 0 - // }; - // }, +let listener = null; + +export class Muncher extends Component { + keydown(e) { + const x = this.props.x; + const y = this.props.y; + + switch (e.keyCode) { + case 32: + console.warn('munch (leave this here until sure event listener has been removed'); + this.props.dispatch(creators.updateValues(0, 0)); + // var i = y * this.props.width + x; + // + // this.setState({ values: this.state.values }, this.checkComplete); + // State.publish('munch/successful'); + // } + // else { + // State.publish('munch/failed', this.state.values[i]); + // } + break; + + case 37: + this.props.dispatch(creators.moveMuncher(MUNCHER.LEFT)); + break; + case 38: + this.props.dispatch(creators.moveMuncher(MUNCHER.UP)); + break; + case 39: + this.props.dispatch(creators.moveMuncher(MUNCHER.RIGHT)); + break; + case 40: + this.props.dispatch(creators.moveMuncher(MUNCHER.DOWN)); + break; + } + }; + + componentDidMount() { + listener = this.keydown.bind(this); + window.addEventListener('keydown', listener); + }; + + componentWillUnmount() { + window.removeEventListener('keydown', listener); + }; render() { - // const classname = ['muncher', 'x' + this.state.x, 'y' + this.state.y]; + const classname = ['muncher', 'x' + this.props.x, 'y' + this.props.y]; return ( -
- //
+
); }; }; + +const select = (state) => { + return { + x: state.muncher.x, + y: state.muncher.y + } +}; + +export default connect(select)(Muncher); diff --git a/js/board/Scorebar.js b/js/board/Scorebar.js index 79abf1a..b2f6540 100644 --- a/js/board/Scorebar.js +++ b/js/board/Scorebar.js @@ -28,15 +28,14 @@ export default class Scorebar extends Component { render() { var lives = []; - // for (var i = 0; i < this.state.lives; i++) { - // lives.push(
); - // } + for (var i = 0; i < 3; i++) { + lives.push(
); + } - // return (
- //
{this.state.currentScore}
- //
{this.state.highScore}
- //
{lives}
- //
); - return

Scorebar

; + return (
+
0
+
0
+
{lives}
+
); }; }; diff --git a/js/board/Values.js b/js/board/Values.js index b769a4c..fc56664 100644 --- a/js/board/Values.js +++ b/js/board/Values.js @@ -1,4 +1,4 @@ -module.exports = { +export const Values = { // Anagrams, multiples, equality generate(n) { var values = []; diff --git a/js/index.js b/js/index.js index a5b79eb..e09a359 100644 --- a/js/index.js +++ b/js/index.js @@ -8,7 +8,10 @@ import App from './app/App'; import * as reducers from './app/Reducers'; const combinedReducers = combineReducers({ - mode: reducers.modeReducer + mode: reducers.modeReducer, + blink: reducers.blinkReducer, + values: reducers.valuesReducer, + muncher: reducers.muncherReducer }); const store = createStore(combinedReducers); diff --git a/js/welcome/NewGame.js b/js/welcome/NewGame.js index 059638a..a469fdb 100644 --- a/js/welcome/NewGame.js +++ b/js/welcome/NewGame.js @@ -1,16 +1,18 @@ import { Component } from 'react'; +import { connect } from 'react-redux'; +import * as creators from '../app/Creators.js'; -const blinkTimer = null; +let blinkTimer = null; const toggleTimeout = function() { - //var hidden = this.state.hidden; which was false - //this.setState({ hidden: !hidden }); - //blinkTimer = setTimeout(toggleTimeout.bind(this), 600); + var hidden = this.props.blink; + this.props.dispatch(creators.toggleBlink()); + blinkTimer = setTimeout(toggleTimeout.bind(this), 600); }; export default class NewGame extends Component { componentDidMount() { - //toggleTimeout.call(this); + toggleTimeout.call(this); }; componentWillUnmount() { @@ -20,12 +22,20 @@ export default class NewGame extends Component { render() { const classname = ['newgame']; - //if (this.state.hidden === true) { - // classname.push('hidden'); - //} + if (this.props.blink === true) { + classname.push('hidden'); + } return (
Press Space Bar To Play
); }; }; + +const select = (state) => { + return { + blink: state.blink + } +}; + +export default connect(select)(NewGame); diff --git a/js/welcome/Welcome.js b/js/welcome/Welcome.js index e41a9c2..5012e29 100644 --- a/js/welcome/Welcome.js +++ b/js/welcome/Welcome.js @@ -7,21 +7,22 @@ import * as creators from '../app/Creators.js'; import NewGame from './NewGame'; import HighScores from './HighScores'; +let listener = null; + export class Welcome extends Component { handleKeydown(e) { if (e.keyCode === 32) { this.props.dispatch(creators.nextMode()); - //this.setState({ screen: 'board' }); } }; componentDidMount() { - window.addEventListener('keydown', this.handleKeydown.bind(this)); + listener = this.handleKeydown.bind(this); + window.addEventListener('keydown', listener); }; componentWillUnmount() { - console.log('need to remove listener') - // remove keydown listener + window.removeEventListener('keydown', listener); }; render() {