Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.93/41: Рейтинг темы: голосов - 41, средняя оценка - 4.93
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32

Пятнашки

03.09.2010, 20:21. Показов 8831. Ответов 61
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Помогите решить следующую задачу:
Нужно написать программу наподобие игры пятнашки...
Суть проблемы в следующем: имеется несколько квадратных блоков, в которых записаны буквы... нужно чтобы при перетаскивании одного блока на соседний этот блок вставал на его место, а соседний на место перетаскиваемого (написать всё это нужно с помощью Drag&Drop или Drag&Dock (если это возможно))... Помогите пожалуйста, не знаю даже с чего начать и какие компоненты использовать для перетаскивания! Заранее благодарю! О_о
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.09.2010, 20:21
Ответы с готовыми решениями:

Пятнашки
Вот у меня такой вопрос. На форме 15 кнопок, одну из них можно передвинуть. Как узнать что соседняя клетка пустая???

Пятнашки)))
подскажите пожалуйста как это делается)))

игра Пятнашки
Здравствуйте!Подскажите пожалуйста как сделать игру 'Пятнашки' с помощью stringgrid.Заранее спасибо)

61
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 01:07
Студворк — интернет-сервис помощи студентам
дай 5 мин подумать...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
04.09.2010, 01:10  [ТС]
да я и не тороплю вовсе... думай столько сколько нужно для достижения результата
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 01:45
ну чтобы драг н дроп работал надо добавить такую вещь в OnMouseDown:
Delphi
1
(Sender as TPicure).DragDrop(<а вот как определить объект который надо писать сюда...>,x,y);
вот, чет даже не знаю... может кто другой подскажет, или завтра на свежую голову осинит, а пока так....

Добавлено через 2 минуты
хотя....

Добавлено через 8 минут
процедура OnMouseDown:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var i, j: byte;
    source:TPictures;
