Форум программистов, компьютерный форум, киберфорум
Наши страницы
ActionScript
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.70/10: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Magikl
6 / 6 / 0
Регистрация: 23.11.2011
Сообщений: 52
1

Перемещение объекта по точкам

18.09.2013, 14:28. Просмотров 1747. Ответов 10
Метки нет (Все метки)

Здравствуйте,
возникла такая проблема:
Нужно переместить объект из 1 конца дороги в другой(появляется в 1).
Я разделил ее на 4 прямых отрезка(так вроде бы проще).
Но из за (автоматического?) округления постоянно появляется погрешность и дальше первой точки объект не движется.
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// unit-объект , xArray и yArray - координаты точек
private function moveTo(fromX:int, fromY:int, toX:int, toY:int):void
{
     var x:int=(toX-fromX)/100;  //на 100 чтобы была плавность ( как раз здесь эта погрешность и появляется).
     var y:int=(toY-fromY)/100;
     unit.setMoveX(x); //в классе юнитов переменная отвечающая за дальность перемещения за 1 тик таймера.
     unit.setMoveY(y);
}
private function unitMove(e:TimerEvent):void
{
     if (unit.getTarget()==0)
     {
          moveTo(unit.x,unit.y,xArray[0],yArray[0]);
          unit.setTarget(1); //в классе юнитов сохраняется номер точки к которой движется юнит.
     }
     else if ((unit.getTarget()==1)&&(unit.x<xArray[1])) 
     {
          unit.x+=unit.getMoveX();
          unit.y+=unit.getMoveY();
     }
// и так далее, но даже к первой точке он приходит с погрешностью в как минимум 1 координату.
}
Во всех примерах в интернете(которые я посмотрел) на эту ему не предлагается никакого другого решения.
0
Изображения
 
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.09.2013, 14:28
Ответы с готовыми решениями:

Перемещение объекта. Условие
Подскажите. Есть такой код для объекта Movie Clip с именем f1. Нужно после...

Перемещение объекта на место клика
Есть два объекта. Первый объект: player. Второй объект: moveArea. Необходимо...

Построение треугольника по трем точкам
Добрый день! В универе дали задание сделать программу, которая строит...

Движение самолета по заданным точкам
Здравствуйте! Нужна помощь в создании игры. Есть самолет, который должен...

Поворот геометрического объекта на 90 градусом заданного по точкам
Поворот ГО на 90 градусом заданного по точкам: List&lt;Point&gt; Points = new...

10
TanaTiX
Модератор
2796 / 1650 / 168
Регистрация: 19.02.2011
Сообщений: 6,006
Завершенные тесты: 2
18.09.2013, 14:52 2
Почему не воспользоваться твинерами? (Я не про стандартный класс Tween, а про библиотеки)
0
Magikl
6 / 6 / 0
Регистрация: 23.11.2011
Сообщений: 52
18.09.2013, 14:55  [ТС] 3
Чтобы ими пользоваться нужно знать что это такое
Мне кажется, что это проще решить без "твиннеров", но пока ничего не придумывается.
0
TanaTiX
Модератор
2796 / 1650 / 168
Регистрация: 19.02.2011
Сообщений: 6,006
Завершенные тесты: 2
18.09.2013, 18:36 4
Magikl, вот сайт одного из наиболее популярных. Там есть и исходники и примеры работы.
0
Magikl
6 / 6 / 0
Регистрация: 23.11.2011
Сообщений: 52
18.09.2013, 18:57  [ТС] 5
Я уже придумал как сделать без твиннеров, но все равно посмотрю, спасибо.
0
nubideus
390 / 272 / 76
Регистрация: 19.09.2011
Сообщений: 828
19.09.2013, 00:30 6
Magikl, округляются координаты экранных объектов (DisplayObject). для избежания этого достаточно завести отдельные переменные типа Number для координат.

