Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизПроблема с динамическим массивом Найти похожие ветки
← →
Zeqfreed (2003-12-14 13:28) [0]Вот собственно код.
...
type
TSprite = class
FRect : TRect;
x,y,w,h : Integer;
Visible : Boolean;
procedure Show(const DestSurf,SourceSurf : IDirectDrawSurface7;
Params : Integer = DDBLTFAST_WAIT or
DDBLTFAST_SRCCOLORKEY);
end;
var
sprites : array of TSprite;
SpriteCount : Integer;...
...procedure AddSprite(Visible : Boolean;w,h,x,y : Integer;Rect : TRect);
begin
SetLength(sprites,SpriteCount);
sprites[SpriteCount] := TSprite.Create; //Здесь происходит ошибка
sprites[SpriteCount].x := x;
sprites[SpriteCount].y := y;
sprites[SpriteCount].w := w;
sprites[SpriteCount].h := h;
sprites[SpriteCount].FRect := Rect;
sprites[SpriteCount].Visible := Visible;
SpriteCount := SpriteCount + 1;
end;...
Пожалуйста, помогите выяснить в чём проблема? Может быть предложите свой вариант.
← →
Zeqfreed (2003-12-14 13:28) [0]Вот собственно код.
...
type
TSprite = class
FRect : TRect;
x,y,w,h : Integer;
Visible : Boolean;
procedure Show(const DestSurf,SourceSurf : IDirectDrawSurface7;
Params : Integer = DDBLTFAST_WAIT or
DDBLTFAST_SRCCOLORKEY);
end;
var
sprites : array of TSprite;
SpriteCount : Integer;...
...procedure AddSprite(Visible : Boolean;w,h,x,y : Integer;Rect : TRect);
begin
SetLength(sprites,SpriteCount);
sprites[SpriteCount] := TSprite.Create; //Здесь происходит ошибка
sprites[SpriteCount].x := x;
sprites[SpriteCount].y := y;
sprites[SpriteCount].w := w;
sprites[SpriteCount].h := h;
sprites[SpriteCount].FRect := Rect;
sprites[SpriteCount].Visible := Visible;
SpriteCount := SpriteCount + 1;
end;...
Пожалуйста, помогите выяснить в чём проблема? Может быть предложите свой вариант.
← →
Anatoly Podgoretsky © (2003-12-14 13:35) [1]Лезешь за пределы выделенной памяти. Используй High
← →
Anatoly Podgoretsky © (2003-12-14 13:35) [1]Лезешь за пределы выделенной памяти. Используй High
← →
Zeqfreed (2003-12-14 13:40) [2]А поподробней?..
← →
Zeqfreed (2003-12-14 13:40) [2]А поподробней?..
← →
Anatoly Podgoretsky © (2003-12-14 13:43) [3]А справка у тебя есть?
И еще желательно также использовать и Length
← →
Anatoly Podgoretsky © (2003-12-14 13:43) [3]А справка у тебя есть?
И еще желательно также использовать и Length
← →
Zeqfreed (2003-12-14 13:46) [4]Справка-то есть! Но неужели трудно написать как надо!!!
← →
Zeqfreed (2003-12-14 13:46) [4]Справка-то есть! Но неужели трудно написать как надо!!!
← →
Anatoly Podgoretsky © (2003-12-14 13:47) [5]А, так ты предлвгаешь мне скопировать сюда из справки?
← →
Anatoly Podgoretsky © (2003-12-14 13:47) [5]А, так ты предлвгаешь мне скопировать сюда из справки?
← →
Zeqfreed (2003-12-14 13:54) [6]Да в справке ведь ничего толкового не написано!
Ну или может это я просто такой тупой. Исправь ПОЖАЛУЙСТА мой код и напиши так, чтобы он работал.
← →
Zeqfreed (2003-12-14 13:54) [6]Да в справке ведь ничего толкового не написано!
Ну или может это я просто такой тупой. Исправь ПОЖАЛУЙСТА мой код и напиши так, чтобы он работал.
← →
Anatoly Podgoretsky © (2003-12-14 14:07) [7]В справке все нормально описано и даже есть пример и меня не поймут если я буду его сюда копировать.
← →
Anatoly Podgoretsky © (2003-12-14 14:07) [7]В справке все нормально описано и даже есть пример и меня не поймут если я буду его сюда копировать.
← →
MrAngel (2003-12-14 14:19) [8]Народ да вы что ?!?!
Уже сразу ошибку налицо видно !!!
Надо не sprites[SpriteCount] := TSprite.Create;
а sprites[SpriteCount-1] := TSprite.Create;
и так далее для всех строк.
Индексирования в массивах ВСЕГДА идут с нуля.
Между прочим это относится к азам программинга, и динамические массивы описаны в книгах для "чайников".
Стыдно, господа, очень стыдно !!!
← →
MrAngel (2003-12-14 14:19) [8]Народ да вы что ?!?!
Уже сразу ошибку налицо видно !!!
Надо не sprites[SpriteCount] := TSprite.Create;
а sprites[SpriteCount-1] := TSprite.Create;
и так далее для всех строк.
Индексирования в массивах ВСЕГДА идут с нуля.
Между прочим это относится к азам программинга, и динамические массивы описаны в книгах для "чайников".
Стыдно, господа, очень стыдно !!!
← →
Zeqfreed (2003-12-14 14:38) [9]Почему надо sprite[SpriteCount-1] := TSprite.Create;?
Ведь если учесть, что SpriteCount = 0, то получим
sprite[-1] := TSprite.Create;!!!
P.S. Когда я заменил SpriteCount : Integer; на SpriteCount : Integer = 1; всё заработало, но при завершении программы выводится "EInvalidPointer"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
← →
Zeqfreed (2003-12-14 14:38) [9]Почему надо sprite[SpriteCount-1] := TSprite.Create;?
Ведь если учесть, что SpriteCount = 0, то получим
sprite[-1] := TSprite.Create;!!!
P.S. Когда я заменил SpriteCount : Integer; на SpriteCount : Integer = 1; всё заработало, но при завершении программы выводится "EInvalidPointer"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
← →
Zeqfreed (2003-12-14 14:41) [10]P.P.S Конечно же перед завершением я освобождаю массив.
Скорее всего неправильно!?:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 1 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
← →
Zeqfreed (2003-12-14 14:41) [10]P.P.S Конечно же перед завершением я освобождаю массив.
Скорее всего неправильно!?:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 1 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
← →
Mihey © (2003-12-14 15:44) [11]2 Zeqfreed:
Допустим у тебя в массиве N элементов. То есть, если все элементы сосчитать, то будет N. Представь, что у тебя на столе N дискет. Теперь тебе их нужно будет пронумеровать. И пронумеровать начиная с 0. То есть, первая дискета будет иметь номер 0, вторая дискета номер 1, n-ная дискета будет иметь номер n-1.
Рассмотрим твой случай. Ты задаёшь длину массив атак:
SetLength(sprites, SpriteCount);
Теперь сделаем то, что тебе советовали - открыть справку. Читаем про SetLength:
procedure SetLength(var S; NewLength: Integer);
NewLength - это новая длина. Это количество элементов в массиве. Представь, что число SpriteCount элементов пронумерованы с нуля. Какой будет индекс у самого верхнего элемента? Правильно, SpriteCount-1. Поэтому процедуру удаления нужно переписать так:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
Учти, что High возвращает не длину, а индекс самого верхнего элемента. То есть, это то же самое, что:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to SpriteCount-1 do
begin
sprites[i].Destroy;
end;
end;
Всё, удачи тебе.
← →
Mihey © (2003-12-14 15:44) [11]2 Zeqfreed:
Допустим у тебя в массиве N элементов. То есть, если все элементы сосчитать, то будет N. Представь, что у тебя на столе N дискет. Теперь тебе их нужно будет пронумеровать. И пронумеровать начиная с 0. То есть, первая дискета будет иметь номер 0, вторая дискета номер 1, n-ная дискета будет иметь номер n-1.
Рассмотрим твой случай. Ты задаёшь длину массив атак:
SetLength(sprites, SpriteCount);
Теперь сделаем то, что тебе советовали - открыть справку. Читаем про SetLength:
procedure SetLength(var S; NewLength: Integer);
NewLength - это новая длина. Это количество элементов в массиве. Представь, что число SpriteCount элементов пронумерованы с нуля. Какой будет индекс у самого верхнего элемента? Правильно, SpriteCount-1. Поэтому процедуру удаления нужно переписать так:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
Учти, что High возвращает не длину, а индекс самого верхнего элемента. То есть, это то же самое, что:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to SpriteCount-1 do
begin
sprites[i].Destroy;
end;
end;
Всё, удачи тебе.
← →
MrAngel (2003-12-14 17:14) [12]
> Почему надо sprite[SpriteCount-1] := TSprite.Create;?
> Ведь если учесть, что SpriteCount = 0, то получим
> sprite[-1] := TSprite.Create;!!!
Ну если SpriteCount = 0 то зачем тогда вообще создавать TSprite ?
Понял теперь смысл ?
← →
MrAngel (2003-12-14 17:14) [12]
> Почему надо sprite[SpriteCount-1] := TSprite.Create;?
> Ведь если учесть, что SpriteCount = 0, то получим
> sprite[-1] := TSprite.Create;!!!
Ну если SpriteCount = 0 то зачем тогда вообще создавать TSprite ?
Понял теперь смысл ?
← →
Zeqfreed (2003-12-15 13:56) [13]Нет, MrAngel, это ты не понял! Переменная SpriteCount служит лишь для того, чтобы задать новую длинну массива в процедуре AddSprite(), и в этой процедуре она увеличивается и при следующем вызове длинна массива устанавливается на еденицу больше.
2Mihey:
Я пробовал:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
Получается ошибка?!
Возможно это из-за того, что изначально я ставлю SpriteCount в 1, но если оставлять её равной нулю то тоже получается ошибка!
← →
Zeqfreed (2003-12-15 13:56) [13]Нет, MrAngel, это ты не понял! Переменная SpriteCount служит лишь для того, чтобы задать новую длинну массива в процедуре AddSprite(), и в этой процедуре она увеличивается и при следующем вызове длинна массива устанавливается на еденицу больше.
2Mihey:
Я пробовал:
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to High(sprites) do
begin
sprites[i].Destroy;
end;
end;
Получается ошибка?!
Возможно это из-за того, что изначально я ставлю SpriteCount в 1, но если оставлять её равной нулю то тоже получается ошибка!
← →
Anatoly Podgoretsky © (2003-12-15 14:00) [14]Zeqfreed (15.12.03 13:56) [13]
Для этого переменная не нужна, есть функция Length и ошибок не будет связанных с глобальной переменной.
← →
Anatoly Podgoretsky © (2003-12-15 14:00) [14]Zeqfreed (15.12.03 13:56) [13]
Для этого переменная не нужна, есть функция Length и ошибок не будет связанных с глобальной переменной.
← →
Mihey © (2003-12-15 14:29) [15]>Возможно это из-за того, что изначально я ставлю SpriteCount в 1, но если оставлять её равной нулю то тоже получается ошибка!
Зачем меняешь SpriteCount??? Сколько создал - столько и удаляй.
← →
Mihey © (2003-12-15 14:29) [15]>Возможно это из-за того, что изначально я ставлю SpriteCount в 1, но если оставлять её равной нулю то тоже получается ошибка!
Зачем меняешь SpriteCount??? Сколько создал - столько и удаляй.
← →
Unknown user © (2003-12-15 19:25) [16]Я бы посоветовал так добавлять спрайт - SetLength(Sprites,Length(Sprites)+1). Затем with Sprites[High(Sprites)] do ... и вперед заполнять значения полей объекта. И еще для объектов предпочтительней исп. TList. А для написания своей игры сначала изучи основы программирования, иначе твой первый камень о который ты споткнулся будет не последним и не самым большим.
← →
Unknown user © (2003-12-15 19:25) [16]Я бы посоветовал так добавлять спрайт - SetLength(Sprites,Length(Sprites)+1). Затем with Sprites[High(Sprites)] do ... и вперед заполнять значения полей объекта. И еще для объектов предпочтительней исп. TList. А для написания своей игры сначала изучи основы программирования, иначе твой первый камень о который ты споткнулся будет не последним и не самым большим.
← →
MrAngel (2003-12-16 18:06) [17]
procedure AddSprite(Visible : Boolean;w,h,x,y : Integer;Rect : TRect);
begin
INC(SpriteCount);
SetLength(sprites,SpriteCount);
sprites[SpriteCount-1] := TSprite.Create;
sprites[SpriteCount-1].x := x;
sprites[SpriteCount-1].y := y;
sprites[SpriteCount-1].w := w;
sprites[SpriteCount-1].h := h;
sprites[SpriteCount-1].FRect := Rect;
sprites[SpriteCount-1].Visible := Visible;
end;
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to SpriteCount-1 do
if Assigned(sprites[i]) then FreeAndNil(sprites[i]);
end;
Вот... это с использованием SpriteCount, если через High и Length, то будет медленней на количество тактов вызова этих процедур минус один (примерно). Поэтому вариант с SpriteCount считаю более правильным.
← →
MrAngel (2003-12-16 18:06) [17]
procedure AddSprite(Visible : Boolean;w,h,x,y : Integer;Rect : TRect);
begin
INC(SpriteCount);
SetLength(sprites,SpriteCount);
sprites[SpriteCount-1] := TSprite.Create;
sprites[SpriteCount-1].x := x;
sprites[SpriteCount-1].y := y;
sprites[SpriteCount-1].w := w;
sprites[SpriteCount-1].h := h;
sprites[SpriteCount-1].FRect := Rect;
sprites[SpriteCount-1].Visible := Visible;
end;
procedure DeleteSprites();
var
i : Integer;
begin
for i := 0 to SpriteCount-1 do
if Assigned(sprites[i]) then FreeAndNil(sprites[i]);
end;
Вот... это с использованием SpriteCount, если через High и Length, то будет медленней на количество тактов вызова этих процедур минус один (примерно). Поэтому вариант с SpriteCount считаю более правильным.
← →
cyborg © (2003-12-16 18:43) [18]Вот деланье этого:
SetLength(sprites,SpriteCount);
при каждом создании спрайта есть ужасно.
← →
cyborg © (2003-12-16 18:43) [18]Вот деланье этого:
SetLength(sprites,SpriteCount);
при каждом создании спрайта есть ужасно.
← →
Unknown user © (2003-12-16 18:44) [19]2 MrAngel. Если ты создашь больше 100 000 спрайтов -то возможно заметишь разницу в 1 мс. Настолько вот медленнее :). А заводить глобальную переменную SpriteCount, хранящую длину массива -это не есть хороший стиль программирования.
← →
Unknown user © (2003-12-16 18:44) [19]2 MrAngel. Если ты создашь больше 100 000 спрайтов -то возможно заметишь разницу в 1 мс. Настолько вот медленнее :). А заводить глобальную переменную SpriteCount, хранящую длину массива -это не есть хороший стиль программирования.
← →
MrAngel (2003-12-17 17:32) [20]Ну не знаю... Тут в общем то всё зависит от ситуации. Если спрайты гоняются туда сюда (а не держатся в памяти) то лучше с переменной. Ну а если ни достаточно редко создаются или удаляются то можно и через SetLength и прочие процедуры.
> Вот деланье этого:
> SetLength(sprites,SpriteCount);
> при каждом создании спрайта есть ужасно.
А как же иначе? Как же иначе, если заранее не известно количество спрайтов ? На пример ситуация с динамическими генерируемыми спрайтами (небо), где во время игры их количество должно меняться. Как же тогда здесь ?
← →
MrAngel (2003-12-17 17:32) [20]Ну не знаю... Тут в общем то всё зависит от ситуации. Если спрайты гоняются туда сюда (а не держатся в памяти) то лучше с переменной. Ну а если ни достаточно редко создаются или удаляются то можно и через SetLength и прочие процедуры.
> Вот деланье этого:
> SetLength(sprites,SpriteCount);
> при каждом создании спрайта есть ужасно.
А как же иначе? Как же иначе, если заранее не известно количество спрайтов ? На пример ситуация с динамическими генерируемыми спрайтами (небо), где во время игры их количество должно меняться. Как же тогда здесь ?
← →
cyborg © (2003-12-17 21:13) [21]А что будет, если спрайт удаляется? Это придётся весь массив переделывать.
Для спрайтов используй на худой конец TStringList, а лучше сам делай свои списки.
← →
cyborg © (2003-12-17 21:13) [21]А что будет, если спрайт удаляется? Это придётся весь массив переделывать.
Для спрайтов используй на худой конец TStringList, а лучше сам делай свои списки.
← →
_drew_ (2003-12-18 02:26) [22]Какие массивы ? При работе с классами или объектами массивы не нужны. Для этого и нужно создавать необходимые свойства и методы.
← →
_drew_ (2003-12-18 02:26) [22]Какие массивы ? При работе с классами или объектами массивы не нужны. Для этого и нужно создавать необходимые свойства и методы.
← →
Free Advisor (2003-12-18 10:35) [23]2 Unknown User
> А заводить глобальную переменную SpriteCount, хранящую длину
> массива -это не есть хороший стиль программирования.
Имхо, хороший стиль программирования в данном случае - это реализация массива связным списком, двунаправленным, для удобства. Ж) Только вопрос в том, нужно ли это? Для начинающих и ленивых вполне сойдетarray of TBotva;
$)
И еще насчет "хорошего тона", Аксиома оптимизации: мы либо выигрываем в скорости, проигрывая в памяти, либо наоборот - третьего не дано.
← →
Free Advisor (2003-12-18 10:35) [23]2 Unknown User
> А заводить глобальную переменную SpriteCount, хранящую длину
> массива -это не есть хороший стиль программирования.
Имхо, хороший стиль программирования в данном случае - это реализация массива связным списком, двунаправленным, для удобства. Ж) Только вопрос в том, нужно ли это? Для начинающих и ленивых вполне сойдетarray of TBotva;
$)
И еще насчет "хорошего тона", Аксиома оптимизации: мы либо выигрываем в скорости, проигрывая в памяти, либо наоборот - третьего не дано.
← →
MrAngel (2003-12-18 21:52) [24]Кстати связный список - тоже вариант, по крайней мере он будет быстро работать. Тут мгновенно решается проблема удаления элементов по выбору.
Если делать удаление из массива, там надо делать смещение данных. Что кстати и делает TStringList и TList.
← →
MrAngel (2003-12-18 21:52) [24]Кстати связный список - тоже вариант, по крайней мере он будет быстро работать. Тут мгновенно решается проблема удаления элементов по выбору.
Если делать удаление из массива, там надо делать смещение данных. Что кстати и делает TStringList и TList.
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.038 c