PDA

Просмотр полной версии : Рисунок пути


supernewbie
20.09.2010, 17:23
Скрипт должен расчитывать и рисовать путь, который он узнает из пакета MoveToLocation, выбрасывая вещи.

x21 - х начала пути.
x11 - х конца пути.

по аналогии устроены другие переменные.

GetTimeFromPath - получение длинны пути.

dropitem - выброс вещи, который шлется на клиент.

procedure PaintMyWay(x11,y11,z11,x21,y21,z21:integer); // объявление процедуры
begin // начало 1
if ((Round(GetTimeFromPath(x21,y21,z21,x11,y11,z11,'p ath')) div 10)=0) then // не равняется ли длинна пути 0?
begin //начало 2
exit; // если да - выходим дабы избежать вылета
end; // конец 2 // если же длинна нашего пути не равна 0 то
//Описание 1: вычесляем разницу между координатами, вычитаем из нее длинну пути
dx1:=(x21 - x11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10); // Описание 1 для x
dy1:=(y21 - y11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10); // Описание 1 для y
dz1:=(z21 - z11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10); // Описание 1 для z
while (dx1>0) or (dx1<0) or (dy1>0) or (dy1<0) or (dz1>0) or (dz1<0) do // начинаем цикл, который выполняется при
// условии что разница между разностью начальной и конечной координат x y z не равна 0.
begin // начало 3
x11:=x11+dx1; // прибавляем к начальному x разницу
y11:=y11+dy1; // прибавляем к начальному y разницу
z11:=z11+dz1; // прибавляем к начальному z разницу
dropItem(x11,y11,z11); // выкидываем вещь в эти координаты
if ((Round(GetTimeFromPath(x21,y21,z21,x11,y11,z11,'p ath')) div 10)=0) then //проверяем новые координаты, не равен ли путь с них 0?
begin //начало 4
exit; //если это так то выходим дабы избежать ошибки
end; //конец 4
dx1:=(x21 - x11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10); // Описание 1 для x
dy1:=(y21 - y11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);// Описание 1 для y
dz1:=(z21 - z11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10); // Описание 1 для z
end; // конец 3
end; // конец 1

В чем заключается ПРОБЛЕМА - при непонятно каких обстоятельствах, рисованый путь искривляется.

J-Fobos
20.09.2010, 20:56
Как понять "рассчитывать путь" ? А еще, если не секрет, зачем это? :)

alexteam
20.09.2010, 21:10
"выкидывай" шмотки в те места в которых клиент сделал validateposition.

supernewbie
20.09.2010, 21:22
Как понять "рассчитывать путь" ? А еще, если не секрет, зачем это? :)
проводить линию прямую, от начала до конца пути, отрезки прямой обозначать аденой.

Добавлено через 10 минут
но мне надо линию епт

J-Fobos
20.09.2010, 22:13
А если по такому алгоритму попробовать?

1) Узнаем dx,dy,dz
dx:=x21-x1;
dy:=y21-y1;
dz:=z21-z1;

3) Узнаем относительную скорость движения чара.

//здесь опционально, вместо 100 надо (методом тыка) выставить другое значение, чтоб рисовалось с нормальной скоростью
vx:=dx/100;
vy:=dy/100;
vz:=dz/100;

4) Далее по таймеру кидаем итем на землю увеличивая координаты на vx, vy, vz пока не достигнем конечной точки. Координаты понятное дело округлять до целого.


ЗЫ: зачем эти линии? :D

supernewbie
20.09.2010, 23:00
фобос, ты че-то не то написал)
во-первых просто делить на сто это получится если линия маленькая - промежутки мелкие, если длинная - промежутки большие

А у меня промежутки зависят от длинны пути.

и вообще это нихрена не то что я просил, линия получается КРИВОЙ. Надо понять почему...

Добавлено через 19 минут
const
Name='1';

var
Path,ID,itemid:integer;
Speed,MoveMul: double;
dx,dy,dz:integer;
dx1,dy1,dz1:integer;
timer:TTimer;
i:integer;

procedure Init; //Вызывается при включении скрипта
begin
timer:=TTimer.Create(nil);
timer.OnTimer:=@Prishel;
timer.enabled:=false;

end;

procedure Free; //Вызывается при выключении скрипта
begin
timer.free;

end;

procedure Say(msg:string);
begin
buf:=#$4A;
WriteD(0);
WriteD(3);
WriteS('Инфо');
WriteS(msg);
SendToClientEx(Name);
end;

procedure Prishel(Sender: TObject);
begin
ClearPath;
timer.enabled:=false;
end;

procedure ClearPath;
begin
for i:=0 to itemid do DeleteObject(i);
itemid:=0;
end;

procedure DeleteObject(l:integer);
begin
buf:=#$08;
WriteD(l);
SendToClientEx(Name);
end;

function MyRound(r:double) : double;
begin
result:=Round(r*10)/10;
end;

procedure dropItem(x1,y1,z1:integer);
begin
buf:=#$16;
WriteD(id);
WriteD(itemid);
WriteD(57);
WriteD(x1);
WriteD(y1);
WriteD(z1);
WriteD(0);
WriteQ(0);
WriteD(0);
SendToClientEx(Name);
Inc(itemid);
end;

