diff --git a/js/level-out/model/LevelOutModel.ts b/js/level-out/model/LevelOutModel.ts index cba829a..2c47565 100644 --- a/js/level-out/model/LevelOutModel.ts +++ b/js/level-out/model/LevelOutModel.ts @@ -44,6 +44,7 @@ export default class LevelOutModel implements TModel { public readonly notepadCups: Cup[]; public readonly pipeArray: Pipe[]; public readonly arePipesOpenProperty: Property; + public readonly arePipesEnabledProperty: Property; public readonly doWaterLevelsMatchMeanProperty: TReadOnlyProperty; // visible properties @@ -96,6 +97,9 @@ export default class LevelOutModel implements TModel { this.arePipesOpenProperty = new BooleanProperty( false, { tandem: options.tandem.createTandem( 'arePipesOpenProperty' ) } ); + this.arePipesEnabledProperty = new BooleanProperty( true, { + tandem: options.tandem.createTandem( 'arePipesEnabledProperty' ) + } ); // The tableCups are the "ground truth" and the notepadCups mirror them. this.tableCups = []; diff --git a/js/level-out/view/LevelOutControls.ts b/js/level-out/view/LevelOutControls.ts index 5cdea5b..79b1b26 100644 --- a/js/level-out/view/LevelOutControls.ts +++ b/js/level-out/view/LevelOutControls.ts @@ -36,6 +36,7 @@ export default class LevelOutControls extends MeanShareAndBalanceControls { numberOfCupsProperty: Property, numberOfCupsRangeProperty: Property, arePipesOpenProperty: Property, + arePipesEnabledProperty: Property, providedOptions: LevelOutControlPanelOptions ) { // Checkbox Group @@ -46,7 +47,9 @@ export default class LevelOutControls extends MeanShareAndBalanceControls { } ); // Pipe Switch - const pipeSwitch = new PipeSwitch( arePipesOpenProperty, providedOptions.tandem.createTandem( 'pipeSwitch' ) ); + const pipeSwitch = new PipeSwitch( + arePipesOpenProperty, arePipesEnabledProperty, + providedOptions.tandem.createTandem( 'pipeSwitch' ) ); // Hook up Number Spinner callbacks. numberOfCupsProperty.link( () => { diff --git a/js/level-out/view/LevelOutScreenView.ts b/js/level-out/view/LevelOutScreenView.ts index 363756e..25aa948 100644 --- a/js/level-out/view/LevelOutScreenView.ts +++ b/js/level-out/view/LevelOutScreenView.ts @@ -50,8 +50,10 @@ export default class LevelOutScreenView extends MeanShareAndBalanceScreenView { const options = providedOptions; - const modelViewTransformNotepadCups = ModelViewTransform2.createSinglePointScaleInvertedYMapping( new Vector2( 0, 0 ), new Vector2( 0, MeanShareAndBalanceConstants.NOTEPAD_CUPS_CENTER_Y ), MeanShareAndBalanceConstants.CUP_HEIGHT ); - const modelViewTransformTableCups = ModelViewTransform2.createSinglePointScaleInvertedYMapping( new Vector2( 0, 0 ), new Vector2( 0, MeanShareAndBalanceConstants.TABLE_CUPS_CENTER_Y ), MeanShareAndBalanceConstants.CUP_HEIGHT ); + const modelViewTransformNotepadCups = ModelViewTransform2.createSinglePointScaleInvertedYMapping( new Vector2( 0, 0 ), + new Vector2( 0, MeanShareAndBalanceConstants.NOTEPAD_CUPS_CENTER_Y ), MeanShareAndBalanceConstants.CUP_HEIGHT ); + const modelViewTransformTableCups = ModelViewTransform2.createSinglePointScaleInvertedYMapping( new Vector2( 0, 0 ), + new Vector2( 0, MeanShareAndBalanceConstants.TABLE_CUPS_CENTER_Y ), MeanShareAndBalanceConstants.CUP_HEIGHT ); // Create the sound that will be played when the mean prediction become correct. const meanPredictionSuccessSoundClip = new SoundClip( selectionArpeggio009_mp3, { initialOutputLevel: 0.1 } ); @@ -124,7 +126,8 @@ export default class LevelOutScreenView extends MeanShareAndBalanceScreenView { // Add all cup nodes to the view. const notepadCupNodes: Array = []; model.notepadCups.forEach( ( cupModel, index ) => { - const cupNode = new NotepadCupNode( cupModel, model.tableCups[ index ], modelViewTransformNotepadCups, model.meanProperty, model.tickMarksVisibleProperty, + const cupNode = new NotepadCupNode( cupModel, model.tableCups[ index ], modelViewTransformNotepadCups, + model.meanProperty, model.tickMarksVisibleProperty, { tandem: notepadCupsParentTandem.createTandem( `notepadCupNode${cupModel.linePlacement + 1}` ) } ); notepadCupNodes.push( cupNode ); } ); @@ -143,7 +146,8 @@ export default class LevelOutScreenView extends MeanShareAndBalanceScreenView { const pipeNodes: Array = []; model.pipeArray.forEach( pipeModel => { const index = model.pipeArray.indexOf( pipeModel ); - const pipeNode = new PipeNode( pipeModel, model.arePipesOpenProperty, modelViewTransformNotepadCups, + const pipeNode = new PipeNode( pipeModel, model.arePipesOpenProperty, + model.arePipesEnabledProperty, modelViewTransformNotepadCups, { tandem: pipesParentTandem.createTandem( `pipeNode${index + 1}` ), focusable: index === 0 } ); pipeNodes.push( pipeNode ); @@ -181,7 +185,7 @@ export default class LevelOutScreenView extends MeanShareAndBalanceScreenView { // Controls on Right side of screen const controls = new LevelOutControls( model.tickMarksVisibleProperty, model.predictMeanVisibleProperty, model.numberOfCupsProperty, model.numberOfCupsRangeProperty, - model.arePipesOpenProperty, { tandem: options.tandem.createTandem( 'controls' ) } ); + model.arePipesOpenProperty, model.arePipesEnabledProperty, { tandem: options.tandem.createTandem( 'controls' ) } ); const playAreaBounds = new Bounds2( this.layoutBounds.minX, this.layoutBounds.minY + this.questionBar.height, this.layoutBounds.maxX, this.layoutBounds.maxY ); diff --git a/js/level-out/view/PipeNode.ts b/js/level-out/view/PipeNode.ts index d2c1edf..7fcd47c 100644 --- a/js/level-out/view/PipeNode.ts +++ b/js/level-out/view/PipeNode.ts @@ -33,7 +33,8 @@ export default class PipeNode extends InteractiveHighlighting( Node ) { // Public for traversal order public readonly valveNode: ValveNode; - public constructor( pipe: Pipe, arePipesOpenProperty: Property, modelViewTransform: ModelViewTransform2, providedOptions: PipeNodeOptions ) { + public constructor( pipe: Pipe, arePipesOpenProperty: Property, arePipesEnabledProperty: Property, + modelViewTransform: ModelViewTransform2, providedOptions: PipeNodeOptions ) { const options = providedOptions; // Pipe & valve dimensions @@ -97,6 +98,7 @@ export default class PipeNode extends InteractiveHighlighting( Node ) { const combinedOptions = combineOptions( { visibleProperty: pipe.isActiveProperty, + enabledProperty: arePipesEnabledProperty, children: [ pipeRectangle, pipeStrokeLeft, pipeStrokeBottom, pipeStrokeTop, pipeStrokeRight, valveNode ] }, options ); super( combinedOptions ); @@ -115,6 +117,10 @@ export default class PipeNode extends InteractiveHighlighting( Node ) { // interactive highlighting - set a custom highlight because the pipe nodes have a unique combined highlight // collectively in the ScreenView this.interactiveHighlight = Shape.bounds( this.localBounds ); + + arePipesEnabledProperty.link( enabled => { + enabled ? this.opacity = 1 : this.opacity = 0.5; + } ); } } diff --git a/js/level-out/view/PipeSwitch.ts b/js/level-out/view/PipeSwitch.ts index a0162a6..dad0633 100644 --- a/js/level-out/view/PipeSwitch.ts +++ b/js/level-out/view/PipeSwitch.ts @@ -14,31 +14,32 @@ import Vector2 from '../../../../dot/js/Vector2.js'; import Dimension2 from '../../../../dot/js/Dimension2.js'; import ABSwitch, { ABSwitchOptions } from '../../../../sun/js/ABSwitch.js'; import Tandem from '../../../../tandem/js/Tandem.js'; -import { combineOptions } from '../../../../phet-core/js/optionize.js'; import nullSoundPlayer from '../../../../tambo/js/shared-sound-players/nullSoundPlayer.js'; export default class PipeSwitch extends ABSwitch { - public constructor( arePipesOpenProperty: Property, tandem: Tandem ) { + public constructor( arePipesOpenProperty: Property, arePipesEnabledProperty: Property, tandem: Tandem ) { + + const closedValveIcon = new ValveNode( new Vector2( 0, 0 ), new Property( 0 ) ); + + const openValveIcon = new ValveNode( new Vector2( 0, 0 ), new Property( Math.PI / 2 ) ); + + const options: ABSwitchOptions = { + align: 'top', + justify: 'left', + enabledProperty: arePipesEnabledProperty, + tandem: tandem, - const options = { toggleSwitchOptions: { size: new Dimension2( 40, 20 ), // Turn off default sound production for switch - sounds for the pipes changing are handled elsewhere. switchToLeftSoundPlayer: nullSoundPlayer, switchToRightSoundPlayer: nullSoundPlayer - }, - tandem: tandem + } }; - const closedValveIcon = new ValveNode( new Vector2( 0, 0 ), new Property( 0 ) ); - - const openValveIcon = new ValveNode( new Vector2( 0, 0 ), new Property( Math.PI / 2 ) ); - - const combinedOptions = combineOptions( { align: 'top', justify: 'left' }, options ); - - super( arePipesOpenProperty, false, closedValveIcon, true, openValveIcon, combinedOptions ); + super( arePipesOpenProperty, false, closedValveIcon, true, openValveIcon, options ); } }