Reference formula:
G is the constant of gravitation.
VaR numparticipant LES: uint = 50; // total number of particles var G: Number = 0.03; // constant of gravitation var participant LES: array = new array (numparticipant les); var bounce: number =-0.4; // boundary bounce system // initialize function Init (): void {participant = new array (); For (var I: uint = 0; I <numparticipant les; I ++) {var size: Number = math. random () * 12 + 3; var particle: ball = new ball (size, math. random () * 0 xffffff); particle. X = math. random () * stage. stagewidth; particle. y = math. random () * stage. stageheight; particle. mass = math. pI * size; // the correlation between the quality and the cross-sectional area of the ball. That is, the larger the head, the heavier the addchild (particle. push (particle);} addeventlistener (event. enter_frame, enterframehandler);} function enterframehandler (Event: Event): void {for (var I: uint = 0; I <numparticipant; I ++) {var: Particle: ball = participant [I]; particle. X + = particle. VX; particle. Y + = particle. vy;} for (I = 0; I <numpays-1; I ++) {var parta: ball = participant [I]; for (VAR J: uint = I + 1; j <numparticipant; j ++) {var partb: ball = participant [J]; checkcollision (parta, partb); // checks gravitate (parta, partb); // gravitation processing} checkwils (parta); // Boundary Detection} // gravitation processing function gravitate (parta: ball, partb: ball): void {var DX: number = partb. x-partA.x; var DY: Number = partb. y-partA.y; var distsq: Number = DX * dx + dy * dy; var Dist: Number = math. SQRT (distsq); var force: Number = g * parta. mass * partb. mass/distsq; // calculate the universal gravitation of parta and partb var forcex: Number = force * dx/Dist; // that is: force * Cos () -- component VaR forcey: Number = force * dy/Dist in the X direction; // force * sin (a) -- component parta in the Y direction. VX + = forcex/parta. mass; // Newton's law A = F/M is embodied here in parta. vy + = forcey/parta. mass; partb. VX-= forcex/partb. mass; partb. vy-= forcey/partb. mass;} // Collision Detection Function checkcollision (ball0: ball, ball1: ball): void {var DX: Number = ball1.x-ball0.x; var DY: number = ball1.y-ball0.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); If (Dist <ball0.radius + ball1.radius) {var angle: Number = math. atan2 (dy, dx); var sin: Number = math. sin (angle); var cos: Number = math. cos (angle); var pos0: Point = new point (0, 0); var pos1: Point = rotate (dx, Dy, sin, cos, true); var vel0: point = rotate (ball0.vx, ball0.vy, sin, cos, true); var vel1: Point = rotate (ball1.vx, ball1.vy, sin, cos, true); var vxtotal: number = vel0.x-vel1.x; vel0.x = (ball0.mass-ball1.mass) * vel0.x + 2 * ball1.mass * vel1.x)/(ball0.mass + ball1.mass); vel1.x = vxtotal + vel0.x; var sumradius: number = ball0.radius + ball1.radius; var overlap: Number = sumRadius-Math.abs (pos0.x-pos1.x); var aradio: Number = ball0.radius/sumradius; var bradio: Number = ball1.radius/sumradius; if (Overlap> 0) {If (pos0.x> pos1.x) {pos0.x + = overlap * aradio; pos1.x-= overlap * bradio;} else {pos0.x-= overlap * aradio; pos1.x + = overlap * bradio;} var pos0f: Object = rotate (pos0.x, pos0.y, sin, cos, false); var pos1f: Object = rotate (pos1.x, pos1.y, sin, cos, false); ball1.x = ball0.x + pos1f. x; ball1.y = ball0.y + pos1f. y; ball0.x = ball0.x + pos0f. x; ball0.y = ball0.y + pos0f. y; var vel0f: Object = rotate (vel0.x, vel0.y, sin, cos, false); var vel1f: Object = rotate (vel1.x, vel1.y, sin, cos, false ); ball0.vx = vel0f. x; ball0.vy = vel0f. y; ball1.vx = vel1f. x; ball1.vy = vel1f. Y ;}}// coordinate rotation auxiliary method function rotate (X: Number, Y: Number, sin: Number, cos: Number, reverse: Boolean): point {var result: point = new point (); If (reverse) {result. X = x * Cos + y * sin; result. y = y * Cos-x * sin;} else {result. X = x * Cos-y * sin; result. y = y * Cos + x * sin;} return result;} // stage Boundary Detection Function checkwils (B: ball) {If (B. x <B. radius) {B. X = B. radius; B. VX * = bounce;} else if (B. x> stage. stageWidth-b.radius) {B. X = stage. stageWidth-b.radius; B. VX * = bounce;} If (B. Y <B. radius) {B. y = B. radius; B. vy * = bounce;} else if (B. y> stage. stageHeight-b.radius) {B. y = stage. stageHeight-b.radius; B. vy * = bounce;} Init (); btnreset. addeventlistener (mouseevent. mouse_down, mousedownhandler); function mousedownhandler (E: mouseevent): void {removeeventlistener (event. enter_frame, enterframehandler); For (var I: uint = 0; I <numparticipant les; I ++) {var particle: ball = participant [I]; particle. X = math. random () * stage. stagewidth; particle. y = math. random () * stage. stageheight; particle. VX = 0; particle. vy = 0;} addeventlistener (event. enter_frame, enterframehandler );}
CodeAlthough it is very long, many of them are directly copied by the encapsulated method in the previous article. It should be hard to understand.
Simulate the Earth's revolution around the Sun:
VaR numparticipant LES: uint = 2; // total number of particles var G: Number = 0.03; // constant of gravitation var participant LES: array = new array (numparticipant les); var I: Number = 0; // initialize function Init (): void {participant = new array (); var Sun: ball = new ball (30, 0xff0000); Sun. X = stage. stagewidth/2; Sun. y = stage. stageheight/2; Sun. mass = 900000; addchild (Sun); participant. push (Sun); var planet: ball = new ball (10, 0x0000ff); planet. X = stage. stagewidth/2 + 200; planet. y = stage. stageheight/2; planet. vy = 8; planet. mass = 1; addchild (planet); participant. push (planet); addeventlistener (event. enter_frame, enterframehandler); graphics. linestyle (1, 0 xdddddd); graphics. moveTo (planet. x, planet. y);} function enterframehandler (Event: Event): void {for (var I: uint = 0; I <numparticle; I ++) {var particle: ball = participant [I]; particle. X + = particle. VX; particle. Y + = particle. vy;} for (I = 0; I <numpays-1; I ++) {var parta: ball = participant [I]; for (VAR J: uint = I + 1; j <numparticipant; j ++) {var partb: ball = participant [J]; gravitate (parta, partb ); // gravity processing }}// gravity processing function gravitate (parta: ball, partb: ball): void {var DX: Number = partb. x-partA.x; var DY: Number = partb. y-partA.y; var distsq: Number = DX * dx + dy * dy; var Dist: Number = math. SQRT (distsq); var force: Number = g * parta. mass * partb. mass/distsq; // calculate the universal gravitation of parta and partb var forcex: Number = force * dx/Dist; // that is: force * Cos () -- var forcey: Number = force * dy/Dist; // force * sin () -- The component of universal gravitation in the Y direction/* parta. VX + = forcex/parta. mass; // Newton's law A = F/M is embodied here in parta. vy + = forcey/parta. mass; */partb. VX-= forcex/partb. mass; partb. vy-= forcey/partb. mass; trace (I); if (I <= 1000) {graphics. lineto (partb. x, partb. y); I ++;} else {graphics. clear (); graphics. linestyle (1, 0 xdddddd); graphics. moveTo (partb. x, partb. y); I = 0 ;}} Init ();
The code is modified on the basis of the first paragraph. We can see that the speed is slow at the "distant day" (the farther the distance is, the smaller the gravitation, and the lower the acceleration ), fast Speed at "recent day" (the closer the distance, the greater the gravitation, the greater the corresponding acceleration)
Node garden nodegarden:
I can't say why I call this name. The author of actionscript3.0 in animation is called this one anyway.
VaR participant: array; var numparticipant LES: uint = 60; var mindist: Number = 100; var springamount: Number = 0.0004; var friction: Number = 0.9995; function Init (): void {stage. scalemode = stagescalemode. no_scale; stage. align = stagealign. top_left; participant = new array (); For (var I: uint = 0; I <numparticipant; I ++) {var particle: ball = new ball (math. random () * 3 + 2, 0 xffffff); particle. X = math. random () * stage. stagewidth; particle. y = math. random () * stage. stageheight; particle. VX = math. random () * 6-3; particle. vy = math. random () * 6-3; addchild (particle); particle. push (particle);} addeventlistener (event. enter_frame, enterframehandler);} function enterframehandler (Event: Event): void {graphics. clear (); For (var I: uint = 0; I <numparticipant; I ++) {var particle: ball = participant [I]; particle. X + = particle. VX; particle. Y + = particle. vy; // If (particle. x> stage. stagewidth) {particle. X = 0;} else if (particle. x <0) {particle. X = stage. stagewidth;} If (particle. y> stage. stageheight) {particle. y = 0;} else if (particle. Y <0) {particle. y = stage. stageheight ;}}for (I = 0; I <numparticipant les-1; I ++) {var parta: ball = participant [I]; for (VAR J: uint = I + 1; j <numparticipant; j ++) {var partb: ball = participant [J]; Spring (parta, partb ); // each particle performs elastic motion processing with other particles} parta. VX * = friction; parta. vy * = friction;} function spring (parta: ball, partb: ball): void {var DX: Number = partb. x-partA.x; var DY: Number = partb. y-partA.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); If (Dist <mindist) {graphics. linestyle (1, 0x00ff00, 1-Dist/mindist); // note the transparency settings here: when the two balls are getting closer and closer, the lines become more and more obvious. When the distance is getting farther and farther, the lines become lighter and lighter graphics. moveTo (parta. x, parta. y); graphics. lineto (partb. x, partb. y); // similar to the auto motion processing var ax: Number = DX * springamount; var ay: Number = Dy * springamount; // a ball accelerates parta. VX + = ax; parta. vy + = Ay; // The B-ball deceleration partb. VX-= ax; partb. vy-= Ay; // a ball gets faster and slower, so it gets closer and closer (of course: the premise is within the effective distance)} Init ();
For this effect, it is recommended that you review the elastic movement: Flash/flex Study Notes (40): elastic movement-spring
It can be slightly improved by adding quality factors:
VaR participant: array; var numparticipant LES: uint = 30; var mindist: Number = 120; var springamount: Number = 0.03; var friction: Number = 0.998; var stageheight: Number = stage. stageheight; var stagewidth: Number = stage. stagewidth; function Init (): void {stage. scalemode = stagescalemode. no_scale; stage. align = stagealign. top_left; participant = new array (); For (var I: uint = 0; I <numparticipant; I ++) {var particle: ball = new ball (math. random () * 5 + 2, 0 xffffff); particle. X = math. random () * stagewidth; particle. y = math. random () * stageheight; particle. VX = math. random () * 6-3; particle. vy = math. random () * 6-3; particle. mass = math. pI * particle. radius * particle. radius; // Add quality addchild (particle); particle. push (particle);} addeventlistener (event. enter_frame, enterframehandler); stage. addeventlistener (mouseevent. mouse_move, mousemovehandler);} // mouse interaction function mousemovehandler (E: mouseevent): void {var DX: Number = mousex-stagewidth/2; var DY: number = mousey-stageheight/2; for (var I: uint = 0; I <numparticipant; I ++) {var B: ball = participant [I]; B. x-= dx/B. mass; B. y-= Dy/B. mass ;}} function enterframehandler (E: Event): void {graphics. clear (); For (var I: uint = 0; I <numparticipant; I ++) {var particle: ball = participant [I]; particle. X + = particle. VX; particle. Y + = particle. vy; // If (particle. x> stagewidth) {particle. X = 0;} else if (particle. x <0) {particle. X = stagewidth;} If (particle. y> stageheight) {particle. y = 0;} else if (particle. Y <0) {particle. y = stageheight ;}}for (I = 0; I <numparticipant les-1; I ++) {var parta: ball = participant [I]; for (VAR J: uint = I + 1; j <numparticipant; j ++) {var partb: ball = participant [J]; Spring (parta, partb ); // each particle performs elastic motion processing with other particles} parta. VX * = friction; parta. vy * = friction;} function spring (parta: ball, partb: ball): void {var DX: Number = partb. x-partA.x; var DY: Number = partb. y-partA.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); If (Dist <mindist) {graphics. linestyle (1, 0x00ff00, 1-Dist/mindist); // note the transparency settings here: when the two balls are getting closer and closer, the lines become more and more obvious. When the distance is getting farther and farther, the lines become lighter and lighter graphics. moveTo (parta. x, parta. y); graphics. lineto (partb. x, partb. y); // similar to the auto motion processing var ax: Number = DX * springamount; var ay: Number = Dy * springamount; // a ball accelerates parta. VX + = AX/parta. mass; parta. vy + = Ay/parta. mass; // B-ball deceleration partb. VX-= AX/partb. mass; partb. vy-= Ay/partb. mass; // a ball gets faster and slower, so it gets closer (of course: the premise is within the effective distance)} Init ();
The following results are also available on many flash websites, with good results and simple principles:
VaR ballcount: uint = 100; var friction: Number = 0.95; var massradio = 0.005; var arrball: array = new array (ballcount); var stagewidth: Number = stage. stagewidth; var stageheight: Number = stage. stageheight; For (var I: uint = 0; I <ballcount; I ++) {arrball [I] = new ball (math. random () * 10 + 3, math. random () * 0 xffffff); arrball [I]. X = math. random () * stagewidth; arrball [I]. y = math. random () * stageheight; arrball [I]. mass = massradio * arrball [I]. radius; addchild (arrball [I]);} stage. addeventlistener (event. enter_frame, enterframehandler); stage. addeventlistener (mouseevent. mouse_move, mousemovehandler); function enterframehandler (E: Event): void {for (var I: uint = 0; I <ballcount; I ++) {var B: ball = arrball [I]; B. VX * = friction; B. vy * = friction; B. X + = B. VX; B. Y + = B. vy; // If (B. x> stagewidth + B. radius) {B. X =-B. radius;} else if (B. x <-B. radius) {B. X = stagewidth + B. radius;} If (B. y> stageheight + B. radius) {B. y =-B. radius;} else if (B. Y <-B. radius) {B. y = stageheight + B. radius ;}} function mousemovehandler (E: mouseevent): void {var centerx: Number = 0.5 * stagewidth; var centery: Number = 0.5 * stageheight; var DX: number = mousex-centerx; var DY: Number = mousey-centery; For (var I: uint = 0; I <ballcount; I ++) {var B: ball = arrball [I]; // set the speed. VX =-DX * B. mass; B. vy =-dy * B. mass ;}}
The following are its variants:
VaR ballcount: uint = 200; var friction: Number = 0.95; var massradio = 0.1; var arrball: array = new array (ballcount); var stagewidth: Number = stage. stagewidth; var stageheight: Number = stage. stageheight; VaR _ oldx: Number, _ Oldy: Number; VaR _ framecount = 0; For (var I: uint = 0; I <ballcount; I ++) {arrball [I] = new ball (math. random () * 10 + 2, math. random () * 0 xffffff); arrball [I]. X = math. random () * stagewidth; arrball [I]. y = math. random () * stageheight; arrball [I]. mass = massradio * arrball [I]. radius; addchild (arrball [I]);} stage. addeventlistener (event. enter_frame, enterframehandler); function enterframehandler (E: Event): void {var DX: Number = mousex-_ oldx; var DY: Number = mousey-_ Oldy; for (I = 0; I <ballcount; I ++) {var B: ball = arrball [I]; If (math. ABS (dx)> 0) {B. VX =-DX * B. mass;} If (math. ABS (dy)> 0) {B. vy =-dy * B. mass;} B. VX * = friction; B. vy * = friction; B. X + = B. VX; B. Y + = B. vy; // If (B. x> stagewidth + B. radius) {B. X =-B. radius;} else if (B. x <-B. radius) {B. X = stagewidth + B. radius;} If (B. y> stageheight + B. radius) {B. y =-B. radius;} else if (B. Y <-B. radius) {B. y = stageheight + B. radius ;}} trace (_ framecount); // record "Speed" If (_ framecount> = 2) {_ framecount = 0; _ oldx = mousex; _ Oldy = Mousey;} else {_ framecount ++ ;}}