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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.12.2012, 11:32   #1
Fireblade-fan
Пользователь
 
Регистрация: 23.11.2011
Сообщений: 34
По умолчанию мигает PaintBox

Нужно написать прогу, в которой хаотично двигаются квадраты разного размера. Каждый квадрат это отдельный поток. При столкновении, квадрат меньшего размера исчезает (поток убивается) и так до тех пор, пока не останется один квадрат.
Я рисую эти квадраты на PaintBox. При столкновении один исчезает, а другие начинают мигать. Если поиграться с количеством и скоростью, то они могут и не исчезать вовсе. Плюс еще, у меня должно выводиться сообщение, что остался один квадрат, но у меня оно не выводится.
Подскажите пожалуйста, где нужно исправить ))

Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Button1: TButton;
    Label3: TLabel;
    Edit2: TEdit;
    Label4: TLabel;
    Edit3: TEdit;
    Panel1: TPanel;
    PaintBox: TPaintBox;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure GetData;
  end;

  Molecula = record
     x, y:Integer;          // êîîðäèíàòû
     Vx, Vy: Integer;       // ñîñòàâëÿþùèå ñêîðîñòè
     angle: real;           // óãîë ïîëåòà
     speed: byte;
  end;

var
  Form1: TForm1;
  Vmax, n: integer;
  R: array [1..100] of integer;
  mol: array [1..100] of molecula;
  run: boolean;
  HThread: array[1..150] of Thread;
  Mutex : THandle;

implementation

{$R *.dfm}

procedure TForm1.GetData;
var i:integer;
begin
   Randomize;
   n:=strtoint(Edit3.Text);     // êîëè÷åñòâî
   for i:=1 to n do R[i]:=(10+random(25));     // ðàçìåð
   Vmax:=strtoint(Edit2.Text);  // ìàêñèìàëüíàÿ ñêîðîñòü äâèæåíèÿ
end;

procedure TForm1.Button1Click(Sender: TObject);
var i, j: byte;
    temp: integer;
begin
  GetData;

  // çàïóñê äâèæåíèÿ
  //PaintBox.Refresh;
  PaintBox.Canvas.Brush.Color:=clWhite;
  PaintBox.Canvas.Pen.Color:=clWhite;
  PaintBox.Canvas.Rectangle(0,0,400,400);

  PaintBox.Canvas.Brush.Color:=clBlue;
  PaintBox.Canvas.Pen.Color:=clBlue;

  Randomize;

  // îïðåäåëåíèå íà÷àëüíîãî ïîëîæåíèÿ
  for i:=1 to N do
  begin
    // íà÷àëüíûå êîîðäèíàòû
    mol[i].x:=RandomRange(R[i], PaintBox.Width-R[i]);
    mol[i].y:=RandomRange(R[i], PaintBox.Height-R[i]);

    // íà÷àëüíîå íàïðàâëåíèå äâèæåíèÿ
    mol[i].angle:=Random(360)*Pi/180;
    mol[i].speed:=RandomRange(1, Vmax);

    // cîñòàâëÿþùèå äâèæåíèÿ  ïî îñÿì
    mol[i].Vx := Round(mol[i].speed * Sin(mol[i].angle));
    mol[i].Vy := Round(mol[i].speed * Cos(mol[i].angle));

    // âûâîä íà ýêðàí
    PaintBox.Canvas.Rectangle(mol[i].x-R[i], mol[i].y-R[i], mol[i].x+R[i], mol[i].y+R[i]);
  end;
  Mutex:= CreateMutex (nil, false, nil);
 for i:=1 to n do
  begin
    HThread[i] := Thread.Create(false,i,n);
    sleep(100);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
  for i:=1 to n do HThread[i].Terminate;
  CloseHandle(Mutex);
end;

end.
Fireblade-fan вне форума Ответить с цитированием
Старый 21.12.2012, 11:33   #2
Fireblade-fan
Пользователь
 
