diff --git a/App.js b/App.js index 91a9d74..c0be2cb 100644 --- a/App.js +++ b/App.js @@ -7,8 +7,8 @@ import Board from './components/board/board.component'; import Welcome from './components/welcome/welcome.component'; export const SETTINGS = { - GRID_WIDTH: 3, - GRID_HEIGHT: 3, + GRID_WIDTH: 6, + GRID_HEIGHT: 5, LIVES: 3 }; diff --git a/actions/board/message.actions.js b/actions/board/message.actions.js index 243b076..d8ee854 100644 --- a/actions/board/message.actions.js +++ b/actions/board/message.actions.js @@ -2,12 +2,10 @@ export const MESSAGE_ACTION = 'MESSAGE_ACTION'; export const DISPLAY = 'DISPLAY'; export const HIDE = 'HIDE'; -export const display = (line1, line2, hidden) => ({ +export const display = (message) => ({ type: MESSAGE_ACTION, action: DISPLAY, - line1: line1, - line2: line2, - hidden: hidden + message: message }); export const hide = () => ({ diff --git a/actions/board/muncher.actions.js b/actions/board/muncher.actions.js index 35d7af5..6ba10cc 100644 --- a/actions/board/muncher.actions.js +++ b/actions/board/muncher.actions.js @@ -4,6 +4,8 @@ export const RIGHT = 'RIGHT'; export const UP = 'UP'; export const DOWN = 'DOWN'; export const MUNCH = 'MUNCH'; +export const FREEZE = 'FREEZE'; +export const UNFREEZE = 'UNFREEZE'; export const moveLeft = () => ({ type: MUNCHER_ACTION, @@ -29,3 +31,13 @@ export const munch = (x, y) => ({ type: MUNCHER_ACTION, action: MUNCH }); + +export const freeze = () => ({ + type: MUNCHER_ACTION, + action: FREEZE +}); + +export const unfreeze = () => ({ + type: MUNCHER_ACTION, + action:UNFREEZE +}); diff --git a/actions/board/troggle.actions.js b/actions/board/troggle.actions.js new file mode 100644 index 0000000..bc0486e --- /dev/null +++ b/actions/board/troggle.actions.js @@ -0,0 +1,16 @@ +export const TROGGLE_ACTION = 'TROGGLE_ACTION'; +export const CREATE = 'CREATE'; +export const MOVE = 'MOVE'; + +export const create = () => ({ + type: TROGGLE_ACTION, + action: CREATE +}); + +export const move = (index, muncherX, muncherY) => ({ + type: TROGGLE_ACTION, + action: MOVE, + index: index, + muncherX: muncherX, + muncherY: muncherY +}); diff --git a/components/board/board.component.js b/components/board/board.component.js index c76977b..a077654 100644 --- a/components/board/board.component.js +++ b/components/board/board.component.js @@ -8,14 +8,16 @@ import Titlebar from './titlebar.component'; import Grid from './grid.component'; import Message from './message.component'; import Muncher from './muncher.component'; +import Troggle from './troggle.component'; import Values from '../../reducers/Values'; import { SETTINGS } from '../../App'; import * as BoardActions from '../../actions/board/board.actions'; -import * as MuncherActions from '../../actions/board/muncher.actions'; import * as ScorebarActions from '../../actions/board/scorebar.actions'; import * as MessageActions from '../../actions/board/message.actions'; +import * as MuncherActions from '../../actions/board/muncher.actions'; +import * as TroggleActions from '../../actions/board/troggle.actions'; const exclamations = [ 'Congratulations!', @@ -28,95 +30,101 @@ const exclamations = [ 'Shazam!' ]; -let muncherListener = null; -let messageListener = null; - -export default class Board extends Component { - componentDidMount(n) { - muncherListener = this.muncherKeydown.bind(this); - messageListener = this.messageKeydown.bind(this); +const troggleMoveTimers = []; +const troggleCreateTimers = []; - window.addEventListener('keydown', muncherListener); - // window.addEventListener('keydown', messageListener); +// const toggleMoveTimeout = function() { +// this.props.dispatch(TroggleActions.move()); +// }; - this.props.dispatch(BoardActions.nextLevel()); - }; +const continuations = { + muncher: null, + message: null +}; - muncherKeydown(e) { - switch (e.keyCode) { - case 32: - this.munch(); - break; +let listener = null; - case 37: - this.props.dispatch(MuncherActions.moveLeft()); - break; +export default class Board extends Component { + nextLevel() { + this.props.dispatch(BoardActions.nextLevel()); - case 38: - this.props.dispatch(MuncherActions.moveUp()); - break; + const troggleCount = 1; //Math.min(Math.ceil(this.props.board.level / 2), 5); + for (let i = 0; i < troggleCount; i++) { + this.props.dispatch(TroggleActions.create()); + troggleMoveTimers.push(setTimeout(this.moveTroggle.bind(this, i), 1000)); + } - case 39: - this.props.dispatch(MuncherActions.moveRight()); - break; + // toggleTimeout.call(this); + }; - case 40: - this.props.dispatch(MuncherActions.moveDown()); - break; - } + componentDidMount() { + listener = this.keydown.bind(this); + window.addEventListener('keydown', listener); + this.nextLevel(); }; - messageKeydown(e) { - if (e.keyCode === 32) { - window.removeEventListener('keydown', messageListener); - window.addEventListener('keydown', muncherListener); + componentWillUnmount() { + window.removeEventListener('keydown', listener); - this.props.dispatch(MessageActions.hide()); - } + // destroy all troggle timers }; - componentWillUnmount() { - window.removeEventListener('keydown', muncherListener); - window.removeEventListener('keydown', messageListener); + moveTroggle(index) { + this.props.dispatch(TroggleActions.move(index)); + clearTimeout(troggleMoveTimers[index]); + troggleMoveTimers[index] = setTimeout(this.moveTroggle.bind(this, index), 1000); }; - munch() { - const { board, muncher, dispatch } = this.props; - const index = muncher.y * SETTINGS.GRID_HEIGHT + muncher.x; + // Keydown listener for spacebar, since it is bound to munch event and + // message hide event. Couldn't find a more modular way to do this. + keydown(e) { + if (e.keyCode !== 32) { + return; + } - dispatch(MuncherActions.munch()); + if (this.props.message.hidden === false) { + this.props.dispatch(MessageActions.hide()); + this.props.dispatch(MuncherActions.unfreeze()); - if (board.values[index].valid) { - dispatch(BoardActions.hideValue(index)); - dispatch(ScorebarActions.munchSucceeded()); + if (Values.checkComplete(this.props.board.values, this.props.board.level)) { + console.warn("NEXT LEVEL") + } } else { - window.removeEventListener('keydown', muncherListener); - window.addEventListener('keydown', messageListener); - - const msg = Values.getError(board.values[index].value, board.level); - dispatch(MessageActions.display(msg, 'Press Spacebar to Continue')); - dispatch(ScorebarActions.munchFailed()); - } - - if (Values.checkComplete(this.props.board.values, board.level)) { - window.removeEventListener('keydown', muncherListener); - window.addEventListener('keydown', messageListener); - - const msg = exclamations[Math.floor(Math.random() * exclamations.length)]; - dispatch(MessageActions.display(msg, 'Press Spacebar to Continue')); - dispatch(BoardActions.nextLevel()); + const index = this.props.muncher.y * SETTINGS.GRID_HEIGHT + this.props.muncher.x + const { board, dispatch } = this.props; + + if (board.values[index].valid) { + dispatch(BoardActions.hideValue(index)); + dispatch(ScorebarActions.munchSucceeded()); + } + else { + const msg = Values.getError(board.values[index].value, board.level); + dispatch(MessageActions.display(msg)); + dispatch(ScorebarActions.munchFailed()); + dispatch(MuncherActions.freeze()); + } + + if (Values.checkComplete(this.props.board.values, board.level)) { + const msg = exclamations[Math.floor(Math.random() * exclamations.length)]; + dispatch(MessageActions.display(msg)); + } } }; render() { - const { board, muncher, message } = this.props; + const { board, message, troggles } = this.props; + const troggleElements = []; + for (let i = 0; i < troggles.length; i++) { + troggleElements.push(); + } return (
-
); }; @@ -126,7 +134,8 @@ const select = (state) => { return { board: state.board, muncher: state.muncher, - message: state.message + message: state.message, + troggles: state.troggles }; } diff --git a/components/board/grid.component.js b/components/board/grid.component.js index dba8402..4f3d6a6 100644 --- a/components/board/grid.component.js +++ b/components/board/grid.component.js @@ -11,7 +11,7 @@ export default class Grid extends Component { this.props.values.map((v, i) => { const x = i % SETTINGS.GRID_WIDTH; - const y = Math.floor(i / SETTINGS.GRID_HEIGHT); + const y = Math.floor(i / SETTINGS.GRID_WIDTH); cells.push(); }); diff --git a/components/board/message.component.js b/components/board/message.component.js index b6ce4c6..b7f47b6 100644 --- a/components/board/message.component.js +++ b/components/board/message.component.js @@ -12,9 +12,9 @@ export default class Message extends Component { return (
- {this.props.line1} + {this.props.message}
- {this.props.line2} + Press Spacebar to continue.
); }; diff --git a/components/board/muncher.component.js b/components/board/muncher.component.js index f903cc4..46d59ab 100644 --- a/components/board/muncher.component.js +++ b/components/board/muncher.component.js @@ -1,8 +1,57 @@ require('../../sass/board/muncher.scss'); import { Component } from 'react'; +import { connect } from 'react-redux'; +import * as MuncherActions from '../../actions/board/muncher.actions'; +import { SETTINGS } from '../../App'; + +let listener = null; + +export class Muncher extends Component { + componentDidMount() { + listener = this.keydown.bind(this); + window.addEventListener('keydown', listener); + }; + + componentWillUnmount() { + window.removeEventListener('keydown', listener); + }; + + keydown(e) { + if (this.props.frozen === true) { + return; + } + + const x = this.props.x; + const y = this.props.y; + + switch (e.keyCode) { + case 37: + if (x !== 0) { + this.props.dispatch(MuncherActions.moveLeft()); + } + break; + + case 38: + if (y !== 0) { + this.props.dispatch(MuncherActions.moveUp()); + } + break; + + case 39: + if (x !== SETTINGS.GRID_WIDTH - 1) { + this.props.dispatch(MuncherActions.moveRight()); + } + break; + + case 40: + if (y !== SETTINGS.GRID_HEIGHT - 1) { + this.props.dispatch(MuncherActions.moveDown()); + } + break; + } + }; -export default class Muncher extends Component { render() { const classname = ['muncher', 'x' + this.props.x, 'y' + this.props.y]; @@ -11,3 +60,9 @@ export default class Muncher extends Component { ); }; }; + +const select = (state) => { + return state.muncher; +} + +export default connect(select)(Muncher); diff --git a/components/board/troggle.component.js b/components/board/troggle.component.js new file mode 100644 index 0000000..ec6728f --- /dev/null +++ b/components/board/troggle.component.js @@ -0,0 +1,13 @@ +require('../../sass/board/troggle.scss'); + +import { Component } from 'react'; + +export default class Muncher extends Component { + render() { + const classname = ['troggle', 'x' + this.props.x, 'y' + this.props.y]; + + return ( +
+ ); + }; +}; diff --git a/components/welcome/welcome.component.js b/components/welcome/welcome.component.js index 93906f6..c6158cc 100644 --- a/components/welcome/welcome.component.js +++ b/components/welcome/welcome.component.js @@ -6,7 +6,6 @@ import NewGame from './new-game.component'; import HighScores from './high-scores.component'; export default class Welcome extends Component { - render() { return (
diff --git a/index.js b/index.js index da09496..7bcc0a7 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,7 @@ import boardReducer from './reducers/board/board.reducer'; import muncherReducer from './reducers/board/muncher.reducer'; import scorebarReducer from './reducers/board/scorebar.reducer'; import messageReducer from './reducers/board/message.reducer'; +import troggleReducer from './reducers/board/troggle.reducer'; const reducers = combineReducers({ mode: modeReducer, @@ -18,7 +19,8 @@ const reducers = combineReducers({ muncher: muncherReducer, scorebar: scorebarReducer, board: boardReducer, - message: messageReducer + message: messageReducer, + troggles: troggleReducer }); const store = createStore(reducers); diff --git a/reducers/board/message.reducer.js b/reducers/board/message.reducer.js index eac90e6..60bcf7b 100644 --- a/reducers/board/message.reducer.js +++ b/reducers/board/message.reducer.js @@ -2,7 +2,7 @@ const Immutable = require('immutable'); import * as MessageActions from '../../actions/board/message.actions'; -const initial = { line1: '', line2: '', hidden: true }; +const initial = { message: '', hidden: true }; const reducer = (state = initial, action) => { if (action.type !== MessageActions.MESSAGE_ACTION) { @@ -12,9 +12,8 @@ const reducer = (state = initial, action) => { switch (action.action) { case MessageActions.DISPLAY: return Immutable.Map(state) - .set('line1', action.line1) - .set('line2', action.line2) .set('hidden', false) + .set('message', action.message) .toObject(); case MessageActions.HIDE: diff --git a/reducers/board/muncher.reducer.js b/reducers/board/muncher.reducer.js index c9ef356..fa444d8 100644 --- a/reducers/board/muncher.reducer.js +++ b/reducers/board/muncher.reducer.js @@ -1,7 +1,8 @@ +const Immutable = require('immutable'); import * as MuncherActions from '../../actions/board/muncher.actions'; import { SETTINGS } from '../../App'; -const initial = { x: 0, y: 0 }; +const initial = { x: 0, y: 0, frozen: false }; const reducer = (state = initial, action) => { if (action.type !== MuncherActions.MUNCHER_ACTION) { @@ -10,31 +11,22 @@ const reducer = (state = initial, action) => { switch (action.action) { case MuncherActions.LEFT: - if (state.x === 0) { - return state; - } - return { x: state.x - 1, y: state.y }; + return Immutable.Map(state).set('x', state.x - 1).toObject(); case MuncherActions.RIGHT: - if (state.x === SETTINGS.GRID_WIDTH - 1) { - return state; - } - return { x: state.x + 1, y: state.y }; + return Immutable.Map(state).set('x', state.x + 1).toObject(); case MuncherActions.UP: - if (state.y === 0) { - return state; - } - return { x: state.x, y: state.y - 1 }; + return Immutable.Map(state).set('y', state.y - 1).toObject(); case MuncherActions.DOWN: - if (state.y === SETTINGS.GRID_HEIGHT - 1) { - return state; - } - return { x: state.x, y: state.y + 1 }; + return Immutable.Map(state).set('y', state.y + 1).toObject(); - case MuncherActions.MUNCH: - return state; + case MuncherActions.FREEZE: + return Immutable.Map(state).set('frozen', true).toObject(); + + case MuncherActions.UNFREEZE: + return Immutable.Map(state).set('frozen', false).toObject(); } return state; diff --git a/reducers/board/troggle.reducer.js b/reducers/board/troggle.reducer.js new file mode 100644 index 0000000..b6ee755 --- /dev/null +++ b/reducers/board/troggle.reducer.js @@ -0,0 +1,71 @@ +const Immutable = require('immutable'); + +import * as TroggleActions from '../../actions/board/troggle.actions'; +import { SETTINGS } from '../../App'; +const initial = []; + +const reducer = (state = initial, action) => { + if (action.type !== TroggleActions.TROGGLE_ACTION) { + return state; + } + + switch (action.action) { + case TroggleActions.MOVE: + // Randomize movement with boolean flags. + const moveToAttack = Boolean(Math.round(Math.random())); + const moveAlongXAxis = Boolean(Math.round(Math.random())); + const moveInPositiveDirection = Boolean(Math.round(Math.random())); + + const x = state[action.index].x; + const y = state[action.index].y; + let newX = x; + let newY = y; + + // DO NOT CONSOLIDATE. Attack first, ask questions later. + if (moveAlongXAxis === true) { + if (x === SETTINGS.GRID_WIDTH - 1 || + (moveToAttack && x >= action.muncherX)) { + newX = x - 1; + } + else if (x === 0 || + (moveToAttack && x < action.muncherX)) { + newX = x + 1; + } + else if (moveInPositiveDirection) { + newX = x + 1; + } + else if (!moveInPositiveDirection) { + newX = x - 1; + } + } + else { + if (y === SETTINGS.GRID_HEIGHT - 1 || + (moveToAttack && y >= action.muncherY)) { + newY = y - 1; + } + else if (y === 0 || + (moveToAttack && y < action.muncherY)) { + newY = y + 1; + } + else if (moveInPositiveDirection) { + newY = y + 1; + } + else if (!moveInPositiveDirection) { + newY = y - 1; + } + } + + return Immutable.fromJS(state) + .setIn([action.index, 'x'], newX) + .setIn([action.index, 'y'], newY) + .toJS(); + + case TroggleActions.CREATE: + return Immutable.List(state).push({ x: 0, y: 0 }).toArray(); + break; + } + + return state; +}; + +export default reducer; diff --git a/sass/board/troggle.scss b/sass/board/troggle.scss new file mode 100644 index 0000000..fd5454e --- /dev/null +++ b/sass/board/troggle.scss @@ -0,0 +1,10 @@ +.troggle { + $bg: crimson; + + background: $bg; + height:100px; + margin-top:110px; + opacity: 0.5; + position:absolute; + width:100px; +}