• 0
Anasazi

Пример работы с TObjectList

Вопросы

Всем привет. Чиатю книгу Осипова по Delphi. В книге есть один пример создания простой игры, вроде бы в нем все понятно кроме одного момента.

По задумке один таймер должен создавать шарики и присваивать им случайные координаты. Второй таймер должен опускать шарики вниз.

С первым все просто и понятно понятно:

procedure TForm1.Timer1Timer(Sender: TObject);
Var
Circle:Tcircle;
begin
Randomize;
Circle:=TCircle.Create(nil);
List.Add(circle);
Circle.Parent:=Form1;
Circle.Position.Y:=0;
Circle.Position.X:=Random(Round(Form1.Width-Circle.Width));
end;

А вот со вторым какие-то чудеса:

procedure TForm1.Timer2Timer(Sender: TObject);
var
i: integer;
begin
For i:=0 to List.Count-1 do
with List.Items do
begin
Position.Y:=Position.Y+0.5;

Я не могу понять почему при перемещении шариков вниз мы пишем просто Position.Y:=Position.Y+0.5;

Как компилятор понимает что это Position.Y именно шарика, а не формы допустим или квадрата?

Я привык обращаться к свойству Position так Rectengle1.Position.Y.

Подскажите пожалуйста как так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 ответов на этот вопрос

  • 0
1 час назад, Anasazi сказал:

Я не могу понять почему при перемещении шариков вниз мы пишем просто Position.Y:=Position.Y+0.5;

Как компилятор понимает что это Position.Y именно шарика, а не формы допустим или квадрата?

Я привык обращаться к свойству Position так Rectengle1.Position.Y.

Подскажите пожалуйста как так.

если вам не понятен этот код

For i:=0 to List.Count-1 do
with List.Items[i] do
begin
	Position.Y:=Position.Y+0.5;
end;

то его можно переписать следующим образом

for i:=0 to List.Count-1 do
    List.Items[i].Position.Y := List.Items[i].Position.Y+0.5;

 

UPDATE: http://delphicode.org/delphi/with.htm

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, ZuBy сказал:

то его можно переписать следующим образом

И это будет гораздо более правильно. не используйте with!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
2 часа назад, kami сказал:

И это будет гораздо более правильно. не используйте with!

ну почему сразу не используйте, нужно просто знать как с этим работать.

например вот в таких конструкциях очень удобно, не требуется заводить переменную

with TStringList.Create do
begin
  Text := 'ТЕКСТ';
  SaveToFile('c:\file.txt');
  Free;
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
18 минут назад, ZuBy сказал:

например вот в таких конструкциях очень удобно

Не буду разводить холивар, тем более что with или не with имеет кучу обсуждений, в которых высказывались и именитые разработчики. Скажем так - использование with делает код не явным  (например - в классе, где используется эта конструкция с with тоже есть метод SaveToFile или свойство Text) и плохо читается сторонним разработчиком. Но - каждый решает для себя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 03.11.2016 в 16:04, ZuBy сказал:

если вам не понятен этот код


For i:=0 to List.Count-1 do
with List.Items[i] do
begin
	Position.Y:=Position.Y+0.5;
end;

то его можно переписать следующим образом


for i:=0 to List.Count-1 do
    List.Items[i].Position.Y := List.Items[i].Position.Y+0.5;

 

UPDATE: http://delphicode.org/delphi/with.htm

Спасибо! Так гораздо понятнее!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 03.11.2016 в 22:49, ZuBy сказал:

ну почему сразу не используйте, нужно просто знать как с этим работать.

например вот в таких конструкциях очень удобно, не требуется заводить переменную


with TStringList.Create do
begin
  Text := 'ТЕКСТ';
  SaveToFile('c:\file.txt');
  Free;
end;

 

Все же более правильный вариант будет такой:

with TStringList.Create do
try
  Text := 'ТЕКСТ';
  SaveToFile('c:\file.txt');
finally  
  Free;
end;

Иначе, если при каких то проблемах с файлом, Free не будет вызван и мы получим утечку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 03.11.2016 в 19:04, ZuBy сказал:

если вам не понятен этот код


For i:=0 to List.Count-1 do
with List.Items[i] do
begin
	Position.Y:=Position.Y+0.5;
end;

то его можно переписать следующим образом


for i:=0 to List.Count-1 do
    List.Items[i].Position.Y := List.Items[i].Position.Y+0.5;

 

UPDATE: http://delphicode.org/delphi/with.htm

Еще пару вариантов. 
1. Можно немного сократить, не указывая Items (почему - ищите в "корнях" property)

for i:=0 to List.Count-1 do
    List[i].Position.Y := List[i].Position.Y+0.5;

2. Можно использовать такой вариант
 

var
  c: TCircle;
begin
  for c in List do
    c.Position.Y := c.Position.Y + 0.5;
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От Alex7wrt
      Добрый день
      Столкнулся с такой задачей:
      Существует несколько TObjectList<TRectangle>. При создании каждого из них  AOwnsObjects задано как True. 
      RectList[i]:=TObjectList<TRectangle>.Create(True); ............ Nrect:=TRectangle.Create(nil); Nrect.Parent:=Form1; RectList[i].Add(Nrect); Существует ли способ определить, к какому из  TObjectList принадлежит элемент? 
    • От ivadimos
      Извиняюсь за псевдокод.

      Есть класс (A), у него есть несколько дочерних(B1.B2...)
      Создаю лист объектов TList<A>, в него добавляю объекты классов B1, B2...
       
      Есть третий класс С, который имеет перегруженный метод для всех дочерних классов (A).
      procedure p(obj: B1);
      procedure p(obj B2);

      Но объект в классе С всегда воспринимается как объект класса А.
      Как я могу решить проблему?
       
    • От PFC
      Есть класс:
      class TMyObjectInt : public TObject { private: int Value; public: __fastcall TMyObjectInt (int _Value); __fastcall ~TMyObjectInt(); }; Есть ComboBox:
      for (int i = 1; i <= 10; i++) cbxItems->Items->AddObject(IntToStr(i), new TMyObjectInt(i)); Почему при вызове ->Clear() не вызываются деструкторы для TObject'ов? Казалось бы базовый TObject замечательно для этого подходит, даже деструктор у него виртуальным объявлен.
      Я могу написать свою функцию очистки, но это потенциально приводит к ошибкам, особенно если я отдаю указатель на ComboBox за пределы своей формы.
       
      Кстати, так же ведут себя и многие другие контролы, да и в VCL было так же.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу