Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Вниз

Непонятные глюки со спрайтами и Delphi   Найти похожие ветки 

 
NailMan   (2003-08-13 16:17) [0]

Пишу я сейчас парсер конфигов для загрузки моделек. При добавлении спрайтов(габаритных фонарей) к актеру все идет пучком: спрайты создаются в глобальном массиве спрайтов, но когда делро доходит до рендера -происходит глюк. Заключается он в том что если в конфиге описаны 3 координаты и цвет 3-х спрайтов, то они в дальнейшем нормально функционируют при перемещении актера(спрайты привязаны к актеру в определенных точках и при перемещениях/поворотах актер двигает все за собой), но стоит добавить четвертый спрайт(точку) и это спрайт перемещает 2-й спрайт на свое место и сам находясь там же перестает двигаться за объектом(только поворачивается).

Функция загрузки спрайта и кусок парсера ниже:

//Загрузка спрайта
Procedure TActor.LoadFlare(n:string;Var Spr:TGameSprite);
var
v,s:td3dvector;
c:td3dcolorvalue;
begin
//В строке n находится строка вида
//(-1.8,4.1,10.2)(1,0,0,1)(4,4,4)
//где первая скобка - координаты, вторая - цвет RGBA, третья - масштаб
v:=extractcoords(n);
c:=extractcolorvalue(n);
s:=extractcoords(n);
Spr:=TGameSprite.Create("Flare1.BMP",GSpr_FLARE);
Spr.Color:=D3DCOLOR_COLORVALUE(C.r,
c.g,
c.b,
c.a);
//Задаем считанные координаты точки привязки базовым(привязочным) координатам спрайта
Spr.POSZ:=v;
Spr.FSize:=s;
//ресетим матрицу. В принципе этого можно и не делать, так как при перемещении спрайта его матрица заполняется полность вручную.
d3dxmatrixidentity(Spr.Fmat);
end;


И вот кусок парсера файла конфигурации актера

...
//Signal flares section
SlaveSprCount:=0;
SearchLnstr(f,"[Signal flares]",false);
readlnstr(f,n);
count:=extractdword(n); //Вычленяет Dword из строки вида "xxx=123"
For i:=0 to Count-1 do
begin
readlnstr(f,n);
//получаем индекс незанятого(=nil) спрайта в общем массиве и помещаем его в список связанных спрайтов у актера
SlaveSpr[SlaveSprCount]:=GetFreeIndex(FREE_SPRITE);
//для наглядности присваиваем индекс левой переменной
Z:=SlaveSpr[SlaveSprCount];
//грузим спрайт
LoadFlare(n,Z);
Spr[Z].Enabled:=true;
end;
...


Вот кусок процедуры перемещения актера:

Procedure TActor.AMoveTo;
var i:integer;
m:td3dmatrix;
begin
//собственное перемещение координат и положения актера
Moveto;
...
For i:=0 to SlaveSprCount-1 do
begin
//быстрое копирование матрицы через строковую операцию movsd или через 3DNow!
FastMatrixMove(world.fMat,M);
//обнуление координат
m._41 := 0;
m._42 := 0;
m._43 := 0;
//трансформирование координат спрайта матрицей актера(относительно центра актера) и координатами привязки
D3DXVec3TransformCoord(Spr[SlaveSpr[i]].fpos,Spr[SlaveSpr[i]].posz,m);
//смещение положения(трансформированного относительно нуля) спрайта в координаты актера
D3DXVec3Add(tempvec,Spr[SlaveSpr[i]].fpos,World.POS);
Spr[SlaveObj[i]].SetPos(tempvec);
end;
...


вот...
собсно как я и говорил уже, в случае 3-х привязанных спрайтов, они двигаются вместе с актером нормально(и расположены в тех точках как задано в конфиге). Стоит добавить четвертую точку/спрайт как все смещается и неправильно двигается(этот самый четвертый спрайт).
Координаты и другие параметры четвертого спрайта на результат не влияют.
Пятый и так далее спрайты ничего дают еще худшую картину.
Максимальное количество подчиненнхй спрайтов(индексов) у актера ограничено 64 штуками.

Вобщем в чем глюк может быть?


 
NailMan   (2003-08-13 16:23) [1]

Да недоглядел когда вставлял кусок в окно редактирования(когда вырезал логгинг создания спрайта):

в куске где парсится конфиг, после строки
Spr[Z].Enabled:=true;
идет конечно же еще и строка
Inc(SlaveSprCount);


 
cyborg   (2003-08-13 23:23) [2]

Трудно разобраться в том, чего сам не писал.

Что такое TGameSprite?
extractcoords(n); как работает? Почему 2 раза одно и тоже к разным переменным делаешь?
v:=extractcoords(n);
s:=extractcoords(n);

