Starting high scores. Initials picker finished.

master
Ben Burlingham 9 years ago
parent d35d0792c4
commit 9ebdfe6e97
  1. 3
      AppSettings.js
  2. 8
      actions/welcome/new-game.actions.js
  3. 15
      actions/welcome/welcome.actions.js
  4. 0
      components/welcome/high-score.component.js
  5. 26
      components/welcome/high-scores.component.js
  6. 42
      components/welcome/initials.component.js
  7. 51
      components/welcome/new-game.component.js
  8. 42
      components/welcome/welcome.component.js
  9. 4
      controllers/board/board.controller.js
  10. 6
      controllers/board/grid.controller.js
  11. 24
      controllers/board/scorebar.controller.js
  12. 4
      controllers/board/titlebar.controller.js
  13. 4
      controllers/options/options.controller.js
  14. 91
      controllers/welcome/initials.controller.js
  15. 43
      controllers/welcome/welcome.controller.js
  16. 13
      index.js
  17. 2
      reducers/mode.reducer.js
  18. 0
      reducers/welcome/high-scores.reducer.js
  19. 16
      reducers/welcome/new-game.reducer.js
  20. 40
      reducers/welcome/welcome.reducer.js
  21. 12
      sass/board/scorebar.scss
  22. 1
      sass/reset.scss
  23. 25
      sass/welcome/highscores.scss
  24. 96
      sass/welcome/welcome.scss

@ -1,7 +1,8 @@
const SETTINGS = {
GRID_WIDTH: 6,
GRID_HEIGHT: 5,
LIVES: 3
LIVES: 3,
LOCAL_STORAGE_KEY: 'number-munchers-high-scores'
};
export default SETTINGS;

@ -1,8 +0,0 @@
// New game component actions and action creators.
export const NEWGAME_ACTION = 'NEWGAME_ACTION';
export const BLINK = 'BLINK';
export const blink = () => ({
type: NEWGAME_ACTION,
action: BLINK
});

@ -0,0 +1,15 @@
export const WELCOME_ACTION = 'WELCOME_ACTION';
export const UPDATE_SCORES = 'WELCOME_UPDATE_SCORES';
export const UPDATE_INITIALS = 'WELCOME_UDPATE_INITIALS';
export const updateScores = (scores) => ({
type: WELCOME_ACTION,
action: UPDATE_SCORES,
scores: scores
});
export const updateInitials = (initials) => ({
type: WELCOME_ACTION,
action: UPDATE_INITIALS,
initials: initials
});

@ -1,26 +0,0 @@
require('../../sass/welcome/highscores.scss');
import { Component } from 'react';
import HighScoreEntry from './high-score-entry.component';
export default class HighScores extends Component {
render() {
const vals = [
{ initials: "ABA", score: "219283", rank: "1" },
{ initials: "ABA", score: "107112", rank: "2" },
{ initials: "ABA", score: "81091", rank: "3" },
{ initials: "ABA", score: "67747", rank: "4" },
{ initials: "ABA", score: "9283", rank: "5" },
{ initials: "ABA", score: "928", rank: "6" }
];
var entries = [];
vals.map(function(v, i) {
entries.push(<HighScoreEntry initials={v.initials} score={v.score} rank={v.rank} key={i} />);
});
return (
<div className='highscores'>{entries}</div>
);
}
};

@ -0,0 +1,42 @@
import { Component } from 'react';
import { connect } from 'react-redux';
import InitialsCtrl from '../../controllers/welcome/initials.controller';
export class Initials extends Component {
componentDidMount() {
InitialsCtrl.setDispatch(this.props.dispatch);
};
render() {
const class1 = ['initial'];
const class2 = ['initial'];
const class3 = ['initial'];
if (this.props.initials[0].active === true) {
class1.push('blink');
}
if (this.props.initials[1].active === true) {
class2.push('blink');
}
if (this.props.initials[2].active === true) {
class3.push('blink');
}
return (
<div className='initials'>
<div className={class1.join(' ')}>{this.props.initials[0].initial}</div>
<div className={class2.join(' ')}>{this.props.initials[1].initial}</div>
<div className={class3.join(' ')}>{this.props.initials[2].initial}</div>
</div>
);
};
};
const select = (state) => {
return {
initials: state.welcome.initials
}
};
export default connect(select)(Initials);

