Как стать автором
Обновить
147
0.2

Пользователь

Отправить сообщение
Есть фирмы, где программу пишут один-два человека, и никаких систем контроля версий никто никогда не применял и не планирует применять.
И я инженер, а не программист или инженер-программист.
Дело в том, что программа от этого сокращается раза эдак в два (когда 2D). Кроме того, данная абстракция позволяет лучше понять суть производимых с координатами операций.


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

У меня работает


А у меня portable-версия не работает.
многие данные по смыслу являются векторами. Вот и работайте с ними, как с векторами.


А, вы не про std:vector. Тогда зачем координаты представлять векторами?
Им не надо «учиться» пользоваться. Надо просто начать и выучить две команды — git commit и git push. Ну хорошо, один раз будет нужно сделать git init


Я чтобы попробовать поставил git отдельно на компьютер и скачал книжку. Так вот, не получилось. В книжке написано — сделайте git add *.cc. Хорошая идея. Только вот как добавить несколько проектов? Как добавить папку? Не написано в той главе, где упоминается git add. А git clone вызывало ошибку kerlen322.dll — у меня Windows XP, а оно, которое скачанное, желает как минимум висту.

По этим ужасным простыням кода низкого качества, в котором отсутствует функциональное деление, использование констант и логичное именование переменных.


По-моему, всё это есть как в этом коде, так и в коде остальных статей. Констант, конечно, нет. Я всё-таки предпочитаю define. Но уж именование переменных и функциональное деление там точно есть.

Разбивка простыней на части помогает их структурировать.


Не соглашусь. От множества мелких функций будет в глазах рябить.

многие данные по смыслу являются векторами. Вот и работайте с ними, как с векторами.


Для шахмат такого лучше не делать. В движке это сделано и так. А эта программа порт с PSP и там я точно их не использовал, потому как, помнится, компилятор там был использован C, а не C++.

а не продираться через x1; x2; dx; и прочее.


Но в данном случае как раз x1,x2 и dx очень даже содержательны. x1;y1-начальные координаты, dx-размер по x.
Исключение составляют функции текстурирования в 2.5D движке — им 15 лет и я тогда написал именно так, а разбираться заново стало лень. Там действительно t1-индекс внутри текстуры, x1-координата, ну и т.д.

4)константные данные следует помещать в const, а не толкать в дефайны.


Не люблю глобальные переменные. А вот define смотрится органично и находится в тексте очень легко — большие буквы. А недостатки есть у многих вещей, но это не повод от них отказываться.
Не, я только косынку умею играть. Научил друг в далёком 2004 году. С тех пор и играю. :)
Кстати, сапёр у меня тоже есть самодельный. Может, и по нему какую-нибудь статью напишу. Вдруг кому столь простые игры интересны будут.
Надо же, кому-то не понравился этот мой комментарий. :) Удивительно.
А про шахматы у меня статья уже была. :) Вот эта.
Золотые времена! :)
В штатном видеорежиме спектрума или в каком-то своём у профи? В штатном должно хватать скорости на асме — там спрайт ведь небольшой.
Знаю. Но пока не научился им пользоваться. И вряд ли скоро научусь…
UPD. Прошу прощения, пока редактировал текст под макросы, сделал ошибку в функции MoveCard — цикл не до 52, а до 53 должен быть. А я чего-то решил, что правильно всё-таки до 52. Нет. :) Архив перезалит.

Скачавшие старую версию не смогут её выиграть — там из-за этой ошибки теряется карта,
А разве у нас не три разных по физике масс, которые константами и системой единиц приведены в единство? Гравитационная (F=G*M1*M2/R^2), инертная (F=ma) и та, что в E=m*c^2.
А на этот вопрос какой ответ? :)
Это который от Сильвермана — Build. Это легендарный 100%. Shadow Warrion, Blood, Duke Nukem 3D.