Регистрация: 23.11.2011
Сообщений: 34
По умолчанию

Код:
Код:
unit Unit2;

interface

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

type
  Thread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
  t:integer;
  t1:integer;
  ThreadName: integer;
  ThreadName1: integer;
  constructor Create(CreateSuspennded: Boolean; const Name: Integer; const Name1:integer);
  Destructor Destroy; override;
  procedure del;
  procedure Write;
  end;
  var k:integer;

implementation
uses Unit1;

constructor Thread.Create(CreateSuspennded: Boolean; const Name: Integer; const Name1:integer);
begin
  inherited Create(CreateSuspennded);
  ThreadName := Name;
  ThreadName1 := Name1;
end;

destructor Thread.Destroy;
begin
inherited Destroy;
end;

procedure Thread.Del;
begin
 Form1.PaintBox.Canvas.Brush.Color:=clWhite;
 Form1.PaintBox.Canvas.Pen.Color:=clWhite;
 Form1.PaintBox.Canvas.Rectangle(mol[t].x-R[t], mol[t].y-R[t], mol[t].x+R[t], mol[t].y+R[t]);
end;

procedure Thread.Write;
begin
 Form1.PaintBox.Canvas.Brush.Color:=clBlue;
 Form1.PaintBox.Canvas.Pen.Color:=clBlue;
 Form1.PaintBox.Canvas.Rectangle(mol[t].x-R[t], mol[t].y-R[t], mol[t].x+R[t], mol[t].y+R[t]);
end;

procedure Thread.Execute;
var i,m,j,temp:integer;
begin
  i:=ThreadName;  m:=ThreadName1;
 while not terminated do
  begin
    if WaitForSingleObject(Mutex, INFINITE) = WAIT_OBJECT_0 then
    try
       with Form1.Canvas do
       begin
          Lock;
          t:=i;
          Synchronize(del);
          //sleep(10);
          for j:=1 to m do
            if j<>i then
            begin
              // îïðåäåëÿåì ñòîëêíîâåíèå
              if sqrt((sqr(mol[i].x-mol[j].x)+sqr(mol[i].y-mol[j].y)))<(2*R[i]+1) then
              begin
                if k=1 then
                   ShowMessage('Îñòàëñÿ ïîñëåäíèé êâàäðàò');
                if R[j]>R[i] then
                begin
                  HThread[i].Terminate;
                  sleep(5);
                  k:=m-1;
                end
                else
                begin
                  HThread[j].Terminate;
                  sleep(5);
                  k:=m-1;
                end;
                Form1.PaintBox.Canvas.Brush.Color:=clWhite;
                Form1.PaintBox.Canvas.Pen.Color:=clWhite;
                Form1.PaintBox.Canvas.Rectangle(0,0,400,400);
              end;
            end;
          // ñäâèãàåì íà íîâóþ ïîçèöèþ.
          mol[i].x:=mol[i].x+mol[i].Vx;
          mol[i].y:=mol[i].y+mol[i].Vy;
          // ïðîâåðêà íà âûõîä çà ãðàíèöû îáëàñòè
          if mol[i].x>Form1.PaintBox.Width-R[i] then
          begin
            mol[i].x:=Form1.PaintBox.Width-R[i];
            mol[i].Vx:=-mol[i].Vx;
          end;
          if mol[i].x<R[i] then
          begin
            mol[i].x:=R[i];
            mol[i].Vx:=-mol[i].Vx;
          end;
          if Mol[i].y>Form1.PaintBox.Height-R[i] then
          begin
            mol[i].y:=Form1.PaintBox.Height-R[i];
            mol[i].Vy:=-mol[i].Vy;
          end;
          if mol[i].y<R[i] then
          begin
            mol[i].y:=R[i];
            mol[i].Vy:=-Mol[i].Vy;
          end;
          t1:=i;
          Synchronize(write);
          sleep(10);
          UnLock;
      end;
    finally  ReleaseMutex(Mutex);
    sleep(4);
  end;

