parent
d35d0792c4
commit
9ebdfe6e97
24 changed files with 406 additions and 162 deletions
@ -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); |
||||
|
@ -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; |
@ -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; |
@ -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…
Reference in new issue