From 49904f80687ee2262e984a1de14da92420a09af4 Mon Sep 17 00:00:00 2001 From: Luisav1 Date: Wed, 14 Sep 2022 18:36:05 -0600 Subject: [PATCH] Add query parameters for the nucleon counts. See https://github.com/phetsims/build-a-nucleus/issues/57. --- js/chart-intro/view/ChartIntroScreenView.ts | 8 +---- js/common/BANQueryParameters.ts | 35 ++++++++++++++++++++ js/common/view/BANScreenView.ts | 20 ++++++++++++ js/decay/view/DecayScreenView.ts | 36 +++++++++------------ 4 files changed, 72 insertions(+), 27 deletions(-) create mode 100644 js/common/BANQueryParameters.ts diff --git a/js/chart-intro/view/ChartIntroScreenView.ts b/js/chart-intro/view/ChartIntroScreenView.ts index 048c5b2..5dacaab 100644 --- a/js/chart-intro/view/ChartIntroScreenView.ts +++ b/js/chart-intro/view/ChartIntroScreenView.ts @@ -31,15 +31,12 @@ import PeriodicTableAndIsotopeSymbol from './PeriodicTableAndIsotopeSymbol.js'; // constants const LABEL_FONT = new PhetFont( BANConstants.REGULAR_FONT_SIZE ); const NUCLEON_CAPTURE_RADIUS = 100; -const NUMBER_OF_NUCLEON_LAYERS = 22; // This is based on max number of particles, may need adjustment if that changes. // types export type NuclideChartIntroScreenViewOptions = BANScreenViewOptions; class ChartIntroScreenView extends BANScreenView { - public static NUMBER_OF_NUCLEON_LAYERS: number; - private readonly atomNode: Node; // layers where nucleons exist @@ -159,7 +156,7 @@ class ChartIntroScreenView extends BANScreenView { // Add the nucleonLayers this.nucleonLayers = []; - _.times( NUMBER_OF_NUCLEON_LAYERS, () => { + _.times( BANScreenView.NUMBER_OF_NUCLEON_LAYERS, () => { const nucleonLayer = new Node(); this.nucleonLayers.push( nucleonLayer ); this.particleViewLayerNode.addChild( nucleonLayer ); @@ -285,8 +282,5 @@ class ChartIntroScreenView extends BANScreenView { } } -// export for usage when creating shred Particles -ChartIntroScreenView.NUMBER_OF_NUCLEON_LAYERS = NUMBER_OF_NUCLEON_LAYERS; - buildANucleus.register( 'ChartIntroScreenView', ChartIntroScreenView ); export default ChartIntroScreenView; \ No newline at end of file diff --git a/js/common/BANQueryParameters.ts b/js/common/BANQueryParameters.ts new file mode 100644 index 0000000..ef8f69c --- /dev/null +++ b/js/common/BANQueryParameters.ts @@ -0,0 +1,35 @@ +// Copyright 2021-2022, University of Colorado Boulder + +/** + * BANQueryParameters defines query parameters that are specific to this simulation. + * + * @author Luisa Vargas + * @author Chris Klusendorf (PhET Interactive Simulations) + */ + + +import buildANucleus from '../buildANucleus.js'; +import BANConstants from './BANConstants.js'; + +const BANQueryParameters = QueryStringMachine.getAll( { + + // the number of neutrons in the atom that the sim starts up with + neutrons: { + public: true, + type: 'number', + defaultValue: 0, + isValidValue: ( number: number ) => Number.isInteger( number ) && number >= 0 && number <= BANConstants.MAX_NUMBER_OF_NEUTRONS + }, + + // the number of protons in the atom that the sim starts up with + protons: { + public: true, + type: 'number', + defaultValue: 0, + isValidValue: ( number: number ) => Number.isInteger( number ) && number >= 0 && number <= BANConstants.MAX_NUMBER_OF_PROTONS + } + +} ); + +buildANucleus.register( 'BANQueryParameters', BANQueryParameters ); +export default BANQueryParameters; \ No newline at end of file diff --git a/js/common/view/BANScreenView.ts b/js/common/view/BANScreenView.ts index 73af779..3336cb3 100644 --- a/js/common/view/BANScreenView.ts +++ b/js/common/view/BANScreenView.ts @@ -35,6 +35,7 @@ import arrayRemove from '../../../../phet-core/js/arrayRemove.js'; const MIN_ELECTRON_CLOUD_RADIUS = 42.5; const TOUCH_AREA_Y_DILATION = 3; +const NUMBER_OF_NUCLEON_LAYERS = 22; // This is based on max number of particles, may need adjustment if that changes. // types export type BANScreenViewOptions = ScreenViewOptions; @@ -45,6 +46,8 @@ const HORIZONTAL_DISTANCE_BETWEEN_ARROW_BUTTONS = 160; abstract class BANScreenView extends ScreenView { + public static NUMBER_OF_NUCLEON_LAYERS: number; + protected model: M; private timeSinceCountdownStarted: number; private previousProtonCount: number; @@ -414,6 +417,20 @@ abstract class BANScreenView extends ScreenView { this.protonArrowButtons = protonArrowButtons; } + /** + * Create and add a nucleon of particleType immediately to the particleAtom. + */ + public addNucleonImmediatelyToAtom( particleType: ParticleType ): void { + const particle = new Particle( particleType.name.toLowerCase(), { + maxZLayer: BANScreenView.NUMBER_OF_NUCLEON_LAYERS - 1 + } ); + + // place the particle the center of the particleAtom and add it to the model and particleAtom + particle.setPositionAndDestination( this.model.particleAtom.positionProperty.value ); + this.model.addParticle( particle ); + this.model.particleAtom.addParticle( particle ); + } + /** * Set the input enabled and visibility of a creator node. */ @@ -611,5 +628,8 @@ abstract class BANScreenView extends ScreenView { } } +// export for usage when creating shred Particles +BANScreenView.NUMBER_OF_NUCLEON_LAYERS = NUMBER_OF_NUCLEON_LAYERS; + buildANucleus.register( 'BANScreenView', BANScreenView ); export default BANScreenView; \ No newline at end of file diff --git a/js/decay/view/DecayScreenView.ts b/js/decay/view/DecayScreenView.ts index 140c444..afd463d 100644 --- a/js/decay/view/DecayScreenView.ts +++ b/js/decay/view/DecayScreenView.ts @@ -40,11 +40,11 @@ import StringUtils from '../../../../phetcommon/js/util/StringUtils.js'; import Multilink from '../../../../axon/js/Multilink.js'; import ReturnButton from '../../../../scenery-phet/js/buttons/ReturnButton.js'; import StringProperty from '../../../../axon/js/StringProperty.js'; +import BANQueryParameters from '../../common/BANQueryParameters.js'; // constants const LABEL_FONT = new PhetFont( BANConstants.REGULAR_FONT_SIZE ); const NUCLEON_CAPTURE_RADIUS = 100; -const NUMBER_OF_NUCLEON_LAYERS = 22; // This is based on max number of particles, may need adjustment if that changes. const NUMBER_OF_PROTONS_IN_ALPHA_PARTICLE = 2; const NUMBER_OF_NEUTRONS_IN_ALPHA_PARTICLE = 2; @@ -53,8 +53,6 @@ export type DecayScreenViewOptions = BANScreenViewOptions; class DecayScreenView extends BANScreenView { - public static NUMBER_OF_NUCLEON_LAYERS: number; - private readonly stabilityIndicator: Text; private readonly atomNode: Node; @@ -151,7 +149,7 @@ class DecayScreenView extends BANScreenView { for ( let i = 0; i < Math.abs( nucleonCountDifference ); i++ ) { if ( nucleonCountDifference > 0 ) { - addNucleonImmediatelyToAtom( particleType ); + this.addNucleonImmediatelyToAtom( particleType ); } else if ( nucleonCountDifference < 0 ) { removeNucleonImmediatelyFromAtom( particleType ); @@ -165,18 +163,6 @@ class DecayScreenView extends BANScreenView { this.animateAndRemoveParticle( particleToRemove ); }; - // create and add a nucleon of particleType immediately to the particleAtom - const addNucleonImmediatelyToAtom = ( particleType: ParticleType ) => { - const particle = new Particle( particleType.name.toLowerCase(), { - maxZLayer: DecayScreenView.NUMBER_OF_NUCLEON_LAYERS - 1 - } ); - - // place the particle the center of the particleAtom and add it to the model and particleAtom - particle.setPositionAndDestination( this.model.particleAtom.positionProperty.value ); - this.model.addParticle( particle ); - this.model.particleAtom.addParticle( particle ); - }; - // show the undoDecayButton const showAndRepositionUndoDecayButton = ( decayType: string ) => { repositionUndoDecayButton( decayType ); @@ -293,6 +279,7 @@ class DecayScreenView extends BANScreenView { // update the cloud size as the massNumber changes model.particleAtom.protonCountProperty.link( updateCloudSize ); + // TODO: should be moved to BANScreenView bc repeated in Chart screen view // Maps a number of electrons to a diameter in screen coordinates for the electron shell. This mapping function is // based on the real size relationships between the various atoms, but has some tweakable parameters to reduce the // range and scale to provide values that are usable for our needs on the canvas. @@ -372,7 +359,7 @@ class DecayScreenView extends BANScreenView { // Add the nucleonLayers this.nucleonLayers = []; - _.times( NUMBER_OF_NUCLEON_LAYERS, () => { + _.times( BANScreenView.NUMBER_OF_NUCLEON_LAYERS, () => { const nucleonLayer = new Node(); this.nucleonLayers.push( nucleonLayer ); this.particleViewLayerNode.addChild( nucleonLayer ); @@ -472,6 +459,18 @@ class DecayScreenView extends BANScreenView { this.nucleonLayers[ zLayer ].addChild( particleView! ); } } ); + + // TODO: should be moved to BANScreenView + // add initial neutrons and protons specified by the query parameters to the atom + _.times( Math.max( BANQueryParameters.neutrons, BANQueryParameters.protons ), () => { + if ( this.model.particleAtom.neutronCountProperty.value < BANQueryParameters.neutrons ) { + this.addNucleonImmediatelyToAtom( ParticleType.NEUTRON ); + } + if ( this.model.particleAtom.protonCountProperty.value < BANQueryParameters.protons ) { + this.addNucleonImmediatelyToAtom( ParticleType.PROTON ); + } + // TODO: need to detect if this forms a nuclide that shouldn't exist and then call QueryStringMachine.addWarning here and model.reset() + } ); } /** @@ -670,8 +669,5 @@ class DecayScreenView extends BANScreenView { } } -// export for usage when creating shred Particles -DecayScreenView.NUMBER_OF_NUCLEON_LAYERS = NUMBER_OF_NUCLEON_LAYERS; - buildANucleus.register( 'DecayScreenView', DecayScreenView ); export default DecayScreenView; \ No newline at end of file