Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Помогите найти ошибку (столкновение шариков) (http://www.flasher.ru/forum/showthread.php?t=205187)

baka 22.11.2013 18:00

Помогите найти ошибку (столкновение шариков)
 
Вложений: 1
Привет!
Пытаюсь использовать метод расчета столкновений шариков, описанный в книге "Программирование игр на Flash MX" Джоба Макара.
http://animbook.mirmap.com/content/view/33/43/

Используя скопированные из книги функции.
Где я допустил ошибку, почему шарики склеиваются?
Скореев сего гдето какаято глупость из за не внимательности -_- не могу найти =(
Помогите плиз.
Код AS3:

package lol{
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
        import flash.ui.Mouse;
 
        public class main extends MovieClip {
                var i:int;
                var j:int;
                var timerRate:int=30;
                var timer:Timer=new Timer(timerRate,0);
                var ob;
                //
                //свалка хлама
                var xmov1:Number ,ymov1:Number ,xmov2:Number ,ymov2:Number ,xl1:Number ,yl1:Number ,xl2:Number ,yl2:Number ,
                R:Number ,a:Number ,b:Number ,c:Number ,d:Number ,e:Number ,f:Number ,g:Number ,h:Number ,k:Number ,sqRoot:Number ,
                t1:Number ,t2:Number ,mass1:Number ,mass2:Number ,xVel1:Number ,xVel2:Number ,yVel1:Number ,yVel2:Number ,
                run:Number ,rise:Number ,Theta:Number ,cosTheta:Number ,sinTheta:Number ,xVel1prime:Number ,xVel2prime:Number ,yVel1prime:Number ,
                yVel2prime:Number ,P:Number ,V:Number ,v2f:Number ,v1f:Number ,whatTime:Number,ballsCollided:Boolean,b1:Object ,b2:Object;
                //^свалка хлама
                //
                var ballContainer:MovieClip=new MovieClip  ;
                var ballArray=new Array(0);
                var skolkoBalls:int;
                //
                public function main() {
                        //
                        stage.addChild(ballContainer);
                        //
                        //
                        timer.addEventListener(TimerEvent.TIMER,timerListener);
                        timer.start();
 
                        //
                        addBall(20,200,5);
                        addBall(300,203,-5);
                        //
                }
                //
                public function addBall(xx,yy,xmov):void {
                        ballArray.push(new Ball(xx,yy,xmov));
                        ballContainer.addChild(ballArray[ballArray.length - 1]);
                }
                //
                public function timerListener(e:TimerEvent):void {
                        moveballs();
                        ball2ballCollisions();
                        renderballs();
 
                }
                //
                function ball2ballCollisions() {
                        //
                        b1=ballArray[0];
                        b2=ballArray[1];
                        if (b1&&b2) {
                                checkCollision(b1,b2);
                        }
                        //
                }
                function moveballs() {
                        //
                        skolkoBalls=ballArray.length;
                        if (skolkoBalls>0) {
                                for (i=0; i<skolkoBalls; i++) {
                                        //
                                        moveObjects(ballArray[i]);
                                        //
                                }
                        }
                        //
                }
                function renderballs() {
                        //
                        skolkoBalls=ballArray.length;
                        if (skolkoBalls>0) {
                                for (i=0; i<skolkoBalls; i++) {
                                        //
                                        renderObjects(ballArray[i]);
                                        //
                                }
                        }
                }
                //
                function moveObjects(ob):void {
                        if (! ob) {
                                return;
                        }
                        ob.tempx=ob.xpos+ob.xmov;
                        ob.tempy=ob.ypos+ob.ymov;
                        //
                }
                function renderObjects(ob) {
                        ob.xpos=ob.tempx;
                        ob.ypos=ob.tempy;
                        ob.x=ob.xpos;
                        ob.y=ob.ypos;
                }
                //
                function checkCollision(b1, b2) {
                        xmov1=b1.xmov;
                        ymov1=b1.ymov;
                        xmov2=b2.xmov;
                        ymov2=b2.ymov;
                        //инициализировать переменные координат
                        xl1=b1.xpos;
                        yl1=b1.ypos;
                        xl2=b2.xpos;
                        yl2=b2.ypos;
                        //определить константы
                        R=b1.radius+b2.radius;
                        a=-2*xmov1*xmov2+xmov1*xmov1+xmov2*xmov2;
                        b=-2*xl1*xmov2-2*xl2*xmov1+2*xl1*xmov1+2*xl2*xmov2;
                        c=-2*xl1*xl2+xl1*xl1+xl2*xl2;
                        d=-2*ymov1*ymov2+ymov1*ymov1+ymov2*ymov2;
                        e=-2*yl1*ymov2-2*yl2*ymov1+2*yl1*ymov1+2*yl2*ymov2;
                        f=-2*yl1*yl2+yl1*yl1+yl2*yl2;
                        g=a+d;
                        h=b+e;
                        k=c+f-R*R;
                        //решить квадратное уравнение
                        sqRoot=Math.sqrt(h*h-4*g*k);
                        t1 = (- h + sqRoot) / (2 * g);
                        t2 = (- h - sqRoot) / (2 * g);
                        if (t1>0&&t1<=1) {
                                whatTime=t1;
                                ballsCollided=true;
                        }
                        if (t2>0&&t2<=1) {
                                if (t2<t1) {
                                        whatTime=t2;
                                        ballsCollided=true;
                                }
                        }
                        if (ballsCollided) {
                                ball2BallReaction(b1,b2,xl1,xl2,yl1,yl2,whatTime);
                        }
 
                }
                //
                function ball2BallReaction(b1, b2, x1, x2, y1, y2, time) {
                        //найти массы
                        mass1=b1.mass;
                        mass2=b2.mass;
                        //-----установить переменные начальных векторных скоростей
                        xVel1=b1.xmov;
                        xVel2=b2.xmov;
                        yVel1=b1.ymov;
                        yVel2=b2.ymov;
                        //
                        //run = x1 - x2;
                        //rise = y1 - y2;
                        run=x1-x2;
                        rise=y1-y2;
                        //
                        Theta=Math.atan2(rise,run);
                        cosTheta=Math.cos(Theta);
                        sinTheta=Math.sin(Theta);
                        //найти векторные скорости вдоль линии действия
                        xVel1prime=xVel1*cosTheta+yVel1*sinTheta;
                        xVel2prime=xVel2*cosTheta+yVel2*sinTheta;
                        //найти векторные скорости, перпендикулярные линии действия
                        yVel1prime=yVel1*cosTheta-xVel1*sinTheta;
                        yVel2prime=yVel2*cosTheta-xVel2*sinTheta;
                        //уравнения сохранения
                        P=mass1*xVel1prime+mass2*xVel2prime;
                        V=xVel1prime-xVel2prime;
                        v2f = (P + mass1 * V) / (mass1 + mass2);
                        v1f=v2f-xVel1prime+xVel2prime;
                        xVel1prime=v1f;
                        xVel2prime=v2f;
                        //проецирование в систему координат Flash на оси x и y
                        xVel1=xVel1prime*cosTheta-yVel1prime*sinTheta;
                        xVel2=xVel2prime*cosTheta-yVel2prime*sinTheta;
                        yVel1=yVel1prime*cosTheta+xVel1prime*sinTheta;
                        yVel2=yVel2prime*cosTheta+xVel2prime*sinTheta;
                        //изменение старой позиции
                        b1.tempx=b1.xpos+b1.xmov*time;
                        b1.tempy=b1.ypos+b1.ymov*time;
                        b1.xmov=xVel1;
                        b1.ymov=yVel1;
                        b2.tempx=b2.xpos+b2.xmov*time;
                        b2.tempy=b2.ypos+b2.ymov*time;
                        b2.xmov=xVel2;
                        b2.ymov=yVel2;
 
                }
                //
        }
}

шарик:
Код AS3:

package lol{
        //
        import flash.display.*;
        import flash.events.*;
        //
        public class Ball extends MC_Ball {
                public var xx:Number,yy:Number,xmov:Number,ymov:Number,speed_:Number,mass:Number,tempx:Number,tempy:Number,xpos:Number,ypos:Number,obj_id:Number,
                radius:Number;
                //private var tempArr1:Array,TempX_1:int,TempY_1:int,distance_:Number;
                public function Ball(xx,yy,speed) {
                        //                       
                        //
                        this.x=xx;
                        this.y=yy;
                        //
                        speed_=2;
                        mass=10;
                        radius=21/2;
                        //
                        xmov=speed;
                        ymov=0
                        //
                        xpos=xx;
                        ypos=yy;
                        tempx=xx;
                        tempy=yy;                       
                        //
                }
        }
        //
}


baka 22.11.2013 21:10

Удалите тему, она наверное мусор -_-

Я все починил сам.
"//свалка хлама" задать локально внутри функций надо бы.
Все переменные внешние, ballsCollided стало true и все =)

а чтобы работало как есть - добавить ballsCollided=false; в начало функции проверки столкновений


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

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