Аркадный движок
Оформил: XVeL
Автор: JibSkeart
WEB-сайт: http://daddy.mirgames.ru
Как реализован движок. Есть прямая (AB) у этой прямой имеем
координаты X1,Y1,X2,Y2
Дальше что нам
нужно ? Ну исходя из того что у нас есть не только прямые
но и Герой или другие создания Нам нужно знать стоит наше
создание на прямой или нет ... А что такое наш герой да и
другие объекты ??? Да ничего больше как обычная точка с двумя
координатами Xobj,Yobj Так вот продолжаем, что бы проверить
стоим мы на прямой или нет, мы смотрим (вычисляем) Растояние
от точки (XObj,Yobj) до прямой (AB) (подобные формулы можно
найти в любом справочнике по математике) Конечная формула у
меня получилась такой
A:=-Y2+Y1; B:=X2-X1; C:=-X2*Y1+Y2*X1; D :=
Round((A*Xpos+B*Ypos+C)/(Sqrt(Sqr(A)+Sqr(B))));
| Ну ладно мы нашли а дальше то
что ?? Хмм ну дальше тут интереснее я додумался сделать так...
Вот растояние от точки до прямой у меня равно 0 значит мы
стоим , и нам теперь хочется побегать по просторам уровня (или
пока прямой):) Представьте, что у нас прямая (AB) под углом 45
градусов. Левый край находится внизу правый вверху
AB(100,200,200,100) мы стоим и находимся на середине прямой
Если мы нажмем влево нам надо спустится по этой примой, вправо
поднятся ... как это сделать ??? Да просто находим кофицинт
приращения FDdx,FDdy относительно нашего шага _StepX -
Const... Для этого нам нужно знать угол относительно
горизонтали тоесть я "приделываю" к нашей прямой (по которой
нам пока еще не удается побегать) горизонтальную прямую и
нахожу угол между ними
Вот так получился
конечный результат нахождения угла между прямыми со всякими
проверками...
A2:=-yy2+yy1; B2:=xx2-xx1;
A1:=-y2+y1; B1:=x2-x1;
If (A1*B2-A2*B1><0) and (A1*A2+B1*B2><0) Then _Alpha :=(A1*B2-A2*B1)/(A1*A2+B1*B2)
else
_Alpha:=0;
_AlphaRad := ArcTan(_Alpha);
_AlphaDeg := RadToDeg(ArcTan(_Alpha));
_Fddx:=Sin(_AlphaRad)*_StepX;
_Fddy:=Cos(_AlphaRad)*_StepY;
If _AlphaRad>0 Then _Fddx:=-_Fddx;
If _AlphaRad>0 Then _Fddy:=-_Fddy;
Ага все нашли
и если мы теперь стоим на нашей прямой и мы знаем коэффецинты
приращ. мы можем побегать это будет выглядеть так XObj :=
Xobj+Fddx; - вот здесь можно и не вычеслять FDdx потомучто он
будет всегда равен ( изходя из ентой формулы
_Fddx:=Sin(_AlphaRad)*_StepX; ) _StepX !!! YObj :=
Yobj+Fddy; Теперь если мы стоим то мы можем прыгнуть присеть
итд ну это зависит только от вашей фантазии Да тут у меня еще
есть корректировочка я еще нахожу точку пересечения двух
прямых где одна прямая эта та по которой мы бегаем а вторая
спускается из XObj ,YObj вертикально вниз это я делал для того
чтобы если до линии +-StepY то я автоматом "падаю
(прикрепляюсь) на эту линию " так как не всегда у вас будет
роастояние от точки до прямой равнятся 0 так как мы будем
падать с определенным шагом (скоростью) воот представте что мы
падаем, шаг равен 8, а на данный момент растояние до прямой =
4 в следующем моменте растояние будет равняься -4 !!! и мне
приходится в такой момент переносить координаты героя на
коорд. точки пересеч да вообщем это даже незаметно ... воот
видали так что енто погрешность моего движка :) Ну а если у
нас прямых много ,то нам нужно знать от линии Номер , Угол
,Приращения итд... вообщем на какой прямой мы стоим и что нам
от нее ожидать :) или какая из линий ближе к нам. я это делал
в обычном массиве
( Да, в данном алгоритме я применял
длинну линии 32 (можно и другую или просто все линии разные)
здесь я хотел придумать более оптимальный вариант поиска
линий. Представьте что у нас на уровне 10000 линий.... поняли
??? Долго воот ... И пока ентот массив из 10000 прокрутит , а
также если у нас будут другие Твари бегать на уровне и так же
будут искать ближайшие линии плюс искать путь.... уфф короче
он требует оптимальности :)) в голове что то крутится по этому
поводу, но пока ничего, если вдруг придумаете буду рад увидеть
это хотя есть такой момент отсортировать все линии по порядку
с левой верхней по праваю нижнюю там уже можно и вычеслить
какие линию вокруг , рядом с Героем и цикл большой не
понадобится... это так же как в массиве найти элементы точек
вокруг точки...)
For i:=0 to _LinesCount-1 do
begin
//Если линия не вертикальна и в пределах экрана то
If not _ListLines[i].vert and _Visible(i) Then
begin
//вычисляем растояние от точки до этих прямых авось на кокую да встанем
LLine(_X,_Y, {Координаты героя}
_ListLines[i]._XY1.X, {Координаты прямой}
_ListLines[i]._XY1.Y,
_ListLines[i]._XY2.X,
_ListLines[i]._XY2.Y,
_LBDist); {Растояние}
If (_LBDist>=8)and(_LBDist<-8) Then
begin
...
// если условие выполнилось то выдергиваем индекс линия
// для дальнейших работ с ней а также сообщаяем что мы наконецто куда-то приземлились :)
end;
end;
end;
Так же я ищу стенки только
уже в цикле смотрю только те вертикальные прямые которые
видны (внутри идет проверка на вертикальные прямые ) и так же
изучаю растояние до них если растояние поподает в -+8 смотря с
какой стороны относительно героя находится то мы туда и не
можем идти Ну вообшем все основные моменты я рассказал Вообшем
я состряпал три основных класса с которыми все енто работает
Все с него начинается класс "Линия"
CLine=class Содержит в себе X1,Y1,X2,Y2
также как только мы присвоили координаты вычесляет угол
смотрит вертикальная она или нет
Это уже список
линий CLines=class Содержит список линий
(массив типа CLine) Знает количество линий :) Умеет
сохранять карту(список линий) Также загружать карты
Чистить
Ну и он самый главный :) наследник всего
хорошего от класса Списка линий (CLines)
CEngine=class(CLines) Унаследовал все от класса
CLines (если не знаете как это читаете литературу ...) но
научился смотреть относительно координат героя ближнии
прямые Управлять героем и другим ...
Вообщем-то сам движок несложен, его даже можно
упростить И как, сечас даже постораюсь обьяснить Ну первое,
что я хотел бы переделать так это ... какие то не рациональные
в моем движке моменты со стеной тоесть смотрим где стена итд,
некрасиво как то. в принципе то работает, но хотелось бы
упроситьть и сделать более универсальным и тут на днях я
придумал как сие сделать, но возможно столкнусь с другими
проблемами Так вот, начинаем излогать свои мысли Во первых у
нас есть прямая по которой мы двигаемся Ладно мы нашли угол
относительно горизонтали итд мы двигаемся , но стена, как по
другому на это посмотреть чисто физиологически ??? Ага вот тут
и наступает момент когда нужна физика ! Представь что ты идешь
по прямой она поднимается и тебе все сложнее и сложнее на нее
идти а потом бац и уклон еще круче и ты просто не можешь на
нее забратся Хех так вот можно сделать так Есть тело которое
находится в состоянии равновесии и стоит на плоскости (в нашем
случае прямой) под углом к горизонтали (Alpha = 45) ну возьмем
этот угол :) для примера тоесть тело не скатывается мы
прилогаем к нему силу либо веррх либо, вниз и тело скользит !
Естественно что, если угол больше 45(в нашем случае) и мы не
прилогаем силы , то тело начнет скользить вниз, а если мы
попытаемся "залезть" на макс угол то мы будем как бы
,мгновенно скатыватся.
Тогда нам нужно знать :
1. Угол относительно горизонтали 2. Массу
тела (у нас будет точка) - постояное мне кажется енто
сдеся и не столь важно можно залепить любое число 3.
Коэффециент трения (или силу трения ) при том
максимальном угле при котором тело наход-ся в состоянии
равновесия - тоже константа (отсюда пока следует что скорость
= 0) Максимальный угол предстовляет из себя тот угол на
который наш герой еще может залесть если угол больше то он
либо скатывается либо лезет медленно Видели наверное в 3D
играх когда на крутой склон пытаешся залесть начинаешь
скатыватся чем круче склон тем быстрее. Сие я увидел в Serius
Sam 2 там что то пожожее 4. Силу с котрой мы толкаем
тело ... - постоянное Силу можно вычеслить так, пусть
тело движется со скоростью (с шагом) 6 пикселей в сек :) по
горизонтальной поверхности нам надо найти силу которую в
данный момент прикладывают к телу
5. исходя из силы
будем находить шаг (или скорость) движения тела (Силу
мы нашли она у нас всегда одинакова ) тоесть тут сразу видно
что если с той силой, с которой ,мы толкаем тело по гориз.
поверхности мы будем толкать вверх по наклонной поверхности
шаг будет разным или даже если мы толкаем на крутую гору
отрицательным то есть, будет тутже скатыватся или если мы
будем толкать с горки будем быстрее бежать вот и все
впринципе думаю что он более удачный чем тот что у мя раньше
И другой момент А Ведь можно сделать его а-ля 3d это
когда мы бегаем также по одной плоскостит но все элементы по
настоящемму трех мерные, помните Тарзан гаму ??? Да и
нетолько, если мы возьмем вместо линии плоскость ??
Тут
можно взять пример: arcengine.zip
Будут вопросы пишите , ответим JibSkeart(Salimgareev
Marat) JibSkeart@yandex.ru
|