Skip to content

Commit

Permalink
added game states
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-zelenkov committed Jun 4, 2014
1 parent cfe3ac6 commit 9dd2e69
Show file tree
Hide file tree
Showing 17 changed files with 206 additions and 79 deletions.
17 changes: 17 additions & 0 deletions js/common/enum/GameState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2002-2014, University of Colorado Boulder

/**
* Possible game states in the 'Arithmetic'.
*
* @author Andrey Zelenkov (Mlearner)
*/
define( function() {
'use strict';

return Object.freeze( {
EQUATION_FILLED: 'equationFilled',
LEVEL_FINISHED: 'levelFinished',
NEXT_TASK: 'nextTask',
START: 'start'
} );
} );
68 changes: 39 additions & 29 deletions js/common/model/ArithmeticModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ define( function( require ) {

// modules
var inherit = require( 'PHET_CORE/inherit' );
var FaceModel = require( 'ARITHMETIC/common/model/FaceModel' );
var GameModel = require( 'ARITHMETIC/common/model/GameModel' );
var Property = require( 'AXON/Property' );
var PropertySet = require( 'AXON/PropertySet' );
Expand All @@ -24,6 +25,7 @@ define( function( require ) {
var GameAudioPlayer = require( 'VEGAS/GameAudioPlayer' );

// constants
var GAME_STATE = require( 'ARITHMETIC/common/enum/GameState' );
var levels = [
// level 1
{
Expand Down Expand Up @@ -59,7 +61,6 @@ define( function( require ) {
scoreTotal: 0, // total user score for current games
time: 0, // current time
input: '', // user's input value
isLevelCompleted: false, // flag of level completing. If true - show statistic node
isSound: true, // is sound active
isTimer: false // is time mode active
} );
Expand All @@ -70,6 +71,8 @@ define( function( require ) {
// model for single game
this.game = new GameModel( this.property( 'level' ), levels );

this.smileFace = new FaceModel();

// best times and scores, equal to number of levels
this.bestTimes = [];
this.bestScores = [];
Expand All @@ -88,45 +91,55 @@ define( function( require ) {
// init game after choosing level
this.property( 'level' ).lazyLink( function( levelNumber ) {
if ( levelNumber ) {
self.setTask();
self.game.state = GAME_STATE.NEXT_TASK;
}
else {
self.game.reset();
}
} );

this.game.property( 'multiplierLeft' ).lazyLink( this.checkNextTask.bind( this ) );
this.game.property( 'multiplierRight' ).lazyLink( this.checkNextTask.bind( this ) );
this.game.property( 'product' ).lazyLink( this.checkNextTask.bind( this ) );
}

return inherit( PropertySet, ArithmeticModel, {
checkNextTask: function() {
if ( this.checkAnswer() ) {
this.setTask();
}
},
checkAnswer: function() {
if ( this.game.multiplierLeft && this.game.multiplierRight && this.game.product ) {

// set next task if equation was filled
this.game.property( 'state' ).lazyLink( function( state ) {
if ( state === GAME_STATE.EQUATION_FILLED ) {
// show smile face
this.game.isFaceVisible = true;
self.smileFace.isVisible = true;

// correct answer
if ( this.game.multiplierLeft * this.game.multiplierRight === this.game.product ) {
this.scoreTotal += this.game.scoreGame;
this.gameAudioPlayer.correctAnswer();
return true;
if ( self.game.multiplierLeft * self.game.multiplierRight === self.game.product ) {

// increase total score
self.scoreTotal += self.game.scoreGame;

// set smile face view and play sound
self.smileFace.scoreFace = self.game.scoreGame;
self.smileFace.isSmile = true;
self.gameAudioPlayer.correctAnswer();

// mark answer in answer sheet
self.game.answerSheet[self.game.multiplierLeft - 1][self.game.multiplierRight - 1] = true;

// set next task
self.game.state = GAME_STATE.NEXT_TASK;
}
// wrong answer
else {
this.game.scoreGame = 0;
this.gameAudioPlayer.wrongAnswer();
return false;

// player will not get points for this task
self.game.scoreGame = 0;

// set smile face view and play sound
self.smileFace.scoreFace = self.game.scoreGame;
self.smileFace.isSmile = false;
self.gameAudioPlayer.wrongAnswer();

// return to start state
self.game.state = GAME_STATE.START;
}
}
return false;
},
} );
}

return inherit( PropertySet, ArithmeticModel, {
checkInput: function() {
// should be defined in child constructors
},
Expand All @@ -136,9 +149,6 @@ define( function( require ) {
reset: function() {
PropertySet.prototype.reset.call( this );
},
setTask: function() {
// should be defined in child constructors
},
step: function( dt ) {
// if timer is on and level is select - add time
if ( this.isTimer && this.level ) {
Expand Down
24 changes: 24 additions & 0 deletions js/common/model/FaceModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2002-2013, University of Colorado Boulder

/**
* Model for smile face in the 'Arithmetic' simulation.
*
* @author Andrey Zelenkov (MLearner)
*/
define( function( require ) {
'use strict';

// modules
var inherit = require( 'PHET_CORE/inherit' );
var PropertySet = require( 'AXON/PropertySet' );

function FaceModel() {
PropertySet.call( this, {
scoreFace: 1, // score near smile face
isVisible: false, // flag of smile face visibility
isSmile: true // flag of smile face emotion
} );
}

return inherit( PropertySet, FaceModel );
} );
28 changes: 19 additions & 9 deletions js/common/model/GameModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ define( function( require ) {
var inherit = require( 'PHET_CORE/inherit' );
var PropertySet = require( 'AXON/PropertySet' );

// constants
var GAME_STATE = require( 'ARITHMETIC/common/enum/GameState' );

function GameModel( levelProperty, levels ) {
var self = this;

PropertySet.call( this, {
multiplierLeft: undefined, // left multiplier
multiplierRight: undefined, // right multiplier
product: undefined, // product of multiplication
state: undefined, // current game state
isFaceVisible: false, // flag of smile face visibility
state: GAME_STATE.START, // current game state
scoreGame: 1 // score for current game
} );

Expand All @@ -41,43 +43,51 @@ define( function( require ) {
// fill arrays appropriate to right multipliers
self.answerSheet.forEach( function( el ) {
_.times( answerSheetSize, function() {
el.push( false );
el.push( true );
} );
} );

self.answerSheet[1][1] = false;
}
} );
}

return inherit( PropertySet, GameModel, {
reset: function() {
// reset properties
PropertySet.prototype.reset.call( this );
},
// return available left and right multipliers according to answer sheet
getAvailableMultipliers: function() {
var availableLeftMultipliers = [];
var availableRightMultipliers = [];
var availableMultipliersLeft = [];
var availableMultipliersRight = [];
var multiplierLeft;
var multiplierRight;

// find available left multipliers
this.answerSheet.forEach( function( rightMultipliers, index ) {
if ( rightMultipliers.indexOf( false ) !== -1 ) {
availableLeftMultipliers.push( index + 1 );
availableMultipliersLeft.push( index + 1 );
}
} );

// no more available multipliers
if ( !availableMultipliersLeft.length ) {
return null;
}

// set left multiplier
multiplierLeft = _.shuffle( availableLeftMultipliers )[0];
multiplierLeft = _.shuffle( availableMultipliersLeft )[0];

// find available right multipliers
this.answerSheet[multiplierLeft - 1].forEach( function( isRightMultiplierAnswered, index ) {
if ( !isRightMultiplierAnswered ) {
availableRightMultipliers.push( index + 1 );
availableMultipliersRight.push( index + 1 );
}
} );

// set right multiplier
multiplierRight = _.shuffle( availableRightMultipliers )[0];
multiplierRight = _.shuffle( availableMultipliersRight )[0];

return {
multiplierLeft: multiplierLeft,
Expand Down
5 changes: 5 additions & 0 deletions js/common/view/EquationInputNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ define( function( require ) {
},
unfocus: function() {
// TODO: stop blinking cursor
},
reset: function(){
this._inputText.setText( PLACEHOLDER );
updateBoxPosition( this._box );
this.disable();
}
} );
} );
16 changes: 11 additions & 5 deletions js/common/view/FaceWithScoreConfiguredNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ define( function( require ) {
var FaceWithScoreNode = require( 'SCENERY_PHET/FaceWithScoreNode' );
var inherit = require( 'PHET_CORE/inherit' );

function FaceWithScoreConfiguredNode( scoreGameProperty, isFaceVisibleProperty ) {
function FaceWithScoreConfiguredNode( smileFaceModel ) {
var self = this;
FaceWithScoreNode.call( this, {
faceOpacity: 1,
Expand All @@ -23,13 +23,19 @@ define( function( require ) {
} );

// add observers
scoreGameProperty.link( function( scoreGame ) {
// set score and smile emotion

// set score of smile face
smileFaceModel.property( 'scoreFace' ).link( function( scoreGame ) {
self.setScore( scoreGame );
self[scoreGame ? 'smile' : 'frown' ]();
} );

isFaceVisibleProperty.linkAttribute( self, 'visible' );
// set smile face emotion
smileFaceModel.property( 'isSmile' ).link( function( isFaceSmile ) {
self[isFaceSmile ? 'smile' : 'frown' ]();
} );

// set visibility of smile face
smileFaceModel.property( 'isVisible' ).linkAttribute( self, 'visible' );
}

return inherit( FaceWithScoreNode, FaceWithScoreConfiguredNode );
Expand Down
9 changes: 6 additions & 3 deletions js/common/view/LevelCompletedConfiguredNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ define( function( require ) {
var LevelCompletedNode = require( 'VEGAS/LevelCompletedNode' );
var Node = require( 'SCENERY/nodes/Node' );

function LevelCompletedConfiguredNode( levels, levelProperty, isLevelCompletedProperty, scoreTotalProperty, isTimerProperty, timeProperty, bestTimes ) {
// constants
var GAME_STATE = require( 'ARITHMETIC/common/enum/GameState' );

function LevelCompletedConfiguredNode( levels, levelProperty, stateProperty, scoreTotalProperty, isTimerProperty, timeProperty, bestTimes ) {
var self = this;
Node.call( this );

isLevelCompletedProperty.lazyLink( function( isLevelCompleted ) {
if ( isLevelCompleted ) {
stateProperty.lazyLink( function( state ) {
if ( state === GAME_STATE.LEVEL_FINISHED ) {
self.addChild( new LevelCompletedNode(
levelProperty.value,
scoreTotalProperty.value,
Expand Down
5 changes: 2 additions & 3 deletions js/common/view/WorkspaceNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,15 @@ define( function( require ) {

// add smile face
this.addChild( new FaceWithScoreConfiguredNode(
model.game.property( 'scoreGame' ),
model.game.property( 'isFaceVisible' )
model.smileFace
).mutate( {bottom: layoutBounds.maxY * 0.95, left: layoutBounds.maxX * 0.04} )
);

// add node with statistic (will be shown after completing level)
this.addChild( new LevelCompletedConfiguredNode(
model.levels,
model.property( 'level' ),
model.property( 'isLevelCompleted' ),
model.game.property( 'state' ),
model.property( 'scoreTotal' ),
model.property( 'isTimer' ),
model.property( 'time' ),
Expand Down
15 changes: 14 additions & 1 deletion js/common/view/table/MultiplicationTableNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ define( function( require ) {
var VBox = require( 'SCENERY/nodes/VBox' );

// constants
var GAME_STATE = require( 'ARITHMETIC/common/enum/GameState' );
var TABLE_SIZE = Constants.SIZE;

function MultiplicationTableNode( levelProperty, levels ) {
function MultiplicationTableNode( levelProperty, levels, gameModel ) {
var self = this;
Node.call( this );

Expand Down Expand Up @@ -102,6 +103,18 @@ define( function( require ) {
self.clearCells( levelNumberPrev );
}
} );

gameModel.property( 'state' ).link( function( state ) {
if ( state === GAME_STATE.NEXT_TASK ) {
gameModel.answerSheet.forEach( function( multipliersLeft, multipliersLeftIndex ) {
multipliersLeft.forEach( function( isVisible, multipliersRightIndex ) {
if ( isVisible ) {
self.cells[levelProperty.value - 1][multipliersLeftIndex + 1][multipliersRightIndex + 1].showText();
}
} );
} );
}
} );
}

return inherit( Node, MultiplicationTableNode, {
Expand Down
18 changes: 10 additions & 8 deletions js/divide/model/DivideModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ define( function( require ) {
// get available multipliers
var multipliers = this.game.getAvailableMultipliers();

// set product
this.game.product = multipliers.multiplierLeft * multipliers.multiplierRight;
if ( multipliers ) {
// set product
this.game.product = multipliers.multiplierLeft * multipliers.multiplierRight;

// set left or right multiplier
if ( Math.random() < 0.5 ) {
this.game.multiplierLeft = multipliers.multiplierLeft;
}
else {
this.game.multiplierRight = multipliers.multiplierRight;
// set left or right multiplier
if ( Math.random() < 0.5 ) {
this.game.multiplierLeft = multipliers.multiplierLeft;
}
else {
this.game.multiplierRight = multipliers.multiplierRight;
}
}
}
} );
Expand Down
2 changes: 1 addition & 1 deletion js/divide/view/MultiplicationTableDivideNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ define( function( require ) {

function MultiplicationTableDivideNode( gameModel, levelProperty, levels ) {
var self = this;
MultiplicationTableNode.call( this, levelProperty, levels );
MultiplicationTableNode.call( this, levelProperty, levels, gameModel );

// set left multiplier selected
gameModel.property( 'multiplierLeft' ).lazyLink( function() {
Expand Down
Loading

0 comments on commit 9dd2e69

Please sign in to comment.