Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.01.2015, 21:02   #1
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию Пристыковка

Собрал типа пазлов, где картинка разрезается на 16 частей и загружается в динамически созданные Image, вопрос такой как организовать пристыковку каждой картинки к нужному месту?
Примерно как показал на картинке- расстояние маленькое- можно стыковать.
Сейчас наверно куча советов, нужно проверять у нужной имаги значения Left и Top к нужному ей "кубику" это и так понятно, как сделать это реально?
Есть ли еще может какие методы?
Изображения
Тип файла: jpg 1111.jpg (8.4 Кб, 91 просмотров)
NIKOLAYY2 вне форума Ответить с цитированием
Старый 19.01.2015, 21:14   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Есть ли еще может какие методы?
Да. Я бы использовал готовые разметчики типа DrawGrid.
Только у меня один вопрос: А как стыковка должна идти? Одна часть паззла накладываться полностью на другую? Если да, то как потом ты собираешься вытаскивать ту которая окажется внизу?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 19.01.2015, 21:19   #3
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Исходя из всего очевидно нужно получать имя компонента за который мы ухватили, накидал для простоты примера с шейпами:
Код:
var
  Form1: TForm1;
  tx, ty: Integer;
  imshap: Integer; //äëÿ èìåíè (íîìåðà) øåéïà

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i, j: Byte;
begin
  for i := 1 to 5 do
    for j := 1 to 4 do
      with TShape.Create(Self) do
      begin
        imshap := imshap + 1;
        Left := 100 * i - 100;
        Top := 100 * j - 100;
        Width := 100;
        Height := 100;
        Name := 'Shape' + IntToStr(imshap);
        Brush.Color := RGB(Random(256), Random(256), Random(256));
        OnMouseDown := Shape1MouseDown;
        OnMouseMove := Shape1MouseMove;
        Parent := Self;
      end;
  DoubleBuffered := True;
end;

procedure TForm1.Shape1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Shift = [ssLeft] then
    with (Sender as TControl) do
    begin
      Left := Left + X - tx;
      Top := Top + Y - ty;
    end;
  Label2.Caption := 'X= ' + IntToStr(X) + ', Y= ' + IntToStr(Y);
  Caption := (Sender as TControl).Name;
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  tx := X;
  ty := Y;
  (Sender as TControl).BringToFront;
  Label1.Caption := 'Èìÿ øåéïà = ' + (Sender as TControl).Name;
end;
по захвату шейпа и его сдвигу- я получаю его имя, что использовать в качестве "подложки" под каждый компонент?
Изображения
Тип файла: jpg 2222.jpg (45.9 Кб, 93 просмотров)
NIKOLAYY2 вне форума Ответить с цитированием
Старый 19.01.2015, 21:23   #4
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Stilet
Ну можно попробовать DrawGrid.
Цитата:
как потом ты собираешься вытаскивать ту которая окажется внизу?
Ну я думаю поможет
Код:
(Sender as TControl).BringToFront;
Или нет?
NIKOLAYY2 вне форума Ответить с цитированием
Старый 19.01.2015, 21:50   #5
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Stilet
Как быохота и попроще и тем самым временем не так чтоб сложно было, ну вот сам проект что накидал:

Код:
const
  plkv = 100; //ïëîùàäü êâàäðàòà (ðàçìåð âûâîäà ãðàôèêè)