begin
  (Sender as TPictures).dr:=false;
  source:=nil;
  for i:=1 to 6 do
    for j:=1 to 5 do
    begin
      if  (((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height)) then
        Source:=mas[i,j];
    end;
  (Sender as TPicure).DragDrop(Source,x,y);
end;
Добавлено через 25 секунд
если заработает - я маг!

Добавлено через 2 минуты
Цитата Сообщение от Vas-e-na Посмотреть сообщение
Delphi
1
source:TPictures;
обрати внимание, я забыл, щас подправил...

Добавлено через 7 минут
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var i, j: byte;
    source:TPictures;
begin
  (Sender as TPictures).dr:=false;
  source:=nil;
  for i:=1 to 6 do
    for j:=1 to 5 do
    begin
      if  (((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height)) then
        Source:=mas[i,j];
    end;
  if source<>nil then
  begin
    (Sender as TPictures).left:=(Source as TPictures).left;
    (Sender as TPictures).top:=(Source as TPictures).top;
    (Source as TPictures).left:=oldX;
    (Source as TPictures).top:=oldY;
  end
  else
  begin
    (Sender as TPictures).Left:=oldx;
    (Sender as TPictures).top:=oldy;
  end;
вот и теперь процедуры OnDragOver и OnDragDrop можно просто удалить, мы сам реализовали всё...

Добавлено через 1 минуту
а красивой анимацией мы займемся завтра (биолгически), т.е. сегодня (календарно) вечером
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
04.09.2010, 21:55  [ТС]
жду продолжения!
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 22:05
AlexXXX12389, я что тут подумал, я ошибся, TImage не обладает свойсвами AlphaBlend, поэтому плавное затемнение-осветление не сделать, поэтому надо подумать либо какой компонент вместо него взять за основу, либо же как добавить это свойство компоненту.
Эту проблему, я не уверен что сам смогу решить, но это не значит что я не смогу рассказать про потоки, и показать как с помощью них сделать анимацию-движения...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
04.09.2010, 22:22  [ТС]


Добавлено через 13 минут
можно ли дописать программу на основе TImage (чтобы хоть как нибудь работало)? а про компонент я поспрашиваю у кого нибудь ещё
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 22:22
вообщем так, для обработки эффекта для картинок вам прийдется написать функцию самому (можете в раздел графики полезть - вам помогут), суть функции заключается в чем:
1. в качестве одного из параметров передается Tbitmap, который модернизируется и возвращается обратно
2. Работать надо с Tbitmap.Canvas.Pixels[j,i], а конкретно с RGB значениями
вот, такая функция правильно описанная, поможет и сделать все эффекты
когда будет готова такая вещь, можно будет занятся потоками или же я могу про потоки щас рассказать???
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
04.09.2010, 22:29  [ТС]
ну можно и сейчас рассказать про потоки
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 22:57
итак, потоки, есть два возможных варианта создания потока:
1. С помощью WInAPI
2. С помощью класса TThread
благодаря мои лабораторным в универе я понял, что разницы никакой нет, а использовать класс удобнее, поэтому будем использовать его
Итак, для создания потока нам нужно описать класс наследуемый от Tthread (я думаю это не сложно, точно также как класс TPictures), но у этого класса есть основные моменты, а именно процедура Execute - в теле этой процедуры описывается то действие которое должен выполнять поток.
Итак, в краце с потоком мы разобрались, далее по ходу проясним все ньюансы...
Теперь, нам нужно определится какие действия наш поток будет выполнять, допустим, после того как мы "отпустили" наш объект Tpictures он плавно вернулся на место, т.е. вот это только плавно:
Цитата Сообщение от Vas-e-na Посмотреть сообщение
Delphi
1
2
3
4
begin
 (Sender as TPictures).Left:=oldx;
 (Sender as TPictures).top:=oldy;
 end;
Итак, что нужно сделать, для начала создадим класс на основе TThread и назовем этот класс TReturnThread, в разделе protected объявим процедуру Execute, а за ней напишем такое слово ovveride (хотите узнать что это почитайте про переопределение), отделенное точкой с запятой, нажмем CTRL+SHIFT+C и у нас готова заготовка.

Добавлено через 5 минут
заготовка есть, теперь смотрим, с чем потоку нужно работать и он этого не сможет узнать.... естесвенно это наш объект - Sender, его то и надо передать потоку но как? для этого нужно переопределить конструктор, в разделе public объявляем конструктор:
Delphi
1
constructor Create(CreateSuspended: boolean; Picture: Tpictures); overload;
и точно также как в прошлый раз создаем заготовку...

Добавлено через 2 минуты
теперь у нас появилась возможность что-то передать потоку, но вот хранить пока негде, поэтому в разделе private добавим переменную в которой будем хранить объект...

Добавлено через 1 минуту
скелет для потока готов, однако нужно сделать еще одну вещь, мы используем собственный класс, значит надо добавить его в uses юнита.
итак я готов посомтреть на скелет потока, и можно начать его заполнять...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
04.09.2010, 23:13  [ТС]
Delphi
1
2
3
4
5
6
7
8
9
type
  TReturnThread = class(TThread)
  protected
    procedure execute; override;
  private
    Img:TPictures;
  public
    constructor Create(CreateSuspended: boolean; Picture: Tpictures); overload;
  end;
Добавлено через 2 минуты
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
constructor TReturnThread.Create(CreateSuspended: boolean; Picture: TPictures);
begin
 
end;
 
procedure TReturnThread.execute;
begin
  inherited;
 
end;
 
end.
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
04.09.2010, 23:57
теперь, конструктор:
Delphi
1
2
3
4
5
constructor TReturnThread.Create(CreateSuspended: boolean; Picture: TPictures);
begin
  Create(CreateSuspended); // вызов конструктора базового класса
  Img:=Picture; // no comment 
end;
Добавлено через 1 минуту
это просто, дальше будем писать саму анимацию....

Добавлено через 3 минуты
для начала сделаем заготовку:
Delphi
1
2
3
4
5
6
7
8
procedure TReturnThread.execute;
begin
  inherited;
  while not terminated do
  begin
  
  end;
end;
Добавлено через 8 минут
теперь то что внутри будет, в принципе вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TReturnThread.execute;
var dx,dy: ShortInt;
begin
  inherited;
  if Img.Left<From1.oldX then dx:=-1 else dx:=1;
  if Img.Top<From1.oldY then dy:=-1 else dy:=1;
  while not terminated do
  begin
    if Img.Left<>From1.oldX then Img.Left:=Img.Left:=+dx;
    if Img.Top<>From1.oldY then Img.Top:=Img.Top:=+dy;
    sleep(40); // (40мс -> 25 кадров в сек)
  end;
end;
теперь нужно не забыть до,авить unit1 (или как он называется) в uses но только не вверху, а после implementation:
Delphi
1
2
implementation
uses unit1;
это нужно чтобы использовать форму...

Добавлено через 2 минуты
единственно теперь переменные OldX и OldY нужно перенести в public раздел (у формы!!!)

вот, в принципе и все, в зависимоти от того как ты опишешь уже действие всё и будет зависеть...

Добавлено через 24 секунды
теперь последний этап, нам нужно подключить поток...

Добавлено через 6 минут
мы возвращаемся в модуль формы, добавляем в uses (implementation) модуль потока
перходим в процедуру onMouseDown, добавляем переменную (имя, допустим ReturnThread) типа TReturnThread и заменяем вот это:
Delphi
1
2
3
4
begin
    (Sender as TPictures).Left:=oldx;
    (Sender as TPictures).top:=oldy;
  end;
на вот этот код:
Delphi
1
2
3
4
5
begin
  ReturnThread:=TReturnThread.Create(true,(Sender as Tpictures));
  ReturnThread.FreeOnTerminate:=true; 
  ReturnThread.Resume; // запускаем поток.
end;
PS забыл кое что в модуле потока:
Delphi
1
2
3
4
5
6
7
8
 while not terminated do
  begin
    if Img.Left<>From1.oldX then Img.Left:=Img.Left:=+dx;
    if Img.Top<>From1.oldY then Img.Top:=Img.Top:=+dy;
    sleep(40);
    // цикл то надо когда нить остановить...
    if (Img.Left=From1.oldX)and(Img.Top=From1.oldY) then break;
  end;
Добавлено через 2 минуты
вот, и теперь, если я написал все правильно, то если вы оттащите любой ваш объект на пустое место формы он плавно вернется назад...

НО есть маленькие ньюансы синхронизации, поэтому, давайте сделаем следующее:

Добавлено через 8 минут
пардон, чет я совсем перемудрил начиная с этого сообщения Пятнашки я перепутал процедуру MouseDown с MouseUP....

давайте вы покажите весь код всех модулей, я проверю, и мы займемся синхронизацией...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
05.09.2010, 00:01  [ТС]
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, jpeg;
 
type
  TPictures = class(TImage)
  public
    dr:boolean;
  end;
type
  TReturnThread = class(TThread)
  protected
    procedure execute; override;
  private
    Img:TPictures;
  public
    constructor Create(CreateSuspended: boolean; Picture: Tpictures); overload;
  end;
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
    procedure MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    mas:array[1..6,1..5] of TPictures;
  public
    oldY,oldX,dx,dy:integer;
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
var i,j:byte;
begin
for i := 1 to 6 do
  for j := 1 to 5 do
    begin
      mas[i,j]:=TPictures.Create(self);
      mas[i,j].Parent:=self;
      mas[i,j].dr:=false;
      mas[i,j].Width:=40;
      mas[i,j].Height:=40;
      mas[i,j].Left:=40*i;
      mas[i,j].Top:=40*j;
      mas[i,j].Caption:='1';
      mas[i,j].OnMouseDown:=MouseDown;
      mas[i,j].OnMouseMove:=MouseMove;
      mas[i,j].OnMouseUp:=MouseUp;
    end;
end;
 
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var i,j:byte; source:TPictures; ReturnThread:TReturnThread;
begin
  (Sender as TPictures).dr:=false;
  source:=nil;
  for i:=1 to 6 do
    for j:=1 to 5 do
    begin
      if  (((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height)) then
        Source:=mas[i,j];
    end;
  if source<>nil then
  begin
    (Sender as TPictures).left:=(Source as TPictures).left;
    (Sender as TPictures).top:=(Source as TPictures).top;
    (Source as TPictures).left:=oldX;
    (Source as TPictures).top:=oldY;
  end
  else
  begin
    ReturnThread:=TReturnThread.Create(true,(Sender as Tpictures));
    ReturnThread.FreeOnTerminate:=true;
    ReturnThread.Resume;
  end;
end;
 
procedure TForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (Sender as TPictures).dr then
begin
 (Sender as TPictures).Left:=(Sender as TPictures).Left+X-dx;
(Sender as TPictures).Top:=(Sender as TPictures).Top+Y-dy;
end;
end;
 
procedure TForm1.MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 (Sender as TPictures).dr:=false;
end;
 
{ TReturnThread }
 
constructor TReturnThread.Create(CreateSuspended: boolean; Picture: TPictures);
begin
  Create(CreateSuspended);
  Img:=Picture;
end;
 
procedure TReturnThread.execute;
var dx,dy: ShortInt;
begin
  inherited;
  if Img.Left<Form1.oldX then dx:=-1 else dx:=1;
  if Img.Top<Form1.oldY then dy:=-1 else dy:=1;
  while not terminated do
  begin
    if Img.Left<>Form1.oldX then Img.Left:=Img.Left+dx;
    if Img.Top<>Form1.oldY then Img.Top:=Img.Top+dy;
    sleep(40); // (40мс -> 25 кадров в сек)
    if (Img.Left=Form1.oldX)and(Img.Top=Form1.oldY) then break;
  end;
end;
end.
Добавлено через 1 минуту
всё в одном модуле
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
05.09.2010, 00:09
ну как я и говорил, все что в onMouseDown идет в OnMouseUp, а в mouse down пока это должно быть записано:
Delphi
1
2
oldX:=(Sender as TPicuture).Left;
oldY:=(Sender as TPicuture).Top;
Добавлено через 2 минуты
теперь
1. добавим в класс Tpictures public переменную типа TReturnThread
2. в onMouseUP вместо локальной переменной будем использовать переменную Tpicture bp Sender'a
хочу увидеть получилось ли (заодно узнаем как усвоены знания)

Добавлено через 1 минуту
Цитата Сообщение от AlexXXX12389 Посмотреть сообщение
type
кстати type перед каждым классом писать не надо...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
05.09.2010, 00:59  [ТС]
наверно я совсем тупой, но у меня не получается добавить переменную типа TReturnThread, потому как компилятор такого типа не знает

Добавлено через 2 минуты
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
  TPictures = class(TButton)
  public
    dr:boolean;
    ReturnThread:TReturnThread;
  end;
  TReturnThread = class(TThread)
  protected
    procedure execute; override;
  private
    Img:TPictures;
  public
    constructor Create(CreateSuspended: boolean; Picture: TPictures); overload;
  end;
что не так делаю??? ткните носом

Добавлено через 5 минут
или нужно вынести описание классов в отдельные модули?
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
05.09.2010, 01:29
это называется зависисмостью, а с моим руководством мы сделали циклическую зависимость, а это плохо, от неё надо избавится...

Добавлено через 16 минут
придумал, замените в классе TPictures TReturnThread на просто TThread

Добавлено через 32 секунды
и выполните пункт 2 моего предыдущего сообщения...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
05.09.2010, 01:45  [ТС]
Вот что получилось
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;
 
type
    TPictures = class(TButton)
  public
    dr:boolean;
    ReturnThread:TThread;
  end;
  TReturnThread = class(TThread)
  protected
    procedure execute; override;
  private
    Img:TPictures;
  public
    constructor Create(CreateSuspended: boolean; Picture: TPictures); overload;
  end;
    TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
    procedure MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    mas:array[1..6,1..5] of TPictures;
  public
    oldY,oldX,dx,dy:integer;
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
var i,j:byte;
begin
for i := 1 to 6 do
  for j := 1 to 5 do
    begin
      mas[i,j]:=TPictures.Create(self);
      mas[i,j].Parent:=self;
      mas[i,j].dr:=false;
      mas[i,j].Width:=40;
      mas[i,j].Height:=40;
      mas[i,j].Left:=40*i;
      mas[i,j].Top:=40*j;
      mas[i,j].Caption:='1';
      mas[i,j].OnMouseDown:=MouseDown;
      mas[i,j].OnMouseMove:=MouseMove;
      mas[i,j].OnMouseUp:=MouseUp;
    end;
end;
 
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  oldX:=(Sender as TPictures).Left;
  oldY:=(Sender as TPictures).Top;
end;
 
procedure TForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (Sender as TPictures).dr then
begin
 (Sender as TPictures).Left:=(Sender as TPictures).Left+X-dx;
(Sender as TPictures).Top:=(Sender as TPictures).Top+Y-dy;
end;
end;
 
procedure TForm1.MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  var i,j:byte; source:TPictures;
begin
  (Sender as TPictures).dr:=false;
  source:=nil;
  for i:=1 to 6 do
    for j:=1 to 5 do
    begin
      if  (((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height)) then
        Source:=mas[i,j];
    end;
  if source<>nil then
  begin
    (Sender as TPictures).left:=(Source as TPictures).left;
    (Sender as TPictures).top:=(Source as TPictures).top;
    (Source as TPictures).left:=oldX;
    (Source as TPictures).top:=oldY;
  end
  else
  begin
    (Sender as TPictures).ReturnThread:=TReturnThread.Create(true,(Sender as Tpictures));
    (Sender as TPictures).ReturnThread.FreeOnTerminate:=true;
    (Sender as TPictures).ReturnThread.Resume;
  end;
end;
 
{ TReturnThread }
 
constructor TReturnThread.Create(CreateSuspended: boolean; Picture: TPictures);
begin
  Create(CreateSuspended);
  Img:=Picture;
end;
 
procedure TReturnThread.execute;
var dx,dy: ShortInt;
begin
  inherited;
  if Img.Left<Form1.oldX then dx:=-1 else dx:=1;
  if Img.Top<Form1.oldY then dy:=-1 else dy:=1;
  while not terminated do
  begin
    if Img.Left<>Form1.oldX then Img.Left:=Img.Left+dx;
    if Img.Top<>Form1.oldY then Img.Top:=Img.Top+dy;
    sleep(40);
    if (Img.Left=Form1.oldX)and(Img.Top=Form1.oldY) then break;
  end;
end;
end.
Только почему-то не работает, объекты вообще не таскаются
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
05.09.2010, 02:14
щас все подправим, я как раз над этим работаю...

Добавлено через 7 минут
вообщем, вот пока что должно получится:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;
 
type
 
  TPictures = class(TShape)
  public
    dr:boolean;
    returnThread:TThread;
  end;
 
  { TReturnThread }
 
  TReturnThread = class(TThread)
  protected
    procedure execute; override;
  private
    Img:TPictures;
    oldX,oldY:integer;
  public
    constructor Create(CreateSuspended: boolean; Picture: Tpictures; X,Y: integer); overload;
  end;
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    mas:array[1..6,1..5] of TPictures;
  public
    oldY,oldX,dx,dy:integer;
    { Public declarations }
  end;
 
 
var
  Form1: TForm1; 
 
implementation
 
{$R *.dfm}
 
{ TReturnThread }
 
procedure TReturnThread.execute;
  var dx,dy: ShortInt;
begin
  inherited;
  if Img.Left<oldX then dx:=1 else dx:=-1;
  if Img.Top<oldY then dy:=1 else dy:=-1;
  while not terminated do
  begin
    if Img.Left<>oldX then Img.Left:=Img.Left+dx;
    if Img.Top<>oldY then Img.Top:=Img.Top+dy;
    sleep(40);
    if (Img.Left=oldX)and(Img.Top=oldY) then break;
  end;
  img.returnThread:=nil;
end;
 
constructor TReturnThread.Create(CreateSuspended: boolean; Picture: Tpictures; X, Y: integer);
begin
  Create(CreateSuspended);
  Img:=Picture;
  oldX:=x;
  oldY:=y;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var i,j:byte;
begin
for i := 1 to 6 do
  for j := 1 to 5 do
    begin
      mas[i,j]:=TPictures.Create(self);
      mas[i,j].Parent:=self;
      mas[i,j].dr:=false;
      mas[i,j].Width:=40;
      mas[i,j].Height:=40;
      mas[i,j].Left:=40*i;
      mas[i,j].Top:=40*j;
      mas[i,j].Caption:='1';
      mas[i,j].OnMouseDown:=MouseDown;
      mas[i,j].OnMouseMove:=MouseMove;
      mas[i,j].OnMouseUp:=MouseUp;
      mas[i,j].returnThread:=nil;
      mas[i,j].Brush.Color:=Random($FFFFFF);
    end;
end;
 
procedure TForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if (Sender as TPictures).dr then
  begin
    (Sender as TPictures).Left:=(Sender as TPictures).Left+X-dx;
    (Sender as TPictures).Top:=(Sender as TPictures).Top+Y-dy;
  end;
end;
 
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Sender as TPictures).returnThread<>nil then exit;
  (Sender as TPictures).dr:=true;
  oldX:=(Sender as TPictures).Left;
  oldY:=(Sender as TPictures).Top;
  dX:=x;
  dY:=y;
  (Sender as TPictures).BringToFront;
end;
 
procedure TForm1.MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var i,j:byte; source:TPictures;
begin
  if(Sender as TPictures).dr=false then exit;
  (Sender as TPictures).dr:=false;
  source:=nil;
  for i:=1 to 6 do
    for j:=1 to 5 do
    begin
      if Sender<>mas[i,j] then
      if  (((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height)) then
        Source:=mas[i,j];
    end;
  if source<>nil then
  begin
    (Sender as TPictures).left:=(Source as TPictures).left;
    (Sender as TPictures).top:=(Source as TPictures).top;
    (Source as TPictures).left:=oldX;
    (Source as TPictures).top:=oldY;
  end
  else
  begin
    (Sender as TPictures).ReturnThread:=TReturnThread.Create(true,(Sender as Tpictures),oldx,oldy);
    (Sender as TPictures).ReturnThread.FreeOnTerminate:=true;
    (Sender as TPictures).ReturnThread.Resume;
  end;
end;
 
end.
только вот работает drag&drop не так как нужно... а краш тесты проводить нет сил...
PS я заменил tImage на tShape чтобы видно было

Добавлено через 12 минут
*ля....
Delphi
1
2
3
4
(((Sender as TPictures).Left-dx)>(mas[i,j].Left))
         and (((Sender as TPictures).Left-dx)<(mas[i,j].Left+mas[i,j].Width))
         and (((Sender as TPictures).top-dy)>(mas[i,j].top))
         and (((Sender as TPictures).top-dy)<(mas[i,j].top+mas[i,j].height))
не -dx а +dx, не -dy а +dy!!! я идиот...

Добавлено через 58 секунд
ладно, остальное завтра, а пока можете поразвлекаться и поразбираться с кодом, посмотреть что я исправил и дописал...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
05.09.2010, 22:07  [ТС]
ну вот, что-то похожее вырисовывается!!!

Добавлено через 34 минуты
жду продолжения с нетерпением!
0
 Аватар для Vas-e-na
420 / 417 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
06.09.2010, 23:48
простите немного занят, нет времени, будет время напишу...
1
15 / 0 / 0
Регистрация: 16.09.2009
Сообщений: 32
06.09.2010, 23:51  [ТС]
Хорошо, буду ждать!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.09.2010, 23:51

Задание Пятнашки
Лабораторная работа по динамическим компонентам. &quot;Пятнашки&quot; ( без отчета) Я не знаю, что это и как это делать... Небыл на занятие и...

Пятнашки с подсказкой
Помогите, пожалуйста, справиться с задачей! Мне нужно создать пятнашки в Delphi, причём с подсказкой, т.е. что бы по нажатию на кнопку на...

Пятнашки из букв
Привет Интересует игра Пятнашки, но не из цифр, а из букв алфавита, т.е. разложение их - A, Б, В, Г итд

Пятнашки в картинках
ЗДравствуйте, у меня есть игра пятнашки с кнопками, как переделать ее в игру с картинками?? То, что надо создать массив картинок, я знаю, а...

Пятнашки на делфи
Здравствуйте! У меня возникла небольшая проблема с написанием игры пятнашки на делфи. на форме у меня есть 16 элементов типа button. При...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru