Dynamic verlet collision with mc?
forked from Verlet Triangle (diff: 51)
ActionScript3 source code
/**
* Copyright bahngoura ( http://wonderfl.net/user/bahngoura )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/u9GI
*/
// forked from fakestar0826's Verlet Triangle
// forked from fakestar0826's Verlet Method
//
//
// What would be the best way to check if each verletPoint is touching the ground MC
// and then make the points interact realisticly in the same way they do with the stage bottom?
// I'm asking becouse I want the verlet points to always interact wiht what i have drawn.
// For instance if I would drawn an uneven ground with the brush tool...
// Is it even Possible?? :)
//
//
//
package {
import flash.geom.Rectangle;
import flash.events.Event;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.MovieClip;
public class FlashTest extends Sprite {
private var _pointA:VerletPoint;
private var _pointB:VerletPoint;
private var _pointC:VerletPoint;
private var _stickA:VerletStick;
private var _stickB:VerletStick;
private var _stickC:VerletStick;
private var _stageRect:Rectangle;
public var ground:MovieClip = new MovieClip();
public function FlashTest() {
// write as3 code here..
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
ground.graphics.beginFill(0x000000);
ground.graphics.drawRect(0, 0, 300, 40);
ground.graphics.endFill();
addChild(ground);
ground.x = 100;
ground.y = 300;
ground.rotation = -10;
_stageRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
_pointA = new VerletPoint(100, 100);
_pointB = new VerletPoint(200, 100);
_pointC = new VerletPoint(150, 200);
_stickA = new VerletStick(_pointA, _pointB);
_stickB = new VerletStick(_pointB, _pointC);
_stickC = new VerletStick(_pointC, _pointA);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
_pointA.y += 0.5;
_pointA.update();
_pointB.y += 0.5;
_pointB.update();
_pointC.y += 0.5;
_pointC.update();
//繰り返しを増やすと剛体に近づく。stickのupdateメソッドにより、点同士の斥力?が働くため
for(var i:int = 0;i < 1;i++)
{
_pointA.constrain(_stageRect);
_pointB.constrain(_stageRect);
_pointC.constrain(_stageRect);
_stickA.update();
_stickB.update();
_stickC.update();
}
graphics.clear();
_pointA.render(graphics);
_pointB.render(graphics);
_pointC.render(graphics);
_stickA.render(graphics);
_stickB.render(graphics);
_stickC.render(graphics);
}
}
}
import flash.display.MovieClip;
import flash.display.Graphics;
import flash.geom.Rectangle;
class VerletPoint
{
public var x:Number;
public var y:Number;
private var _oldX:Number;
private var _oldY:Number;
public var movieclip:String = new String;
public function VerletPoint(x:Number, y:Number)
{
setPosition(x, y);
}
public function update():void
{
var tempX:Number = x;
var tempY:Number = y;
x += vx;
y += vy;
_oldX = tempX;
_oldY = tempY;
}
public function setPosition(x:Number, y:Number):void
{
this.x = _oldX = x;
this.y = _oldY = y;
}
public function constrain(rect:Rectangle):void
{
x = Math.max(rect.left, Math.min(rect.right, x));
y = Math.max(rect.top, Math.min(rect.bottom, y));
// if (ground.hitTestPoint(this.x,this.y, true)){
// }
}
// public function constrain(movieclip):void
// {
//x = Math.max(rect.left, Math.min(rect.right, x));
//y = Math.max(rect.top, Math.min(rect.bottom, y));
// if (movieclip.hitTestPoint(this.x,this.y, true)){
trace("tja");
// }
// }
public function set vx(value:Number):void
{
_oldX = x - value;
}
public function get vx():Number
{
return x - _oldX;
}
public function set vy(value:Number):void
{
_oldY = y - value;
}
public function get vy():Number
{
return y - _oldY;
}
public function render(g:Graphics):void
{
g.beginFill(0);
g.drawCircle(x, y, 4);
g.endFill();
}
}
class VerletStick
{
private var _pointA:VerletPoint;
private var _pointB:VerletPoint;
private var _length:Number;
public function VerletStick(pointA:VerletPoint, pointB:VerletPoint, length:Number = -1)
{
_pointA = pointA;
_pointB = pointB;
if(length == -1)
{
var dx:Number = _pointA.x - _pointB.x;
var dy:Number = _pointA.y - _pointB.y;
_length = Math.sqrt(dx * dx + dy * dy);
}
else
{
_length = length;
}
}
public function update():void
{
var dx:Number = _pointB.x - _pointA.x;
var dy:Number = _pointB.y - _pointA.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var diff:Number = _length - dist;
var offsetX:Number = (diff * dx / dist)/* it means diff * cos(θ)*/ / 2;
var offsetY:Number = (diff * dy / dist)/* it means diff * sin(θ)*/ / 2;
_pointA.x -= offsetX;
_pointA.y -= offsetY;
_pointB.x += offsetX;
_pointB.y += offsetY;
}
public function render(g:Graphics):void
{
g.lineStyle(0);
g.moveTo(_pointA.x, _pointA.y);
g.lineTo(_pointB.x, _pointB.y);
}
}