var
  Form1: TForm1;
  image: Timage;
  j, i: integer;
  s: integer;
  tx, ty: Integer;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  s := 0;
  for i := 1 to 4 do
    for j := 1 to 4 do
    begin
      inc(s); //èìÿ èìàãè
      //íàõîäèì äèíàì. ñîçäàííûé êîìïîíåò èìàãó
      with TImage(FindComponent('im' + IntToStr(s))) do
      begin
        //êîïèðóåì ÷àñòè êàíâû â öèêëå ðàïðåäåëÿÿ íóæíûå îáëàñòè
        Canvas.CopyRect(Rect(0, 0, plkv, plkv), image1.Canvas, Rect(j * 50 - 50, i * 50 - 50, j * 50, i * 50));
        Left := -100 + j * 105;
        Top := -100 + i * 105;
      end;
    end;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   //çàïîìèíàåì êîðäèíàòû êëèêà
  tx := X;
  ty := Y;
  //êàðòèíêó ïîâåðõ
  (Sender as TImage).BringToFront;
  Caption:= (Sender as TImage).Name;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Shift = [ssLeft] then
    with (Sender as TImage) do
    begin
      Left := Left + X - tx;
      Top := Top + Y - ty;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  DoubleBuffered := True;
  for i := 1 to 20 do
  begin
    //ñîçäàåì 20 îáüåêòîâ èìàãè
    image := TImage.Create(Self);
    with image do
    begin
      Parent := Self;
      Width := plkv; //ðàçìåð îïèñàí â êîíñòàíòå
      Height := plkv;
      Name := 'im' + IntToStr(i);

      OnMouseMove := Image1MouseMove; //îáðàáîòàåì ñîáûòèÿ
      OnMouseDown := Image1MouseDown;
    end;
  end;
  Zagizobr; //çàãðóçèì òåïåðü êàíâó â íàøè èìàãè
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  Image1.Picture.LoadFromFile('animals.bmp');
  Zagizobr;
end;

procedure TForm1.Zagizobr;
begin
  //ïðîöåäóðà âûâåäà êàíâû
  s := 0;
  for i := 1 to 4 do
    for j := 1 to 4 do
    begin
      inc(s); //èìÿ èìàãè
      with TImage(FindComponent('im' + IntToStr(s))) do
      begin
        Canvas.CopyRect(Rect(0, 0, plkv, plkv), image1.Canvas, Rect(j * 50 - 50,
         i * 50 - 50, j * 50, i * 50));
        Left := Random(300);
        Top := Random(300);
      end;
    end;
end;

procedure TForm1.BitBtn3Click(Sender: TObject);
begin
  Zagizobr; //ïåðåìåøàåì åùå ðàç
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  s := 0;
  for i := 1 to 4 do
    for j := 1 to 4 do
    begin
      inc(s); //èìÿ èìàãè
      //íàõîäèì äèíàì. ñîçäàííûé êîìïîíåò èìàãó
      with TImage(FindComponent('im' + IntToStr(s))) do
      begin
        //êîïèðóåì ÷àñòè êàíâû â öèêëå ðàïðåäåëÿÿ íóæíûå îáëàñòè
        Canvas.CopyRect(Rect(0, 0, plkv, plkv), image1.Canvas, Rect(j * 50 - 50, i * 50 - 50, j * 50, i * 50));
        Left := -100 + (1+ Random(4)) * 105;
        Top := -100 + (1+ Random(4)) * 105;
      end;
    end;
end;

end.
Пока есть две версии, либо использовать под имаги шейпы, можно вручную накидать (или динамически создать на нужныхместах)
Далее либо FindComponent , либо Api функцию пересечения двух прямоугольников IntersectRect в примере за которую имагу я схватился я определяю, а вот как узнавать куда ее ложить? на какой шейп?
Есть такая мысль что если мы схватились за имагу-1, и мы знаем что она первая, то мы и искать должны на событие имаги - MouseMove шейп-1 при помощи FindComponent верно?
Самое главное как можно проще и чтоб работало.
Изображения
Тип файла: jpg 3333.jpg (82.4 Кб, 140 просмотров)
NIKOLAYY2 вне форума Ответить с цитированием
Старый 19.01.2015, 22:44   #6
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Создал динамически шейпы в нужных местах и-
Пишу такой код на динамически созданное событие ImageMouseMove, код довольно грубый, но не в этом дело. Пока задача пристыковать имагу-1 к шейпу-1, сообщение показывает вроде все правильно Нужные прямоугольники сравнялись! но имага должна прилипнуть уже к "своему" месту, а она неприлипает. Как так сделать чтобы она уже прилипла наконец то?