Но к этой статье приложен не он, а самодельный, гораздо менее мощный.
И вот что меня удивляет. 20 лет, как вышел Duke 3D. Армия программистов. А движков самодельных (хоть с OpenGL, Direct 3D, хоть сотфверных) сделано очень мало. Как так-то? Вообще странно, столько программистов, а весь инет не завален их интересными программами (например, графическими). То ли они пишут только на работе, а дома нет, то ли ещё есть какая причина, но при таком количестве программистов их программ должно быть сильно дофига.
Так это ж самая очевидная схема работы с порталами. :) Я сперва именно геометрический портал и сделал. А потом, много позже, сообразил, что можно по экрану отсекать в случае, когда стены не могут наклоняться влево-вправо. В общем, для Wolf-3D под OpenGL геометрический портал просто идеален. Только надо при выводе стен не выводить одну и ту же стенку дважды (делать отметку о том, что стена уже выведена) и выводить не фрагмент, видимый через портал, а всю стену сразу. Так же и с персонажами и прочими объектами — выводить только из тех секторов-квадратов, которые были выведены через портал и заодно можно проверить, что объекты вообще видны в портал (описать прямоугольник вида сверху вокруг объектов и сравнивать его попадание в портал).
Конвертировал вот такой вот функцией в редакторе 3DEngineEditor. Карта задаётся в текстовом файле:'#'-стена.

//---------------------------------------------------------------------------
//импорт карты из текстового файла
//---------------------------------------------------------------------------
void CDocument_Map::ImportMapFromTXT(FILE *file,CDialog_SettingsWall *cDialog_SettingsWall_Ptr,CDialog_SettingsSector *cDialog_SettingsSector_Ptr)
{
 long n;
 DeleteAll();
 //считываем текстовый файл в плоский массив (0-следующая строка)
 vector<unsigned char> vector_data;
 bool element=false;
 long x=0;
 long y=0;
 long max_x=0;
 while(1)
 {
  unsigned char b;
  if (fread(&b,sizeof(char),1,file)<=0) break;//файл закончился
  if (b<static_cast<unsigned char>(' '))
  {
   if (element==true)//если в строке что-то было считано, делаем перевод строки 
   {
    y++;
    vector_data.push_back(0);
   }
   element=false;
   if (x>max_x) max_x=x;
   x=0;//строка начинается заново
   continue;
  }
  element=true;
  x++;
  vector_data.push_back(b);
 }
 long max_y=y;
 //разворачиваем считанную карту в двумерный массив [max_y][max_x] и заполняем его точками
 vector< vector<unsigned char> > vector_map(max_y,vector<unsigned char>(max_x,'.'));
 x=0;
 y=0;
 long size=vector_data.size();
 for(n=0;n<size;n++)
 {
  if (vector_data[n]==0 || n==size-1)
  {
   y++;
   x=0;
   continue;
  }
  if (vector_data[n]==static_cast<unsigned char>('#')) vector_map[max_y-y-1][x]=static_cast<unsigned char>('#');//непустое поле
  x++;
 }
 vector_data.clear();
 //создаём сектора и сегменты по считанной карте
 CSector cSector_Create;//создаваемый сектор
 cSector_Create.vector_SSectorPoint.clear();
 cSector_Create.Select=false;
 cSector_Create.sSector_State=cDialog_SettingsSector_Ptr->GetState();
 CWall cWall_Create;//создаваемая стена
 cWall_Create.Frontier=false;
 cWall_Create.Select=false;
 cWall_Create.sWall_State=cDialog_SettingsWall_Ptr->GetState();
 for(y=0;y<max_y;y++)
 {
  for(x=0;x<max_x;x++)
  {
   unsigned char b=vector_map[y][x];
   if (b==static_cast<unsigned char>('.'))//сектор пустой
   {
    //создаём пустой сектор
    cSector_Create.vector_SSectorPoint.clear();
    //добавляем точки четырёхугольника, описывающего сектор
    SSectorPoint sSectorPoint[4];
    sSectorPoint[0].X=(x+1)*100;
    sSectorPoint[0].Y=(y+1)*100;
    sSectorPoint[1].X=(x+1)*100;
    sSectorPoint[1].Y=(y+0)*100;
    sSectorPoint[2].X=(x+0)*100;
    sSectorPoint[2].Y=(y+0)*100;
    sSectorPoint[3].X=(x+0)*100;
    sSectorPoint[3].Y=(y+1)*100;

    cSector_Create.vector_SSectorPoint.push_back(sSectorPoint[0]);
    cSector_Create.vector_SSectorPoint.push_back(sSectorPoint[1]);
    cSector_Create.vector_SSectorPoint.push_back(sSectorPoint[2]);
    cSector_Create.vector_SSectorPoint.push_back(sSectorPoint[3]);
    //добавляем сектор в список секторов
    vector_CSector.push_back(cSector_Create);
	//если вокруг сектора есть стектора-стены, то добавляем стену, иначе добавляем линию раздела
	for(n=0;n<4;n++)
	{
     long next_n=(n+1)%4;
     cWall_Create.X1=sSectorPoint[n].X;
     cWall_Create.Y1=sSectorPoint[n].Y;
     cWall_Create.X2=sSectorPoint[next_n].X;
     cWall_Create.Y2=sSectorPoint[next_n].Y;
     cWall_Create.Frontier=true;//стена - линия раздела
	 if (n==0)//правая стена
	 {
      if (x<max_x-1)
	  {
       if (vector_map[y][x+1]!=static_cast<unsigned char>('.')) cWall_Create.Frontier=false;//сектор справа - стена
	  }
	  else cWall_Create.Frontier=false;
	 }

	 if (n==1)//нижняя стена
	 {
      if (y>0)
	  {
       if (vector_map[y-1][x]!=static_cast<unsigned char>('.')) cWall_Create.Frontier=false;//сектор снизу - стена
                                                           else continue;//не ставим портал, так как он уже есть с этой стороны
	  }
	  else cWall_Create.Frontier=false;
	 }

	 if (n==2)//левая стена
	 {
      if (x>0)
	  {
       if (vector_map[y][x-1]!=static_cast<unsigned char>('.')) cWall_Create.Frontier=false;//сектор слева - стена
	                                                       else continue;//не ставим портал, так как он уже есть с этой стороны
	  }
	  else cWall_Create.Frontier=false;
	 }

	 if (n==3)//верхняя стена
	 {
      if (y<max_y-1)
	  {
       if (vector_map[y+1][x]!=static_cast<unsigned char>('.')) cWall_Create.Frontier=false;//сектор сверху - стена
	  }
	  else cWall_Create.Frontier=false;
	 }
	 //добавляем сегмент
     vector_CWall.push_back(cWall_Create);
	}
   }
  }
 }
}
Всё, понял в чём дело. В функции конвертации карты из Wold-3D создавался двойной набор порталов. Вот оно и дико тормозило. Исправил — и всё заработало на ура. :) Не такая уж там и большая рекурсия, даже без объединения квадратов.