procedure PaintMyWay(x11,y11,z11,x21,y21,z21:integer);
begin
if ((Round(GetTimeFromPath(x21,y21,z21,x11,y11,z11,'p ath')) div 10)=0) then
begin
exit;
end;
dx1:=(x21 - x11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
dy1:=(y21 - y11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
dz1:=(z21 - z11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
while (dx1>0) or (dx1<0) or (dy1>0) or (dy1<0) or (dz1>0) or (dz1<0) do
begin
x11:=x11+dx1;
y11:=y11+dy1;
z11:=z11+dz1;
dropItem(x11,y11,z11);
if ((Round(GetTimeFromPath(x21,y21,z21,x11,y11,z11,'p ath')) div 10)=0) then
begin
exit;
end;
dx1:=(x21 - x11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
dy1:=(y21 - y11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
dz1:=(z21 - z11) div Round(Round(GetTimeFromPath(x21,y21,z21,x11,y11,z1 1,'path')) div 10);
end;
end;

function GetTimeFromPath(x1,y1,z1,x2,y2,z2:integer;keyword: string) : double;
begin
if (keyword='time') then result:=Round((sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1))+((z2-z1)*(z2-z1)))) / Speed);
if (keyword='path') then result:=Round((sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1))+((z2-z1)*(z2-z1)))));
end;

//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin
if FromServer and (ConnectName=Name) and (pck[1]=#$2F) and (ReadD(2)=ID) then
begin
timer.enabled:=false;
ClearPath;
//Say('Твой путь равен '+vartostr(GetTimeFromPath(ReadD(14),ReadD(18),Rea dD(22),ReadD(2),ReadD(6),ReadD(10)))+'.');
Say('Вы пройдете этот путь за '+vartostr(GetTimeFromPath(ReadD(18),ReadD(22),Rea dD(26),ReadD(6),ReadD(10),ReadD(14),'time'))+' секунд.');
PaintMyWay(ReadD(18),ReadD(22),ReadD(26),ReadD(6), ReadD(10),ReadD(14));
timer.interval:=(Round(GetTimeFromPath(ReadD(18),R eadD(22),ReadD(26),ReadD(6),ReadD(10),ReadD(14),'t ime')))*1000;
timer.enabled:=true;
end;

if FromServer and (ConnectName=Name) and (pck[1]=#$32) then
begin
ID:=ReadD(18);
Speed:=(ReadD(470+(length(ReadS(22))*2+2)))*(ReadF (502+(length(ReadS(22))*2+2)));
end;

end.

Добавлено через 47 секунд
вот фул код смотри

J-Fobos
20.09.2010, 23:39
Поставь не 100, а 10000000000 и будет идеальная линия :D

supernewbie
21.09.2010, 07:02
не врубаешься ты)

J-Fobos
21.09.2010, 10:45
Врубаюсь)) Ты чужих ботов уводить от места кача собираешься))
Ты учитывай, что в игре есть такая вещь как "вы не можете бросить так далеко", длинных дистанций у тебя не будет и мой алгоритм вполне подходит.

supernewbie
21.09.2010, 14:28
dropitem - выброс вещи, который шлется на клиент.

НУ ЕШКИН КОТ...
http://imglink.ru/pictures/21-09-10/164a79cbc55fe2b276dae1f0389596c1.jpg

А во вторых, вот ты зайди в игру и потести, выбрасывай в разные стороны и смотри кривизну.

J-Fobos
21.09.2010, 21:22
Проверил, мой алгоритм хорошо работает =р
Сразу его и усовершенствовал, сделал деление не на 100, а сделал чтоб менялось в зависимости от пройденного пути, вообще красиво получилось =)

supernewbie
21.09.2010, 23:30
код выложишь, не?

J-Fobos
22.09.2010, 14:04
А самому написать, не? :)
Я бегал по колизею, там координата z не изменяется и я ее не учитывал.

var
vx,vy:real;

procedure lines;
var
dx,dy,x1,x2,y1,y2:integer;
s:real;

begin
dx:=x2-x1;
dy:=y2-y1;
if (dx=0) and (dy=0) then exit;
s:=sqrt(dx*dx+dy*dy);
vx:=dx/s;
vy:=dy/s;
Timer01.Enabled:=True;
end;

Ну а в таймере у меня бросается предмет, координаты броска и остановка таймера определяются так:
x1:=round(x1+vx);
y1:=round(y1+vy);
if x1>=x2 then Timer01.Enabled:=False;

Я отредактировал сообщение, оптимизировал код, убрал лишнюю переменную, без нее можно нормально обойтись.

supernewbie
24.09.2010, 13:18
while x11<x21 do
begin
dx1:=x21-x11;
dy1:=y21-y11;
dz1:=z21-z11;
if (dx1=0) and (dy1=0) and (dz1=0) then exit;
s:=sqrt(dx1*dx1+dy1*dy1+dz1*dz1);
vx1:=dx1/s;
vy1:=dy1/s;
vz1:=dz1/s;
x11:=round(x11+vx1);
y11:=round(y11+vy1);
z11:=round(z11+vz1);
dropItem(57,x11,y11,z11);
end;