Now, lets start working with constraints.
Let me explain:
There are 2 particles connected at a distance of 100px, and they're at a distance of 120px. If whe make a simple calcule:
er = ad-ds
where 'ad' is the actual distance and 'ds' is the constaint distance.
The result of this calcule may be 20, so whe divide it by two (two particles!) and the distance to add for both particles will be 10. The final calcule is this:
er = (ad-ds)/2;
Now, just move each particle in each other's direction in this amount.
Cool, isn't it? :D
Now, let's apply this script to a constraint script (based on Emanuele Feronato's script):
function constraint(p1,p2,dis){
dx = p1._x - p2._x;
dy = p1._y - p2._y;
actDis = Math.sqrt((dx*dx)+(dy*dy));
actDir = Math.atan2(dy,dx);
error = (actDis-dis)/2;
p1._x += Math.cos(actDir)*error;
p1._y += Math.sin(actDir)*error;
p2._x -= Math.cos(actDir)*error;
p2._y -= Math.sin(actDir)*error;
}
Pretty fancy, huh?
Now, let's apply this to a simulation:
particle1 = _root.createEmptyMovieClip("ball",_root.getNextHighestDepth());
particle1._x = Stage.width*.25;
particle1._y = Stage.height/2;
particle1.lineStyle(4,0,100);
particle1.beginFill(0xFFFF00,100);
particle1.moveTo(-15,-15);
particle1.lineTo(-15,15);
particle1.lineTo(15,15);
particle1.lineTo(15,-15);
particle1.moveTo(-15,-15);
particle2 = particle1.duplicateMovieClip("particle2",_root.getNextHighestDepth());
particle2._x = Stage.width*.75;
particle2._y = Stage.height/2;
setInterval(constraint,1000/24,particle1,particle2,300);
function constraint(p1,p2,dis){
dx = p1._x - p2._x;
dy = p1._y - p2._y;
actDis = Math.sqrt((dx*dx)+(dy*dy));
actDir = Math.atan2(dy,dx);
error = (actDis-dis)/2;
p1._x -= Math.cos(actDir)*error;
p1._y -= Math.sin(actDir)*error;
p2._x += Math.cos(actDir)*error;
p2._y += Math.sin(actDir)*error;
}
particle1.onPress = function(){
particle1.startDrag();
}
particle1.onRelease = function(){
particle1.stopDrag();
}
particle1.onReleaseOutside = function(){
particle1.stopDrag();
}
particle2.onPress = function(){
particle2.startDrag();
}
particle2.onRelease = function(){
particle2.stopDrag();
}
particle2.onReleaseOutside = function(){
particle2.stopDrag();
}
What would you see when you run it are two yellow squares on the screen, if you drag them, you may see that both squares react for the dragging.
---
Now, there's a issue that is really annoying: You attach some particles on the screen and constraint them, but they start to move left! What's happening? Well, what's happening is that Flash rounds some values (like x and y positions, alpha etc), so _x and _y are rounded down.
To fix that, instead of using _x and _y, create two vars named X and Y and on the particle's onEnterFrame function add a script to set _x and _Y positions to those X and Y vars.
---
Now, before add this to a verlet simulation, lets add a small function to limit particles position:
function stay_inside(b){
with(b){
X = Math.max(X,0+_width/2);
X = Math.min(X,Stage.width-_width/2);
Y = Math.max(Y,0+_height/2);
Y = Math.min(Y,Stage.height-_height/2);
}
}
And NOW you add it to a simulation, I have a ready script here, just paste it on root and run ;)
grav = .3;
// Create particle 1 and draw a square in it:
particle1 = _root.createEmptyMovieClip("ball",_root.getNextHighestDepth());
particle1._x = Stage.width*.25;
particle1._y = Stage.height/2;
particle1.X = particle1._x;
particle1.Y = particle1._y;
particle1.oldx = particle1._x;
particle1.oldy = particle1._y;
particle1.lineStyle(4,0,100);
particle1.beginFill(0xFFFF00,100);
particle1.moveTo(-15,-15);
particle1.lineTo(-15,15);
particle1.lineTo(15,15);
particle1.lineTo(15,-15);
particle1.moveTo(-15,-15);
// Now duplicates particle 1 in particle 2:
particle2 = particle1.duplicateMovieClip("particle2",_root.getNextHighestDepth());
particle2._x = Stage.width*.75;
particle2._y = Stage.height/2;
particle2.X = particle2._x;
particle2.Y = particle2._y;
particle2.oldx = particle2._x;
particle2.oldy = particle2._y;
// Runs everything:
function onEnterFrame(){
// Verlet particle 1:
verlet(particle1);
// Verlet particle 2:
verlet(particle2);
// constraint them togheter:
constraint(particle1,particle2,100);
// Don't let them go outside the screen!:
stay_inside(particle1);
stay_inside(particle2);
// This part draws a line between the two particles:
_root.clear();
_root.lineStyle(4,0,100);
_root.moveTo(particle1.X,particle1.Y);
_root.lineTo(particle2.X,particle2.Y);
}
function constraint(p1,p2,dis){
dx = p1.X - p2.X;
dy = p1.Y - p2.Y;
actDis = Math.sqrt((dx*dx)+(dy*dy));
actDir = Math.atan2(dy,dx);
error = (actDis-dis)/2;
p1.X -= Math.cos(actDir)*error;
p1.Y -= Math.sin(actDir)*error;
p2.X += Math.cos(actDir)*error;
p2.Y += Math.sin(actDir)*error;
}
particle1.onPress = function(){
particle1.drag = true;
}
particle1.onRelease = function(){
particle1.drag = false;
}
particle1.onReleaseOutside = function(){
particle1.drag = false;
}
particle1.onEnterFrame = function(){
if(particle1.drag){
particle1.X = _root._xmouse;
particle1.Y = _root._ymouse;
}
particle1._x = particle1.X;
particle1._y = particle1.Y;
}
particle2.onPress = function(){
particle2.drag = true;
}
particle2.onRelease = function(){
particle2.drag = false;
}
particle2.onReleaseOutside = function(){
particle2.drag = false;
}
particle2.onEnterFrame = function(){
if(particle2.drag){
particle2.X = _root._xmouse;
particle2.Y = _root._ymouse;
}
particle2._x = particle2.X;
particle2._y = particle2.Y;
}
function stay_inside(b){
with(b){
X = Math.max(X,0+_width/2);
X = Math.min(X,Stage.width-_width/2);
Y = Math.max(Y,0+_height/2);
Y = Math.min(Y,Stage.height-_height/2);
}
}
function verlet(b){
with(b){
tempx = X;
tempy = Y;
X = X + (X - oldx);
Y = Y + (Y - oldy);
Y += _root.grav;
oldx = tempx;
oldy = tempy;
}
}
And this is the result:
Next up is the spring system! :D
Goodbye, and thanks for reading ;)
6/01/2008
Subscribe to:
Post Comments (Atom)
ViciousPud.WF.jpg)
1 comment:
Hey there!
This is looking great so far! I was wondering if you wanted to do a banner swap? I'm trying to network a lot of flash blogs together :)
If so, you can find more info on my site, http://www.frozenhaddock.co.uk :)
Thanks!
Post a Comment