для равномерного движения по ломанной линии я делал
это
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    
 
    package  
    {
            import flash.geom.Point;
           
            public class BrokenLine
            {
                    private var data:Vector.<Point> = new Vector.<Point>();
                    private var _length:Number = 0;
                   
                    function BrokenLine(data:Vector.<Point> = null) {
                            setData((data != null) ? data : new <Point>[]);
                    }
                   
                    public function get length():Number {
                            return _length;
                    }
                   
                    public function unshift(x:Number, y:Number):Number {
                            if(x != data[0].x || y != data[0].y){
                                    data.unshift(new Point(x, y));
                                    this._length += data[0].subtract(data[1]).length;
                            }
                            return this._length;
                    }
                   
                    /*
                    public function shift():Point {
                            this._length -= data[0].subtract(data[1]).length;
                            return data.shift();
                    }
                    */
                   
                    public function push(x:Number, y:Number):Number {
                            if(x != data[data.length - 1].x || y != data[data.length - 1].y){
                                    data.push(new Point(x, y));
                                    this._length += data[data.length - 2].subtract(data[data.length - 1]).length;
                            }
                            return this._length;
                    }
                   
                    /*
                    public function pop():Point {
                            this._length -= data[data.length - 2].subtract(data[data.length - 1]).length;
                            return data.pop();
                    }
                    */
                   
                    public function getPoint(length:Number = 0):Point {
                            return getPoints(new <Number>[length])[0];
                    }
                   
                    public function getPointFromEnd(length:Number = 0):Point {
                            return getPoint(this._length - length);
                    }
                   
                    public function getPoints(lengths:Vector.<Number>):Vector.<Point> {
                            var result:Vector.<Point> = new Vector.<Point>(lengths.length, true);
                            var resultPointer:uint = 0;
                            var traversedLength:Number = 0;
                            var distinction:Number = 0;
                            var length:Number = lengths[resultPointer];
                           
                            for (var i:uint = 1; i < data.length; i++) {
                                    var loc:Point = data[i];
                                    var prevLoc:Point = data[i - 1];
                                   
                                    if (length < 0 || length > this._length ) {
                                            throw new RangeError("invalid argument");
                                    }
                                   
                                    distinction = Math.sqrt((loc.x - prevLoc.x) * (loc.x - prevLoc.x) + (loc.y - prevLoc.y) * (loc.y - prevLoc.y));
                                    traversedLength += distinction;
                                   
                                    if (i == data.length - 1) {
                                            traversedLength = this._length;
                                    }
                                   
                                    if (traversedLength >= length) {
                                            var t:Number = (length - (traversedLength - distinction)) / distinction;
                                           
                                            result[resultPointer++] = new Point((loc.x - prevLoc.x) * t + prevLoc.x, (loc.y - prevLoc.y) * t + prevLoc.y);
                                           
                                            if (resultPointer < lengths.length) {
                                                    length = lengths[resultPointer];
                                                    if (length >= lengths[~-resultPointer]) {
                                                            traversedLength -= distinction;
                                                            i--;
                                                    }else {
                                                            traversedLength = 0;
                                                            i = 0;
                                                    }
                                            }else {
                                                    break;
                                            }
                                    }
                            }
                            return result;
                    }
                   
                    public function getPointsFromEnd(lengths:Vector.<Number>):Vector.<Point> {
                            var newLengths:Vector.<Number> = new Vector.<Number>();
                           
                            for (var i:int = 0; i < lengths.length; i++ ) {
                                    newLengths.unshift(this._length - lengths[i]);
                            }
                            return getPoints(newLengths).reverse();
                    }
                   
                    public function getAllPoints(length:Number):Vector.<Point> {
                            var lengths:Vector.<Number> = new Vector.<Number>();
                           
                            for (var i:int = 0; i <= this._length / length; i++ ) {
                                    lengths.push(i * length);
                            }
                            return getPoints(lengths);
                    }
                   
                    public function getAllPointsFromEnd(length:Number):Vector.<Point> {
                            var lengths:Vector.<Number> = new Vector.<Number>();
                           
                            for (var i:int = 0; i <= this._length / length; i++ ) {
                                    lengths.push(i * length);
                            }
                            return getPointsFromEnd(lengths);
                    }
                   
                    public function deleteFromStart(length:Number):Number {
                            cut(length);
                            return this._length;
                    }
                   
                    public function deleteFromEnd(length:Number):Number {
                            setData(cut(this._length - length));
                            return this._length;
                    }
                   
                    public function setData(points:Vector.<Point>):Number {
                            this._length = 0;
                           
                            this.data.splice(0, this.data.length);
                           
                            if (points.length) {
                                    this.data.push(points.shift());
                                    addData(points);
                            }else {
                                    this.data.push(new Point());
                            }
                            return this._length;
                    }
                   
                    public function addData(points:Vector.<Point>):Number {
                            for (var i:int = 0; i < points.length; i++ ) {
                                    push(points[i].x, points[i].y);
                            }
                            return this._length;
                    }
                   
                    public function clone():BrokenLine {
                            return new BrokenLine(this.data);
                    }
                   
                    public function cut(length:Number):Vector.<Point> {
                            var result:Vector.<Point> = null;
                            var traversedLength:Number = 0;
                            var distinction:Number = 0;
                           
                            if (length < 0 || length >= this._length) {
                                    throw new RangeError("invalid argument");
                            }
                           
                            for (var i:int = 1; i < data.length; i++ ) {
                                    var loc:Point = data[i];
                                    var prevLoc:Point = data[i - 1];
                                   
                                    traversedLength += distinction;
                                    distinction = Point.distance(loc, prevLoc);
                                   
                                    if (traversedLength + distinction >= length) {
                                            var t:Number = (length - traversedLength) / distinction;
                                           
                                            result = data.splice(0, i, Point.interpolate(loc, prevLoc, t));
                                            result.push(data[0]);
                                           
                                            if (data[0].equals(data[1])) {
                                                    data.shift();
                                            }
                                           
                                            this._length -= traversedLength + distinction * t;
                                            break;
                                    }
                            }
                            return result;
                    }
            }
     
    }


