Графика и Игры \ DirectX и DelphiX \ Как рисовать? - Математика
Автор: @lex
WEB-сайт: shimigon.narod.ru
Приветствую, уважаемые программисты игр!
Я наконец-то закончил свой игровой проект Central Defenser и хочу поделиться с вами несколькими функциями
математических рассчетов для двумерных игр.
Я не использую DXSpriteEngine и прочие примочки DelphiX, поэтому все пришлось рассчитывать самому.
Как известно весьма продвинутая функция для рисования DrawRotate использует в параметре angle не совсем стандартный с геометрической точки зрения угол.
Полный его оборот равен 256 градусов, а при увеличении значения, рисунок будет поворачиваться по часовой стрелке.
Все мои спрайты направлены вверх, то есть: Я использую угол поворота от -128 до 128 градусов, что как раз и составляет полный оборот,
поэтому функции могут неправильно работать при других значениях.
Следующая функция позволяет при известном вашем положении (ux,uy) и положении точки, к которой надо повернуться (px,py), определить необходимый угол поворота:
function mkrot(ux,uy,px,py:integer):integer;
var zx,zy:real;
n:real;
dddd:integer;
begin
zx:=(px-ux)/100;
zy:=(py-uy)/100;
if (zx=0) then if (zy>0) then begin mkrot:=128; exit; end else begin mkrot:=0; exit; end;
n:=zy/zx;
if (zx<0) then dddd:=-64 else dddd:=64;
mkrot:=round(128*arctan(n)/pi)+dddd;
end;
Ее также можно использовать для определения угла поворота при заданных проекциях скорости движения по осям X и Y,
для этого в параметры ux и uy передаем 0, а в px и py - скорости по X и Y.
Следующий "обрезок кода" приближает текущий угол поворота (crot) к требуемому (rot) на 4 градуса, он лишен того недостатка, который был в примере к первой части этой статьи:
if (crot-rot<0) then if (crot-rot>-128) then crot:=crot+4 else crot:=crot-4;
if (crot-rot>0) then if (crot-rot<128) then crot:=crot-4 else crot:=crot+4;
if (crot<-128) then crot:=crot+256;
if (crot>128) then crot:=crot-256;
А эта процедура по заданному углу поворота и скорости движения, записывает в глобальные переменные cx и cy, проекции движения на оси X и Y:
procedure CalcCXCY(rot,speed:integer);
var cr,n:real;
begin
if (rot<0) then n:=-64 else n:=64;
cr:=rot;
cr:=(cr-n)*pi/128;
cx:=cos(cr)*speed;
cy:=sin(cr)*speed;
if (cx<0) then cx:=-cx;
if (cy<0) then cy:=-cy;
if (rot<-64) then cx:=-cx else if (rot<0) then begin cx:=-cx; cy:=-cy; end else
if (rot<64) then cy:=-cy;
end;
Ее работа представлена на данном примере
А на сегодня пока это всё!
|