Skip to content

Commit

Permalink
Moved AtomNode => model/Atom, see #64
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Feb 15, 2018
1 parent 518484d commit cb6fa54
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013-2018, University of Colorado Boulder

/**
* Displays a single atom
* Model for a single atom
*
* @author Andrey Zelenkov (Mlearner)
* @author John Blanco (PhET Interactive Simulations)
Expand All @@ -11,39 +11,33 @@ define( function( require ) {
'use strict';

// modules
var Circle = require( 'SCENERY/nodes/Circle' );
var friction = require( 'FRICTION/friction' );
var FrictionConstants = require( 'FRICTION/friction/FrictionConstants' );
var Image = require( 'SCENERY/nodes/Image' );
var inherit = require( 'PHET_CORE/inherit' );
var Node = require( 'SCENERY/nodes/Node' );
var Util = require( 'DOT/Util' );
var Vector2 = require( 'DOT/Vector2' );

// constants
var STEPS = 250; // steps until atom has completed evaporation movement
var IMAGE_SCALE = 3;
var ATOM_NODES = {}; // key = {string} color, value = node

/**
* @param {FrictionModel} model
* @param {Object} [options]
* @constructor
*/
function AtomNode( model, options ) {
function Atom( model, options ) {
var self = this;
var radius = model.atoms.radius;

// @public (read-only) {boolean} flag records whether we are on the top book
this.isTopAtom = options.color === FrictionConstants.TOP_BOOK_ATOMS_COLOR;

// @private - marked as true when the atom is evaporated
this.isEvaporated = false;

// @public {number} - the x-position of the AtomNode
// @public {number} - the x-position of the Atom
this.positionX = 0;

// @public {number} - the y-position of the AtomNode
// @public {number} - the y-position of the Atom
this.positionY = 0;

// @private {number} - origin for oscillation
Expand All @@ -61,30 +55,6 @@ define( function( require ) {
// @private {number} initial coordinate for resetting
this.initialY = options.y;

Node.call( this, { x: this.originX, y: this.originY } );

// function for creating or obtaining atom graphic for a given color
if ( !ATOM_NODES[ options.color ] ) {

// Scale up before rasterization so it won't be too pixellated/fuzzy, value empirically determined.
var container = new Node( { scale: 1 / IMAGE_SCALE } );

// TODO: should we use shaded sphere?
var atomNode = new Circle( radius, { fill: options.color, stroke: 'black', lineWidth: 1, scale: IMAGE_SCALE } );
atomNode.addChild( new Circle( radius * 0.3, { fill: 'white', x: radius * 0.3, y: -radius * 0.3 } ) );
atomNode.toImage( function( img, x, y ) {

// add a node with that image to our container
container.addChild( new Node( {
children: [
new Image( img, { x: -x, y: -y } )
]
} ) );
} );
ATOM_NODES[ options.color ] = container;
}
this.addChild( ATOM_NODES[ options.color ] );

// move the atom as the top book moves if it is part of that book
var motionVector = new Vector2(); // Optimization to minimize garbage collection.
model.bookPositionProperty.lazyLink( function( newPosition, oldPosition ) {
Expand All @@ -103,16 +73,16 @@ define( function( require ) {
} );
}

friction.register( 'AtomNode', AtomNode );
friction.register( 'Atom', Atom );

return inherit( Node, AtomNode, {
return inherit( Object, Atom, {

/**
* When the oscillation has exceeded the threshold, the AtomNode animates to one side of the screen and disappears.
* When the oscillation has exceeded the threshold, the Atom animates to one side of the screen and disappears.
* @public
*/
evaporate: function() {
assert && assert( !this.isEvaporated, 'AtomNode was already evaporated' );
assert && assert( !this.isEvaporated, 'Atom was already evaporated' );
var self = this;

this.isEvaporated = true;
Expand All @@ -131,14 +101,14 @@ define( function( require ) {

if ( Math.abs( self.originX ) > 4 * self.model.width ) {
self.model.stepEmitter.removeListener( self.handler );
self.setVisible( false );
}
};

this.model.stepEmitter.addListener( self.handler );
},

/**
* Restores the initial conditions.
* @public
*/
reset: function() {
Expand All @@ -149,8 +119,7 @@ define( function( require ) {
if ( this.model.stepEmitter.hasListener( this.handler ) ) {
this.model.stepEmitter.removeListener( this.handler );
}
this.setVisible( true );
this.isEvaporated = false;
}
} );
} );
} );
12 changes: 6 additions & 6 deletions js/friction/model/FrictionModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ define( function( require ) {
tandem: tandem.createTandem( 'evaporationEmitter' )
} );

// @public - array of all AtomNodes which able to evaporate, need for resetting game
// @public - array of all Atoms which able to evaporate, need for resetting game
// TODO: Why does the model have arrays of Nodes?
this.toEvaporateSample = [];

// @public (read-only) - current set of AtomNodes which may evaporate, but not yet evaporated (generally the lowest
// @public (read-only) - current set of Atoms which may evaporate, but not yet evaporated (generally the lowest
// row in the top book)
// TODO: it seems incorrect to have a list of Nodes in the model
this.toEvaporate = [];
Expand Down Expand Up @@ -272,7 +272,7 @@ define( function( require ) {
},

/**
* This must be called after MagnifierNode adds AtomNodes to the toEvaporateSample, or atoms don't fly off
* This must be called after MagnifierNode adds Atoms to the toEvaporateSample, or atoms don't fly off
* TODO: It would be better if this could be called during the constructor and didn't need a view step first
* @public
*/
Expand Down Expand Up @@ -344,9 +344,9 @@ define( function( require ) {

// choose a random atom from the current row and evaporate it
var currentEvaporationRow = this.toEvaporate[ this.toEvaporate.length - 1 ];
var atomNode = currentEvaporationRow.splice( Math.floor( phet.joist.random.nextDouble() * currentEvaporationRow.length ), 1 )[ 0 ];
if ( atomNode ) {
atomNode.evaporate();
var atom = currentEvaporationRow.splice( Math.floor( phet.joist.random.nextDouble() * currentEvaporationRow.length ), 1 )[ 0 ];
if ( atom ) {
atom.evaporate();
this.evaporationEmitter.emit();

// cooling due to evaporation
Expand Down
2 changes: 1 addition & 1 deletion js/friction/view/FrictionScreenView.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ define( function( require ) {
tandem: tandem.createTandem( 'resetAllButton' )
} ) );

// Initialize the model now that MagnifierNode has added the toEvaporateSample AtomNodes
// Initialize the model now that MagnifierNode has added the toEvaporateSample Atoms
model.init();
}

Expand Down
12 changes: 6 additions & 6 deletions js/friction/view/magnifier/AtomCanvasNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ define( function( require ) {
);
context.fill();

// @private - array that holds the AtomNode views
// @private - array that holds the Atoms
this.atomCanvasNodeAtoms = [];
}

Expand All @@ -105,23 +105,23 @@ define( function( require ) {

// render each of the atoms on the canvas
for ( var i = 0; i < this.atomCanvasNodeAtoms.length; i++ ) {
var atomNode = this.atomCanvasNodeAtoms[ i ];
var atom = this.atomCanvasNodeAtoms[ i ];
context.drawImage(
this.particleImageCanvas,
atomNode.isTopAtom ? 0 : PARTICLE_IMAGE_SIZE,
atom.isTopAtom ? 0 : PARTICLE_IMAGE_SIZE,
0,
PARTICLE_IMAGE_SIZE,
PARTICLE_IMAGE_SIZE,
atomNode.positionX - particleImageSize / 2,
atomNode.positionY - particleImageSize / 2,
atom.positionX - particleImageSize / 2,
atom.positionY - particleImageSize / 2,
particleImageSize,
particleImageSize
);
}
},

/**
* When an AtomNode view is created, we want a reference so we can quickly scan a list of atoms
* When an Atom is created, we want a reference so we can quickly scan a list of atoms
* @param atom
* @public
*/
Expand Down
10 changes: 5 additions & 5 deletions js/friction/view/magnifier/MagnifierNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ define( function( require ) {
var AccessiblePeer = require( 'SCENERY/accessibility/AccessiblePeer' );
var ArrowNode = require( 'SCENERY_PHET/ArrowNode' );
var AtomCanvasNode = require( 'FRICTION/friction/view/magnifier/AtomCanvasNode' );
var AtomNode = require( 'FRICTION/friction/view/magnifier/AtomNode' );
var Atom = require( 'FRICTION/friction/model/Atom' );
var Bounds2 = require( 'DOT/Bounds2' );
var Circle = require( 'SCENERY/nodes/Circle' );
var DragHandler = require( 'FRICTION/friction/view/DragHandler' );
Expand Down Expand Up @@ -250,7 +250,7 @@ define( function( require ) {

// @private - Add the canvas where the atoms will be rendered. NOTE: For better performance (particularly on iPad), we are
// using CanvasNode to render the atoms instead of individual nodes. All atoms are displayed there, even though we
// still create AtomNode view instances.
// still create Atom instances.
this.atomCanvasNode = new AtomCanvasNode( {
canvasBounds: new Bounds2( 0, 0, WIDTH, HEIGHT )
} );
Expand Down Expand Up @@ -317,11 +317,11 @@ define( function( require ) {
var offset = layer[ i ].offset || 0;
evaporate = layer[ i ].evaporate || false;
for ( var n = 0; n < layer[ i ].num; n++ ) {
var atomNode = new AtomNode( model, { y: y, x: x + ( offset + n ) * dx, color: color } );
var atom = new Atom( model, { y: y, x: x + ( offset + n ) * dx, color: color } );
if ( evaporate ) {
row.push( atomNode );
row.push( atom );
}
self.atomCanvasNode.registerAtom( atomNode );
self.atomCanvasNode.registerAtom( atom );
}
}
if ( evaporate ) {
Expand Down

0 comments on commit cb6fa54

Please sign in to comment.