Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Пишу Ragdoll (http://www.flasher.ru/forum/showthread.php?t=116009)

Crash512 01.05.2009 01:26

Спасибо за ответ=) Странно... У меня весь этот "рэгдолл" теперь непрерывно вращается по часовой стрелке... Код скопировал полностью=)

Герыч 01.05.2009 02:09

Вот, даже сделал всё с классами) теперь все joint'ы в одном месте:

Код AS3:

package gerich.verlet
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Main extends Sprite
        {
                private var pt:Array = new Array();
                private var joints:Array = new Array();
                private var mousejoints:Array = new Array();
                private var particles:Sprite = new Sprite();
                private var canvas:Shape = new Shape();
                private var grav:Number = 100;
                private var timeSqr:Number;
 
                // ========================================================== //
                public function Main():void
                {
                        stage.frameRate = 40;
 
                        timeSqr=1/stage.frameRate;timeSqr*=timeSqr;
 
                        addChild(canvas);
 
                        addChild(particles);
 
                        pt.push(new Particle(270,150));
                        pt.push(new Particle(270,175));
                        pt.push(new Particle(270,200));
                        pt.push(new Particle(270,225));
                        pt.push(new Particle(270,250));
                        pt.push(new Particle(270,275));
                        pt.push(new Particle(255,285));
                        pt.push(new Particle(285,285));
 
                        joints.push(new MouseJoint(pt[0], pt[1], 25));
                        joints.push(new Joint(pt[1], pt[2], 25));
                        joints.push(new Joint(pt[2], pt[3], 25));
                        joints.push(new Joint(pt[3], pt[4], 25));
                        joints.push(new Joint(pt[4], pt[5], 25));
                        joints.push(new Joint(pt[5], pt[6], 25));
                        joints.push(new Joint(pt[5], pt[7], 25));
                        joints.push(new Joint(pt[6], pt[7], 25));
 
                        for (var i in joints)
                        {
                                if(joints[i] is MouseJoint)
                                        mousejoints.push(joints[i]);
                        }
 
                        for (var i in pt)
                        {
                                particles.addChild(pt[i]);
                        }
 
                        addEventListener(Event.ENTER_FRAME, checkJoints);
                        addEventListener(Event.ENTER_FRAME, ptMouse);
                }
                // ========================================================== //
                private function checkJoints(event:Event):void
                {
                        var dx:Number;
                        var dy:Number;
 
                        canvas.graphics.clear();
 
                        // Gravity
 
                        for (var i in pt)
                        {
                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                pt[i].xx += dx;
                                pt[i].yy += dy+grav*timeSqr;
                        }
 
                        // Joints
 
                        for (var z:int=0; z<5; z++)
                        {
                                for (var i in joints)
                                {
                                        joints[i].Apply();
                                }
                        }
 
                        for (var i in pt)
                        {
                                pt[i].x = pt[i].xx;
                                pt[i].y = pt[i].yy;
                        }
                        // Lines
                        for (var i in joints)
                        {
                                joints[i].Draw(canvas);
                        }
                }
                // ========================================================== //
                private function ptMouse(event:Event):void
                {
                        for (var i in mousejoints)
                        {
                                mousejoints[i].SetMouse( mouseX,mouseY);
                                mousejoints[i].Draw(canvas);;
                        }
                }
        }
}
 
// ***** [ Particle Class ] ***************************************** //
 
import flash.display.Sprite;
 
internal class Particle extends Sprite
{
        public var old_x:Number;
        public var old_y:Number;
        public var xx:Number;
        public var yy:Number;
 
        // ========================================================== //
        public function Particle(_x:int, _y:int):void
        {
                x = _x;
                y = _y;
 
                xx = _x;
                yy = _y;
 
                old_x = _x;
                old_y = _y;
 
                graphics.lineStyle(1, 0x000000);
                graphics.beginFill(0xFFD22B);
                graphics.drawCircle(0,0,5);
                graphics.endFill();
        }
        // ========================================================== //
}
 
import flash.display.Shape;
 
internal class Joint
{
        public var p1:Particle;
        public var p2:Particle;
        public var len:Number;
 
