Troggles complete.

master
Ben Burlingham 9 years ago
parent a19dd163ad
commit 44620c2a3f
  1. 10
      actions/board/message.actions.js
  2. 12
      actions/board/scorebar.actions.js
  3. 16
      actions/board/troggle.actions.js
  4. 5
      components/board/troggles.component.js
  5. 60
      controllers/board.controller.js
  6. 65
      controllers/message.controller.js
  7. 10
      controllers/muncher.controller.js
  8. 43
      controllers/scorebar.controller.js
  9. 55
      controllers/troggle.controller.js
  10. 22
      reducers/board/message.reducer.js
  11. 22
      reducers/board/scorebar.reducer.js
  12. 18
      reducers/board/troggle.reducer.js

@ -1,7 +1,6 @@
export const MESSAGE_ACTION = 'MESSAGE_ACTION'; export const MESSAGE_ACTION = 'MESSAGE_ACTION';
export const SHOW = 'SHOW'; export const SHOW = 'MESSAGE_SHOW';
export const HIDE = 'HIDE'; export const HIDE = 'MESSAGE_HIDE';
export const EXCLAIM = 'EXCLAIM';
export const show = (message) => ({ export const show = (message) => ({
type: MESSAGE_ACTION, type: MESSAGE_ACTION,
@ -9,11 +8,6 @@ export const show = (message) => ({
message: message message: message
}); });
export const exclaim = () => ({
type: MESSAGE_ACTION,
action: EXCLAIM
});
export const hide = () => ({ export const hide = () => ({
type: MESSAGE_ACTION, type: MESSAGE_ACTION,
action: HIDE action: HIDE

@ -1,13 +1,7 @@
export const SCOREBAR_ACTION = 'SCOREBAR_ACTION'; export const SCOREBAR_ACTION = 'SCOREBAR_ACTION';
export const MUNCH_SUCCEEDED = 'SCOREBAR_MUNCH_SUCCEEDED'; export const UPDATE = 'SCOREBAR_UPDATE';
export const MUNCH_FAILED = 'SCOREBAR_MUNCH_FAILED';
export const munchSucceeded = () => ({ export const update = () => ({
type: SCOREBAR_ACTION, type: SCOREBAR_ACTION,
action: MUNCH_SUCCEEDED, action: UPDATE
});
export const munchFailed = () => ({
type: SCOREBAR_ACTION,
action: MUNCH_FAILED
}); });

@ -1,18 +1,22 @@
export const TROGGLE_ACTION = 'TROGGLE_ACTION'; export const TROGGLE_ACTION = 'TROGGLE_ACTION';
export const CREATE = 'TROGGLE_CREATE'; export const CREATE = 'TROGGLE_CREATE';
export const MOVE = 'TROGGLE_MOVE'; export const UPDATE = 'TROGGLE_UPDATE';
export const CLEAR_ALL = 'TROGGLE_CLEAR_ALL'; export const CLEAR_ALL = 'TROGGLE_CLEAR_ALL';
export const create = (index) => ({ export const create = (index, x, y) => ({
type: TROGGLE_ACTION, type: TROGGLE_ACTION,
action: CREATE, action: CREATE,
index: index index: index,
x: x,
y: y
}); });
export const move = (index) => ({ export const update = (index, x, y) => ({
type: TROGGLE_ACTION, type: TROGGLE_ACTION,
action: MOVE, action: UPDATE,
index: index index: index,
x: x,
y: y
}); });
export const clearAll = () => ({ export const clearAll = () => ({

@ -15,7 +15,7 @@ export class Troggles extends Component {
const { troggles, muncher } = this.props; const { troggles, muncher } = this.props;
const troggleElements = Array.from(Array(troggles.length), (v, i) => { const troggleElements = Array.from(Array(troggles.length), (v, i) => {
return <Troggle x={troggles[i].x} y={troggles[i].y} mx={muncher.x} my={muncher.y} key={i} />; return <Troggle x={troggles[i].x} y={troggles[i].y} key={i} />;
}); });
return <div className='troggles'>{troggleElements}</div> return <div className='troggles'>{troggleElements}</div>
@ -24,8 +24,7 @@ export class Troggles extends Component {
const select = (state) => { const select = (state) => {
return { return {
troggles: state.troggles, troggles: state.troggles
muncher: state.muncher
}; };
} }

@ -1,15 +1,14 @@
import { SETTINGS } from '../App.js'; import { SETTINGS } from '../App.js';
import * as ScorebarActions from '../actions/board/scorebar.actions';
import * as MessageActions from '../actions/board/message.actions';
import TroggleCtrl from './troggle.controller'; import TroggleCtrl from './troggle.controller';
import MessageCtrl from './message.controller'; import MessageCtrl from './message.controller';
import MuncherCtrl from './muncher.controller'; import MuncherCtrl from './muncher.controller';
import GridCtrl from './grid.controller'; import GridCtrl from './grid.controller';
import TitlebarCtrl from './titlebar.controller'; import TitlebarCtrl from './titlebar.controller';
import ScorebarCtrl from './scorebar.controller';
let level = -1; let level = -1;
let collision = false;
let dispatch; let dispatch;
const BoardCtrl = { const BoardCtrl = {
@ -18,30 +17,51 @@ const BoardCtrl = {
GridCtrl.setDispatch(d); GridCtrl.setDispatch(d);
MuncherCtrl.setDispatch(d); MuncherCtrl.setDispatch(d);
TitlebarCtrl.setDispatch(d); TitlebarCtrl.setDispatch(d);
ScorebarCtrl.setDispatch(d);
MessageCtrl.setDispatch(d);
TroggleCtrl.setDispatch(d);
}, },
isCollision: () => collision,
munch() { munch() {
const index = MuncherCtrl.getY() * SETTINGS.GRID_WIDTH + MuncherCtrl.getX(); const index = MuncherCtrl.getY() * SETTINGS.GRID_WIDTH + MuncherCtrl.getX();
if (GridCtrl.getValues()[index].valid) { if (GridCtrl.getValues()[index].valid) {
GridCtrl.hideValue(index); GridCtrl.hideValue(index);
ScorebarCtrl.munchSucceeded();
if (GridCtrl.isCompleted() === true) { if (GridCtrl.isCompleted() === true) {
dispatch(MessageActions.exclaim()); MessageCtrl.goodNews('Level complete!');
} }
} }
else { else {
dispatch(MessageActions.show(`Uh oh - ${GridCtrl.getValues()[index].value} is not a match.`)); TroggleCtrl.freeze();
MessageCtrl.badNews(`${GridCtrl.getValues()[index].value} is not a match.`);
ScorebarCtrl.munchFailed();
} }
}, },
keyListener(e) { keyListener(e) {
if (e.keyCode === 32 && GridCtrl.isCompleted() === true) { if (e.keyCode === 32 && ScorebarCtrl.getLives() === 0) {
MessageCtrl.show("Game over!");
}
else if (e.keyCode === 32 && GridCtrl.isCompleted() === true) {
this.nextLevel(); this.nextLevel();
dispatch(MessageActions.hide()); ScorebarCtrl.levelUp(level);
MessageCtrl.hide();
}
else if (e.keyCode === 32 && BoardCtrl.isCollision() === true) {
collision = false;
TroggleCtrl.clearTroggles();
TroggleCtrl.createTroggles(level);
TroggleCtrl.unfreeze();
ScorebarCtrl.eatenByTroggle();
MessageCtrl.hide();
} }
else if (e.keyCode === 32 && MessageCtrl.isShowing() === true) { else if (e.keyCode === 32 && MessageCtrl.isShowing() === true) {
dispatch(MessageActions.hide()); TroggleCtrl.unfreeze();
MessageCtrl.hide();
} }
else if (e.keyCode === 32 && MessageCtrl.isShowing() === false) { else if (e.keyCode === 32 && MessageCtrl.isShowing() === false) {
this.munch(); this.munch();
@ -55,16 +75,24 @@ const BoardCtrl = {
level++; level++;
GridCtrl.generateValues(level); GridCtrl.generateValues(level);
TitlebarCtrl.setTitle(level); TitlebarCtrl.setTitle(level);
// TroggleCtrl.clearAll(this.props.dispatch); TroggleCtrl.clearTroggles();
// TroggleCtrl.createTroggles(this.props.dispatch); TroggleCtrl.createTroggles(level);
}, },
// if (troggles[i].x === muncher.x && troggles[i].y === muncher.y) { checkCollision() {
// this.props.dispatch(MessageActions.show("You've been eaten by a troggle!")); const x = MuncherCtrl.getX();
// this.props.dispatch(ScorebarActions.munchFailed()); const y = MuncherCtrl.getY();
// TroggleCtrl.frozen = true;
// ReactDOM.findDOMNode(this.refs.message).focus(); const troggles = TroggleCtrl.getTroggles();
// } for (let i = 0; i < troggles.length; i++) {
if (troggles[i].x === x && troggles[i].y === y) {
collision = true;
TroggleCtrl.freeze();
MessageCtrl.badNews("You've been eaten by a troggle!");
break;
}
}
}
}; };
export default BoardCtrl; export default BoardCtrl;

@ -1,8 +1,69 @@
import * as MessageActions from '../actions/board/message.actions';
const positives = [
'All finished!',
'Boom!',
'Capital!',
'Congratulations!',
'Great job!',
'Huzzah!',
'Hooray!',
'Hot dog!',
'Marvelous!',
'Nice work!',
'Shazam!',
'Spot on!',
'Whee!',
'Wonderful!',
'Woohoo!',
'Yippee!'
];
const negatives = [
'Cripes!',
'Darn it!',
'Doggone it!',
'Drat!',
'Fiddlesticks!',
'Good grief!',
'Oh dear!',
'Oh no!',
'Rats!',
'Shazbot!',
'Shoot!',
'Shucks!',
'Too bad!',
'Uh oh!'
];
let dispatch;
let show = false; let show = false;
const MessageCtrl = { const MessageCtrl = {
hide: () => show = false, setDispatch: (d) => dispatch = d,
show: () => show = true,
hide: () => {
show = false;
dispatch(MessageActions.hide());
},
show: (msg) => {
show = true;
dispatch(MessageActions.show(`${msg}`));
},
goodNews: (msg) => {
show = true;
const exclaim = positives[Math.floor(positives.length * Math.random())];
dispatch(MessageActions.show(`${exclaim} ${msg}`));
},
badNews: (msg) => {
show = true;
const exclaim = negatives[Math.floor(negatives.length * Math.random())];
dispatch(MessageActions.show(`${exclaim} ${msg}`));
},
isShowing: () => show isShowing: () => show
}; };

@ -1,4 +1,5 @@
import * as MuncherActions from '../actions/board/muncher.actions'; import * as MuncherActions from '../actions/board/muncher.actions';
import BoardCtrl from './board.controller';
import { SETTINGS } from '../App'; import { SETTINGS } from '../App';
let x = 0; let x = 0;
@ -15,31 +16,32 @@ const MuncherCtrl = {
case 37: case 37:
if (x !== 0) { if (x !== 0) {
x -= 1; x -= 1;
dispatch(MuncherActions.update());
} }
break; break;
case 38: case 38:
if (y !== 0) { if (y !== 0) {
y -= 1; y -= 1;
dispatch(MuncherActions.update());
} }
break; break;
case 39: case 39:
if (x !== SETTINGS.GRID_WIDTH - 1) { if (x !== SETTINGS.GRID_WIDTH - 1) {
x += 1; x += 1;
dispatch(MuncherActions.update());
} }
break; break;
case 40: case 40:
if (y !== SETTINGS.GRID_HEIGHT - 1) { if (y !== SETTINGS.GRID_HEIGHT - 1) {
y += 1; y += 1;
dispatch(MuncherActions.update());
} }
break; break;
} }
if (e.keyCode >= 37 || e.keyCode <= 40) {
dispatch(MuncherActions.update());
BoardCtrl.checkCollision();
}
} }
}; };

@ -0,0 +1,43 @@
import * as ScorebarActions from '../actions/board/scorebar.actions';
import { SETTINGS } from '../App';
let dispatch;
let lives = 3;
let currentScore = 0;
let highScore = 7;
const ScorebarCtrl = {
setDispatch: d => dispatch = d,
getCurrentScore: () => currentScore,
getHighScore: () => highScore,
getLives: () => lives,
munchSucceeded: () => {
currentScore += 10;
dispatch(ScorebarActions.update());
},
munchFailed: () => {
lives--;
currentScore -= 5;
dispatch(ScorebarActions.update());
},
eatenByTroggle: () => {
lives--;
dispatch(ScorebarActions.update());
},
levelUp: (level) => {
currentScore += 25;
dispatch(ScorebarActions.update());
},
reset: () => {
lives = SETTINGS.LIVES;
currentScore = 0;
}
};
export default ScorebarCtrl;

@ -1,16 +1,30 @@
import { SETTINGS } from '../App'; import { SETTINGS } from '../App';
import * as TroggleActions from '../actions/board/troggle.actions'; import * as TroggleActions from '../actions/board/troggle.actions';
import MuncherCtrl from './muncher.controller';
import BoardCtrl from './board.controller';
const troggles = [];
const troggleMoveTimers = []; const troggleMoveTimers = [];
const troggleCreateTimers = []; const troggleCreateTimers = [];
let frozen = false;
let dispatch;
const TroggleCtrl = { const TroggleCtrl = {
frozen: false, setDispatch: (d) => dispatch = d,
getTroggles: () => troggles,
freeze: () => frozen = true,
unfreeze: () => frozen = false,
isFrozen: () => frozen,
clearAll(dispatch) { clearTroggles() {
dispatch(TroggleActions.clearAll()); dispatch(TroggleActions.clearAll());
troggles.length = 0;
troggleMoveTimers.forEach((timer) => { troggleMoveTimers.forEach((timer) => {
clearTimeout(timer); clearTimeout(timer);
}); });
@ -20,41 +34,50 @@ const TroggleCtrl = {
}); });
}, },
createTroggle(index, dispatch) { createTroggle(index) {
dispatch(TroggleActions.create(index)); const coords = this.getStartingCoords();
troggles[index] = { x: coords.x, y: coords.y };
dispatch(TroggleActions.create(index, coords.x, coords.y));
const ref = this.moveTroggle.bind(this, index, dispatch); const ref = this.moveTroggle.bind(this, index);
troggleMoveTimers[index] = setTimeout(ref, 1000); troggleMoveTimers[index] = setTimeout(ref, 1000);
}, },
createTroggles(dispatch, level) { createTroggles(level) {
// const count = Math.min(Math.ceil((level + 1) / 2), 5); // const count = Math.min(Math.ceil((level + 1) / 2), 5);
const count = 3; const count = 3;
for (let index = 0; index < count; index++) { for (let index = 0; index < count; index++) {
const ref = this.createTroggle.bind(this, index, dispatch); const ref = this.createTroggle.bind(this, index);
troggleCreateTimers[index] = setTimeout(ref, (index) * 1000); troggleCreateTimers[index] = setTimeout(ref, (index) * 1000);
// troggleCreateTimers[index] = setTimeout(ref, (index + 1) * 5000); // troggleCreateTimers[index] = setTimeout(ref, (index + 1) * 5000);
} }
}, },
moveTroggle(index, dispatch) { moveTroggle(index) {
if (this.frozen === false) { if (frozen === false) {
dispatch(TroggleActions.move(index)); const coords = this.getMoveCoords(troggles[index].x, troggles[index].y);
troggles[index].x = coords.x;
troggles[index].y = coords.y;
BoardCtrl.checkCollision();
dispatch(TroggleActions.update(index, coords.x, coords.y));
} }
const ref = this.moveTroggle.bind(this, index, dispatch); const ref = this.moveTroggle.bind(this, index);
troggleMoveTimers[index] = setTimeout(ref, 1000); troggleMoveTimers[index] = setTimeout(ref, 1000);
}, },
getMoveCoords(currX, currY, muncherX, muncherY) { getMoveCoords(currX, currY) {
// Randomize movement with boolean flags. // Randomize movement with boolean flags. Aggression can be controlled here.
const moveToAttack = Boolean(Math.round(Math.random())); const moveToAttack = Boolean(Math.random() > 0.35);
const moveAlongXAxis = Boolean(Math.round(Math.random())); const moveAlongXAxis = Boolean(Math.random() > 0.5);
const moveInPositiveDirection = Boolean(Math.round(Math.random())); const moveInPositiveDirection = Boolean(Math.random() > 0.5);
let newX = currX; let newX = currX;
let newY = currY; let newY = currY;
let muncherX = MuncherCtrl.getX();
let muncherY = MuncherCtrl.getY();
// DO NOT CONSOLIDATE. Attack first, ask questions later. // DO NOT CONSOLIDATE. Attack first, ask questions later.
if (moveAlongXAxis === true) { if (moveAlongXAxis === true) {

@ -1,18 +1,6 @@
const Immutable = require('immutable'); const Immutable = require('immutable');
import * as MessageActions from '../../actions/board/message.actions'; import * as MessageActions from '../../actions/board/message.actions';
import MessageCtrl from '../../controllers/message.controller';
const exclamations = [
'Congratulations!',
'Yippee!',
'Woohoo!',
'Nice work!',
'Great job!',
'Boom!',
'All finished!',
'Shazam!'
];
const initial = { message: '', hidden: true }; const initial = { message: '', hidden: true };
@ -22,23 +10,13 @@ const reducer = (state = initial, action) => {
} }
switch (action.action) { switch (action.action) {
case MessageActions.EXCLAIM:
MessageCtrl.show();
const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
return Immutable.Map(state)
.set('hidden', false)
.set('message', msg)
.toObject();
case MessageActions.SHOW: case MessageActions.SHOW:
MessageCtrl.show();
return Immutable.Map(state) return Immutable.Map(state)
.set('hidden', false) .set('hidden', false)
.set('message', action.message) .set('message', action.message)
.toObject(); .toObject();
case MessageActions.HIDE: case MessageActions.HIDE:
MessageCtrl.hide();
return Immutable.Map(state) return Immutable.Map(state)
.set('hidden', true) .set('hidden', true)
.toObject(); .toObject();

@ -1,24 +1,24 @@
const Immutable = require('immutable'); const Immutable = require('immutable');
import * as ScorebarActions from '../../actions/board/scorebar.actions'; import * as ScorebarActions from '../../actions/board/scorebar.actions';
import { SETTINGS } from '../../App'; import ScorebarCtrl from '../../controllers/scorebar.controller.js';
const initial = { current: 0, high: 999, lives: SETTINGS.LIVES }; const initial = {
current: ScorebarCtrl.getCurrentScore(),
high: ScorebarCtrl.getHighScore(),
lives: ScorebarCtrl.getLives()
};
const reducer = (state = initial, action) => { const reducer = (state = initial, action) => {
if (action.type !== ScorebarActions.SCOREBAR_ACTION) { if (action.type !== ScorebarActions.SCOREBAR_ACTION) {
return state; return state;
} }
switch (action.action) { return Immutable.Map(state)
case ScorebarActions.MUNCH_SUCCEEDED: .set('current', ScorebarCtrl.getCurrentScore())
return Immutable.Map(state).set('current', state.current + 10).toObject(); .set('high', ScorebarCtrl.getHighScore())
.set('lives', ScorebarCtrl.getLives())
case ScorebarActions.MUNCH_FAILED: .toObject();
return Immutable.Map(state).set('lives', state.lives - 1).toObject();
}
return state;
}; };
export default reducer; export default reducer;

@ -1,7 +1,6 @@
const Immutable = require('immutable'); const Immutable = require('immutable');
import * as TroggleActions from '../../actions/board/troggle.actions'; import * as TroggleActions from '../../actions/board/troggle.actions';
import TroggleCtrl from '../../controllers/troggle.controller';
const initial = []; const initial = [];
@ -11,21 +10,20 @@ const reducer = (state = initial, action) => {
} }
switch (action.action) { switch (action.action) {
case TroggleActions.MOVE: case TroggleActions.UPDATE:
const t = state[action.index];
const coords1 = TroggleCtrl.getMoveCoords(t.x, t.y, t.mx, t.my);
return Immutable.fromJS(state) return Immutable.fromJS(state)
.setIn([action.index, 'x'], coords1.x) .setIn([action.index, 'x'], action.x)
.setIn([action.index, 'y'], coords1.y) .setIn([action.index, 'y'], action.y)
.toJS(); .toJS();
case TroggleActions.CREATE: case TroggleActions.CREATE:
const coords2 = TroggleCtrl.getStartingCoords(); return Immutable.List(state)
return Immutable.List(state).set(action.index, { x: coords2.x, y: coords2.y }).toArray(); .set(action.index, { x: action.x, y: action.y })
.toArray();
case TroggleActions.CLEAR_ALL: case TroggleActions.CLEAR_ALL:
return Immutable.List().toArray(); return Immutable.List()
.toArray();
}; };
return state; return state;

Loading…
Cancel
Save