оно умеет
ActionScript 3
1
line.getPoint(line.length / 2); // вернет точку, которая на середине линии
то есть можно двигаться по пути с равной скоростью.
demo.swf
0
TanaTiX
Модератор
2796 / 1650 / 168
Регистрация: 19.02.2011
Сообщений: 6,006
Завершенные тесты: 2
19.09.2013, 10:04 7
Цитата Сообщение от nubideus Посмотреть сообщение
// вернет точку, которая на середине линии
Есть еще такая штука
0
Magikl
6 / 6 / 0
Регистрация: 23.11.2011
Сообщений: 52
19.09.2013, 14:22  [ТС] 8
Не хочется разбираться в куче чужого кода, да и все гораздо проще.
ActionScript 3
1
2
3
4
var s:Number=Math.sqrt((toX-fromX)*(toX-fromX)+(toY-fromY)*(toY-fromY)); //вычисляем расстояние от 1-й точки до 2-й(чтобы вычислить косинус и синус угла)
var sin:Number=(toY-fromY)/s; 
var cos:Number=(toX-fromX)/s;
s=(playerUnitsArray[index].getTime2()-playerUnitsArray[index].getTime1())*1; //тут вычисляем расстояние которое НУЖНО пройти за промежуток времени между тиками таймера(они,оказывается, тикают не точно(могут с задержкой, могут и без)). getTime2-время тика таймера, getTime1- первый раз - время создания юнита, далее-время последнего перемещения.
Не уверен поймет ли кто-нибудь мои каракули, но вдруг кто-нибудь разберется
0
Миниатюры
Перемещение объекта по точкам  
nubideus
390 / 272 / 76
Регистрация: 19.09.2011
Сообщений: 828
19.09.2013, 15:53 9
Цитата Сообщение от Magikl Посмотреть сообщение
тиками таймера(они,оказывается, тикают не точно(могут с задержкой, могут и без))
Timer пытается синхронизироваться с событием ENTER_FRAME, или они оба пытаются синхронизироваться с внутренним таймером.
короче, Timer не рекомендуется использовать для обновления позиций экранных объектов. лучше использовать ENTER_FRAME.

Цитата Сообщение от Magikl Посмотреть сообщение
Не хочется разбираться в куче чужого кода, да и все гораздо проще.
а вот и правильно, велосипеды - это хорошо.

TanaTiX, Point.interpolate у меня для скорости делается руками:
Цитата Сообщение от nubideus Посмотреть сообщение
new Point((loc.x - prevLoc.x) * t + prevLoc.x, (loc.y - prevLoc.y) * t + prevLoc.y);
Point.distance, Point.interpolate замедляют в несколько раз
0
Magikl
6 / 6 / 0
Регистрация: 23.11.2011
Сообщений: 52
19.09.2013, 16:15  [ТС] 10
Цитата Сообщение от nubideus Посмотреть сообщение
Timer пытается синхронизироваться с событием ENTER_FRAME, или они оба пытаются синхронизироваться с внутренним таймером.
короче, Timer не рекомендуется использовать для обновления позиций экранных объектов. лучше использовать ENTER_FRAME.
Спасибо за совет, теперь буду привыкать не использовать таймер.
0
TanaTiX
Модератор
2796 / 1650 / 168
Регистрация: 19.02.2011
Сообщений: 6,006
Завершенные тесты: 2
19.09.2013, 16:28 11
Цитата Сообщение от nubideus Посмотреть сообщение
Timer не рекомендуется использовать для обновления позиций экранных объектов. лучше использовать ENTER_FRAME
Это зависит от конкретной задачи. Если нужна большая точность, то лучше использовать связку ENTER_FRAME+getTimer.
0
19.09.2013, 16:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2013, 16:28

Перемещение объекта
Всем привет. Немного запутался с перемещением.. Игра 2d. Нажимаем в любую точку...

Перемещение объекта
Есть код осуществляющий поворот объектов из 3дмакса по имени:...

Перемещение 2 d объекта
Помогите пожалуйста. Могу нарисовать несколько треугольников в различных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru