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

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

GLScene как сделать консоль!! [Delphi, Windows]


Страницы:   1 2

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 и шифт).

Поделись кусочком кода, коим ты это делаешь...


Страницы:   1 2

Наверх

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