From 9517567915bf7308b9c66b75f38d67e4413374d3 Mon Sep 17 00:00:00 2001 From: Luisav1 Date: Fri, 17 Dec 2021 14:42:42 -0700 Subject: [PATCH] Create all levels and level selection buttons but don't add all buttons based off of the gameLevels query parameter. See https://github.com/phetsims/number-play/issues/105. --- js/game/model/NumberPlayGameModel.ts | 26 +--------- .../view/NumberPlayGameLevelSelectionNode.ts | 50 +++++++++++++++---- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/js/game/model/NumberPlayGameModel.ts b/js/game/model/NumberPlayGameModel.ts index 4dc1d249..81a97d92 100644 --- a/js/game/model/NumberPlayGameModel.ts +++ b/js/game/model/NumberPlayGameModel.ts @@ -12,8 +12,6 @@ import Tandem from '../../../../tandem/js/Tandem.js'; import numberPlay from '../../numberPlay.js'; import SubitizeGameLevel from './SubitizeGameLevel.js'; import CountingGameLevel from './CountingGameLevel.js'; -import NumberPlayQueryParameters from '../../common/NumberPlayQueryParameters.js'; -import NumberPlayConstants from '../../common/NumberPlayConstants.js'; import NumberPlayGameLevel from './NumberPlayGameLevel.js'; class NumberPlayGameModel { @@ -25,15 +23,9 @@ class NumberPlayGameModel { constructor( tandem: Tandem ) { - // get the level numbers specified by the gameLevels query parameter - const gameALevelNumbers = NumberPlayGameModel.getLevelNumbers( NumberPlayQueryParameters.gameLevels, - NumberPlayConstants.A ); - const gameBLevelNumbers = NumberPlayGameModel.getLevelNumbers( NumberPlayQueryParameters.gameLevels, - NumberPlayConstants.B ); - // create the levels for each game - this.countingLevels = gameALevelNumbers.map( gameALevelNumber => new CountingGameLevel( gameALevelNumber ) ); - this.subitizeLevels = gameBLevelNumbers.map( gameBLevelNumber => new SubitizeGameLevel( gameBLevelNumber ) ); + this.countingLevels = [ new CountingGameLevel( 1 ), new CountingGameLevel( 2 ) ]; + this.subitizeLevels = [ new SubitizeGameLevel( 1 ), new SubitizeGameLevel( 2 ) ]; this.levels = [ ...this.countingLevels, ...this.subitizeLevels ]; // the selected game level - null means 'no selection' so that the view returns to the level-selection UI @@ -52,20 +44,6 @@ class NumberPlayGameModel { public step( dt: number ): void { this.levels.forEach( level => level.step( dt ) ); } - - /** - * Returns the level number for each level code that matches the provided level character by extracting the level - * numbers from the level codes. It also sorts them to ensure level x is displayed before level x+1 in case the level - * codes were provided out of order. - * - * @param levelCodes - the array of two-character codes that represent game levels - * @param levelCharacter - the character that indicates which level codes should be kept and turned into numbers - */ - private static getLevelNumbers( levelCodes: string[], levelCharacter: string ): number[] { - const levelsCodesToInclude = levelCodes.filter( levelCode => levelCode.includes( levelCharacter ) ); - const levelNumbers = levelsCodesToInclude.map( levelName => parseInt( levelName.replace( levelCharacter, '' ) ) ); // eslint-disable-line - return _.sortBy( levelNumbers ); - } } numberPlay.register( 'NumberPlayGameModel', NumberPlayGameModel ); diff --git a/js/game/view/NumberPlayGameLevelSelectionNode.ts b/js/game/view/NumberPlayGameLevelSelectionNode.ts index f7f603b6..d1f7e2f5 100644 --- a/js/game/view/NumberPlayGameLevelSelectionNode.ts +++ b/js/game/view/NumberPlayGameLevelSelectionNode.ts @@ -10,7 +10,7 @@ import Bounds2 from '../../../../dot/js/Bounds2.js'; import ResetAllButton from '../../../../scenery-phet/js/buttons/ResetAllButton.js'; -import { ColorProperty, HBox, Image, Node, Text, VBox } from '../../../../scenery/js/imports.js'; +import { ColorProperty, HBox, Image, Node, ProfileColorProperty, Text, VBox } from '../../../../scenery/js/imports.js'; import LevelSelectionButton from '../../../../vegas/js/LevelSelectionButton.js'; import ScoreDisplayNumberAndStar from '../../../../vegas/js/ScoreDisplayNumberAndStar.js'; import NumberPlayConstants from '../../common/NumberPlayConstants.js'; @@ -24,6 +24,7 @@ import countingGameIcon1 from '../../../images/counting_game_icon_1_png.js'; import subitizeGameIcon2 from '../../../images/subitize_game_icon_2_png.js'; import countingGameIcon2 from '../../../images/counting_game_icon_2_png.js'; import NumberPlayGameLevel from '../model/NumberPlayGameLevel.js'; +import NumberPlayQueryParameters from '../../common/NumberPlayQueryParameters.js'; // types type GameLevelToButtonImageType = { @@ -58,8 +59,8 @@ class NumberPlayGameLevelSelectionNode extends Node { titleText.top = layoutBounds.top + 42; this.addChild( titleText ); - // creates a level-selection button for each level - const createLevelSelectionButton = ( level: NumberPlayGameLevel, baseColor: ColorProperty ) => { + // creates a level selection button for each level + const createLevelSelectionButton = ( level: NumberPlayGameLevel, baseColor: ColorProperty ): LevelSelectionButton => { return new LevelSelectionButton( new Image( GAME_LEVEL_TO_BUTTON_IMAGE[ level.gameName ][ level.levelNumber ] ), level.scoreProperty, { iconToScoreDisplayYSpace: 0, @@ -73,15 +74,28 @@ class NumberPlayGameLevelSelectionNode extends Node { } ); }; - // create the level selection buttons for the 'Counting' game - const countingGameLevelSelectionButtons = model.countingLevels.map( - level => createLevelSelectionButton( level, NumberPlayColors.countingGameColorProperty ) - ); + // creates all level selection buttons for a level and returns only the levels specified by the gameLevels query parameter + const getLevelSelectionButtons = ( + levels: NumberPlayGameLevel[], + gameType: string, + gameColorProperty: ProfileColorProperty + ): LevelSelectionButton[] => { + const levelSelectionButtons: LevelSelectionButton[] = []; + const levelNumbers = NumberPlayGameLevelSelectionNode.getLevelNumbers( NumberPlayQueryParameters.gameLevels, gameType ); + levels.forEach( level => { + const levelSelectionButton = createLevelSelectionButton( level, gameColorProperty ); + if ( levelNumbers.includes( level.levelNumber ) ) { + levelSelectionButtons.push( levelSelectionButton ); + } + } ); + return levelSelectionButtons; + }; - // create the level selection buttons for the 'Subitize' game - const subitizeGameLevelSelectionButtons = model.subitizeLevels.map( - level => createLevelSelectionButton( level, NumberPlayColors.subitizeGameColorProperty ) - ); + // create the level selection buttons for the each game + const countingGameLevelSelectionButtons = getLevelSelectionButtons( model.countingLevels, NumberPlayConstants.A, + NumberPlayColors.countingGameColorProperty ); + const subitizeGameLevelSelectionButtons = getLevelSelectionButtons( model.subitizeLevels, NumberPlayConstants.B, + NumberPlayColors.subitizeGameColorProperty ); // arrange and add the level selection buttons const levelSelectionButtonsBox = new VBox( { @@ -111,6 +125,20 @@ class NumberPlayGameLevelSelectionNode extends Node { } ); this.addChild( resetAllButton ); } + + /** + * Returns the level number for each level code that matches the provided level character by extracting the level + * numbers from the level codes. It also sorts them to ensure level x is displayed before level x+1 in case the level + * codes were provided out of order. + * + * @param levelCodes - the array of two-character codes that represent game levels + * @param levelCharacter - the character that indicates which level codes should be kept and turned into numbers + */ + private static getLevelNumbers( levelCodes: string[], levelCharacter: string ): number[] { + const levelsCodesToInclude = levelCodes.filter( levelCode => levelCode.includes( levelCharacter ) ); + const levelNumbers = levelsCodesToInclude.map( levelName => parseInt( levelName.replace( levelCharacter, '' ) ) ); // eslint-disable-line + return _.sortBy( levelNumbers ); + } } numberPlay.register( 'NumberPlayGameLevelSelectionNode', NumberPlayGameLevelSelectionNode );