Starting split of high score entry screen and welcome screen.

master
Ben Burlingham 9 years ago
parent 9ebdfe6e97
commit 7bfab9163b
  1. 7
      actions/mode.actions.js
  2. 7
      actions/welcome/welcome.actions.js
  3. 63
      components/high-score/high-score.component.js
  4. 5
      components/high-score/initials.component.js
  5. 2
      components/welcome/hof-row.component.js
  6. 30
      components/welcome/welcome.component.js
  7. 71
      controllers/high-score/high-score.controller.js
  8. 28
      controllers/high-score/initials.controller.js
  9. 47
      controllers/welcome/welcome.controller.js
  10. 1
      index.js
  11. 2
      readme.md
  12. 30
      reducers/high-score/high-score.reducer.js
  13. 24
      reducers/welcome/welcome.reducer.js
  14. 16
      sass/blink.scss
  15. 104
      sass/high-score/high-score.scss
  16. 103
      sass/welcome/welcome.scss

@ -1,7 +1,7 @@
// Game mode actions and action creators.
export const MODE_ACTION = 'MODE_ACTION'; export const MODE_ACTION = 'MODE_ACTION';
export const WELCOME = 'MODE_WELCOME'; export const WELCOME = 'MODE_WELCOME';
export const OPTIONS = 'MODE_OPTIONS'; export const OPTIONS = 'MODE_OPTIONS';
export const HIGHSCORE = 'MODE_HIGH_SCORE';
export const BOARD = 'MODE_BOARD'; export const BOARD = 'MODE_BOARD';
export const welcome = () => ({ export const welcome = () => ({
@ -14,6 +14,11 @@ export const options = () => ({
action: OPTIONS action: OPTIONS
}); });
export const highscore = () => ({
type: MODE_ACTION,
action: HIGHSCORE
});
export const board = () => ({ export const board = () => ({
type: MODE_ACTION, type: MODE_ACTION,
action: BOARD action: BOARD

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

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

@ -6,9 +6,14 @@ import InitialsCtrl from '../../controllers/welcome/initials.controller';
export class Initials extends Component { export class Initials extends Component {
componentDidMount() { componentDidMount() {
InitialsCtrl.setDispatch(this.props.dispatch); InitialsCtrl.setDispatch(this.props.dispatch);
InitialsCtrl.update();
}; };
render() { render() {
if (this.props.initials.length === 0) {
return <div className='initials'></div>;
}
const class1 = ['initial']; const class1 = ['initial'];
const class2 = ['initial']; const class2 = ['initial'];
const class3 = ['initial']; const class3 = ['initial'];

@ -1,6 +1,6 @@
import { Component } from 'react'; import { Component } from 'react';
export default class HighScoreEntry extends Component { export default class HofRow extends Component {
render() { render() {
return ( return (
<div className='entry'> <div className='entry'>

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

@ -0,0 +1,71 @@
import * as WelcomeActions from '../../actions/welcome/welcome.actions';
import InitialsCtrl from './initials.controller';
import SETTINGS from '../../AppSettings';
let dispatch;
let finalScore = 800;
const scores = [
{ initials: "AAA", score: "0" },
{ initials: "AAA", score: "0" },
{ initials: "AAA", score: "0" },
{ initials: "AAA", score: "0" },
{ initials: "AAA", score: "0" },
];
const WelcomeCtrl = {
setDispatch: (d) => dispatch = d,
isHighScore: () => finalScore > 0,
gameOver: (score) => {
let found = -1;
finalScore = -1;
for (let i = 0; i < scores.length; i++) {
if (scores[i].score < score) {
found = i;
}
}
finalScore = -1;
if (found > -1) {
// scores.splice(found, { initials: 'ZZZ', score: score });
// scores.pop();
finalScore = score;
}
},
update: () => {
const scores = localStorage.getItem(SETTINGS.LOCAL_STORAGE_KEY);
if (scores !== null) {
dispatch(WelcomeActions.updateScores(scores));
}
},
keydown: (e) => {
if ((gameOverFlag === true && e.keyCode === 13) || (gameOverFlag === true && e.keyCode === 32)) {
}
else if (gameOverFlag === true) {
InitialsCtrl.keydown(e);
}
else if (e.keyCode === 32) {
this.props.dispatch(ModeActions.options());
}
},
doTheThing: () => {
const scores = localStorage.getItem(SETTINGS.LOCAL_STORAGE_KEY);
if (scores !== null) {
return scores[0].score;
}
return 0;
// localStorage.setItem(SETTINGS.LOCAL_STORAGE_KEY, scores);
},
};
export default WelcomeCtrl;

@ -16,15 +16,12 @@ const InitialsCtrl = {
keydown: function(e) { keydown: function(e) {
switch (e.keyCode) { switch (e.keyCode) {
case 13:
case 32:
break;
case 37: case 37:
active--; active--;
if (active === -1) { if (active === -1) {
active = initials.length - 1; active = initials.length - 1;
} }
this.updateInitials(); this.update();
break; break;
case 38: case 38:
code = initials[active].initial.charCodeAt(0); code = initials[active].initial.charCodeAt(0);
@ -33,14 +30,14 @@ const InitialsCtrl = {
code = 90; code = 90;
} }
initials[active].initial = String.fromCharCode(code); initials[active].initial = String.fromCharCode(code);
this.updateInitials(); this.update();
break; break;
case 39: case 39:
active++; active++;
if (active === initials.length) { if (active === initials.length) {
active = 0; active = 0;
} }
this.updateInitials(); this.update();
break; break;
case 40: case 40:
code = initials[active].initial.charCodeAt(0); code = initials[active].initial.charCodeAt(0);
@ -49,7 +46,7 @@ const InitialsCtrl = {
code = 65; code = 65;
} }
initials[active].initial = String.fromCharCode(code); initials[active].initial = String.fromCharCode(code);
this.updateInitials(); this.update();
break; break;
} }
@ -59,11 +56,11 @@ const InitialsCtrl = {
if (active < initials.length - 1) { if (active < initials.length - 1) {
active++; active++;
} }
this.updateInitials(); this.update();
} }
}, },
updateInitials: () => { update: () => {
initials = initials.map((v) => { initials = initials.map((v) => {
v.active = false; v.active = false;
return v; return v;
@ -72,19 +69,6 @@ const InitialsCtrl = {
initials[active].active = true; initials[active].active = true;
dispatch(WelcomeActions.updateInitials(initials)); 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);
} }
}; };

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

@ -1,4 +1,5 @@
require('./sass/reset.scss'); require('./sass/reset.scss');
require('./sass/blink.scss');
import { render } from 'react-dom'; import { render } from 'react-dom';
import { createStore, combineReducers } from 'redux' import { createStore, combineReducers } from 'redux'

@ -10,4 +10,6 @@ Run `npm install` to install the required Node packages.
Run `npm run dev` in the project root to start the [webpack dev server](https://webpack.github.io/docs/webpack-dev-server.html). Run `npm run dev` in the project root to start the [webpack dev server](https://webpack.github.io/docs/webpack-dev-server.html).
Run `npm run prod` in the project root to assemble prod bundles.
Navigate to http://localhost:8080/. Navigate to http://localhost:8080/.

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

@ -2,35 +2,17 @@ const Immutable = require('immutable');
import * as WelcomeActions from '../../actions/welcome/welcome.actions'; import * as WelcomeActions from '../../actions/welcome/welcome.actions';
const initial = { const initial = { scores: [] };
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) => { const reducer = (state = initial, action) => {
if (action.type !== WelcomeActions.WELCOME_ACTION) { if (action.type !== WelcomeActions.WELCOME_ACTION) {
return state; return state;
} }
// if (action.action === WelcomeActions.UPDATE_SCORES) {
// return action.scores;
// }
switch (action.action) { switch (action.action) {
case WelcomeActions.UPDATE_INITIALS: case WelcomeActions.UPDATE_SCORES:
return Immutable.Map(state) return Immutable.Map(state)
.set('initials', action.initials) .set('scores', action.scores)
.toObject(); .toObject();
} }

@ -0,0 +1,16 @@
@keyframes blink {
50% {
opacity: 0.6;
}
}
@-webkit-keyframes blink {
50% {
opacity: 0.6;
}
}
.blink {
animation: blink 1s step-start 0s infinite;
-webkit-animation: blink 1s step-start 0s infinite;
}

@ -0,0 +1,104 @@
.high-score {
$w: 350px;
padding:20px;
text-align:center;
img {
width:$w;
}
.line {
line-height:30px;
}
.spacer {
height:100px;
}
@keyframes blink {
50% {
opacity: 0.6;
}
}
@-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;
// }
// }

@ -1,5 +1,6 @@
.welcome { .welcome {
$w: 350px; $fs: 14px;
$w: 400px;
padding:20px; padding:20px;
text-align:center; text-align:center;
@ -9,92 +10,38 @@
} }
.line { .line {
line-height:30px; font-size:14px;
line-height:70px;
margin:0 auto;
width: $w;
} }
@keyframes blink { hr {
50% { border:0;
opacity: 0.6; border-top:1px solid #ccc;
} margin:20px auto;
width: $w;
} }
@-webkit-keyframes blink { .entry {
50% { font-size:16px;
opacity: 0.6; line-height:40px;
}
} }
.blink { .rank {
animation: blink 1s step-start 0s infinite; display:inline-block;
-webkit-animation: blink 1s step-start 0s infinite; text-align:left;
width:50px;
} }
.initial { .initials {
display:inline-block; display:inline-block;
width:100px;
} }
// .highscores { .score {
// margin:0 auto; display:inline-block;
// width:350px; text-align:right;
// } width:200px;
// }
// .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