PDA

View Full Version : Simple physics



tekoer
November 30th, 2008, 08:40 AM
Hey, I've been researching alot about various physics engines for flash and there seem to be alot of good ones out there. Although they seem quite complicated for the very simple thing I am trying to create, which is an object that falls down but is constrained to a string so it bounces a bit and then stops. Would it be possible for somebody to make an example so i can dissect it and maybe get a thing or two out of it?
I attach an image so you can see what i mean.

Sage_of_Fire
November 30th, 2008, 12:52 PM
You can't get much simpler than 21 lines of code! Just make a symbol, put it on the stage, name it "dot", and cut-and-paste this script into your fla's script window (F9 will show it to you). You should get a ball that follows your cursor. When you move your mouse then click, the ball will bounce off the walls until you click again. Try it out:


stage.frameRate = 100;
stage.addEventListener(Event.ENTER_FRAME, updateDot, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_DOWN, throwDot, false, 0, true);
var clicked:Boolean = false;
function updateDot(evt:Event):void {
if (!clicked) {
dot.xSpeed = stage.mouseX - dot.x;
dot.ySpeed = stage.mouseY - dot.y;
dot.x = stage.mouseX;
dot.y = stage.mouseY;
} else {
dot.xSpeed = (dot.x + dot.width/2 + dot.xSpeed > stage.stageWidth || dot.x - dot.width/2 + dot.xSpeed < 0) ? -dot.xSpeed : dot.xSpeed;
dot.x += dot.xSpeed;
dot.ySpeed = (dot.y + dot.height/2 + dot.ySpeed > stage.stageHeight || dot.y - dot.height/2 + dot.ySpeed < 0 ) ? -dot.ySpeed : dot.ySpeed;
dot.y += dot.ySpeed;
}
}
function throwDot(evt:MouseEvent):void {
clicked = (!clicked) ? true : false;
}

It ought to be a good starting point for you.

tekoer
December 1st, 2008, 03:24 AM
Interesting script, but there is not much gravity involved there. The ball is just supposed to fall down but be constrained by the string.

ViktorHesselbom
December 1st, 2008, 04:56 AM
One example could be to use verlet integration. Google "Advanced Character Physics" to read a great article about it.

Here I quickly whipped up an example of a string attached to the mouse. Read the article so you know what is actually happening. If you want to attach a movie clip (the ball) simply set it's position to the same as the last particle's position (particles[9].pos.x/.pos.y).

Keep in mind that I wrote it pretty quickly so it's far from perfect.

var gravity = new Point (0, 10);
var particles = new Array ();
var joints = new Array ();
var t = 0;
for (var i = 0; i < 10; i ++)
particles.push ({ pos : new Point(0, i * 4), old_pos : new Point (0, i * 4) });
for (i = 1; i < 10; i ++)
joints.push ({ a : particles [i - 1], b : particles [i], rest : 10 });
addEventListener ("enterFrame", update);

function update (e)
{
var dt = (getTimer () - t) / 100;
t = getTimer ();

// verlet
for each (var i in particles)
{
var temp = i.pos.clone ();
i.pos.x += i.pos.x - i.old_pos.x + gravity.x * dt * dt;
i.pos.y += i.pos.y - i.old_pos.y + gravity.y * dt * dt;
i.old_pos = temp;
}

// satisfy
for (var j = 0; j < 30; j ++)
for each (i in joints)
{
var delta = i.b.pos.clone ();
delta = delta.subtract (i.a.pos.clone ());
var deltalength = Math.sqrt (delta.x * delta.x + delta.y * delta.y); // dot
var diff = (deltalength - i.rest) / deltalength;
var offset = new Point (delta.x * 0.5 * diff, delta.y * 0.5 * diff);

i.a.pos.offset (offset.x, offset.y);
i.b.pos.offset (-offset.x, -offset.y);
}

particles[0].pos = new Point (mouseX, mouseY);

// draw
graphics.clear ();
graphics.lineStyle (2);
for each (i in joints)
{
graphics.moveTo (i.a.pos.x, i.a.pos.y);
graphics.lineTo (i.b.pos.x, i.b.pos.y);
}
}

luhter
December 1st, 2008, 06:29 AM
ActionScript Code:

package
{
import flash.display.*;
import flash.events.*;
import flash.utils.*;


dynamic public class ball extends MovieClip
{
public var gravity,k,cord,friction; // the variables , k-elastic constant
public var clip:MovieClip; //drawing clip;
private var Mcord:MovieClip; // cord clip;
private var mainInt:Number; //interval
private var bx,by; //private var: bx,by-animation starting point


public function ball(cord){
//initialize
this.cord=cord;
this.friction=0; // e [0,1]
this.gravity=0;

//draws
this.clip=new MovieClip();
addChild(clip);

this.addEventListener(Event.ADDED_TO_STAGE, Constructor); // waits until clip is added to stage
}

private function Constructor(e:Event)

{
//draws the cord and initialize the starting point
Mcord=new MovieClip();
addChild(Mcord);
bx=clip.x;
by=clip.y;

//sets the motion interval at 0.5 sec
mainInt=setInterval(Gravity,50);
}

private function Gravity()
{

/* beware not physicaly accurate! */

clip.y+=gravity;// velocity imposed by gravity changes the y

if(clip.y>cord+cord*k) clip.y=cord+cord*k; // string has a maxiumum elastic width


if(gravity<0) gravity*=-1; // if velocity reached it's peak in the opposite direction

//if string enters in tension so it act with a reaction equal to the action
if(clip.y>cord){
gravity-=gravity*friction*(clip.y/cord);
/*
(clip.y/cord) is to add a slight acceleration though is not this simple in Real Life
(clip.y/cord) e [1,k]
*/
if(gravity<0.5) gravity=0; // force becomes to small to interest us, you can modify the value if you work at a low scale
gravity*=-1;
}

Mcord.graphics.clear();
Mcord.graphics.lineStyle(1);
Mcord.graphics.moveTo(bx,by);
Mcord.graphics.lineTo(clip.x,clip.y);

//if there is no force no need to compute so clears the memory
if(gravity==0) clearInterval(mainInt);

}


}
}





Add this to a file called ball.as
In the flash add:

ActionScript Code:

var b=new ball(100);
b.gravity=40;
b.k=0.6;
b.friction=0.5
b.x=150;
b.y=0;
b.clip.graphics.beginFill(0xAAAAAA);
b.clip.graphics.drawCircle(0,0,15);
b.clip.graphics.endFill();
addChild(b);





Beware! Like I wrote in the code this is just a simple simulation I made and the physics in real life acts slight different