Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Странные глюки. (http://www.flasher.ru/forum/showthread.php?t=151599)

AlexCooper 02.03.2011 16:05

Странные глюки.
 
Здравствуйте.
Сегодня ночью наткнулся на целый ряд не понятных мне багов. Когда трасировка к примеру
Код:

course.controlpoint[0][0]==Math.floor(course._x)
показывала false при course.controlpoint[0][0]=163 && Math.floor(course._x)=163. Но это еще не всё. Попрошу лучше взглянуть на код. Так как при выполнении одного условия в строчке 56 просчитываются довольно большое количество итераций в пустую. Это можно увидеть при снятии закоментированных трейсеров.
Дальше идёт код, правда немного не красивый но я не успел еще привести его до толку. Но больше всего интересует такой вопрос с свойствами _х и _у с аналогичными course.controlpoint[0][0] и course.controlpoint[0][1] данными, когда там одинаковые числа а выводит false, причём если не использовать Math.floor то вообщепроисходить всеголишь 1 итерация.
Код AS1/AS2:

//import flash.display.Graphics;
 
class Vector2D
{
 
                private var _x:Number;
                private var _y:Number;
 
                public function Vector2D(x:Number,y:Number)
                {
                        _x = x;
                        _y = y;
                }
 
                public function draw(graphics:MovieClip, color):Void
                {
                        graphics.lineStyle(0, color);
                        graphics.moveTo(0, 0);
                        graphics.lineTo(_x, _y);
                }
 
                public function clone():Vector2D
                {
                        return new Vector2D(x, y);
                }
 
                public function zero():Vector2D
                {
                        _x = 0;
                        _y = 0;
                        return this;
                }
 
                public function isZero():Boolean
                {
                        return _x == 0 && _y == 0;
                }
 
                public function set length(value:Number):Void
                {
                        var a:Number = angle;
                        _x = Math.cos(a) * value;
                        _y = Math.sin(a) * value;
                }
                public function get length():Number
                {
                        return Math.sqrt(lengthSQ);
                }
 
                public function get lengthSQ():Number
                {
                        return _x * _x + _y * _y;
                }
 
                public function set angle(value:Number):Void
                {
                        var len:Number = length;
                        _x = Math.cos(value) * len;
                        _y = Math.sin(value) * len;
                }
                public function get angle():Number
                {
                        return Math.atan2(_y, _x);
                }
 
                public function set corner(value:Number):Void
                {
                        var len:Number = length;
                        _x = Math.cos(value*Math.PI/180) * len;
                        _y = Math.sin(value*Math.PI/180) * len;
                }
 
                public function get corner():Number
                {
                        return angle * 180 / Math.PI;
                }
 
                public function normalize():Vector2D
                {
                        if(length == 0)
                        {
                                _x = 1;
                                return this;
                        }
                        var len:Number = length;
                        _x /= len;
                        _y /= len;
                        return this;
                }
 
                public function truncate(max:Number):Vector2D
                {
                        length = Math.min(max, length);
                        return this;
                }
 
                public function reverse():Vector2D
                {
                        _x = -_x;
                        _y = -_y;
                        return this;
                }
 
                public function isNormalized():Boolean
                {
                        return length == 1.0;
                }
 
                public function dotProd(v2:Vector2D):Number
                {
                        return _x * v2.x + _y * v2.y;
                }
 
                public function crossProd(v2:Vector2D):Number
                {
                        return _x * v2.y - _y * v2.x;
                }
 
 
                public static function angleBetween(v1:Vector2D, v2:Vector2D):Number
                {
                        if(!v1.isNormalized()) v1 = v1.clone().normalize();
                        if(!v2.isNormalized()) v2 = v2.clone().normalize();
                        return Math.acos(v1.dotProd(v2));
                }
 
                  public static function cornerBetween(v1:Vector2D, v2:Vector2D):Number
                {
                        return angleBetween(v1,v2) * 180 / Math.PI;
                }
 
                public function sign(v2:Vector2D)
                {
                        return perp.dotProd(v2) < 0 ? -1 : 1;
                }
 
                public function get perp():Vector2D
                {
                        return new Vector2D(-y, x);
                }
 
                public function dist(v2:Vector2D):Number
                {
                        return Math.sqrt(distSQ(v2));
                }
 
                public function distSQ(v2:Vector2D):Number
                {
                        var dx:Number = v2.x - x;
                        var dy:Number = v2.y - y;
                        return dx * dx + dy * dy;
                }
 
                public function add(v2:Vector2D):Vector2D
                {
                        return new Vector2D(_x + v2.x, _y + v2.y);
                }
 
                public function subtract(v2:Vector2D):Vector2D
                {
                        return new Vector2D(_x - v2.x, _y - v2.y);
                }
 
                public function multiply(value:Number):Vector2D
                {
                        return new Vector2D(_x * value, _y * value);
                }
 
                public function divide(value:Number):Vector2D
                {
                        return new Vector2D(_x / value, _y / value);
                }
 
                public function equals(v2:Vector2D):Boolean
                {
                        return _x == v2.x && _y == v2.y;
                }
 
                public function set x(value:Number):Void
                {
                        _x = value;
                }
                public function get x():Number
                {
                        return _x;
                }
 
                public function set y(value:Number):Void
                {
                        _y = value;
                }
                public function get y():Number
                {
                        return _y;
                }
 
                public function toString():String
                {
                        return "[Vector2D (x:" + _x + ", y:" + _y + ")]";
                }
}

и в самом флеше поместите небольшой мувик с назначенным ему "ship" идентификатором.
Код AS1/AS2:

import Vector2D;
 
var t:MovieClip = _root.createEmptyMovieClip("triang_mc", 1);
        thickness = 1;
        lineColor = 0xff0000;
        alpha = 100;
 
        triang_mc.lineStyle(thickness, lineColor, alpha);
 
ship.m=20;
ship.speed=20;
ship.stopl=30;
ship.radius=180/ship.m;
 
triang_mc.moveTo(ship._x, ship._y);
 
X=ship._x+Math.cos(Math.PI/180*(ship._rotation+90))*ship.radius;
Y=ship._y+Math.sin(Math.PI/180*(ship._rotation+90))*ship.radius;
triang_mc.lineTo(X, Y);
var course:MovieClip = new MovieClip();
 
course.axis = new Vector2D(Math.cos(Math.PI/180*ship._rotation),Math.sin(Math.PI/180*ship._rotation));
 
course.target = new Vector2D(dot._x-ship._x,dot._y-ship._y);
 
triang_mc.lineStyle(0, 0xFF0000);
triang_mc.moveTo(ship._x, ship._y);
 
BuildRoute = function()
{
                r++;
 
                course.target.x=course.tx-course._x;
                course.target.y=course.ty-course._y;
 
                //trace(Vector2D.cornerBetween(course.route,course.target));
 
                if (Vector2D.cornerBetween(course.route,course.target)>course.m)
                {
 
                        course.route.corner+=course.shift*course.m;
                        course._rotation=course.route.corner;
 
                } else
                {
                        course.route=course.target;
                        course._rotation=course.target.corner;
                }
 
                course._x+= (course.target.length>course.speed) ? Math.cos(Math.PI/180*course._rotation)*course.speed : course.target.x;
                course._y+= (course.target.length>course.speed) ? Math.sin(Math.PI/180*course._rotation)*course.speed : course.target.y;
 
                course._x=Math.floor(course._x);
                course._y=Math.floor(course._y);
 
                if ((course.controlpoint[0][0]==Math.floor(course._x) && course.controlpoint[0][1]==Math.floor(course._y)) || (Vector2D.cornerBetween(course.route,course.axis)<course.m && !course.route.equals(course.target)))
                {
 
 
                        //triang_mc.lineTo(course._x, course._y);
                        course.speed-=1;
//trace('Speed:'+course.speed);
                        course.controlpoint.splice(1);
                        course.route.x=course.axis.x;
                        course.route.y=course.axis.y;
                        course.route = course.axis.clone();
                        course.route.corner+=course.shift;
                        course._x=Math.floor(ship._x);
                        course._y=Math.floor(ship._y);
 
                } else
                {
                        if (course.target.length<course.speed)
                        {
                                if (course.target.equals(course.route))
                                {
                                        course.controlpoint.push([course._x, course._y,course._rotation]);
 
                                        return false;
                                }
                                else
                                {
                                        course.speed-=1;
 
                                        course.controlpoint.splice(0);
                                        course.route.x=course.axis.x;
                                        course.route.y=course.axis.y;
                                        course.route = course.axis.clone();
                                        course.route.corner+=course.shift;
                                        course._x=Math.floor(ship._x);
                                        course._y=Math.floor(ship._y);
 
                                        /*/triang_mc.clear();
                                        triang_mc.lineStyle(0, 0xFF0000);
                                        triang_mc.moveTo(course.controlpoint[0][0],course.controlpoint[0][1]);*/

                                }
 
                        } else
                        {
                                course.controlpoint.push([course._x, course._y,course._rotation]);
                                //triang_mc.lineTo(course._x, course._y);
                        }
 
                }
                return true;
}
 
function traceRoute()
{
        triang_mc.lineStyle(0, 0xFF0000);
        triang_mc.moveTo(course.controlpoint[0][0],course.controlpoint[0][1]);
 
        for (step=1; step< course.controlpoint.length; step++)
        {
                triang_mc.lineTo(course.controlpoint[step][0],course.controlpoint[step][1]);
        }
}
 
_root.bufferT = getTimer();
_root.onMouseDown = function()
{
        delete ship.onEnterFrame;
 
        if (getTimer()-_root.bufferT>500)
        {
                ship._x= Math.floor(ship._x);
                ship._y= Math.floor(ship._y);
                course.tx = Math.floor(_xmouse);
                course.ty = Math.floor(_ymouse);
                course._x = ship._x;
                course._y = ship._y;
                course._rotation = ship._rotation;
                course.controlpoint = new Array();
 
                for (prop in ship)
                {
                        course[prop]=ship[prop];
                }
 
                course.axis.x=Math.cos(Math.PI/180*course._rotation);
                course.axis.y=Math.sin(Math.PI/180*course._rotation);
 
                course.target.x=course.tx-course._x;
                course.target.y=course.ty-course._y;
 
                course.axis.length=1;
 
                course.route = course.axis.clone();
 
                if (Vector2D.cornerBetween(course.axis,course.target)>=course.m)
                {
                        course.shift = 1;
 
                        course.route.corner+=course.shift;
 
                        if (Vector2D.cornerBetween(course.route,course.target)>Vector2D.cornerBetween(course.axis,course.target))
                        {
                                course.shift*=-1;
                        }
                } else course.shift = 0;
 
                course.route.x=course.axis.x;
                course.route.y=course.axis.y;
 
                course.controlpoint.push([course._x, course._y,course._rotation]);
 
                r = 0;
                while (BuildRoute());
 
                trace('Search iteration :: '+r);
        } else
        {
                traceRoute();
                delete ship.onEnterFrame;
                //trace(course.controlpoint);
                ship.dx=(course.controlpoint[1][0]-ship._x)/10;
                ship.dy=(course.controlpoint[1][1]-ship._y)/10;
                ship.dr=(course.controlpoint[1][2]-ship._rotation)/10;
                ship.s=0;
                ship.st=1;
                ship.onEnterFrame = function()
                {
                        //trace(course.controlpoint[++ship.st][0]);
                        this._x+=this.dx;
                        this._y+=this.dy;
                        this._rotation+=this.dr;
                        if (++this.s==10)
                        {
                                this.s=0;
                                this.dx=(_root.course.controlpoint[++this.st][0]-this._x)/10;
                                this.dy=(_root.course.controlpoint[this.st][1]-this._y)/10;
                                this.dr=(_root.course.controlpoint[this.st][2]-this._rotation)/10;
                        }
                }
        }
        _root.bufferT = getTimer();
        //traceRoute();
}

предыдущая тема http://www.flasher.ru/forum/showthread.php?t=151244

Hauts 02.03.2011 16:21

Формализуйте вопросы и выложите исходники, иначе проблематично разобраться.

AlexCooper 03.03.2011 04:06

Вложений: 1
Глюки уже не тревожат, вот только при больших значениях speed и flexbility и кликах как можно больше к мувику возможны "зависания" + не правильный просчёт. А вообще вектора рулят))

