The "display" package has the "Sprite" and the "Graphics" classes.
for timer events
for keystroke events no matter where the user happens to be
Here is the SWF meta tag:
sets stage's background color, etc.
/**
* Copyright bill.billson103 ( http://wonderfl.net/user/bill.billson103 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/QHND
*/
package {
import flash.display.*; // The "display" package has the "Sprite" and the "Graphics" classes.
import flash.geom.*;
import flash.events.*;
import flash.text.*;
import flash.filters.*;
import flash.utils.*; // for timer events
import mx.core.FlexGlobals; // for keystroke events no matter where the user happens to be
// Here is the SWF meta tag:
[SWF(percentWidth = "100%", percentHeight = "100%", backgroundColor = "#efef00", frameRate = "120")] // sets stage's background color, etc.
public class sphereBox extends Sprite { //instead of "extends Sprite", where a sprite is a layer that can be moved and manipulated (like a single graphical sprite might use). Can still use "extends MovieClip" or "extends Sprite", though.
// Declarations for class variables follow.
//protected var username:TextField;
//protected var password:TextField; // protected means that only things from same class or its subclasses can access it
protected var myFormat:TextFormat = new TextFormat();
internal var coordText:TextField = new TextField();
public var moreText:TextField = new TextField(); // publlic means ANY other class can use it (even things in classes from other packages)
internal var extraText:TextField = new TextField(); // internal means ONLY things from classes in the SAME PACKAGE as this class
internal var numClicks:int = 0;
//private var shapes:Array = []; // an array of all the shapes to be used
//private var phases:Array = []; // the phases of the shapes (see this used later)
//private var shapesContainer:Sprite = new Sprite(); // the Sprite holds everything seen later
//private var atom1:myAtomClass = new myAtomClass(); // an atom for displaying
private var theTimer:Timer; // timer for keeping track of time
private var numAtoms:int=6;
private var atoms:Array = new Array();
private var xc:Array = new Array(); // position (units: pixels)
private var yc:Array = new Array();
private var dx:Array = new Array(); // velocity (units: pixels/clock tick)
private var dy:Array = new Array();
private var x1:int=40; // old
private var y1:int=40; // old
private var dx1:int=3; // old
private var dy1:int=2; // old
private var xmin:int=0;
private var ymin:int=0;
private var xmin1:int=0; // old
private var ymin1:int=0; // old
private var xmax:int=stage.width;
private var ymax:int=stage.height;
private var xmax1:int=stage.width; // old
private var ymax1:int=stage.height; // old
private var xBuffer:int=30;
private var yBuffer:int=30;
private var delay:int=20;
private var dxsave:Array = new Array();
private var dysave:Array = new Array();
private var dxsave1:int; // old
private var dysave1:int; // old
private var dxlim:int=20;
private var dylim:int=20;
private var dxlim1:int=20; // old
private var dylim1:int=20; // old
private var sizes:Array = new Array();
private var size1:int=30; // old
private var sizeMax:int=100;
private var sizeMin:int=10;
private var sizeMax1:int=100; // old
private var sizeMin1:int=10; // old
private var gravity:Boolean=false;
private var rotationAngle:Number=0; //old
private var rotationSpeed:Number=5; // old
private var rotAngles:Array= new Array(); // angle of sphere (degrees)
private var rotSpeeds:Array = new Array(); // angular velocity of sphere (degrees/clock tick)
private var noRotation:Boolean = true;
private var doChase:Boolean = false;
private var cursorX:int;
private var cursorY:int;
private var attraction:Boolean=true;
private var wildChase:Boolean=false;
private var helpbox:TextField;
private var infobox:TextField;
private var showingHelpBox:Boolean=false;
private var focus:int=0; // sphere of interest
public function sphereBox() { // the (always) first function is the "constructor" that is triggered when this actionscript is referenced (by the webpage)
super(); // inherit all the imports from the superclass MovieClip for the new class helloWorld.
doInit(); // To set everything up.
// Construct boxes.
/* username = new TextField();
username.text="Enter username";
username.type="input"; // "input" means editable; "dynamic" to disable this
username.border=true;
username.height=20;
username.width=140;
addChild(username);
password = new TextField();
password.text="Password";
password.type="input";
password.y=25;
password.border=true;
password.height=60;
password.width=140;
password.background=true;
password.backgroundColor=0x32788f
password.textColor=0xf3fc44; // Get RGB colors quickly from http://www.colorpicker.com/
password.multiline=true;
password.wordWrap=true; // all these optinos are at http://help.adobe.com/en_US/as3/dev/WS8d7bb3e8da6fb92f-20050207122bd5f80cb-8000.html
addChild(password); */
// Listen for change events from the text fields.
// username.addEventListener(Event.CHANGE, loginChangeHandler);
// password.addEventListener(Event.CHANGE, loginChangeHandler);
stage.addEventListener(MouseEvent.CLICK, _onStageMouseDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE, _onStageMouseMove);
stage.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown); // for only when user has stage active and is in it (i.e. the cursor is)
// infobox.text="Post adding events...";
// FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown); // for no matter where cursor/user happens to be
// Create a Timer-class object in order to give fluid movement.
theTimer = new Timer(delay, 0); // time of one cycle (a.ka. interval) in milliseconds; go for # of cycles given by second argument (0=forever)
theTimer.addEventListener(TimerEvent.TIMER, _onTick); // execute given function at each interval
//stage.addEventListener(TimerEvent.TIMER_COMPLETE, _onTimerComplete); // to do if the timer is finished the given # of cycles
theTimer.start(); // start the timer
// infobox.text="Timer has been started.";
//
// Make a circle.
/* var myCircle:Shape = new Shape(); // The instance with name myCircle is created.
myCircle.graphics.beginFill(0x990000); // Fill the circle with the color #990000.
myCircle.graphics.lineStyle(2, 0x000000); // Give the ellipse a black, two-pixel-thick line.
myCircle.graphics.drawCircle((stage.stageWidth - 100) / 2, (stage.stageHeight - 100) / 2, 100); // Draw the circle, assigning it an x position, y positiion, and a radius.
myCircle.graphics.endFill(); // End the filling of the circle. Must always have this when finished with drawing in the shape.
addChild(myCircle); // Add a child.
var t:TextField = new TextField(); // declares variable as a text field
t.text = "Hello World"; // assigns my words to my variable
t.x = 100; // moves my text to the right 100 pixels
t.y = 150;
t.textColor = 0x0db5ad; // sets the RGB color of the text
t.backgroundColor = 0x111111; // sets the background color for the text that is displayed (hopefully)
t.height = 20;
addChild(t); // displays my variable as text on the screen
*/
/*
moreText.text = "Hello Class!";
moreText.x=100;
moreText.y=200;
moreText.textColor = 0x737306;
addChild(moreText);
extraText.text = "Hello Class!";
extraText.x=200;
extraText.y=175;
extraText.opaqueBackground=true;
extraText.background = true;
extraText.backgroundColor= 0x808000;
extraText.textColor = 0x300000;
addChild(extraText);
*/
} // End of the main function my3Dviewer.
public function doInit():void {
// Do all initializations.
makeBackground();
cursorTracker();
// Using multiple atoms this time.
var ii:int;
xmax=stage.width;
ymax=stage.height;
for (ii=0; ii<numAtoms; ii++) {
atoms.push(new myAtomClass());
rotAngles.push(0);
rotSpeeds.push(0);
sizes.push(30);
addChild(atoms[ii]);
xc.push(((ii+1)*70)%xmax);
yc.push(((ii+1)*51)%ymax);
dx.push(3-ii);
dy.push(2);
if (xc[ii]<xBuffer) {xc[ii]=(xmax-xBuffer)-xc[ii];}
if (xc[ii]>(xmax-xBuffer)) {xc[ii]=xBuffer+(x-(xmax-xBuffer));}
dxsave.push(dx[ii]);
dysave.push(dy[ii]);
atoms[ii].SetCoordinates(xc[ii], yc[ii], 0, rotAngles[ii], xc[ii], yc[ii]);
}
//atom1 = new myAtomClass(); // old
//xmax1 = stage.width; // old
//ymax1 = stage.height; // old
//addChild(atom1); // old
//atom1.SetCoordinates(xc[ii], yc[ii], 0, rotAngles[ii], xc[ii], yc[ii]); // old
coordText.width=120;
// information text field
/* infobox = new TextField();
infobox.x=50;
infobox.y=350;
infobox.width=300;
infobox.height=300;
infobox.textColor=0x884410;
infobox.text="INFO";
stage.addChild(infobox); */
} // End of function doInit().
public function helpScreen():void {
if (!showingHelpBox) {
helpbox = new TextField();
helpbox.x=50;
helpbox.y=120;
helpbox.width=300;
helpbox.height=300;
helpbox.textColor=0x884410;
helpbox.text="OPTIONS \n\n";
helpbox.appendText(" h : Help screen.\n");
helpbox.appendText(" n : Spin on/off.\n");
helpbox.appendText(" g : Toggles gravity.\n");
helpbox.appendText(" c : Chase mode on/off.\n");
helpbox.appendText(" w : Toggles wild chase.\n");
helpbox.appendText(" a : Toggles chase attraction/repulsion.\n");
helpbox.appendText(" f/d : Increases/decreases clock speed.\n");
helpbox.appendText(" z : Toggles size of sphere.\n");
helpbox.appendText(" t : Toggle translucency of sphere.\n");
helpbox.appendText(" s : Stop sphere.\n");
helpbox.appendText(" Arrow Keys : Alter velocity.\n");
helpbox.appendText(" Space key : Show/hide sphere.\n");
helpbox.appendText(" +/- : Change diameter of sphere.\n");
addChild(helpbox); // could also explicitly use stage.addChild(helpbox) to same end
showingHelpBox=true;
} else {
removeChild(helpbox);
showingHelpBox=false;
}
}
public function makeBackground():void {
// Make the background for the stage.
var mtx:Matrix = new Matrix();
mtx.createGradientBox(stage.stageWidth * 1.5, stage.stageHeight * 1.5, 0, -stage.stageWidth * 0.25, -stage.stageHeight * 0.25);
var theBackground:Shape = new Shape();
theBackground.graphics.beginGradientFill(GradientType.RADIAL, [0xbef4f7, 0xb4d3eb], [1.0, 1.0], [0, 255], mtx);
theBackground.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
addChild(theBackground);
} // end of function makeBackground
public function cursorTracker():void {
//The section below is going to display more text.
coordText.text = "Starting";
coordText.x = 160;
coordText.y = 90;
coordText.textColor = 0xff5000;
addChild(coordText);
} // end function cursorTracker
/* protected function loginChangeHandler(event:Event):void {
if ((username.text == "tyler") &&
(password.text == "shadowcopy")) {
// authentication verified -- continue
myFormat.font="Verdana";
myFormat.bold=true;
myFormat.size=16;
myFormat.italic=true;
myFormat.underline=true;
moreText.defaultTextFormat=myFormat;
moreText.text = "AUTHENTICATION PASSED";
moreText.x=80;
moreText.y=60;
moreText.textColor=0xff1010;
moreText.width=250;
addChild(moreText);
}
} // end of function loginChangeHandler */
protected function _onStageMouseDown(e:Event):void {
trace(e);
numClicks++;
//extraText.text="CLICK " + numClicks;
//infobox.text="CLICK #" + numClicks;
trace("Does this show up?"); // should print to the screen... mostly for debug mode and need to turn off "Omit trace statements" setting in Publish settings
//atom1.toggleVisible();
var ii:int
for (ii=0; ii<numAtoms; ii++) {
atoms[ii].toggleTranslucency();
}
if (showingHelpBox) {
stage.removeChild(helpbox);
showingHelpBox=false;
}
} // end of function _onStageMouseDown
protected function _onStageMouseMove(e:MouseEvent):void {
var currentX:Number = parent.mouseX;
var currentY:Number = parent.mouseY;
cursorX = int(currentX);
cursorY = int(currentY);
coordText.text=currentX +", "+ currentY;
} // end of function _onStageMouseMove
protected function _onKeyDown(e:KeyboardEvent):void {
var bShiftPressed:Boolean = e.shiftKey;
var bAltPressed:Boolean = e.altKey;
var bCtrlPressed:Boolean = e.ctrlKey;
var ii:int;
//infobox.text="Key pressed.";
//if (e.keyCode == 32 && bAltPressed) {
if (e.keyCode == 32) { // space bar
for (ii=0; ii<numAtoms; ii++) {
atoms[ii].toggleVisible();
}
}
//if (e.keyCode == ("S").charCodeAt(0) && bCtrlPressed) {
if (e.keyCode == ("S").charCodeAt(0)) {
//if (e.keyCode == 83 && bCtrlPressed) {
//if ( bCtrlPressed) {
if (dx[0] != 0 || dy[0] != 0) {
dxsave[0]=dx[0]; dysave[0]=dy[0];
dx[0]=0; dy[0]=0;
gravity=false;
} else {
dx[0]=dxsave[0]; dy[0]=dysave[0];
}
}
//if (e.keyCode == ("Z").charCodeAt(0) && bAltPressed) {
if (e.keyCode == ("Z").charCodeAt(0)) {
atoms[0].toggleScale();
}
const letters:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//const letter_A:int = letters[0].charCodeAt(0);
const letter_A:int = ("A").charCodeAt(0);
const letter_C:int = ("C").charCodeAt(0);
const letter_D:int = ("D").charCodeAt(0);
const letter_F:int = ("F").charCodeAt(0);
const letter_G:int = ("G").charCodeAt(0);
const letter_H:int = ("H").charCodeAt(0);
const letter_N:int = ("N").charCodeAt(0);
const letter_T:int = ("T").charCodeAt(0);
const letter_W:int = ("W").charCodeAt(0);
switch (e.keyCode) {
case letter_G: // turn on gravity
gravity = !gravity;
break;
case letter_F: // speed up timer clock (shorten delay with minimum of 1 millisecond for ticks)
if (delay>1) { delay--; }
//delay=5;
theTimer.removeEventListener(TimerEvent.TIMER, _onTick);
theTimer = new Timer(delay, 0); // time of one cycle (a.ka. interval) in milliseconds; go for # of cycles given by second argument (0=forever)
theTimer.addEventListener(TimerEvent.TIMER, _onTick); // execute given function at each interval
theTimer.start(); // start the timer
break;
case letter_C: // cursor chasing toggle
//case 67: // letter 'c'
doChase = !doChase;
break;
case letter_A: // whether cursor is attractive or repulsive
attraction = !attraction;
break;
case letter_W: // toggles wild (i.e. more random) cursor chase
wildChase = !wildChase;
break;
case letter_D: // slow down timer clock (no upper limit for how far apart ticks can be)
delay++;
theTimer.removeEventListener(TimerEvent.TIMER, _onTick);
theTimer = new Timer(delay, 0); // time of one cycle (a.ka. interval) in milliseconds; go for # of cycles given by second argument (0=forever)
theTimer.addEventListener(TimerEvent.TIMER, _onTick); // execute given function at each interval
theTimer.start(); // start the timer
break;
case letter_N: // whether or not sphere has rotation enabled (includes caroming with english)
noRotation = !noRotation;
if (!noRotation) {
for (ii=0; ii<numAtoms; ii++) { rotSpeeds[ii]=5.0; }
}
break;
case letter_T: // toggles translucency of sphere
//if ( !bAltPressed) break;
atoms[0].toggleTranslucency();
break;
case 37: // LeftArrow
if (dx[0] > -dxlim) { dx[0]--; }
break;
case 38: // UpArrow
if (dy[0] > -dylim) { dy[0]--; }
break;
case 39: // RightArrow
if (dx[0] < dxlim) { dx[0]++; }
break;
case 40: // DownArrow
if (dy[0] < dylim) { dy[0]++; }
break;
case 187: // =+ key (increase sphere diameter)
//if ( !bCtrlPressed ) break;
if (sizes[0] < sizeMax) { sizes[0]++; }
atoms[0].changeSize(sizes[0]);
xBuffer=sizes[0];
yBuffer=sizes[0];
break;
case 189: // -_ key (decrease sphere diameter)
//if ( !bCtrlPressed ) break;
if (sizes[0] > sizeMin) { sizes[0]--; }
atoms[0].changeSize(sizes[0]);
xBuffer=sizes[0];
yBuffer=sizes[0];
break;
case letter_H: // help menu
helpScreen();
break;
default:
}
} // end function _onKeyDown
protected function _onTick(e:TimerEvent):void {
var i:uint=0;
var distX:int;
var distY:int;
var drawX:int; // actual position to draw sphere's center (x-component)
var drawY:int; // ... (y-component)
var rad:int; // radius of sphere
var impact:Number; // not used yet
var ddx:Number; // change in velocity x-component
var ddy:Number; // change in velocity y-component
var dW:Number; // change in rotational K.E.
var dT:Number; // change in translational K.E.
var T0:Number; // initial translational K.E.
var T1:Number; // final translational K.E.
var W0:Number; // initial rotational K.E.
var W1:Number; // final rotational K.E.
var HMOI:Number=1.0; // will need to calibrate this value for one-half the moment of inertia (units chosen so sphere mass is two and angles are in degrees)
var origdx:Number;
var origdy:Number;
var wasLeft:Boolean=false;
var wasRight:Boolean=false;
var wasTop:Boolean=false;
var wasBottom:Boolean=false;
var wasMovingNeg:Boolean=false;
var wasMovingPos:Boolean=false;
var wasSpinningNeg:Boolean=false;
var wasSpinningPos:Boolean=false;
var absFinalRotSpeed:Number;
var angle:Number;
var goDirection:Number;
var scaleC:Number=1.00; // for help box special effects
var scaleV:Number=0.0;
var scaleA:Number=0.001;
var ii:int;
//infobox.text="Timer ticked." + xc[0] + ", " + yc[0];
if (showingHelpBox) {
if (scaleC>1.10) { scaleA = -0.0001; }
if (scaleC<0.90) { scaleA = 0.0001; }
scaleV += scaleA;
scaleC += scaleV;
helpbox.scaleX=scaleC;
helpbox.scaleY=scaleC;
helpbox.scaleX=2.0;
}
// Calculate movement/behavior for each atom.
for (ii=0; ii<numAtoms; ii++) {
origdx=dx[ii];
origdy=dy[ii];
drawX=xc[ii];
drawY=yc[ii];
rotAngles[ii] += rotSpeeds[ii];
wasSpinningNeg = (rotSpeeds[ii] < 0);
wasSpinningPos = (rotSpeeds[ii] > 0);
// Calculate the initial translational energy. Assume units so that mass has value of two.
T0 = Math.sqrt(Number(dx[ii]*dx[ii])+Number(dy[ii]*dy[ii]));
// Calculate the initial rotational (angular) energy. Assume units so that one-half the moment of inertia is HMOI.
W0 = HMOI*Number(rotSpeeds[ii]*rotSpeeds[ii]);
if (doChase) {
//coordText.text=cursorX +", "+ cursorY + " --- CHASE";
cursorX=parent.mouseX; // or use stage.mouseX ?
cursorY=parent.mouseY; // or use stage.mouseY ?
/* if (Math.abs(cursorX-xc[ii]) > Math.abs(cursorY-yc[ii])) {
ddx = ( xc[ii]>cursorX ? -1 : 1 );
if (Math.abs(ddx) > 5.0) { ddx= (ddx < 0.0 ? -5.0 : 5.0 ); }
dx[ii] += ddx;
} else {
ddy = ( yc[ii]>cursorY ? -1 : 1 );
if (Math.abs(ddy) > 5.0) { ddy= (ddy < 0.0 ? -5.0 : 5.0 ); }
dy[ii] += ddy;
} */
angle= Math.atan2(Number(yc[ii]-cursorY), Number(xc[ii]-cursorX))*180.0/Math.PI;
if (wildChase) {
angle += Math.random()*90.0-45.0;
} else {
angle += Math.random()*45.0-22.5;
}
goDirection = Math.round(angle/90.0);
if (attraction) { goDirection += 2; }
goDirection = int((goDirection < 0 ? goDirection+4 : goDirection));
goDirection = int((goDirection > 4 ? goDirection-4 : goDirection));
switch (goDirection) {
case 0: { if (dx[ii]<10) { dx[ii]++; } break; }
case 1: { if (dy[ii]<10) { dy[ii]++; } break; }
case 2: { if (dx[ii]>-10) { dx[ii]--; } break; }
case 3: { if (dy[ii]>-10) { dy[ii]--; } break; }
default: ;
}
} // end of if (doChase) section
//infobox.text="Got to alpha point. xc[2]="+xc[2]+" drawX="+drawX+"\n";
// } else {
if (xc[ii]<=(xmin+xBuffer)) { // hit left limit
wasLeft=true;
wasMovingNeg = (dy[ii]<0);
wasMovingPos = (dy[ii]>0);
dx[ii]= Math.abs(dx[ii]); // Reflection bounce w.r.t. x-component since hit left wall
//xc[ii]= ((xmin+xBuffer)-xc[ii])+(xmin+xBuffer); // Not using correct-time positioning of sphere (leads to necessary speed corrections to conserve energy and avoid runaway mechanics)
drawX=xmin+xBuffer; // Position to draw sphere's center if compression is being used (i.e. sphere can approach boundary closer than its radius leading to temporary distortion to ellipse).
ddy = rotSpeeds[ii]/2; // Calculate the change in velocity's y-component due to spin of sphere when in contact with boundary.
/* if (rotSpeeds[ii]==0) {
ddy = 0;
} else if (Math.abs(rotSpeeds[ii])<2) {
ddy = (ddy < 0 ? -1 : 1);
} else {
ddy = rotSpeeds[ii]/2;
} */
if (Math.abs(ddy) > 5.0) { ddy= (ddy < 0.0 ? -5.0 : 5.0 ); }
dy[ii] += ddy;
} else if (xc[ii]>=(xmax-xBuffer)) { // hit right limit
wasRight=true;
wasMovingNeg = (dy[ii]<0);
wasMovingPos = (dy[ii]>0);
dx[ii]= -Math.abs(dx[ii]);
//xc[ii]= -(xc[ii]-(xmaxc[ii]-xBuffer))+(xmaxc[ii]-xBuffer);
drawX=xmax-xBuffer;
ddy = -rotSpeeds[ii]/2;
if (Math.abs(ddy) > 5.0) { ddy= (ddy < 0.0 ? -5.0 : 5.0); }
rotSpeeds[ii] -= dy[ii]*3;
dy[ii] += ddy;
}
//infobox.appendText("Got to gamma point.\n---");
if (yc[ii]<=(ymin+yBuffer)) { // hit top limit
//infobox.appendText("Gamma point 1. ");
wasTop=true;
wasMovingNeg = (dx[ii]<0);
wasMovingPos = (dx[ii]>0);
dy[ii]= Math.abs(dy[ii]);
//yc[ii]= ((ymin+yBuffer)-yc[ii])+(ymin+yBuffer);
drawY=ymin+yBuffer;
ddx = -rotSpeeds[ii]/2;
if (Math.abs(ddx) > 5.0) { ddx= (ddx < 0.0 ? -5.0 : 5.0); }
rotSpeeds[ii] -= dx[ii]*3;
dx[ii] += ddx;
} else if (yc[ii]>=(ymax-yBuffer)) { // hit bottom limit
//infobox.appendText("Gamma point 2.\n");
wasBottom=true;
wasMovingNeg = (dx[ii]<0);
wasMovingPos = (dx[ii]>0);
dy[ii]= -Math.abs(dy[ii]);
//yc[ii]= -(yc[ii]-(ymaxc[ii]-yBuffer))+(ymaxc[ii]-yBuffer);
drawY=ymax-yBuffer;
ddx = rotSpeeds[ii]/3;
if (Math.abs(ddx) > 5.0) { ddx= (ddx < 0.0 ? -5.0 : 5.0); }
rotSpeeds[ii] += dx[ii]*3;
dx[ii] += ddx;
} //else { infobox.appendText("Gamma point 3.\n"); }
// }
//infobox.appendText("Got to beta point.");
//infobox.text="Got to beta point. xc[2]="+xc[2];
// Calculate the new translational kinetic energy.
T1 = Math.sqrt(Number(dx[ii]*dx[ii])+Number(dy[ii]*dy[ii]));
// Calculate the new rotational speed using conservation of energy.
// ... So first calculate the change in translational kinetic energy. Assume units giving mass of two.
dT=T1-T0;
// Calculate the final rotational kinetic energy.
W1 = T0+W0-T1;
// Calculate the final rotational speed.
if (W1>=0.0) {
absFinalRotSpeed = Math.sqrt(Number(W1) / HMOI);
// Lastly, find the sign for the final rotational speed based on the original movements.
if (wasLeft) {
if (wasMovingNeg) { rotSpeeds[ii] = -absFinalRotSpeed; } else { rotSpeeds[ii] = absFinalRotSpeed; }
}
if (wasRight) {
if (wasMovingPos) { rotSpeeds[ii] = -absFinalRotSpeed; } else { rotSpeeds[ii] = absFinalRotSpeed; }
}
if (wasTop) {
if (wasMovingPos) { rotSpeeds[ii] = -absFinalRotSpeed; } else { rotSpeeds[ii] = absFinalRotSpeed; }
}
if (wasBottom) {
if (wasMovingNeg) { rotSpeeds[ii] = -absFinalRotSpeed; } else { rotSpeeds[ii] = absFinalRotSpeed; }
}
}
//rotSpeeds[ii] += dy[ii]*3; // !!!! ... to be replaced with conservation-of-energy formula.
// Done with calculating new rotational speed.
// Some sensibility checks on final angular speed.
if (Math.abs(rotSpeeds[ii]) > 10.0) { rotSpeeds[ii]= (rotSpeeds[ii] < 0.0 ? -10.0 : 10.0); }
if (noRotation) { rotSpeeds[ii]=0; }
//infobox.text="Changing coordinates now.";
xc[ii] += dx[ii];
yc[ii] += dy[ii];
// infobox.text="xc[0], yc[0] = "+xc[0]+", "+yc[0]+"\n";
// infobox.appendText("xc[1], yc[1] = "+xc[1]+", "+yc[1]+"\n");
// infobox.appendText("xc[2], yc[2] = "+xc[2]+", "+yc[2]+"\n");
//if (gravity && (dy[ii] < dylim)) { dy[ii]++; }
if (gravity && (yc[ii] < ( ymax-yBuffer))) { dy[ii]++; }
rad=atoms[ii].getRadius();
distX=Math.min(Math.abs(xc[ii]), Math.abs(xc[ii]-stage.width));
distY=Math.min(Math.abs(yc[ii]), Math.abs(yc[ii]-stage.height));
atoms[ii].SetCoordinates(drawX, drawY, 0, rotAngles[ii], distX, distY);
} // end loop over all atoms (count variable is i)
//infobox.appendText("delta\n");
} // end function _onTick
} // end main class my3Dviewer
} // end of package
import flash.geom.Matrix; // end of package
import flash.display.*;
class myAtomClass extends Sprite { // every atom is a Sprite-derived object
// Declarations grouped:
private var xc:Number = 0.0; // actual atomic coordinates (not screen coordinates)
private var yc:Number = 0.0;
private var zc:Number = 0.0;
private var an:int = 0; // atomic number of atom
private var elName:String = "NA"; // atomic symbol or identifier for atom
private var vis:Boolean = true; // whether the atom is visible
private var xsc:int=50;
private var ysc:int=50;
private var theRadius:int=30;
private var targetRadius:int=30;
private var big:Boolean=false;
private var isTranslucent:Boolean=false;
private var myCircle:Shape = new Shape();
// Functions grouped:
public function myAtomClass():void { // the constructor function that is automatically called upon instantiation
// myCircle.graphics.beginFill(0x2020ff);
var gradMatrix:Matrix = new Matrix();
gradMatrix.createGradientBox(100, 100, Math.PI*0.40, -53, -50); // 100% width and height, rotate (one radian), translate by zero along x and y axis.
myCircle.graphics.beginGradientFill("radial", // fill type (either "radial" or "linear")
[0xddddff, 0x2020ff], // colors
[100, 100], // alphas for two colors (range: 0 to 100; for transparency(100)/opacity(0))
[0, 230], // ratios for two colors (range: 0 to 255; spatial limits of solid colors before gradiation begins)
gradMatrix, // the transformation matrix for scaling, rotating, and translating the gradient
"pad", // spread method (pad just extends final colors, mirror reverses and iterates, repeat just starts over and iterates)
"RGB", // SpreadMethod can be either RGB (default) or linearRGB
-0.40); // focalPointRatio position from one edge of gradient circle to the other (-1 to 1)
myCircle.graphics.lineStyle(1, // line thickness (pixels)
0x000000, // color (RGB)
100, // alpha for line (opacity; range 0-100)
false, // pixel hinting (default: false), whether to hint strokes to full pixels
"normal", // always scale the strokes when scaling is done
"none", // end caps of lines
"miter", // joint style for angles/bends
1); // miter limit (only used if joint style is miter)
//myCircle.graphics.drawCircle(xsc, ysc, theRadius);
myCircle.graphics.drawCircle(0, 0, theRadius);
myCircle.graphics.endFill();
addChild(myCircle);
} // end of constructor function myAtomClass
public function updateAtom():void {
// This function may not be necessary.
}
public function SetCoordinates (x:Number, y:Number, z:Number, theRotAngle:Number, distX:Number, distY:Number):void {
this.xsc=x; this.ysc=y;
this.rotation = theRotAngle;
//this.myCircle.x=this.xsc; this.myCircle.y=this.ysc;
this.x=this.xsc; this.y=this.ysc;
this.scaleX = targetRadius/30.0;
this.scaleY = targetRadius/30.0;
if (targetRadius > distX) {
//this.scaleX=targetRadius/30.0*(distX/targetRadius);
//this.scaleX *= distX/targetRadius;
//this.scaleY /= distX/targetRadius*1.0;
//this.scaleX=distX/targetRadius;
}
if (targetRadius > distY) {
//this.scaleY=targetRadius/30.0*(distY/targetRadius);
//this.scaleY *= distY/targetRadius;
//this.scaleX /= distY/targetRadius*1.0;
//this.scaleY=distY/targetRadius;
}
this.updateAtom(); // this updateAtom function is not really used
} // end of function SetCoordinates
public function makeVisible():void {
this.vis=true;
this.myCircle.visible=this.vis;
}
public function makeInvisible():void {
this.vis=false;
this.myCircle.visible=this.vis;
}
public function toggleVisible():void {
if (this.vis) {
this.makeInvisible();
} else {
this.makeVisible();
}
}
public function toggleScale():void {
if (this.big) {
big=false;
//this.myCircle.scaleX=1.5;
//this.myCircle.scaleY=1.5;
this.changeSize(30);
//this.scaleX=(this.scaleY=1.5);
} else {
big=true;
//this.myCircle.scaleX=1.0;
//this.myCircle.scaleY=1.0;
this.changeSize(45);
//this.scaleX=(this.scaleY=1.0);
}
} // end of function toggleScale
public function toggleTranslucency():void {
this.isTranslucent = !this.isTranslucent;
if (this.isTranslucent) {
myCircle.alpha=0.5;
} else {
myCircle.alpha=1.0;
}
} // end of function toggleTranslucency
public function changeSize(newRadius:Number):void {
this.targetRadius = newRadius;
this.scaleX = targetRadius/30.0;
this.scaleY = targetRadius/30.0;
} // end of function changeSize
public function getRadius():int {
return (this.targetRadius);
} // end of function getRadius
public function update(ox:int, oy:int):void {
var x:int=0;
} // end of function update
} // end of class myAtomClass