Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE);
При вызове метода из программы без использования второго параметра объект рисуется, а при использовании параметра Erase — объект стирается:
Erase, и в нём уже вызывать «рисование с параметром»тут не удаляются уже созданные объекты (да, знаю, при завершении программы, в общем-то пофиг, но «привычки...»)procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin Petals := nil; end;
может выглядеть как (удаляем дублирование)if Random(2) = 1 then Petals[CurPetal] := TPetal.Create(img.Width, img.Height) else Petals[CurPetal] := TOverlappedPetal.Create(img.Width, img.Height);
type
TCustomPetalClass = class of TCustomPetal;
...
var
LPetalClassToCreate: TCustomPetalClass;
...
if Random(2) = 1 then
LPetalClassToCreate := TPetal
else
LPetalClassToCreate := TOverlappedPetal
Petals[CurPetal] := LPetalClassToCreate.Create(img.Width, img.Height);
if Assigned(Petals[CurPetal]) then
procedure TForm1.FormCreate(Sender: TObject);
begin
PetalC := 70;
SetLength(Petals, PetalC);
CurPetal := 0;
timer1.Enabled := True;
end;
type
TForm1 =
private
FPetals: TPetals;
...
end;
...
procedure TForm1.Timer1Timer(Sender: TObject);
begin
FPetals.DrawNext;
img.Canvas.TextOut(10, 10, IntToStr(FPetals.Count) + ' ');
end;
Теперь вот решил допилить, учел практически полностью Ваши замечания
И отдельный метод для стирания писать не стал, т.к. считаю это избыточным,
ведь нужна всего одна строчка, а ее я запрятал
в аналог деструктора (метод kill),
destructor Destroy; override;
А насчет деструктора — в него нельзя передать параметр, поэтому сделал метод kill.
2.1 Для стирания нужен TCanvas, поэтому передаём TImage в конструкторе (тем более, что нам нужны его ширина и высота, которые имеют мало смысла, если рисовать мы будем на каком-то другом канвасе), и запоминаем его (использование интерфейса «дружеского класса» не нарушает инкапсуляцию)
TPetals = class(TObjectList)
P.Add(...) if Assigned(fPetals[Count]) then
TPetals.Free, fSize, fCount становятся не нужны вовсеВ данном случае — НАДО передавать Canvas, потому что Canvas в Delphi — это более универсальная сущность, чем Image. Передадите Image — сможете рисовать только на Image, передадите Canvas — на Image и на других типах, имеющих Canvas.
создайте интерфейс с методами рисования и передавайте его в то, что хочет отрисоваться (фигуру) и реализуйте в том, на чем хотите отрисоваться
main ничего не знает про (= не зависит от) petalclasspetalclass и ничего не знает про mainpetalintfmain
Безболезненная прививка объектного мышления