Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с памятью [Delphi, Windows]


Страницы:   1 2

Proger ©   (2004-06-26 16:09:00) 

Возмоно это ламерский вопрос, но у меня есть проблемка в написании
движка.Предположим есть тип TSprite и Sprite1, Sprite2 этого типа,
я пишу:
 Sprite1 := Sprite2;
 Я так понял здесь передаётся адрес Sprite2, из-за чего естественно
при манипуляциях с Sprite1 меняется и Sprite2 и наоборот.Вроде понятно
выразился.


ПсихЪ_задумчивый   (2004-07-22 15:06:00) [1]

Пока читал - запутался окончательно... (:
Так что нижеследующее скорее всего к ветке не относится.
1. Каждая картинка загружается один раз в массив спрайтов SprArr класса TSprite. Класс пишется вручну.

SetLength( SprArr, SprCount ); // SprCount - число спрайтов
for i := 0 to SprCount - 1 do
begin
 SprArr[i] := TSprite.Create();
 SprArr.LoadFromFile( IntToStr( i )+'.bmp' ); // это к примеру
end;

2. Когда нужно сделать много ракет, то мы делаем:

SetLength( RocetArr, RocetCount );
for i := 0 to RocetCount - 1 do
begin
 RocetArr[i] := TRocet.Create(); // Тут можно сразу параметры задать
 RocetArr[i].SpritePointer := @SprArr[ROCET_SPRITE_NUMBER];
end;

При отрисовки ракет:

for i := 0 to RocetCount - 1 do
 // Если у тебя SpritePointer : TPointer;
 TSprite( RocetArr.SpritePointer ).Draw( RocetArr.SprX, RocetArr.SprY );
 // Если SpritePointer : PSprite; (PSprite : ^TSprite), тогда
 RocetArr.SpritePointer.Draw( RocetArr.SprX, RocetArr.SprY );


Вот, вряд ли это кому-нибудь пригодится. А про спрайты ещё добавлю, что удобнее делать единый интерфейс управления массивом спрайтов, что-то типа SpriteList.


Megabyte-CeerCop   (2004-07-22 14:39:00) [2]

Если попытаюсь помочь, то только запутаю всех окончательно.
А вообще интересно чем этот поиск истины закончится.
Может еще не поздно начать эту ветку с нуля? переформулировав более точно вопрос.


Proger   (2004-06-29 18:19:00) [3]

2 Servelat ©.Письмо получил, но с текстом косяк какой-то.Попробовал каждый раз Create'ить TRocket, потом делаю
SprList[...] := Rocket, потом Rocket.Destroy и после этого
SprList[...] := nil.Как быть?


Proger   (2004-06-28 23:37:00) [4]

2 Servelat ©.Отослал


Servelat   (2004-06-28 23:27:00) [5]

Выложи исходник куда-нить, или на мыло мне пошли.
Почему ты делаешь SprList[...] (тут "..." это число, как я понял) :=TSpriteList.Create? Надо делать TRocket.Create, а дальше присваивать поля, примерно так:
SprList[0]:=TRocket.Create;
TRocket(SprList[0]).X:=1;
TRocket(SprList[0]).Y:=2; //устанавливаешь свойства

Приведение в виде TRocket(SprList[...]) нужно, если у тебя SprList объявлен как array of pointer. Если как-то иначе, то по ситуации. Если что не понятно, все таки пошли исходник мне, или выложи куда, а то не слишком ясно, что ты хочешь.


Proger   (2004-06-28 22:49:00) [6]

2 Servelat ©.А почему тогда глюк если я пишу:
 SprList[...] := TSpriteList.Create(...);
 SprList[...].Поле1 = Spr.Поле1;
 SprList[...].Поле2 = Spr.Поле2;
 ...


Servelat   (2004-06-28 22:47:00) [7]

2 Proger
Я не знаю, что ты хочешь получить. Если тебе надо несколько ракет, то надо создавать несколько экзэмпляров класса TRocket, т.е. "Create'ить". У каждого экземпляра свои свойства, координаты и т.п.


Servelat   (2004-06-28 22:46:00) [8]

2 Proger
Я не знаю, что ты хочешь получить. Если тебе надо несколько ракет, то надо создавать несколько экзэмпляров класса TRocket, т.е. "Create'ить".


Proger   (2004-06-28 22:44:00) [9]

2 Servelat ©.А кроме как Create'ить нет способов?


Servelat   (2004-06-28 22:34:00) [10]

2 Proger
>Вроде понятно выразился.
Нет, не понятно.
Че такое Rocket? Если он объявлен как некий класс TRocket, то
 Предположим я заношу спрайт Rocket c одними параметрами в ячейку SprList[0], далее в SprList[0], где находится
скопированая ракета параметр скорости перемещения увеличивается,
в то же время увиличивается параметр скорости и у ROCKET????

это будет верно. Тогда тебе надо каждый раз писать Rocket:=TRoket.Create; изменять его свойства как хочешь, потом добавлять в твой список. При новой ракете, сново Create'ить рокет и т.д. Тогда в списке на каждой ячейке будет свой экземпляр класса TRocket. А так у тебя есть список указателей, которые указывают на один экземпляр класса. При изменении любого (Rocket или SprList[0]) изменятся все.


Proger   (2004-06-28 22:13:00) [11]

2 Vladimir.Опять глюк со скоростями ракет, пишу так:
Ptr := SprList[Pos];
SprList[Pos] := Spr;
Spr := Ptr;


Vladimir "Chainik"   (2004-06-28 15:41:00) [12]

[28]
Спасибо, теперь понялчто ты имел ввиду.
по идее это можно лечить следующим образом
var ptr1:pointer;
begin
....
ptr1:=Sprite1;
Sprite1:=Sprite2;
Sprite2:=ptr1;
....
end;


[1]
Еще раз перечитал вопрос о проблеме, и у меня несколько озарило, а именно Progr фактически работает с указателями на некоторый объект типа TSprite, и в момент когда он производит приравнивание двух экземпляров этого класса у него происходит следующее:
указатель на Sprite1 заменяется указателем на Sprite2, в результате имеем следующую не совсем хорошую для автора вопроса ситуацию, а именно получается эквивалент операции UNION (объединение) из Си, т.е. работая с одним экземпляром класса он автоматически изменяет и второй экземпляр.
Вариант лечения подобной ситуации см. выше


smb   (2004-06-28 14:42:00) [13]

Vladimir "Chainik"
Скажу чесно. Я не знаю точно, что если Sprite1 := Sprite2, то передаётся указатель на экземпляр класса. Но судя по вопросу и следующим постам - это так.
роисходит по сути копирование содержимого переменной Sprite2 в переменную
Не переменную, а экзепляр класса. В том то и дело, что происходит не копирование содержимого, а передача адреса Sprite2 Sprite1.
Вот как я понял:
Представь, страницу, на которой ссылка на два разных сайта. Если у одной ссылки поменять адрес, то обе ссылки будут указывать на сайт1, но ведь сайт2 никуда не денется.
Я могу быть не прав, но именно так я понял фразу "Утерянная память" by Anatoly Podgoretsky. Память занята.
второй то указатель можно ведь приравнять к nil
Остается первый объект без указателя. И после приравнивания к nil занятой памяти лучше не станет.
Я все это говорю, исходя из предыдущих постов.
Что касается самой проблемы, я думаю лучше использовать запись. Ну вкрайнем случае как одно из полей класса, и присваивать их.


MrAngel   (2004-06-28 13:41:00) [14]

Не ну, а больше просто ни как. Если мы имеем дело с классами, то ни как. А вижу только один способ - тот, что я указал выше.

Если бы был тип record, то тоже обыкновенным копированием из памяти в память не получится, если есть внутри переменные типа поинтер. Ну в смысле получится, но это будет не полное копирование, а частичное, так как будут переменные, которые указывают на одну и ту же область памяти.

Вывод один писать свой собственный "Ассигн", который будет поддерживать "все особенности созданного класса".


Proger   (2004-06-28 13:29:00) [15]

2 Vladimir.Впринципе наверное и можно каждый устанавливать
указатель Sprite2 в nil, но тогда придётся каждый раз
заново Create'ить этот Sprite2.


Proger   (2004-06-28 13:07:00) [16]

2 MrAngel.Ты частично прав, сначала я так и сделал и
вроде бы работает правильнее(скорость у остальных ракет не меняет
ся, НО почему то параметр текущего кадра анимации передаётся
остальным спрайтам.Наверное я как-то неправильно изъясняюсь,
поэтому наверное в близшайшем времени выложу исходники движка и
бета версии игрухи на нём.


Vladimir "Chainik"   (2004-06-28 12:53:00) [17]

[23]
... второй объект остается без адреса ...
следует читать ... второй объект остается без указателя...

Пожалуйста поправте если я не прав


Vladimir "Chainik"   (2004-06-28 12:49:00) [18]

smb   (28.06.04 09:51) [19]
... сначала было два экземпляра класса и два указателя на них, после присвоения указателей один экземпляр заимел два указателя, другой остался без оных вообще. Вот и получилась утерянная память

Уважаемый smb, не мог бы ты поподробней объяснить мне чайнику, каким образом происходит утечка памяти. Ведь когда Proger делает следующее Sprite1 := Sprite2; происходит по сути копирование содержимого переменной Sprite2 в переменную тогоже типа Sprite1, и о каких указателях тогда здесь идет речь?
Второе. Даже при использовании указателей на объекты Sprite1 и Sprite2, при Sprite1 := Sprite2 происходит передача адреса, да второй объект остается без адреса, но второй то указатель можно ведь приравнять к nil.
приношу извинения за тон, просто меня очень заинтриговал данный вопрос


cyborg   (2004-06-28 12:15:00) [19]

Мне неизвестно что такое TSprite у него, объект или запись. Так же что в него входит. Я сказал как данные перенести, а работу мозга никто не отменял.


MrAngel   (2004-06-28 11:58:00) [20]

cyborg © так не пойдет. Не пойдёт если внутри класса есть поля-указатели (Pointer)

Proger   не правильно пробовал :-)
Допустим надо Sprite1 := Sprite2;
Тогда:
Sprite1.Pole1 := Sprite2.Pole1;
Sprite1.Pole2 := Sprite2.Pole2;
Sprite1.Pole3 := Sprite2.Pole3;
Sprite1.Property1 := Sprite2.Property1;
Sprite1.Property2 := Sprite2.Property2;
Sprite1.Property3 := Sprite2.Property3;

И т.д.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо