![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
GLScene как сделать консоль!! [Delphi, Windows]
FRick © (2004-05-31 13:32:00)Во многих играх при нажатие на '~' вылазиет командная строка
гне можно вести код, кто знает помогите!!
dimodim (2004-06-15 06:55:00) [1]
> И ещё вопрос(не в тему) как мне качать камеру чтобы эмитировать
> реалистичную ходьбу?
Качай по оси X
FRick (2004-06-05 18:48:00) [2]Спасибо вам за помощь
я пропаду на месяц
буду Апгрейдить комп!
NailMan (2004-06-04 10:48:00) [3]КиТаЯц
Возможно, просто мне проще было написать свое, дабы не подключать лишние модули.
---
WBR, NailMan aka 2:5020/3337.13
КиТаЯц (2004-06-04 10:11:00) [4]2 NailMan © (04.06.04 09:24) [23]
Спасибо! Я так понимаю, что
CutSpaceInString(var c:string);
то же само, что стандарная
TrimLeft();
;o)
NailMan (2004-06-04 09:24:00) [5]КиТаЯц
> Я конечно и сам могу, но... всегда легче на готовом :) "правильное
> разделение команды от параметров" не подкинеш?
Procedure TUTGameConsole.ExtractCommand(c:string);
var n:string;
begin
//Убираем приглашение строки
CMDLine.Clear;
if c='' then exit;
repeat
//если есть пробелы, то удалем их
If c[1]=' ' then CutSpaceInString(c);
If pos(' ',c)<>0 then
begin n:=copy(c,1,pos(' ',c)-1);Delete(c,1,pos(' ',c));
CMDLine.Add(n);
end
else
begin
if c<>'' then
begin
n:=c; c:='';
CMDLine.Add(n);
end;
end;
until (length(c)=0);
end;
И вырезалка
Procedure CutSpaceInString(var c:string);
begin
repeat
delete(c,1,1);
until (copy(c,1,1)<>' ') or (length(c)=0);
end;
---
WBR, NailMan aka 2:5020/3337.13
КиТаЯц (2004-06-04 07:19:00) [6]2 NailMan ©
> Главное написать правильное разделение команды от параметров(учитывая
> пробелы и множественные пробелы) и обязательно все в верхний
> регистр(или в нижний), чтобы не было гемора с сравнениями
> строк.
Я конечно и сам могу, но... всегда легче на готовом :) "правильное разделение команды от параметров" не подкинеш?
NailMan (2004-06-03 18:30:00) [7]FRick ©
> Я замети что все действия программы пишутся в UTLogging.txt
> с фиксацией даты и времени что должно помочь при отладке!
Ну не все действия записываются в лог, но большинство. Да и дата нужна в редких случаях. Идея лога - отловить на каком месте прога сглюкнула. Скажем(пример) должна быть такая последовательность в логе:
Log: -> Calculating movement capabilities...
Log: -> Scanning and counting engines...Ok
Log: -> Calculate Max Velocities...Ok
А лог прервался(с вылетом виоляции акцесса) на:
Log: -> Calculating movement capabilities...
Log: -> Scanning and counting engines...Ok
Значит при калькуляции максимальной скорости актера произошла ошибочка. Так как у меня при этой калькуляции пробегаются все двигатели актера, то вероятно где-то прога вылезла за пределы массива двигателей и прога обращалась по левому указателю. Так я и нашел багу - лог сам сказал на каком месте была ошибка.
Вообще довольно сомнительно использовать саму консоль для вывода информации о загрузке ресурсов и т.д.(как например в кваке, HL и их клонах). Принципиально ширина консоли маленькая и текста туда влезет немного, а если детализировать лог(как у меня) буквально до мелочей, то будет очень проблематично что-то потом прочитать по этому логу(когда он сбросится в файло). И тем более если вылез AV, программа скорее всего даже и не сбросит данные из консоли в файл.
Я, например, консоль сделал для отладки он-лайн процессов(в будущем). Скажем для отладки и мониторинга AI(в том самом будущем). Или скажем очень помогла при исправлении бага с переключениями LOD на моделях.
Конечно же консоль, имхо, обязана выполнять роль альтернативных "Настроек". Скажем делается кофиг-файл и в реал-тайме можно настроить все что можно настроить(как в кваке).
Я так например пользую консоль при отладке рендерера и работы актеров.
Конечно же снабдить консоль большим количеством команд(работающих :-)) непросто, но реально. У меня например большинство команд почерпнуто из кваки(вплоть до синтаксиса) и есть даже контексная помощь по командам и переменным. Типа обижать юзверя нельзя - закон чести.
> Консоль я наладил скрестил два примера и забил туда каманды
> работает, думаю что любая игра начинается с консоли!
Я тоже сначала написал консоль(когда в пятый раз начал переписывать ядро :-) ), а потом уже все остальное - опыт четырех предыдущих ядер научил уму разуму.
> Как же наладить всё выше и выше перечисленное?
Что касаемо екзекуции команд и экзекуции конфиг-файла:
Все просто - надо писать парсер команды!
Как я реализовывал(теория):
Когда вылезает консоль весь инпут работает на консоль, т.е. отключеются крыс и джой, а обработка нажатых в DInput клавиш идет через вышеупомянутую TControlsManager.ScanKeyBoard.
На выходе этого метода я получаю код действия и символ(если была нажата символьная клавиша). В это случае я прибавляю к переменной CMD:String этот символ.
Когда юзверь жмет ентер, то команда попадает в парсер.
Парсер делает следующее:
- дробит строку на составляющие. Заполняет глобальный CmdLine:TStringList кусками командной строки разделенной пробелами. Т.е. например поступила команда "condump C:\console.txt". Парсер разбивает ее на "condump" и "C:\console.txt" и добавляет(предварительно сделав CmdLine.Clear) последовательно в CmdLine.
В последующем всегда подразумевается что CmdLine.Strings[0] это команда, а все остальные ее элементы есть параметры команды.
- полученная последовательность команды/параметров поступает в анализатор(самая большая часть парсера), где начинаются сравнения команды из CmdLine с конкретными значениями(При дроблении все обязательно переводится в верхний регистр). Например(реальный):
If (cmdline.strings[0]='QUIT') or (cmdline.strings[0]='EXIT') then
begin
SetStatus(STAT_EXITCODE); //Делаем статус программы на принудительный выход
result:=EC_CONSOLECMD; //Типа нужно для выхода из цикла консоли
fittoregion; //не столь важно
exit;
end;
...
//другие специфичные команды не укладывающиеся под шаблон исполнения
...
ExecuteCommand; //Исполняем команду
AddCmdHistory(cmd); //Добавляем ее в историю("консоль")
fittoregion;
ResetCommand; //Обнуляем команду: типа CMD:='';
Ну и самая тут главная процедура ExecuteCommand. Вот типа что там насчет "CONDUMP":
//------------------------------ CONDUMP -----------------------------
If cmdline.Strings[0]='CONDUMP' then
begin
//Если в команде отсутсвует параметр-имя файла, то динамим юзера нах
if cmdline.Count=1 then
begin
History.Add(getcmddesc('File_not_assigned'));
fittoregion;
ResetCommand;
exit;
end;
//если не указан точный путь к файлу, то по умолчанию будем его создавать
//в игровой папке "Logs", иначе по точному пути
If extractfilepath(cmdline.strings[1])='' then
tempstring:='Logs\'+cmdline.strings[1]
else tempstring:=cmdline.strings[1];
//Сохраняем всю историю команд в консоли.
History.SaveToFile(tempstring);
//пишем в консоль что успешно сохранили файл с листингом по такому-то пути в такой-то файл
History.Add(getcmddesc('Console_dumped_to_file')+uppercase(tempstring));
exit;
end;
Усе просто. Надо лишь всегда разделять большую задачу на несколько мелких и их уже выполнять. Главное написать правильное разделение команды от параметров(учитывая пробелы и множественные пробелы) и обязательно все в верхний регистр(или в нижний), чтобы не было гемора с сравнениями строк.
---
WBR, NailMan aka 2:5020/3337.13
FRick (2004-06-03 17:07:00) [8]>А зачем вообще одновременно писать и в консоль и в файл?
>Для сохранения консоли можно сделать команду, >например "CONDUMP" и навесить на нее сохранение того массива >строк который есть в консоли, напрямую в текстовый файло.
>А в файл имхо логично писать лог всех действий программы. >Точнее надо сделать так, чтобы логгинг настраивался, т.е. >командами консоли можно было включить/выключить логгинг каких->то действий(скажем логгинг загрузки текстур, создания объектов >и т.д.) .
Ты абсолютно прав!
Думаю всё надо делать через INI!
Я видел все твой примеры (очень понравились особенно GUI)
заметил что там многие значения не вбиты в EXE'шник
а аккуратно записаны в файлы и разложены по полочькам
и вобще у тебя всё по полочкам!
Я думаю что то что подразумевает комманда "CONDUMP" надо
повесить на выход из программы!
Я замети что все действия программы пишутся в UTLogging.txt
с фиксацией даты и времени что должно помочь при отладке!
Консоль я наладил скрестил два примера и забил туда каманды
работает, думаю что любая игра начинается с консоли!
И ещё я сделал чтобы при запуске стоял только Английский
язык!
Консоль я повесил на F12!
Как же наладить всё выше и выше перечисленное?
КиТаЯц (2004-06-03 14:05:00) [9]2 NailMan © (03.06.04 13:51) [18]
Респект! Согласен полностью. :)
NailMan (2004-06-03 13:51:00) [10]А зачем вообще одновременно писать и в консоль и в файл?
Для сохранения консоли можно сделать команду, например "CONDUMP" и навесить на нее сохранение того массива строк который есть в консоли, напрямую в текстовый файло.
А в файл имхо логично писать лог всех действий программы. Точнее надо сделать так, чтобы логгинг настраивался, т.е. командами консоли можно было включить/выключить логгинг каких-то действий(скажем логгинг загрузки текстур, создания объектов и т.д.) .
---
WBR, NailMan aka 2:5020/3337.13
КиТаЯц (2004-06-03 13:02:00) [11]
> FRick © (02.06.04 00:51) [14]
> Как наладить автозапись всего введенного консоли
> в файл например Console_log.txt я пробовал записывает только
> последний параметор а мне надо в столбик!
Если о моем примере говориш, то наверняка ты просто записываеш значение
ComNow: string;
а надо попорядку все из
ComCom: array [1..256] of string;
ну еще не забыть проверить на заполнение чтобы пустые строки не сохранялись.
FRick (2004-06-02 16:09:00) [12]Хороший линк думаю разберусь!
kerby (2004-06-02 15:31:00) [13]лови линк ;)
http://caperaven.co.za/gls/tutorials/documents/console/console.zip
FRick (2004-06-02 00:51:00) [14]Как наладить автозапись всего введенного консоли
в файл например Console_log.txt я пробовал записывает только
последний параметор а мне надо в столбик!
FRick (2004-06-01 22:46:00) [15]А нет всё разобрался Спасибо за помощь помог!
FRick (2004-06-01 21:29:00) [16]>Может забыл что... Ответь - заработало-нет, помогло-непомогло...
всё работает только текст не вводится
здесь я выложил архив (100kb)
посмотри что к чему:
http://coder-gls.narod.ru/index.html
NailMan (2004-06-01 09:45:00) [17]Соотвественно искомая функция TControlsManager.ScanKeyBoard.
---
WBR, NailMan aka 2:5020/3337.13
NailMan (2004-06-01 09:44:00) [18]
> Поделись кусочком кода, коим ты это делаешь...
http://www.cyborghome.ru/nailman/zakroma/sources/UTControls.pas
Мне лень было чего-то вырезать, только немного добавил чтобы модуль контрол манагера был полным.
---
WBR, NailMan aka 2:5020/3337.13
КиТаЯц (2004-06-01 07:58:00) [19]Эка сильно тебе консоль хочется ;)
Мне тоже сначала хотелось, а потом понял, что иначе ну никак без консоли нельзя, ну очень трудно отлаживать... Ну, да ладно. Держи кусок кривого кода. У меня работает.
const
com001: string = 'exit';
com002: string = 'quit';
com003: string = 'go';
com004: string = 'stop';
var
Console: boolean = False;
ComNow: string;
ComCom: array [1..256] of string;
public
HUDBack: TGLHUDSprite;
HUDText: TGLHUDText;
procedure TMainForm.FormResize(Sender: TObject); // это чтобу симпатично было
begin
if (HUDBack <> nil) then
with HUDBack do begin
Width := GLSceneViewer.Width;
Height := round(GLSceneViewer.Height/3);
Position.X:=round(GLSceneViewer.Width/2);
Position.Y:=round(GLSceneViewer.Height/6);
end;
end;
// а здесь типа рисуем консоль
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_ESCAPE then begin
if Console then Key := 192
else begin
Application.MainForm.Hide; close; // если консоль то убрать иначе выход
end;
end;
if Key = 192 then begin
Console:= not Console;
if Console then begin
GLCadencer.Enabled:= False;
HUDBack:= tglHUDSprite.Create(GLScene);
HUDBack:= tglHUDSprite(GLScene.Objects.AddNewChild(tglHUDSprite));
with HUDBack do begin
Width := GLSceneViewer.Width;
Height := GLSceneViewer.Height/3;
Position.X:=GLSceneViewer.Width/2;
Position.Y:=GLSceneViewer.Height/6;
Material.MaterialLibrary := GLMaterialLibrary;
Material.MaterialOptions:= [moIgnoreFog, moNoLighting];
HUDBack.Material.FrontProperties.Diffuse.Color:= clrDarkSlateGray;
//HUDBack.Material.FrontProperties.Diffuse.Color:= clrRed;
HUDBack.Material.BlendingMode := bmAdditive;
end; //with mt
HUDText:= tglHUDText.Create(GLScene);
HUDText:= tglHUDText(GLScene.Objects.AddNewChild(tglHUDText));
with HUDText do begin
Position.X:= 10; Position.Y:= 10;
BitmapFont := GlFont;
end; //with mt
end else begin
if HUDText <> nil then HUDText.Destroy;
if HUDBack <> nil then HUDBack.Destroy;
GLCadencer.Enabled:= True;
end;
end;
end;
// а здесь типа пишем текст
procedure TMainForm.FormKeyPress(Sender: TObject; var Key: Char);
var i: byte;
begin
if (not Console) then exit;
if Key = #13 then begin
if length(trim(ComNow)) = 0 then exit;
DoCommand(ComNow); // и выполняем команду
//HUDText.Text:=ComNow;
ComCom[high(ComCom)]:= ComNow;
HUDText.Text:=
ComCom[high(ComCom)-7]+#13
+ComCom[high(ComCom)-6]+#13
+ComCom[high(ComCom)-5]+#13
+ComCom[high(ComCom)-4]+#13
+ComCom[high(ComCom)-3]+#13
+ComCom[high(ComCom)-2]+#13
+ComCom[high(ComCom)-1]+#13
+ComCom[high(ComCom)]+#13
+'>';
for I:=1 to high(ComCom)-1 do ComCom[i]:=ComCom[i+1];
ComNow:= '';
end else begin
case Key of
'`','~': ComNow:=ComNow;
Char(VK_BACK): SetLength(ComNow, Length(ComNow)-1);
Char(VK_UP): ComNow:=ComCom[high(ComCom)];
else ComNow:=ComNow+Key;
end; //case
HUDText.Text:=
ComCom[high(ComCom)-8]+#13
+ComCom[high(ComCom)-7]+#13
+ComCom[high(ComCom)-6]+#13
+ComCom[high(ComCom)-5]+#13
+ComCom[high(ComCom)-4]+#13
+ComCom[high(ComCom)-3]+#13
+ComCom[high(ComCom)-2]+#13
+ComCom[high(ComCom)-1]+#13
+'>'+ComNow;
end;
end;
procedure TMainForm.DoCommand (InputText: string);
var TmpText: string;
begin
TmpText:= InputText;
InputText:= trim(AnsiLowerCase(InputText));
if InputText = com001 then Close
else if InputText = com002 then Close
else if InputText = com003 then GLCadencer.Enabled:= True
else if InputText = com004 then GLCadencer.Enabled:= False
// else if InputText = com005 then
// else if InputText = com006 then
// else if InputText = com007 then
else ComNow:= 'Unknow command: "'+TmpText+'"';
end;
Может забыл что... Ответь - заработало-нет, помогло-непомогло...
ПсихЪ (2004-05-31 22:28:00) [20]
> Все просто и тупо. Никаких извратов. Данные с клавы я беру
> директинпутом через немерянную функцию анализа введенной
> клавиши(включая рус/lat и шифт).
Поделись кусочком кода, коим ты это делаешь...