Попробовал конвертировать карту типа Wolf-3D. Получилось плохо и вот почему: если каждую клетку назначить сектором с порталами в 4 стороны (или меньше — со стороны блоков-стен нужно поставить стену, а не портал), то при рекурсивном обходе порталов в некоторых зонах начинаются тормоза (вплоть до FPS=0). Фишка в том, что раз сектора мелкие, обход через все порталы всех остальных порталов и секторов вырождается в здоровенную рекурсию. То есть, вот так втупую лабиринт из Wolf-3D с порталами не подружить. Нужно как-то объединять сектора в один большой сектор, не создавая порталов.
Совсем забыл случай, когда стена пересекает прямую области видимости. В этом случае я просто обрезаю стену областью видимости так, чтобы она была со стороны игрока.
Спасибо. :) Ну, значит, MIT. :)

Правда, не знаю, кому эти исходники пригодиться вообще могут. Мне тут на одном форуме сказали, фигурально, что я фигнёй страдаю с софтверными движками и обычным OpenGL. И что давно вместо «forward rendering» используют Deferred Rendering и надо брать готовый движок типа Ogre3d и не изобретать велосипед. :) И я в общем, почти согласен с первым, но вот со вторым не соглашусь — зачем мне Ogre3D, если я игру делать всё равно не буду. :)

Информация

В рейтинге
2 860-й
Откуда
Санкт-Петербург и область, Россия
Зарегистрирован
Активность