Вместо этого
For i:=0 to Count-1 do
Лучше делать
For i:=1 to Count do затем использовать индекс I-1
Например если коунт будет равен нулю, то цикл будет выполняться, и может возникнуть ошибка, во втором случае цикл исполняться не будет.

Неизвестно что такое For i:=0 to SlaveSprCount-1 do и откуда берётся.


 
NailMan   (2003-08-14 10:29) [3]

Что такое TGameSprite?

TYPE
TGameSprite = CLASS
Private
SpriteType : integer; //Тип спрайта. Влияет только на флаг D3DPT_ при рендере
Public
Fmat : TD3DMatrix; //матрица трансформаций
FPOS : TD3DVector; //Позиция в мире
POSZ : TD3DVector; //Смещение относительно актера(когда он в нуле)
FSize : TD3DVector; //масштаб(Z=1)
TexName : String; //ну это поятно
Enabled : Boolean; //----//---
TextureIndex : Dword; //Индекс текстуры в общем массиве
Color : TD3DCOLOR; //цвет модуляции
Constructor Create(Const FileName:String;SprType:Integer);
Procedure Render;
Procedure MoveTo; //для билбоардинга берется глобальная матрица вида(при передв-ии камеры, она копирует туда свою матрицу)
Procedure SetPos(const v: TD3DVector); //установить спрайт в нужную позицию
END;


extractcoords(n); как работает?

Function ExtractCoords(var n:string):Td3dvector;
begin
delete(n,1,pos("(",n));
result.x:=strtofloat(copy(n,1,pos(",",n)-1)); delete(n,1,pos(",",n));
result.y:=strtofloat(copy(n,1,pos(",",n)-1)); delete(n,1,pos(",",n));
result.z:=strtofloat(copy(n,1,pos(")",n)-1));
delete(n,1,pos(")",n));
end;

Функция вырезает скобку координат из общей строки, выдает вектор, вырезает эту скобку и выдает строку обратно для дальнейших манипуляций.
Почему 2 раза одно и тоже к разным переменным делаешь?
v:=extractcoords(n);
s:=extractcoords(n);

Ну как я и говорил в одной строке несколько скобок с разными данными(порядок параметров в строки всегда постоянный)

Вместо этого
For i:=0 to Count-1 do
Лучше делать
For i:=1 to Count do затем использовать индекс I-1
Например если коунт будет равен нулю, то цикл будет выполняться, и может возникнуть ошибка, во втором случае цикл исполняться не будет.

Ж-) По моему в первом случае при count=0 цикл вообще не выполнится, даже ошибки не получится.

Неизвестно что такое For i:=0 to SlaveSprCount-1 do и откуда берётся.
Ну я же во втором постинге добавил где получается SlaveSprCount. Это количество подчиненных актеру спрайтов. индексы спрайтов хранятся в актере в массиве интегеров SlaveSpr.


 
Sapersky   (2003-08-14 13:54) [4]

Spr[SlaveObj[i]].SetPos(tempvec)

Возможно, здесь должно быть Spr[ SlaveSpr[i]].SetPos(tempvec) ?

Вместо этого
For i:=0 to Count-1 do
Лучше делать
For i:=1 to Count doзатем использовать индекс I-1
Например если коунт будет равен нулю, то цикл будет выполняться, и может возникнуть ошибка, во втором случае цикл исполняться не будет.


Никакой ошибки не будет, будет цикл от 0 до -1, т.е. ни разу, что и требуется. Единственное, что меня здесь волнует - соображает ли компилятор заранее вычесть единицу или делает это на каждой итерации (в случае использования индекса i-1 наверняка приходится вычитать на каждой... хотя не знаю... компиляторы нынче умные пошли).


 
NailMan   (2003-08-14 15:32) [5]

To -> Sapersky ©
Блин точно! А я тут колупаюсь и не догоняю в чем дело. Даже супер подробный лог прикрутил.

Надо это в ветку о том как программисты тупят, что когда-то ходила в "Потрепаться".

ЗЫ: Уря, теперь дела продвинутся далеко, так как долелал таки я свой
ListBox в GUI и консоль. Завтра выложу на свой сайт демо-версию.


 
cyborg   (2003-08-14 22:53) [6]

Никакой ошибки не будет, будет цикл от 0 до -1, т.е. ни разу, что и требуется.

И правда :о), я раньше наткнулся на проблему выхода за границы, поэтому теперь делаю так, как сказал. В данном случае этот совет можно не слушать ;о)



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.041 c
14-80190
Manulo
2004-01-30 18:53
2004.02.25
Женский калькулятор


1-79821
TrogWar
2004-02-11 09:07
2004.02.25
Как создать заставку к проге?


4-80353
Kinderr
2003-12-20 15:42
2004.02.25
Диалог


1-79737
BALU1111
2004-02-12 11:53
2004.02.25
Шифрование данных


7-80316
SlyFox
2003-12-05 08:17
2004.02.25
Запись CD (нужна VCL)!!!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский