Программа демонстрирует возможность создания игры в мозаику
картинки для мозайки
Тим массива
TMassivImage = record
x,y:integer; // от позиции
Bit:Tbitmap; // буфер картинки
end;
var
ImMas:array of TMassivImage; // массив изображений
ImMasCount:integer; // кол-во страниц
CountX,CountY:integer; // кол-во картинок DvigBit:Tbitmap; // буфер для передвижения картинок
напишем несколько процедур и типов данных
// пропорциональное изменение размеров картинки maxWidth ширинка картинки maxHeight // высота картинки Function GetImageWH(thumbnail:Timage;maxWidth,maxHeight:integer):Trect; begin result.Left:=0;result.top:=0; if thumbnail.Width > thumbnail.Height then begin result.Right := maxWidth-2; result.Bottom := (maxWidth * thumbnail.Height) div thumbnail.Width; end else begin result.Bottom := maxHeight-2; result.Right := (maxHeight * thumbnail.Width) div thumbnail.Height; end; end;
procedure TForm1.Button1Click(Sender: TObject); var x,y:integer; begin form1.Image2.Canvas.Pen.Color:=clred; form1.Image2.Canvas.Rectangle(form1.Image2.Canvas.ClipRect); rx:=GetImageWH(form1.Image1,form1.Image1.Width,form1.Image1.Height).Right div (CountX+1); ry:=GetImageWH(form1.Image1,form1.Image1.Width,form1.Image1.Height).Bottom div (CountY+1); DvigBit:=Tbitmap.Create; DvigBit.Width:=rx+1; DvigBit.Height:=ry+1; r:=GetImageWH(form1.Image1,form1.Image1.Width,form1.Image1.Height);
MashtabX:=1; MashtabY:=1;
ImMasCount:=0; Setlength(ImMas,ImMasCount); form1.Image2.Canvas.pen.Color:=clred; form1.Image2.Canvas.pen.Width:=1; {разбиваем (режим) изображение на CountX*CountY квадратиков для мозайки } {создание мозайки } for X:=0 to CountX do for y:=0 to CountY do begin ImMasCount:=ImMasCount+1; Setlength(ImMas,ImMasCount); ImMas[ImMasCount-1].x:=x; ImMas[ImMasCount-1].y:=y; ImMas[ImMasCount-1].Bit:=Tbitmap.Create; ImMas[ImMasCount-1].Bit.Width:=rx*MashtabX; ImMas[ImMasCount-1].Bit.height:=ry*MashtabY; ImMas[ImMasCount-1].Bit.canvas.CopyRect(rect(0,0,rx,ry),image1.Canvas, rect(rx*x*MashtabX,ry*y*MashtabY,(rx*x+rx)*MashtabX,(ry*y+ry)*MashtabY)); form1.Image2.Canvas.Rectangle(rect(rx*x*MashtabX,ry*y*MashtabY,(rx*x+rx)*MashtabX,(ry*y+ry)*MashtabY)); form1.Image2.Canvas.CopyRect(rect(rx*x*MashtabX+1,ry*y*MashtabY+1,(rx*x+rx)*MashtabX-1,(ry*y+ry)*MashtabY-1),ImMas[ImMasCount-1].Bit.canvas,rect(0,0,rx*MashtabX-1,ry*MashtabY-1)); end;
end;
procedure TForm1.FormCreate(Sender: TObject); begin CountX:=3; CountY:=3; // создаем катинку 3 на 3 form1.Image1.Picture.LoadFromFile('din2.bmp'); Button1Click(nil); Button3Click(nil); end;
{Режим дино }
procedure TForm1.Button3Click(Sender: TObject); label loop; var i,x,y:integer;
begin
for X:=0 to CountX do for y:=0 to CountY do begin form1.StringGrid1.Cells[x,y]:='-1'; // создаем массив из -1 элементов в StringGrid end;
for I:=0 to ImMasCount-1 do begin loop: x:=random(CountX+1); // выбираем случайным образом координаты y:=random(CountY+1); if form1.StringGrid1.Cells[x,y]='-1' then begin // если эта координата -1 form1.StringGrid1.Cells[x,y]:=inttostr(i); // то записываем его ImMas[i].x:=x; ImMas[i].y:=y; end else goto loop; // если ячейка не -1 то ищем новую координату application.ProcessMessages; // для антизависания программ создаем событие для системы Windows end;
{Процедура перерисовки мозайки } for X:=0 to CountX do for y:=0 to CountY do begin for I:=0 to ImMasCount-1 do begin if ImMas[i].x=x then if ImMas[i].y=y then begin form1.Image2.Canvas.Rectangle(rect(rx*x*MashtabX,ry*y*MashtabY,(rx*x+rx)*MashtabX,(ry*y+ry)*MashtabY)); form1.Image2.Canvas.CopyRect(rect(rx*x*MashtabX+1,ry*y*MashtabY+1,(rx*x+rx)*MashtabX-1,(ry*y+ry)*MashtabY-1),ImMas[i].Bit.canvas,rect(0,0,rx*MashtabX-1,ry*MashtabY-1)); end;end; end; end;
{ события перетаскивания картинок по форме }
procedure TForm1.Image2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var t2,t:Trect; begin if dvig then begin // если движение t:=rect(0,0,rx,ry); t2:=rect(cx,cy,cx+rx,cy+ry); form1.Image2.Canvas.CopyRect(t2,dvigbit.Canvas,t); // затираем часть изображение dvigBit cY:=y-ty; cx:=x-ty; t2:=rect(cx,cy,cx+rx,cy+ry); dvigBit.Canvas.CopyRect(t,form1.Image2.Canvas,t2); // копируем часть изображения перекртием из form1.Image2.Canvas.CopyRect(t2,ImMas[cI].Bit.Canvas,t); // выводим нужный квадрат end;
form1.StatusBar1.Panels[0].Text:='X = '+Inttostr(x)+' : '+'Y = '+Inttostr(y)+' '+inttostr(x div rx)+':'+inttostr(y div ry); // вывод координат в бар меню
end;
{по координатам X,Y ищем номер блока } Function GetCI(cx,cy:integer):integer; var i:integer; begin result:=-1; for i:=0 to ImMasCount-1 do if (ImMas[i].x=cx) and (ImMas[i].y=cy) then begin result:=i; exit; end; end;
{процедра при нажатии на кнопку мыши } procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var t,t2:Trect; i,Ym,Xm:integer; begin dvig:=false; i:=GetCI(x div rx,y div ry); if i>-1 then begin xm:=ImMas[i].x; ym:=ImMas[i].y; cx:=x; cY:=y; tx:=cx-xm*rx; ty:=cy-ym*ry; cY:=y-ty; cx:=x-ty; t:=rect(0,0,rx,ry); t2:=rect(cx,cy,cx+rx,cy+ry); dvigBit.Canvas.CopyRect(t,form1.Image2.Canvas,t2); dvig:=true; cI:=i; end;
end; {при отпускании кнопки } procedure TForm1.Image2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var t2,t:Trect; ci2:integer; TempX,TempY:integer; begin if dvig then begin // если было движение dvig:=false; // отменяем движение t:=rect(0,0,rx,ry); t2:=rect(cx,cy,cx+rx,cy+ry); form1.Image2.Canvas.CopyRect(t2,dvigbit.Canvas,t); // затираем изображение ci2:=GetCI(x div rx ,y div ry); if (ci2>-1) and (ci>-1) then begin // если оба объекта - картинки TempX:=ImMas[ci].x; TempY:=ImMas[ci].y; // меняем блоки местами ImMas[ci].x:=ImMas[ci2].x; ImMas[ci].y:=ImMas[ci2].y; ImMas[ci2].x:=TempX; ImMas[ci2].y:=TempY; cx:=ImMas[ci].x*rx; cy:=ImMas[ci].y*ry; t:=rect(0,0,rx,ry); t2:=rect(cx,cy,cx+rx,cy+ry); form1.Image2.Canvas.Rectangle(t2.Left-1,t2.top-1,t2.Right+1,t2.Bottom+1); form1.Image2.Canvas.CopyRect(t2,ImMas[cI].Bit.Canvas,t); cx:=ImMas[ci2].x*rx; cy:=ImMas[ci2].y*ry; t:=rect(0,0,rx,ry); t2:=rect(cx,cy,cx+rx,cy+ry); form1.Image2.Canvas.Rectangle(t2.Left-1,t2.top-1,t2.Right+1,t2.Bottom+1); form1.Image2.Canvas.CopyRect(t2,ImMas[cI2].Bit.Canvas,t); end; for X:=0 to CountX do for y:=0 to CountY do begin form1.StringGrid1.Cells[x,y]:=inttostr(GetCI(x,y)); end; end;
end;
исходник программы можно скачать по ссылки http://netsoftware.ucoz.ru/din2.zip при перепечатки материалов указание на автора и сайт автора обязательны.
|