![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Движение объекта [D7, XP]
novai © (2012-03-17 10:35:00)Как в таймере переместить объект из точки (X1, Y1) в точку (X2, Y2) с нужным шагом?
novai (2012-03-17 16:05:00) [1]А, понял
> XStep = 10;
и есть шаг... на этом и остановлюсь
novai (2012-03-17 15:38:00) [2]и еще вопрос, как можно увеличить скорость движения в 22?
novai (2012-03-17 15:30:00) [3]Переделал вот так, вроде работает:
type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
x, y, x1, y1,x2,y2,
dx, dy, l: real;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
x1:= 300; y1:= 300;
x2:= 200; y2:= 50;
//Äëèíà îòðåçêà
L:=sqrt(sqr(y2-y1)+sqr(x2-x1));
//Âåêòîð ïðèðàùåíèÿ
dX:=(x2-x1)/L;
dY:=(y2-y1)/L;
x:= x1;
y:= y1;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
x:= x + dx;
y:= y + dy;
label1.Left:= Round(x);
label1.Top:= Round(y);
canvas.Rectangle(round(x1), round(y1), round(x2), round(y2));
if (label1.Left = x2) and (label1.Top = y2) then Timer1.Enabled:= false;
end;
проблемм быть не должно?
selesasha (2012-03-17 12:50:00) [4]//Длина отрезка
Length:=sqrt(sqr(y2-y1)+sqr(x2-x1));
//Вектор приращения
dX:=(x2-x1)/Length;
dY:=(y2-y1)/Length;
В таймере проверяете не переместился ли объект в нужную точку, если нет то прибавляете приращение к текущим координатам.
Для координат лучше иметь отдельные переменные вещественного типа, и все операции проводить с ними, при выводе уже округлять.
Anatoly Podgoretsky (2012-03-17 12:45:00) [5]LineDDA
CRLF (2012-03-17 12:25:00) [6]не лучше ли параметрическим заданием прямой пользоваться?
begin...end (2012-03-17 12:18:00) [7]Да, я предположил, что шаг по X - целый. В этом случае накопления ошибки не будет.
Inovet (2012-03-17 12:08:00) [8]Только ошибка будет накапливаться, так что дальше сам доделай, как говорилось в
> [11] Inovet © (17.03.12 11:23)
Inovet (2012-03-17 12:06:00) [9]> [15] novai (17.03.12 12:04)
> это и было нужно.
Код выманил-таки.:)
novai (2012-03-17 12:04:00) [10]Спасибо огромное, это и было нужно.
begin...end (2012-03-17 11:52:00) [11]> novai (17.03.12 11:33) [12]
Я не понимаю, о чём Вы.
На форме - два компонента TLabel и один таймер. Код:
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
K, B: Real;
ToRight: Boolean;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
K := (Label1.Top - Label2.Top) / (Label1.Left - Label2.Left);
B := Label1.Top - K * Label1.Left;
ToRight := Label1.Left < Label2.Left
end;
procedure TForm1.Timer1Timer(Sender: TObject);
const
XStep = 10;
var
NewLeft: Integer;
begin
if ToRight then
NewLeft := Label1.Left + XStep
else
NewLeft := Label1.Left - XStep;
if (ToRight and (NewLeft <= Label2.Left)) or (not ToRight and (NewLeft >= Label2.Left)) then
with Label1 do
begin
Left := NewLeft;
Top := Trunc(K * NewLeft + B)
end
else
(Sender as TTimer).Enabled := False
end;
novai (2012-03-17 11:36:00) [12]или его округлять не нужно?
novai (2012-03-17 11:33:00) [13]а где в byte дробная часть? я ее не вижу
Inovet (2012-03-17 11:23:00) [14]> [10] begin...end © (17.03.12 11:18)
> Только придётся округлять до целых.
И расчитывать от прошедшего времени и от начльных координат. Т.е. к уравнению прямой добавить время и получится уравнение движения.
begin...end (2012-03-17 11:18:00) [15]> novai (17.03.12 11:10) [9]
Это прямая. Уравнение прямой: Y = K * X + B. Если прямая проходит через точки (X1, Y1) и (X2, Y2), то K = (Y1 - Y2) / (X1 - X2) и B = Y1 - K * X1. В таймере изменяйте X на величину шага, Y вычисляйте по уравнению прямой. Только придётся округлять до целых.
novai (2012-03-17 11:10:00) [16]
> перейти по различным траекториям.
нужна траектория, для наиболее быстрого перехода из точки 1 в точку 2
novai (2012-03-17 11:10:00) [17]
> прибавляя к старым (Label.Left, Label.Top) величину шага
если я прибавляю 1, то уезжаю вправо вниз под углом 45 и не могу придти в точку 2... значит прибавлять надо не 1, вот я и не могу расчитать этот число...
begin...end (2012-03-17 10:56:00) [18]> novai (17.03.12 10:54) [5]
Из точки 1 в точку 2 можно перейти по различным траекториям.
begin...end (2012-03-17 10:55:00) [19]В чём же проблема? В событии OnTimer вычисляйте новые координаты объекта, прибавляя к старым (Label.Left, Label.Top) величину шага. Если новые координаты таковы, что точка (X2, Y2) ещё не достигнута, назначайте их объекту. Если же она достигнута, выключайте таймер.
novai (2012-03-17 10:54:00) [20]да, я понял про эти переменные.
я не могу понять, как расчитать шаг, чтобы в таймере его прибавлять для left и top и в итоге придти в точку 2