speed - скорость в пикселях за одну итерацию
flexbility - допустимый угол поворота, то-есть манёвренность

так же я дополнил класс Вектор2Д

трёма функциями преобразующие геометрические углы в понятное для нас свойство _rotation (угол наклона)
Код AS1/AS2:

геттеры и сетеры 
public function set corner(value:Number):Void
                {
                        var len:Number = length;
                        _x = Math.cos(value*Math.PI/180) * len;
                        _y = Math.sin(value*Math.PI/180) * len;
                }
 
                public function get corner():Number
                {
                        return angle * 180 / Math.PI;
                }
 
функция возвращающая угол наклона между векторами
public static function cornerBetween(v1:Vector2D, v2:Vector2D):Number
                {
                        return angleBetween(v1,v2) * 180 / Math.PI;
                }

исходный код класса есть в самом начале

AlexCooper 03.03.2011 04:19

Так же хочу поблагодарить Hauts который направил меня на немало полезной информации. Еще раз спасибо, как Видете пришлось переписать по АС2, но за то функциональные возможности взросли в несколько раз

Hauts 03.03.2011 08:44

AlexCooper, спасибо :)

Отличная флэшка получилась! Честно говоря, не думал, что так быстро сделаете.

Кстати в классе вектора я обычно Math.PI/180 выношу в прайват-переменную (кэширую) и использую ее для расчетов, а не делю каждый раз PI на 180.

Котяра 03.03.2011 12:24

Почему AS2?

AlexCooper 03.03.2011 14:06

Да я просто никак не начну писать под AS3 и как следствие не знаю разницы в методах объявление функций в классах (public, private, property)


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

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