Jul 31

«Рокировка» блоков экрана. Часть 2

Продолжение... Начало в статье - «Рокировка» блоков экрана. Часть 1...


Нужно отметить, что значения rW и rH значением определяются DELTA. Как ранее объяснялось уже, когда экрана разрешение 800x600 и DELTA = 8, изображение экрана поделено будет на 8x8 частичек, каждая размером 100x75 (rW = 100, rH = 75).

К тому же, созданный нами битмап redRect, размещён будет внутри самой картинки, с целью замены перемещённого блока. redRect представляет собой простой красный прямоугольником с синим текстом внутри. С этой целью еще использовать можно готовую эмблему либо логотип.

И наконец-то, шырина и высота устанавливается формы, как и у экрана.

Вызов API функции SetWindowPos использовать можно, для того чтобы форму установить именно на переднем плане всегда (OnTop), не перемещаемую и не изменяемую фактически. Процедура под названием InitScreen вызывается. Интервал самого таймера устанавливает, и выполнять начинает известный уже нам обработчик событий OnTimer, запуская саму процедуру DrawScreen.

Процедура InitScreen - Скриншот

Процедура под названием InitScreen, которая вызывается из обработчика события OnCreate, именно с целью используется получения скриншота изображения текущего десктопа, начальную позицию redRect устанавливая и саму сетку рисуя. Код, который рисовать будет сетку и вовсе необязателен.

Чтобы сам скриншот десктопа получить, GetDC используется для GetDesktopWindow. Сама API функция BitBt для передачи картинки используется десктопа в DesktopBitmap. GetDC(GetDesktopWindow) сам дескриптор получает контекста, устройства дисплея для окна - окна указаного, возвращённого именно функцией GetDesktopWindow. Вконце DesktopBitmap с компонентой Image1 ассоциируется. Когда что-то Вам непонятно, хорошо бы просмотреть еще и справочник по Дельфи.

Сама же начальная позиция redRect, случайным образом выбирается. Trunc(Random * DELTA) целое число возвращает от 0 и до DELTA. Продолжая, redRect рисуется именно в точке gx, gy, функцию используя CopyRect самого объекта Canvas. Вновь же, когда Вы с алгоритмом рисования Дельфи не знакомы, то вновь же, хорошо было бы поискать в справке.

Далее с помощью MoveTo и также LineTo сетка рисуется. Сетка является необязательной и только с той целью используется, чтобы различать лучше границы самих блоков.

procedure InitScreen;

var i,j:integer;

begin

//здесь получаем битмап десктопа

DesktopBitmap := TBitmap.Create;

with DesktopBitmap do begin

Width := Screen.Width;

Height := Screen.Height;

end;

BitBlt(DesktopBitmap.Canvas.Handle,

0,0,Screen.Width,Screen.Height,

GetDC(GetDesktopWindow),0,0,SrcCopy);

Shuffler.Image1.Picture.Bitmap := DesktopBitmap;

//находим изначальные координаты redRect

Randomize;

gx := Trunc(Random * DELTA);

gy := Trunc(Random * DELTA);

Shuffler.Image1.Canvas.CopyRect(

Rect(rW * gx, rH * gy, rW * gx + rW, rH * gy + rH),

redRect.Canvas,

Rect(0,0,rW,rH));

//тут рисуем сетку

for i:=0 to DELTA-1 do begin

Shuffler.Image1.Canvas.MoveTo(rW * i,0);

Shuffler.Image1.Canvas.LineTo(rW * i,Screen.Height);

Shuffler.Image1.Canvas.MoveTo(0, rH * i);

Shuffler.Image1.Canvas.LineTo(Screen.Width, rH * i);

end;

end;

Процедура Draw Screen

Самый основной код в процедуре находится DrawScreen. Данная процедура внутри события вызывается OnTimer самого компонента Timer.

procedure DrawScreen;

var

r1,r2:TRect;

Direction:integer;

begin

r1:=Rect(rW * gx , rH * gy, rW * gx + rW , rH * gy + rH);

Direction := Trunc(Random*4);

case Direction of

0: gx := Abs((gx + 1) MOD DELTA); //здесь право

1: gx := Abs((gx - 1) MOD DELTA); //здесь лево

2: gy := Abs((gy + 1) MOD DELTA); //здесь низ

3: gy := Abs((gy - 1) MOD DELTA); //здесь верх

end; //case

r2 := Rect(rW * gx , rH * gy, rW * gx + rW , rH * gy + rH);

with Shuffler.Image1.Canvas do begin

CopyRect(r1, Shuffler.Image1.Canvas, r2);

CopyRect(r2, redRect.Canvas, redRect.Canvas.ClipRect);

end;

end;

Сам код достаточно прост в использовании, несмотря на то, что на первый взгляд он кажется очень сложным. Местами менять только можно смежные части с redRect, являются доступными только четыре возможных варианта.

Именно прямоугольник r1 текущию позицию содержит redRect, а r2 на сам прямоугольник с блоком указывает, который ранее перемещён был. CopyRect для перемещения используется блока выбранного на место redRect, а также рисования redRect его уже в новом месте – именно таким образом обмен данных 2 блоков происходит.

Приятней конечно, обмен блоков анимированный наблюдать, но оставим мы данную задачу для другой статьи )))


Поделитесь вашими мыслями



Ссылки в комментариях будут свободны от nofollow.

Поддерживаемые теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

Ссылки в комментариях будут свободны от nofollow.