        // ========================================================== //
        public function Joint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                p1=_p1;
                p2=_p2;
                len=_len;
        }
        // ========================================================== //
 
        public function Draw(canvas:Shape):void
        {
                canvas.graphics.lineStyle(1,0x000000);
                canvas.graphics.moveTo(p1.x, p1.y);
                canvas.graphics.lineTo(p2.x, p2.y);
        }
        // ========================================================== //
 
        public function Apply():void
        {
                var dx:Number;
                var dy:Number;
                var d_len:Number;
                var diff:Number;
 
                dx = p2.xx-p1.xx;
                dy = p2.yy-p1.yy;
                d_len = Math.sqrt(dx*dx + dy*dy);
                diff = (d_len-len)/d_len;
                dx *= 0.5*diff;
                dy *= 0.5*diff;
 
                p2.xx -= dx;
                p2.yy -= dy;
                p1.xx += dx;
                p1.yy += dy;
        }
        // ========================================================== //
}
 
internal class MouseJoint extends Joint
{
        // ========================================================== //
        public function MouseJoint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                super(_p1,_p2,_len);
        }
 
        // ========================================================== //
        override public function Apply():void
        {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        diff = (d_len-len)/d_len;
                        dx *= diff;
                        dy *= diff;
 
                        p2.xx -= dx;
                        p2.yy -= dy;
        }
 
        // ========================================================== //
        public function SetMouse(mousex:Number,mousey:Number):void
        {
                        p1.x =mousex;
                        p1.xx=mousex;
                        p1.y =mousey;
                        p1.yy=mousey;
        }
        // ========================================================== //
}

P.S. Одна из первых прог с классами на AS3.. лёгкий язык.. очень)

Добавлено через 1 минуту
Цитата:

Сообщение от Crash512 (Сообщение 816861)
Спасибо за ответ=) Странно... У меня весь этот "рэгдолл" теперь непрерывно вращается по часовой стрелке... Код скопировал полностью=)

Я убрал трение вроде.. как я понял оно у тя было:)

Добавлено через 3 минуты
ну ещё я ведь добавил время... а вообще спасибо тебе) прочитал статейку про верлета, лень было самому всё писать, а тут бац почти всё готово)

Crash512 01.05.2009 07:05

Блин.. Всё равно вращается=)) Что я не так делаю?.. Можешь прислать исходник, если у тебя всё нормально?

Герыч 01.05.2009 11:18

я ж говорю, у тя было:
Код AS3:

                                dx = (pt[i].x - pt[i].old_x);
                                dy = (pt[i].y - pt[i].old_y) + grav;
                                pt[i].old_x = pt[i].x;
                                pt[i].old_y = pt[i].y;
                                pt[i].x += dx/1.1;
                                pt[i].y += dy/1.1;

а я сделал
Код AS3:

                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                pt[i].xx += dx;
                                pt[i].yy += dy+grav*timeSqr;

я тут dx и dy чуток по-другому считаю.. и тут нет силы трения

кстати, что значит 1.1 тут:
Код AS3:

                                pt[i].x += dx/1.1;
                                pt[i].y += dy/1.1;

Добавлено через 3 часа 9 минут
Сделал "слабые связи" всмысле как верёвка, а не палка постоянной длины:
Код AS3:

package gerich.verlet
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Main extends Sprite
        {
                private var pt:Array = new Array();
                private var joints:Array = new Array();
                private var mousejoints:Array = new Array();
                private var particles:Sprite = new Sprite();
                private var canvas:Shape = new Shape();
                private var grav:Number = 100;
                private var timeSqr:Number;
 
                // ========================================================== //
                public function Main():void
                {
                        stage.frameRate = 40;
 
                        timeSqr=1/stage.frameRate;timeSqr*=timeSqr;
 
                        addChild(canvas);
 
                        addChild(particles);
 
                        pt.push(new Particle(270,150));
                        pt.push(new Particle(270,175));
 
                        joints.push(new WeakMouseJoint(pt[0], pt[1], 10));
 
                        for (var j:int=1;j<100;j++)
                        {
                                pt.push(new Particle(270,175));
                                joints.push(new WeakJoint(pt[j], pt[j+1], 10));
                        }
 
                        for (var i in joints)
                        {
                                if(joints[i] is MouseJoint)
                                        mousejoints.push(joints[i]);
                        }
 
                        for (var i in pt)
                        {
                                particles.addChild(pt[i]);
                        }
 
                        addEventListener(Event.ENTER_FRAME, checkJoints);
                        addEventListener(Event.ENTER_FRAME, ptMouse);
                }
                // ========================================================== //
                private function checkJoints(event:Event):void
                {
                        var dx:Number;
                        var dy:Number;
 
                        canvas.graphics.clear();
 
                        // Gravity
 
                        for (var i in pt)
                        {
                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                pt[i].xx += dx;
                                pt[i].yy += (dy+grav*timeSqr);
                        }
 
                        // Joints
 
                        for (var z:int=0; z<10; z++)
                        {
                                for (var i in joints)
                                {
                                        joints[i].Apply();
                                }
                                for (var i in pt)
                                {
                                        pt[i].xx=Math.max(pt[i].xx,0);
                                        pt[i].xx=Math.min(pt[i].xx,stage.stageWidth);
                                        pt[i].yy=Math.max(pt[i].yy,0);
                                        pt[i].yy=Math.min(pt[i].yy,stage.stageHeight);
                                }
                        }
 
                        for (var i in pt)
                        {
                                pt[i].x = pt[i].xx;
                                pt[i].y = pt[i].yy;
                        }
                        // Lines
                        for (var i in joints)
                        {
                                joints[i].Draw(canvas);
                        }
                }
                // ========================================================== //
                private function ptMouse(event:Event):void
                {
                        for (var i in mousejoints)
                        {
                                mousejoints[i].SetMouse( mouseX,mouseY);
                                mousejoints[i].Draw(canvas);;
                        }
                }
        }
}
 
// ***** [ Particle Class ] ***************************************** //
 
import flash.display.Sprite;
 
internal class Particle extends Sprite
{
        public var old_x:Number;
        public var old_y:Number;
        public var xx:Number;
        public var yy:Number;
 
        // ========================================================== //
        public function Particle(_x:int, _y:int):void
        {
                x = _x;
                y = _y;
 
                xx = _x;
                yy = _y;
 
                old_x = _x;
                old_y = _y;
 
                graphics.lineStyle(1, 0x000000);
                graphics.beginFill(0xFFD22B);
                graphics.drawCircle(0,0,5);
                graphics.endFill();
        }
        // ========================================================== //
}
 
import flash.display.Shape;
 
internal class Joint
{
        public var p1:Particle;
        public var p2:Particle;
        public var len:Number;
 
        // ========================================================== //
        public function Joint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                p1=_p1;
                p2=_p2;
                len=_len;
        }
        // ========================================================== //
 
        public function Draw(canvas:Shape):void
        {
                canvas.graphics.lineStyle(1,0x000000);
                canvas.graphics.moveTo(p1.x, p1.y);
                canvas.graphics.lineTo(p2.x, p2.y);
        }
        // ========================================================== //
 
        public function Apply():void
        {
                var dx:Number;
                var dy:Number;
                var d_len:Number;
                var diff:Number;
 
                dx = p2.xx-p1.xx;
                dy = p2.yy-p1.yy;
                d_len = Math.sqrt(dx*dx + dy*dy);
                diff = (d_len-len)/d_len;
                dx *= 0.5*diff;
                dy *= 0.5*diff;
 
                p2.xx -= dx;
                p2.yy -= dy;
                p1.xx += dx;
                p1.yy += dy;
        }
        // ========================================================== //
}
 
internal class MouseJoint extends Joint
{
        // ========================================================== //
        public function MouseJoint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                super(_p1,_p2,_len);
        }
 
        // ========================================================== //
        override public function Apply():void
        {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        diff = (d_len-len)/d_len;
                        dx *= diff;
                        dy *= diff;
 
                        p2.xx -= dx;
                        p2.yy -= dy;
        }
 
        // ========================================================== //
        public function SetMouse(mousex:Number,mousey:Number):void
        {
                        p1.x =mousex;
                        p1.xx=mousex;
                        p1.y =mousey;
                        p1.yy=mousey;
        }
        // ========================================================== //
}
 
internal class WeakJoint extends Joint
{
        // ========================================================== //
        public function WeakJoint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                super(_p1,_p2,_len);
        }
 
        // ========================================================== //
        override public function Apply():void
        {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len>len){
                                diff = (d_len-len)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                p2.xx -= dx;
                                p2.yy -= dy;
                                p1.xx += dx;
                                p1.yy += dy;
                        }
        }
 
        // ========================================================== //
}
 
internal class WeakMouseJoint extends MouseJoint
{
        // ========================================================== //
        public function WeakMouseJoint(_p1:Particle, _p2:Particle, _len:Number):void
        {
                super(_p1,_p2,_len);
        }
 
        // ========================================================== //
        override public function Apply():void
        {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len>len)
                        {
                                diff = (d_len-len)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                p2.xx -= dx;
                                p2.yy -= dy;
                        }
                }
 
        // ========================================================== //
}


Герыч 01.05.2009 17:31

Код AS3:

package gerich.verlet
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Main extends Sprite{
                private var pt:Array = new Array();
                private var joints:Array = new Array();
                private var particles:Sprite = new Sprite();
                private var canvas:Shape = new Shape();
                private var grav:Number = 100;
                private var timeSqr:Number;
 
                // ========================================================== //
                public function Main():void{
                        stage.frameRate = 40;
 
                        timeSqr=1/stage.frameRate;timeSqr*=timeSqr;
 
                        addChild(canvas);
 
                        addChild(particles);
 
                        pt.push(new Particle(270,150,true));
 
                        for (var j:int=0;j<30;j++)
                        {
                                pt.push(new Particle(270,175));
                                joints.push(new WeakJoint(pt[j], pt[j+1], 10));
                        }
 
 
                        for (var i in pt){
                                particles.addChild(pt[i]);
                        }
 
                        addEventListener(Event.ENTER_FRAME, checkJoints);
                        addEventListener(Event.ENTER_FRAME, ptMouse);
                }
                // ========================================================== //
 
                private function checkJoints(event:Event):void{
                        var dx:Number;
                        var dy:Number;
 
                        canvas.graphics.clear();
 
                        // Gravity
 
                        for (var i in pt){
                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                pt[i].xx += dx;
                                pt[i].yy += (dy+grav*timeSqr);
                        }
 
                        // Joints
 
 
                        for (var z:int=0; z<30; z++){
                                for (var i in joints){
                                        joints[i].Apply();
                                }
 
                                for (var i in pt){
                                        pt[i].xx=Math.max(pt[i].xx,0);
                                        pt[i].xx=Math.min(pt[i].xx,stage.stageWidth);
                                        pt[i].yy=Math.max(pt[i].yy,0);
                                        pt[i].yy=Math.min(pt[i].yy,stage.stageHeight);
                                }
                        }
 
                        for (var i in pt){
                                pt[i].x = pt[i].xx;
                                pt[i].y = pt[i].yy;
                        }
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
                // ========================================================== //
                private function ptMouse(event:Event):void{
                        for (var i in pt){
                                if(pt[i].isMouse){
                                        pt[i].x=mouseX;
                                        pt[i].y=mouseY;
                                        pt[i].xx=mouseX;
                                        pt[i].yy=mouseY;
                                }
                        }
                        canvas.graphics.clear();
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
        }
}
 
// ***** [ Particle Class ] ***************************************** //
 
        import flash.display.Sprite;
 
        internal class Particle extends Sprite{
                public var old_x:Number;
                public var old_y:Number;
                public var xx:Number;
                public var yy:Number;
                public var isMouse:Boolean;
 
                // ========================================================== //
                public function Particle(_x:int, _y:int, _isMouse:Boolean=false):void{
                        x = _x;
                        y = _y;
 
                        xx = _x;
                        yy = _y;
 
                        old_x = _x;
                        old_y = _y;
 
                        isMouse=_isMouse;
 
                        graphics.lineStyle(1, 0x000000);
                        graphics.beginFill(0xFFD22B);
                        graphics.drawCircle(0,0,5);
                        graphics.endFill();
                }
                // ========================================================== //
        }
 
        import flash.display.Shape;
 
        internal class Joint{
                public var p1:Particle;
                public var p2:Particle;
                public var len:Number;
 
                // ========================================================== //
                public function Joint(_p1:Particle, _p2:Particle, _len:Number):void{
                        p1=_p1;
                        p2=_p2;
                        len=_len;
                }
                // ========================================================== //
 
                public function Draw(canvas:Shape):void{
                        canvas.graphics.lineStyle(1,0x000000);
                        canvas.graphics.moveTo(p1.x, p1.y);
                        canvas.graphics.lineTo(p2.x, p2.y);
                }
                // ========================================================== //
 
                public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        diff = (d_len-len)/d_len;
                        dx *= 0.5*diff;
                        dy *= 0.5*diff;
 
                        if(!p2.isMouse){
                                p2.xx -= dx;
                                p2.yy -= dy;
                        }
                        if(!p1.isMouse){
                                p1.xx += dx;
                                p1.yy += dy;
                        }
 
                }
                // ========================================================== //
        }
 
        internal class WeakJoint extends Joint
        {
                // ========================================================== //
                public function WeakJoint(_p1:Particle, _p2:Particle, _len:Number):void{
                        super(_p1,_p2,_len);
                }
 
                // ========================================================== //
                override public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len>len){
                                diff = (d_len-len)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
 
                // ========================================================== //
        }
 
        internal class RangeJoint extends Joint
        {
                public var lenmax:Number;
                public var lenmin:Number;
                // ========================================================== //
                public function RangeJoint(_p1:Particle, _p2:Particle, _lenmax:Number, _lenmin:Number):void
                {
                        lenmax=_lenmax;
                        lenmin=_lenmin;
                        super(_p1,_p2,_lenmax);
                }
 
                // ========================================================== //
                override public function Apply():void
                {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if((d_len>lenmax)||(d_len<lenmin)){
                                if(d_len>lenmax)
                                        diff = (d_len-lenmax)/d_len;
                                if(d_len<lenmin)
                                        diff = (d_len-lenmin)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
                // ========================================================== //
        }

Теперь работы с мышью более логична) в классе Particle добавил свойство isMouse и убрал лишние классы

Герыч 01.05.2009 23:54

Сделал проверку на нулевую длину для связей:
Код AS3:

package gerich.verlet
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Main extends Sprite{
                private var pt:Array = new Array();
                private var joints:Array = new Array();
                private var particles:Sprite = new Sprite();
                private var canvas:Shape = new Shape();
                private var grav:Number = 500;
                private var timeSqr:Number;
 
                // ========================================================== //
                public function Main():void{
                        stage.frameRate = 40;
 
                        timeSqr=1/stage.frameRate;timeSqr*=timeSqr;
 
                        addChild(canvas);
 
                        addChild(particles);
 
                        pt.push(new Particle(270,150,true));
 
                        for (var j:int=0;j<30;j++)
                        {
                                pt.push(new Particle(270,150));
                                joints.push(new RangeJoint(pt[j], pt[j+1], 8, 20));
                        }
 
 
                        for (var i in pt){
                                particles.addChild(pt[i]);
                        }
 
                        addEventListener(Event.ENTER_FRAME, checkJoints);
                        addEventListener(Event.ENTER_FRAME, ptMouse);
                }
                // ========================================================== //
 
                private function checkJoints(event:Event):void{
                        var dx:Number;
                        var dy:Number;
 
                        canvas.graphics.clear();
 
                        // Gravity
 
                        for (var i in pt){
                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                pt[i].xx += dx;
                                pt[i].yy += (dy+grav*timeSqr);
                        }
 
                        // Joints
 
 
                        for (var z:int=0; z<30; z++){
                                for (var i in joints){
                                        joints[i].Apply();
                                }
 
                                for (var i in pt){
                                        pt[i].xx=Math.max(pt[i].xx,0);
                                        pt[i].xx=Math.min(pt[i].xx,stage.stageWidth);
                                        pt[i].yy=Math.max(pt[i].yy,0);
                                        pt[i].yy=Math.min(pt[i].yy,stage.stageHeight);
                                }
                        }
 
                        for (var i in pt){
                                pt[i].x = pt[i].xx;
                                pt[i].y = pt[i].yy;
                        }
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
                // ========================================================== //
                private function ptMouse(event:Event):void{
                        for (var i in pt){
                                if(pt[i].isMouse){
                                        pt[i].x=mouseX;
                                        pt[i].y=mouseY;
                                        pt[i].xx=mouseX;
                                        pt[i].yy=mouseY;
                                }
                        }
                        canvas.graphics.clear();
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
        }
}
 
// ***** [ Particle Class ] ***************************************** //
 
        import flash.display.Sprite;
 
        internal class Particle extends Sprite{
                public var old_x:Number;
                public var old_y:Number;
                public var xx:Number;
                public var yy:Number;
                public var isMouse:Boolean;
 
                // ========================================================== //
                public function Particle(_x:int, _y:int, _isMouse:Boolean=false):void{
                        x = _x;
                        y = _y;
 
                        xx = _x;
                        yy = _y;
 
                        old_x = _x;
                        old_y = _y;
 
                        isMouse=_isMouse;
 
                        graphics.lineStyle(1, 0x000000);
                        graphics.beginFill(0xFFD22B);
                        graphics.drawCircle(0,0,5);
                        graphics.endFill();
                }
                // ========================================================== //
        }
 
        import flash.display.Shape;
 
        internal class Joint{
                public var p1:Particle;
                public var p2:Particle;
                public var len:Number;
 
                // ========================================================== //
                public function Joint(_p1:Particle, _p2:Particle, _len:Number):void{
                        p1=_p1;
                        p2=_p2;
                        len=_len;
                }
                // ========================================================== //
 
                public function Draw(canvas:Shape):void{
                        canvas.graphics.lineStyle(1,0x000000);
                        canvas.graphics.moveTo(p1.x, p1.y);
                        canvas.graphics.lineTo(p2.x, p2.y);
                }
                // ========================================================== //
 
                public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        diff = (d_len-len)/d_len;
                        dx *= 0.5*diff;
                        dy *= 0.5*diff;
 
                        if(!p2.isMouse){
                                p2.xx -= dx;
                                p2.yy -= dy;
                        }
                        if(!p1.isMouse){
                                p1.xx += dx;
                                p1.yy += dy;
                        }
 
                }
                // ========================================================== //
        }
 
        internal class WeakJoint extends Joint
        {
                // ========================================================== //
                public function WeakJoint(_p1:Particle, _p2:Particle, _len:Number):void{
                        super(_p1,_p2,_len);
                }
 
                // ========================================================== //
                override public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        if(d_len>len){
                                diff = (d_len-len)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
 
                // ========================================================== //
        }
 
        internal class RangeJoint extends Joint
        {
                public var lenmax:Number;
                public var lenmin:Number;
                // ========================================================== //
                public function RangeJoint(_p1:Particle, _p2:Particle, _lenmin:Number, _lenmax:Number):void
                {
                        lenmax=_lenmax;
                        lenmin=_lenmin;
                        super(_p1,_p2,_lenmax);
                }
 
                // ========================================================== //
                override public function Apply():void
                {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        if((d_len>lenmax)||(d_len<lenmin)){
                                if(d_len>lenmax)
                                        diff = (d_len-lenmax)/d_len;
                                if(d_len<lenmin)
                                        diff = (d_len-lenmin)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
                // ========================================================== //
        }

Добавлено через 12 часов 1 минуту
Вопрос ко всем, а как реализовать трение о поверхность(границы нашего квадрата). Как я понимаю, если частица "проникла" в другой объект, то надо добавить силу трения, направленную в противоположную сторону скорости.. но как это сделать? Есть ли у кого хорошие статейки по теме?

Герыч 02.05.2009 23:58

Трение реализовал) но с WeakJoint связями возникают какие-то баги. Верёвка начинает сама шевелиться!
Код AS3:

package gerich.verlet
{
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
 
        public class Main extends Sprite{
                private var pt:Array = new Array();
                private var joints:Array = new Array();
                private var particles:Sprite = new Sprite();
                private var canvas:Shape = new Shape();
                private var grav:Number = 500;
                private var friction:Number = 10;
                private var timeSqr:Number;
 
                // ========================================================== //
                public function Main():void{
                        stage.frameRate = 40;
 
                        timeSqr=1/stage.frameRate;timeSqr*=timeSqr;
 
                        addChild(canvas);
 
                        addChild(particles);
 
                        pt.push(new Particle(270,150,true));
 
                        for (var j:int=0;j<60;j++)
                        {
                                pt.push(new Particle(270,150));
                                joints.push(new WeakJoint(pt[j], pt[j+1], 8));
                        }
 
 
                        for (var i in pt){
                                particles.addChild(pt[i]);
                        }
 
                        addEventListener(Event.ENTER_FRAME, checkJoints);
                        addEventListener(Event.ENTER_FRAME, ptMouse);
                }
                // ========================================================== //
 
                private function checkJoints(event:Event):void{
                        var dx:Number;
                        var dy:Number;
                        var fx:Number;
                        var fy:Number;
 
                        canvas.graphics.clear();
 
                        // Gravity
 
                        for (var i in pt){
                                dx = (pt[i].xx - pt[i].old_x);
                                dy = (pt[i].yy - pt[i].old_y);
                                pt[i].old_x = pt[i].xx;
                                pt[i].old_y = pt[i].yy;
                                fx=pt[i].xx+dx;
                                fy=pt[i].yy+dy+grav*timeSqr;
                                pt[i].xx=fx;
                                pt[i].yy=fy;
                                if(fx<0){
                                        if(dy>0)
                                                pt[i].old_y=Math.max(pt[i].old_y+fx*friction,pt[i].yy);
                                        else
                                                pt[i].old_y=Math.min(pt[i].old_y-fx*friction,pt[i].yy);
                                }
                                if(fx>stage.stageWidth){
                                        if(dy>0)
                                                pt[i].old_y=Math.max(pt[i].old_y+(stage.stageWidth-fx)*friction,pt[i].yy);
                                        else
                                                pt[i].old_y=Math.min(pt[i].old_y-(stage.stageWidth-fx)*friction,pt[i].yy);
                                }
                                if(fy<0){
                                        if(dx>0)
                                                pt[i].old_x=Math.max(pt[i].old_x+fy*friction,pt[i].xx);
                                        else
                                                pt[i].old_x=Math.min(pt[i].old_x-fy*friction,pt[i].xx);
                                }
                                if(fy>stage.stageHeight){
                                        if(dx>0)
                                                pt[i].old_x=Math.max(pt[i].old_x+(stage.stageHeight-fy)*friction,pt[i].xx);
                                        else
                                                pt[i].old_x=Math.min(pt[i].old_x-(stage.stageHeight-fy)*friction,pt[i].xx);
                                }
                        }
 
                        // Joints
 
 
                        for (var z:int=0; z<30; z++){
                                for (var i in joints){
                                        joints[i].Apply();
                                }
 
                                for (var i in pt){
                                        pt[i].xx=Math.max(pt[i].xx,0);
                                        pt[i].xx=Math.min(pt[i].xx,stage.stageWidth);
                                        pt[i].yy=Math.max(pt[i].yy,0);
                                        pt[i].yy=Math.min(pt[i].yy,stage.stageHeight);
                                }
                        }
 
                        for (var i in pt){
                                pt[i].x = pt[i].xx;
                                pt[i].y = pt[i].yy;
                        }
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
                // ========================================================== //
                private function ptMouse(event:Event):void{
                        for (var i in pt){
                                if(pt[i].isMouse){
                                        pt[i].x=mouseX;
                                        pt[i].y=mouseY;
                                        pt[i].xx=mouseX;
                                        pt[i].yy=mouseY;
                                }
                        }
                        canvas.graphics.clear();
                        // Lines
                        for (var i in joints){
                                joints[i].Draw(canvas);
                        }
                }
        }
}
 
// ***** [ Particle Class ] ***************************************** //
 
        import flash.display.Sprite;
 
        internal class Particle extends Sprite{
                public var old_x:Number;
                public var old_y:Number;
                public var xx:Number;
                public var yy:Number;
                public var isMouse:Boolean;
 
                // ========================================================== //
                public function Particle(_x:int, _y:int, _isMouse:Boolean=false):void{
                        x = _x;
                        y = _y;
 
                        xx = _x;
                        yy = _y;
 
                        old_x = _x;
                        old_y = _y;
 
                        isMouse=_isMouse;
 
                        graphics.lineStyle(1, 0x000000);
                        graphics.beginFill(0xFFD22B);
                        graphics.drawCircle(0,0,5);
                        graphics.endFill();
                }
                // ========================================================== //
        }
 
        import flash.display.Shape;
 
        internal class Joint{
                public var p1:Particle;
                public var p2:Particle;
                public var len:Number;
 
                // ========================================================== //
                public function Joint(_p1:Particle, _p2:Particle, _len:Number):void{
                        p1=_p1;
                        p2=_p2;
                        len=_len;
                }
                // ========================================================== //
 
                public function Draw(canvas:Shape):void{
                        canvas.graphics.lineStyle(1,0x000000);
                        canvas.graphics.moveTo(p1.x, p1.y);
                        canvas.graphics.lineTo(p2.x, p2.y);
                }
                // ========================================================== //
 
                public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        diff = (d_len-len)/d_len;
                        dx *= 0.5*diff;
                        dy *= 0.5*diff;
 
                        if(!p2.isMouse){
                                p2.xx -= dx;
                                p2.yy -= dy;
                        }
                        if(!p1.isMouse){
                                p1.xx += dx;
                                p1.yy += dy;
                        }
 
                }
                // ========================================================== //
        }
 
        internal class WeakJoint extends Joint
        {
                // ========================================================== //
                public function WeakJoint(_p1:Particle, _p2:Particle, _len:Number):void{
                        super(_p1,_p2,_len);
                }
 
                // ========================================================== //
                override public function Apply():void{
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        if(d_len>len){
                                diff = (d_len-len)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
 
                // ========================================================== //
        }
 
        internal class RangeJoint extends Joint
        {
                public var lenmax:Number;
                public var lenmin:Number;
                // ========================================================== //
                public function RangeJoint(_p1:Particle, _p2:Particle, _lenmin:Number, _lenmax:Number):void
                {
                        lenmax=_lenmax;
                        lenmin=_lenmin;
                        super(_p1,_p2,_lenmax);
                }
 
                // ========================================================== //
                override public function Apply():void
                {
                        var dx:Number;
                        var dy:Number;
                        var d_len:Number;
                        var diff:Number;
 
                        dx = p2.xx-p1.xx;
                        dy = p2.yy-p1.yy;
                        d_len = Math.sqrt(dx*dx + dy*dy);
                        if(d_len==0){
                                dx=Math.random();
                                dy=Math.random();
                                d_len = Math.sqrt(dx*dx + dy*dy);
                        }
                        if((d_len>lenmax)||(d_len<lenmin)){
                                if(d_len>lenmax)
                                        diff = (d_len-lenmax)/d_len;
                                if(d_len<lenmin)
                                        diff = (d_len-lenmin)/d_len;
                                dx *= diff;
                                dy *= diff;
 
                                if(!p2.isMouse){
                                        p2.xx -= dx;
                                        p2.yy -= dy;
                                }
                                if(!p1.isMouse){
                                        p1.xx += dx;
                                        p1.yy += dy;
                                }
                        }
                }
                // ========================================================== //
        }


Герыч 07.05.2009 21:39

Много сделано, но есть проблемы
 
Вложений: 2
Большинство багов исправил, сделал настройки всякие) прикрепляю 1-ый файл - "хорошая" версия.
Во втором файле проблемы.. когда ставлю жёсткие Joint'ы, то вся конструкция начинает вращаться.
Кто знает решение и причину проблемы, поделитесь..

Crash512 07.05.2009 23:46

О... а можешь мне исходник выслать?.. Надо бы нам как-то скооперироваться, и довести это дело до конца. Мне вот нужны именно жёсткие связи=)

Я даже подумываю о том, что это пора в новую ветку выводить=))
В этой уже дофига кода, надо как-то всё в кучу собрать=)

Герыч 08.05.2009 00:09

Вложений: 1
вот код


Часовой пояс GMT +4, время: 14:51.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.