Применение средств графического отображения для организации непрерывного движения поездов с непрерывным переключением светофора по кольцевой железной дороге, страница 2

     begin

      NextSvetofor.Train:= Train ;

      NextSvetofor.Train.Svetofor:= NextSvetofor ;

      bool:= true ;

     end

      else

       if (NextSvetofor.Train = nil) and (Train = nil) and (tbool or (CountSvetofor = 1)) then

        bool:= true ;

{Выполняется, если возможно удаление светофора без последствий столкновения поездов или других каких-либо проблем }

 if bool then

 begin

  if CountSvetofor = 1 then

   FirstSvetofor:= nil

   else

   begin

{Если светофор является первым, то сделать первым светофор стоящий впереди данного}

    if self = FirstSvetofor then

     FirstSvetofor:= NextSvetofor ;

    BackSvetofor.NextSvetofor:= NextSvetofor ;

    NextSvetofor.BackSvetofor:= BackSvetofor ;

   end ;

  dec(CountSvetofor) ;

{Визуальное изменение кол-во светофоров  в StatusBar1}

  Panels.Text:= 'Кол-во светофоров: ' + IntToStr(CountSvetofor) ;

{Вызов destructor Destroy}

  free ;

  result:= true ;

 end

  else

   result:= false ;

end ;

Метод procedure GoImg  позволяет прорисовать светофор.

procedure TSvetofor.GoImg ;

var

 fColor: TColor ;

begin

 with Сanvas do

  begin

{Определение цвета, который прорисуется на светофоре}

   case StatusColor of

    0: fColor:= clRed ;

    1: fColor:= clYellow ;

    2: fColor:= clGreen ;

   end ;

   Pen.Color:= clBlack ;

   Brush.Color:= fColor ;

{Прорисовка светофора}

   Polygon(xy) ;

   Brush.Color:= clWhite ;

{Прорисовка номера светофора}

   TextOut(IndexPoint.x,IndexPoint.y,IntToStr(Index));

  end ;

end ;

Класспоездов

Экземпляр данного  класса (TTrain) должен уметь определять координаты следующего хода, прорисовывать, а также знать ссылки на следующий и предыдущий экземпляр класса  (TTrain),  в связи использования двунаправленного списка. Так же класс содержит в себе уникальный номер, ссылку на поезд (TSvetofor) перед которым он находится, текущее положение и свет светофора на который он пересек его.

TTrain = class

  private

   Svetofor: TSvetofor ;

   NextTrain: TTrain ;

   BackTrain: TTrain ;

   Index: integer ;

   IndexWPoint, IndexHPoint: integer ;

   StepPos: Byte ;

   SpCol: Byte ;

   PeremBool: boolean ;

   aPositP: Real ;

   TrColor: TColor ;

   x,y: integer  ;

   Canvas: TCanvas ;

   ListBox: TListBox ;

   Panel: TStatusPanel ;

   constructor Create(fSvetofor: TSvetofor ; fNextTrain, fBackTrain: TTrain ; fSpeed: Byte ; faPosit: Real; fTrColor: TColor; fIndex: integer ; fCanvas: TCanvas; fListBox: TListBox ; fPanel: TStatusPanel) ;

    procedure GoStep ;

    procedure XYSet(fa: real) ;

    property aPosit: Real Read aPositP Write XYSet ;

   procedure GoImg ;

  public

   Speed:  Byte ;

    destructor Destroy; override;

 end ;

где:

*  Svetofor – ссылка на светофор на котором;

*  NextTrain – ссылка на следующий поезд;

*  BackTrain – ссылка на предыдущий поезд;

*  Index – номер поезда;

*  IndexWPoint – отступ для прорисовки номера по координате X;

*  IndexHPoint – отступ для прорисовки номера по координате Y;

*  StepPos – индексатор скорости

*  Speed – скорость поезда

*  SpCol – на какой свет проехал поезд (0: красный; 1: желтый; 2: зеленый);

*  PeremBool – true: если поезд пересек aPosit светофора, а false с точностью наоборот;

*  aPositP – угол поезда;

*  TrColor – цвет поезда;

*  Canvas – холст;

*  ListBox – список для хранения поездов;

*  Panel – визуальное отображение кол-ва поездов;

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

constructor  TTrain.Create(fSvetofor: TSvetofor ; fNextTrain, fBackTrain: TTrain; fSpeed: Byte; faPosit: Real; fTrColor: TColor; fIndex: integer ; fPanel: TStatusPanel) ;

begin

 inherited Create ;

{Заполнение полей класса}

 Svetofor:= fSvetofor ;

 NextTrain:= fNextTrain ;

 BackTrain:= fBackTrain ;

{Выбрать индекс автоматически или записать из fIndex}

 if fIndex = -1 then

 begin

  inc(MaxIndexTrain) ;

  Index:= MaxIndexTrain ;

 end

  else

   Index:= fIndex ; 

 Speed:= fSpeed  ;

 aPosit:= faPosit ;

 PeremBool:= false ;

 TrColor:= fTrColor ;

 StepPos:= 0 ;

 SpCol:= 2 ;

 Canvas:= fCanvas ;

 ListBox:= fListBox ;

{Определение констант сдвига текста от центра шара }

 IndexWPoint:= TextWidth(IntToStr(Index))  div 2;

 IndexHPoint:= TextHeight(IntToStr(Index)) div 2 ;

end ;

Метод destructor Destroy позволяет разрушить светофор при его удалении.

destructor TTrain.Destroy ;

begin

{При удалении поезда необходимо переписать ссылки в следующем и предыдущем поезде}

if CountTrain = 1 then

  FirstTrain:= nil

  else

  begin

{Поезд является первым (FirstTrain) в двунаправленном списке}

   if self = FirstTrain then

    FirstTrain:= FirstTrain.NextTrain ;

   BackTrain.NextTrain:= NextTrain ;

   NextTrain.BackTrain:= BackTrain ;

  end ;

{Удаление ссылки в светофоре на данный поезд}

 Svetofor.Train:= nil ;

 dec(CountTrain) ;

{Визуальное изменение кол-во поездов в StatusBar1}

 Panels.Text:= 'Кол-во поездов:  ' + IntToStr(CountTrain) ;

{Переопределить света светофоров}

 PereschetSvetofor ;

 inherited Destroy ;

end ;

Метод procedure GoStep позволяет определить координаты следующего шага.

procedure TTrain.GoStep ;

var

 fa,atp: real ; {Временный переменные углов}

 bool: boolean ;

begin

 bool:= false ;

{Увеличивается индекс шага}

 inc(StepPos) ;

{Если значения скорость совпадут с индексатором скорости}

 if Speed <= StepPos then

 begin

  StepPos:= 0 ;

{В зависимости от света светофора на который проехал поезд определяется угол шага}