@ -1,51 +0,0 @@
import { Component } from 'react';
import { connect } from 'react-redux';
import * as ModeActions from '../../actions/mode.actions';
import * as NewGameActions from '../../actions/welcome/new-game.actions';
let blinkTimer = null;
let newgameListener = null;
const toggleTimeout = function() {
var hidden = this.props.blink;
this.props.dispatch(NewGameActions.blink());
blinkTimer = setTimeout(toggleTimeout.bind(this), 600);
};
export default class NewGame extends Component {
componentDidMount() {
newgameListener = this.handleKeydown.bind(this);
window.addEventListener('keydown', newgameListener);
toggleTimeout.call(this);
};
componentWillUnmount() {
window.removeEventListener('keydown', newgameListener);
clearTimeout(blinkTimer);
};
handleKeydown(e) {
if (e.keyCode === 32) {
this.props.dispatch(ModeActions.options());
}
};
render() {
const classname = ['newgame'];
if (this.props.hidden === true) {
classname.push('hidden');
}
return (
<div className={classname.join(' ')}>Press Space Bar To Play</div>
);
};
};
const select = (state) => {
return state.newgame;
};
export default connect(select)(NewGame);

@ -1,18 +1,50 @@
require('../../sass/welcome/welcome.scss');
import { Component } from 'react';
import { connect } from 'react-redux';
import Initials from './initials.component';
import NewGame from './new-game.component';
import HighScores from './high-scores.component';
import * as ModeActions from '../../actions/mode.actions';
import WelcomeCtrl from '../../controllers/welcome/welcome.controller';
let listener;
export class Welcome extends Component {
componentDidMount() {
listener = WelcomeCtrl.keydown.bind(WelcomeCtrl);
window.addEventListener('keydown', listener);
// HighScoreCtrl.setDispatch(this.props.dispatch);
// HighScoreCtrl.retrieveScores();
// HighScoreCtrl.updateScores(ScorebarCtrl.currentScore);
};
componentWillUnmount() {
window.removeEventListener('keydown', listener);
};
export default class Welcome extends Component {
render() {
// var entries = [];
// this.props.values.map(function(v, i) {
// entries.push(<HighScoreEntry initials={v.initials} score={v.score} rank={v.rank} key={i} />);
// });
return (
<div className='welcome'>
<img src="res/title.png" />
<NewGame />
<HighScores />
<div className='line'>Press Spacebar for new game</div>
<div className='line'>New high score!</div>
<div className='line'>Enter your initials:</div>
<Initials />
</div>
);
};
};
const select = (state) => {
return {
values: state.welcome.scores
}
};
export default connect(select)(Welcome);

@ -6,6 +6,7 @@ import MuncherCtrl from './muncher.controller';
import GridCtrl from './grid.controller';
import TitlebarCtrl from './titlebar.controller';
import ScorebarCtrl from './scorebar.controller';
import WelcomeCtrl from '../welcome/welcome.controller';
import ModeCtrl from '../mode.controller';
let level = -1;
@ -51,13 +52,14 @@ const BoardCtrl = {
}
else if (ScorebarCtrl.isGameOver()) {
level = -1;
WelcomeCtrl.gameOver(ScorebarCtrl.getCurrentScore());
ScorebarCtrl.reset();
MessageCtrl.hide();
TroggleCtrl.unfreeze();
ModeCtrl.welcome();
}
else if (ScorebarCtrl.getLives() === 0) {
ScorebarCtrl.flagGameOver();
ScorebarCtrl.gameOver();
MessageCtrl.show("Game over!");
}
else if (GridCtrl.isCompleted() === true) {

@ -1,5 +1,5 @@
import * as GridActions from '../../actions/board/grid.actions';
import SubtractionModel from '../../models/subtraction.model';
import FactorsModel from '../../models/factors.model';
import SETTINGS from '../../AppSettings';
let values;
@ -10,12 +10,12 @@ const GridCtrl = {
getValues: () => values,
generateValues: (level) => {
values = SubtractionModel.generate(SETTINGS.GRID_WIDTH * SETTINGS.GRID_HEIGHT, level);
values = FactorsModel.generate(SETTINGS.GRID_WIDTH * SETTINGS.GRID_HEIGHT, level);
dispatch(GridActions.update(values));
},
isCompleted: (level) => {
return SubtractionModel.checkComplete(values, level)
return FactorsModel.checkComplete(values, level)
},
hideValue: (index) => {

@ -1,21 +1,32 @@
import * as ScorebarActions from '../../actions/board/scorebar.actions';
import SETTINGS from '../../AppSettings';
const stored = localStorage.getItem(SETTINGS.LOCAL_STORAGE_KEY) || [{ score: 0 }];
let dispatch;
let lives = SETTINGS.LIVES;
let currentScore = 0;
let highScore = 7;
let previousHighScore = stored[0].score;
let highScore = stored[0].score;
let gameOver = false;
const ScorebarCtrl = {
setDispatch: d => dispatch = d,
getLives: () => lives,
getCurrentScore: () => currentScore,
flagGameOver: () => gameOver = true,
isGameOver: () => gameOver,
update: () => {
// Note that loss of points may cause new high to drop below previous.
if (currentScore > previousHighScore) {
highScore = currentScore;
}
else {
highScore = previousHighScore;
}
dispatch(ScorebarActions.update(lives, currentScore, highScore));
},
@ -37,9 +48,18 @@ const ScorebarCtrl = {
levelUp: (level) => {
currentScore += 25;
if (level % 3 === 0) {
lives++;
}
ScorebarCtrl.update();
},
gameOver: () => {
gameOver = true;
},
reset: () => {
lives = SETTINGS.LIVES;
currentScore = 0;

@ -1,5 +1,5 @@
import * as TitlebarActions from '../../actions/board/titlebar.actions';
import SubtractionModel from '../../models/subtraction.model';
import FactorsModel from '../../models/factors.model';
let dispatch;
@ -7,7 +7,7 @@ const TitlebarCtrl = {
setDispatch: d => dispatch = d,
setTitle: (level) => {
const title = SubtractionModel.getTitle(level);
const title = FactorsModel.getTitle(level);
dispatch(TitlebarActions.update(title));
}
};

@ -16,6 +16,10 @@ const OptionsCtrl = {
keyListener(e) {
if (e.keyCode === 32) {
let model =
// switch (selected) {
// case 0:
// }
ModeCtrl.board();
}
else if (e.keyCode === 38) {

@ -0,0 +1,91 @@
import * as WelcomeActions from '../../actions/welcome/welcome.actions';
let dispatch;
let initials = [
{ initial: 'A', active: true },
{ initial: 'A', active: false },
{ initial: 'A', active: false }
];
let active = 0;
let code;
const InitialsCtrl = {
setDispatch: (d) => dispatch = d,
keydown: function(e) {
switch (e.keyCode) {
case 13:
case 32:
break;
case 37:
active--;
if (active === -1) {
active = initials.length - 1;
}
this.updateInitials();
break;
case 38:
code = initials[active].initial.charCodeAt(0);
code--;
if (code === 64) {
code = 90;
}
initials[active].initial = String.fromCharCode(code);
this.updateInitials();
break;
case 39:
active++;
if (active === initials.length) {
active = 0;
}
this.updateInitials();
break;
case 40:
code = initials[active].initial.charCodeAt(0);
code++;
if (code === 91) {
code = 65;
}
initials[active].initial = String.fromCharCode(code);
this.updateInitials();
break;
}
if (e.keyCode >= 65 && e.keyCode <= 90) {
initials[active].initial = String.fromCharCode(e.keyCode);
if (active < initials.length - 1) {
active++;
}
this.updateInitials();
}
},
updateInitials: () => {
initials = initials.map((v) => {
v.active = false;
return v;
});
initials[active].active = true;
dispatch(WelcomeActions.updateInitials(initials));
},
updateScores: (scores) => {
// [
// { initials: "ABA", score: "219283", rank: "1" },
// { initials: "ABA", score: "107112", rank: "2" },
// { initials: "ABA", score: "81091", rank: "3" },
// { initials: "ABA", score: "67747", rank: "4" },
// { initials: "ABA", score: "9283", rank: "5" },
// { initials: "ABA", score: "928", rank: "6" }
// ];
// localStorage.setItem(SETTINGS.LOCAL_STORAGE_KEY, scores);
}
};
export default InitialsCtrl;

@ -0,0 +1,43 @@
import * as WelcomeActions from '../../actions/welcome/welcome.actions';
import InitialsCtrl from './initials.controller';
import SETTINGS from '../../AppSettings';
let dispatch;
let update = true;
const HighScoreCtrl = {
setDispatch: (d) => dispatch = d,
keydown: (e) => {
if (update === true) {
InitialsCtrl.keydown(e);
}
else if (e.keyCode === 32) {
this.props.dispatch(ModeActions.options());
}
},
getHighScore: () => {
const scores = localStorage.getItem(SETTINGS.LOCAL_STORAGE_KEY);
if (scores !== null) {
return scores[0].score;
}
return 0;
},
gameOver: (score) => {
},
retrieveScores: () => {
const scores = localStorage.getItem(SETTINGS.LOCAL_STORAGE_KEY);
if (scores !== null) {
dispatch(WelcomeActions.updateScores(scores));
}
}
};
export default HighScoreCtrl;

@ -6,25 +6,28 @@ import { Provider } from 'react-redux';
import App from './App';
import modeReducer from './reducers/mode.reducer';
import newgameReducer from './reducers/welcome/new-game.reducer';
import welcomeReducer from './reducers/welcome/welcome.reducer';
import optionsReducer from './reducers/options/options.reducer';
import gridReducer from './reducers/board/grid.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';
import titlebarReducer from './reducers/board/titlebar.reducer';
import optionsReducer from './reducers/options/options.reducer';
const reducers = combineReducers({
mode: modeReducer,
newgame: newgameReducer,
welcome: welcomeReducer,
options: optionsReducer,
muncher: muncherReducer,
scorebar: scorebarReducer,
message: messageReducer,
troggles: troggleReducer,
grid: gridReducer,
titlebar: titlebarReducer,
options: optionsReducer
titlebar: titlebarReducer
});
const store = createStore(reducers);

@ -1,6 +1,6 @@
import * as ModeActions from '../actions/mode.actions';
const initial = ModeActions.OPTIONS;
const initial = ModeActions.WELCOME;
const reducer = (state = initial, action) => {
if (action.type !== ModeActions.MODE_ACTION) {

@ -1,16 +0,0 @@
import * as NewGameActions from '../../actions/welcome/new-game.actions';
const initial = { hidden: false };
const reducer = (state = initial, action) => {
if (action.type !== NewGameActions.NEWGAME_ACTION) {
return state;
}
if (action.action === NewGameActions.BLINK) {
return (state.hidden ? { hidden: false } : { hidden: true });
}
return state;
};
export default reducer;

@ -0,0 +1,40 @@
const Immutable = require('immutable');
import * as WelcomeActions from '../../actions/welcome/welcome.actions';
const initial = {
scores: [
{ initials: "AAA", score: "0", rank: "1" },
{ initials: "AAA", score: "0", rank: "1" },
{ initials: "AAA", score: "0", rank: "1" },
{ initials: "AAA", score: "0", rank: "1" },
{ initials: "AAA", score: "0", rank: "1" },
{ initials: "AAA", score: "0", rank: "1" }
],
initials: [
{ initial: 'A', active: true },
{ initial: 'A', active: false },
{ initial: 'A', active: false }
]
};
const reducer = (state = initial, action) => {
if (action.type !== WelcomeActions.WELCOME_ACTION) {
return state;
}
// if (action.action === WelcomeActions.UPDATE_SCORES) {
// return action.scores;
// }
switch (action.action) {
case WelcomeActions.UPDATE_INITIALS:
return Immutable.Map(state)
.set('initials', action.initials)
.toObject();
}
return state;
};
export default reducer;

@ -18,25 +18,25 @@
}
.current-score {
width:30%;
width:35%;
}
.high-score {
text-align:center;
width:40%;
width:30%;
}
.lives {
text-align:right;
width:30%;
width:35%;
}
.life {
background:lime;
display:inline-block;
height:36px;
margin-left:10px;
height:30px;
margin-left:5px;
vertical-align:middle;
width:36px;
width:30px;
}
}

@ -2,6 +2,5 @@
box-sizing:border-box;
font-family:Emulogic;
margin: 0;
outline:none;
padding: 0;
}

@ -1,25 +0,0 @@
.highscores {
font-size: 0;
.entry {
font-size:16px;
line-height:40px;
}
.rank {
display:inline-block;
text-align:left;
width:50px;
}
.initials {
display:inline-block;
width:100px;
}
.score {
display:inline-block;
text-align:right;
width:200px;
}
}

@ -1,22 +1,100 @@
.welcome {
$w: 350px;
padding:20px;
text-align:center;
img {
width:350px;
width:$w;
}
.highscores {
margin:0 auto;
width:350px;
.line {
line-height:30px;
}
.newgame {
margin:20px 0;
transition:opacity 0.1s ease;
@keyframes blink {
50% {
opacity: 0.6;
}
}
&.hidden {
opacity: 0.5;
@-webkit-keyframes blink {
50% {
opacity: 0.6;
}
}
.blink {
animation: blink 1s step-start 0s infinite;
-webkit-animation: blink 1s step-start 0s infinite;
}
.initial {
display:inline-block;
}
// .highscores {
// margin:0 auto;
// width:350px;
// }
//
// .newgame {
// margin:20px 0;
// transition:opacity 0.1s ease;
//
// &.hidden {
// opacity: 0.5;
// }
// }
}
//
// .highscores {
// $w: 350px;
//
// font-size: 0;
//
// hr {
// border:0;
// border-top:1px solid #ccc;
// margin:20px auto;
// width: $w;
// }
//
// .blink {
// animation: blinker 1s none infinite;
// }
//
// @keyframes blinker {
// 50% { opacity: 0.6; }
// }
//
// .line {
// font-size:16px;
// line-height:30px;
// margin: 10px auto;
// text-align:center;
// width:$w;
// };
//
// .entry {
// font-size:16px;
// line-height:40px;
// }
//
// .rank {
// display:inline-block;
// text-align:left;
// width:50px;
// }
//
// .initials {
// display:inline-block;
// width:100px;
// }
//
// .score {
// display:inline-block;
// text-align:right;
// width:200px;
// }
// }

Loading…
Cancel
Save