end;
end;

end.
Fireblade-fan вне форума Ответить с цитированием
Старый 21.12.2012, 11:48   #3
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Потоки тут вообще не нужны.
И если так уж приспичило использовать потоки, то использовать их следует только для расчета параметров визуализации объектов сцены, сама же визуализация объектов сцены по расчитанным в потоках их параметрам должна выполняться исключительно в основном потоке.
xoodoo вне форума Ответить с цитированием
Старый 21.12.2012, 12:46   #4
Кольша
Далеко не
Участник клуба
 
Аватар для Кольша
 
Регистрация: 11.08.2011
Сообщений: 1,512
По умолчанию

может:
Код:
from1.DoubleBuffered:=true;
Кольша вне форума Ответить с цитированием
Старый 21.12.2012, 12:48   #5
Fireblade-fan
Пользователь
 
Регистрация: 23.11.2011
Сообщений: 34
По умолчанию

У меня задание такое, сделать с потоками, каждый квадрат это поток..
Fireblade-fan вне форума Ответить с цитированием
Старый 21.12.2012, 13:38   #6
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
У меня задание такое, сделать с потоками, каждый квадрат это поток
А то что потоки твои наперегонки лезут на канву формы и пейнтбоксов - это ты уже сам додумал ?
Наверняка в задании нет такого идиотского требования.
xoodoo вне форума Ответить с цитированием
Старый 21.12.2012, 16:08   #7
Fireblade-fan
Пользователь
 
Регистрация: 23.11.2011
Сообщений: 34
По умолчанию

Цитата:
Сообщение от Кольша Посмотреть сообщение
может:
Код:
from1.DoubleBuffered:=true;
Попробывал, все так же..

Цитата:
Сообщение от xoodoo Посмотреть сообщение
А то что потоки твои наперегонки лезут на канву формы и пейнтбоксов - это ты уже сам додумал ?
Наверняка в задании нет такого идиотского требования.
Вот точное задание:
"По экрану в хаотическом порядке движутся кубики разного размера (для каждого кубика создается отдельный поток). При столкновении кубики сливаются в один большой (ненужные потоки убиваются и остается только один), пока размер кубика не достигнет заданного диапазона (на экран выводится сообщение об этом)."
Fireblade-fan вне форума Ответить с цитированием
Старый 21.12.2012, 16:37   #8
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
Вот точное задание
Ну и где в задании написано что потоки должны заниматься отрисовкой кубиков ?
Нигде.
xoodoo вне форума Ответить с цитированием
Старый 21.12.2012, 16:56   #9
Fireblade-fan
Пользователь
 
Регистрация: 23.11.2011
Сообщений: 34
По умолчанию

Цитата:
Сообщение от xoodoo Посмотреть сообщение
Ну и где в задании написано что потоки должны заниматься отрисовкой кубиков ?
Нигде.
Хм.. То есть в потоках нужно вычислять только параметры, но не рисовать?
Попробую сделать. Большое спасибо!
Fireblade-fan вне форума Ответить с цитированием
Старый 21.12.2012, 17:02   #10
xoodoo
Форумчанин
 
Регистрация: 11.04.2012
Сообщений: 212
По умолчанию

Цитата:
То есть в потоках нужно вычислять только параметры, но не рисовать?
Именно так.
Можно и рисовать, но не на канве графического объекта под управлением VCL.
xoodoo вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Мигает монитор Jantar Операционные системы общие вопросы 24 05.01.2012 14:43
паскаль работас фалами обясните почему ошибка и как исправить f= file of ysp; на of мигает и просит душки zavarka_dok Помощь студентам 1 22.11.2010 22:31
Скриншот выделеной области экрана. Мигает при выделениии. Casper-SC Общие вопросы .NET 2 27.03.2010 11:49
Paintbox lacost Мультимедиа в Delphi 3 14.01.2009 09:53