Код:
      if (TImage(FindComponent('im' + IntToStr(1))).Left = TShape(FindComponent('sh' + IntToStr(1))).Left) and (TImage(FindComponent('im' + IntToStr(1))).Top = TShape(FindComponent('sh' + IntToStr(1))).Top)  then
      begin
         TImage(FindComponent('im' + IntToStr(1))).Left := TShape(FindComponent('sh' + IntToStr(1))).Left;
         TImage(FindComponent('im' + IntToStr(1))).Top := TShape(FindComponent('sh' + IntToStr(1))).Top;
        // ShowMessage('Нужные прямоугольники сравнялись!');
      end;
Изображения
Тип файла: jpg 4444.jpg (45.7 Кб, 76 просмотров)
NIKOLAYY2 вне форума Ответить с цитированием
Старый 19.01.2015, 22:51   #7
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Давайте метод пример-прилипания прямоугольников разберем попроще, а то на этом примере довольно сложно и вряд ли кто поможет.
Кинем на форму один компонент Shape и один компонент Image, сделаем их одинакового размера и заставим их прилипнуть друг к другу при перетаскивании Image когда их значения Left и Top сравняются.
NIKOLAYY2 вне форума Ответить с цитированием
Старый 20.01.2015, 08:14   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Сейчас я не могу ничего тебе сказать кроме такого примера:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    Shape1: TShape;
    procedure FormCreate(Sender: TObject);
    procedure Shape1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure Shape1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure Shape1EndDrag(Sender, Target: TObject; X, Y: Integer);
    procedure Shape1EndDock(Sender, Target: TObject; X, Y: Integer);
    procedure Shape1StartDrag(Sender: TObject;
      var DragObject: TDragObject);
    procedure FormDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure FormDragDrop(Sender, Source: TObject; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var      atp: TPoint;
  Form1: TForm1;

implementation

uses Types;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Shape1.DragMode:=dmAutomatic;

end;

procedure TForm1.Shape1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin

//
end;

procedure TForm1.Shape1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
   var tp:TPoint;
begin
tp.X:=x;tp.Y:=y;
tp:=Shape1.ClientToParent(tp);
Shape1.Left:=tp.X-atp.X;
Shape1.Top:=tp.Y-atp.Y;

end;

procedure TForm1.Shape1EndDrag(Sender, Target: TObject; X, Y: Integer);
begin
//
end;

procedure TForm1.Shape1EndDock(Sender, Target: TObject; X, Y: Integer);
begin
//
end;

procedure TForm1.Shape1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
//
end;

procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
//
end;

procedure TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer);
   var tp:TPoint;
begin
tp.X:=x;tp.Y:=y;
atp:=Shape1.ClientToParent(tp);
end;

end.
Пример старый, призван перемещать шейп используя DragDrop.
Попробуй порыть в эту сторону.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 20.01.2015, 08:51   #9
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Если я правильно понял суть проблемы, наверно нужно брать не конкретные значения, а какой-то диапазон. То есть если Top-Left отличается на 5-6 пикселей, то считать, что юзер попал и копировать нужные значения координат... Как-то так.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 21.01.2015, 14:19   #10
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Utkin
Да так и надо. Вчера накидал какой-то пример код и вроде заработал как надо, плавно подвожу картинку к нужному месту и она сама встает на место.
Stilet сейчас попробую еще по вашему примеру.
Изображения
Тип файла: jpg 2222.jpg (13.0 Кб, 68 просмотров)
Вложения
Тип файла: zip Эффект_прилипания.zip (204.2 Кб, 10 просмотров)
NIKOLAYY2 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пристыковка Окон OrdJONY Общие вопросы Delphi 15 19.04.2007 12:47