Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.02.2009, 23:25   #11
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Цитата:
Сообщение от Манжосов Денис :) Посмотреть сообщение
В 4 посте есть такой код:
Код:
function keypressed(key: byte): boolean;
var
  keys: TKeyboardState;
begin
  result:=false;
  GetKeyboardState(keys);
  if(keys[key]=128)or(keys[key]=129)then result:=true;
end;
Мне не понятен смысл этой строчки кода:
Код:
if(keys[key]=128)or(keys[key]=129)then result:=true;
Объясните, пожалуйста.
TKeyboardState = array[0..255] of Byte;
function GetKeyboardState(var: KeyState: TKeyboardState);

Копиpует состояние клавиш виpтуальной клавиатуpы в KeyState. Если стаpший бит байта pавен 1, клавиша нажата. Если младший бит байта pавен 1, то с момента запуска системы клавиша нажималась нечетное число pаз.

function keypressed(key: byte): boolean;
var
State:TKeyboardState;
begin
GetKeyboardState(State);
Result:=((State[key] and 128)<>0);
end;

and в этом случае не логический оператор а побитовый. Если непонятно именно это, почитай про побитовые операции.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 05.02.2009 в 23:33.
mutabor вне форума Ответить с цитированием
Старый 06.02.2009, 13:54   #12
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
128 и 129 - код что клавиша с номером key нажата, а почему два значения? ...это учет четных и нечетных нажатий, т.е. после каждого нажатия код этот меняется поочередно то 128, то 129. Так же и на отпущенные клавиши, то 0 говорит о неактивности, то 1.


Ну дело в том, что тема эта гораздо обширнее станет по-видимому, и название обобщающее как нельзя кстати, надеюсь ты не против как автор темы?, да и сама цель наверное не ведет к простому интересу над кодом, в конце концов я думаю будет и итог - какая-нибудь аркадная игрушка.

Да конечно не против, к тому же капитан здесь вы, а главное результат а не название...
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Старый 06.02.2009, 16:23   #13
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

Здравствуйте не знаю правильно ли я делаю задавая еще один вопрос в этой же теме, просто она тоже касается коллизий. Собственно интересует такой вопрос: как определить столкновение с полигоном в opengl? т. е скажем иметься у меня полигон или треугольник (не важно)
с координатами:


Код:
  glBegin(GL_QUADS);
  glTexCoord(0, 0);         glVertex3f(9.0, -10.1,-4.8);
  glTexCoord(1.0,0.0);     glVertex3f(13.0,-10.1,-4.8);
  glTexCoord(1.0, 1.0);    glVertex3f(13.0,-10.1, 2.0);
  glTexCoord(0.0, 1.0);    glVertex3f(9.0, -10.1, 2.0);
  glEnd;
(с наложенной текстурой)
Процедура камеры:

Код:
procedure Camera;
var
   Look, Up: TVector;
   X, Y: Single;
begin
   X := plus* Sin(Rad(a));
   Y := plus * Cos(Rad(a));
   glLoadIdentity;
   Look := GetLookVector(normal, a - 180);
   Up := GetVector(0, 0, 1);
   gluLookAt(X, Y, upcam,
             Look.X + X, Look.Y + Y, Look.Z + upcam,
             Up.X, Up.Y, Up.Z);
   a := a +0.20;
   if a >= 360 then a := 0;
end;
Обработка клавиатуры:

Код:
   if Key = 187 {-} then begin
   plus:=plus-1;
   end;

   if Key = 189 {+} then begin
   plus:=plus+1;
   end;

   // Камера выше
   if Key = 38 {+} then begin
   upcam:=upcam+1;
   end;

   // Камера ниже
   if Key = 40 {+} then begin
   upcam:=upcam-1;
   end;
Я предполагаю что для того чтобы определить столкновение нужно проверять координаты всех вершин нашего объекта (квадрата, полигона, треугольника) или я ошибаюсь, и как это можно сделать? видел готовые исходники примеров коллизий но там что уж больно сложно мне бы сам принцип понять а не в чужом коде разбираться..Спасибо.
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Старый 07.02.2009, 00:12   #14
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Подробно по универсальной системе (1)

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

Вот что-то соорудил довольно простое, ...основа - интерпретация реального положения объектов в координаты на экране, через смещения. Вначале нужен тип объектов, универсальный, вот он:
Код:
// тип модели персонажей
Type
  TUnit = packed record
  //-----------------
  UTexture: TBitmap;     // текстура
  UTexPos:  TBitmap;     // текстура точного позиционирования (не обязательна)
  UH:       Byte;        // высота
  UW:       Byte;        // ширина
  UPosX:    Byte;        // позиция по-X
  UPosY:    Byte;        // позиция по-Y
  UOldPosX: Byte;        // старая позиция по-X
  UOldPosY: Byte;        // старая позиция по-Y
  UMoveX:   ShortInt;    // предел смещения по-X
  UMoveY:   ShortInt;    // предел смещения по-Y
  UDispX:   ShortInt;    // смещение по-X
  UDispY:   ShortInt;    // смещение по-Y
  USpeedY:  real;        // скорость по-Y
  UJump:    Boolean;     // прыжок
  //-----------------
end;
...как обычно нужен массив, чтобы хранить каждый объект в отдельности со всеми его наворотами:
Код:
UnitMas: array[0..1] of TUnit;            // список юнитов
...обойдемся двумя игроками. Вот так можно подготовить данные о каждом объекте (на примере одного):
Код:
With UnitMas[0] do                        // объект 1
    begin
      UTexture := TBitmap.Create;
      UTexture.LoadFromFile('pers1.bmp');   // текстура
      UW := UTexture.Width;                 // ширина
      UH := UTexture.Height;                // высота
      UTexPos := TBitmap.Create;
      UTexPos.LoadFromFile('perspos1.bmp'); // текстура позиции
      UPosX := 1;                           // позиция по-X
      UOldPosX := UPosX;
      UOldPosY := UPosY;
    end;
Карта создается аналогичным образом, что здесь уже выше был показан. Опрос клавиатуры выглядит вот так:
Код:
// опрос клавиатуры
  // если кнопка "D", смещение для объекта 1
  if keypressed(68) then UnitMas[0].UDispX := 2;
  // если кнопка "A", смещение для объекта 1
  if keypressed(65) then UnitMas[0].UDispX := -2;
  // если кнопка "W", смещение для объекта 1
  if keypressed(87) then UnitMas[0].UJump := true else UnitMas[0].UJump := false;

  // если кнопка "вправа", смещение для объекта 2
  if keypressed(39) then UnitMas[1].UDispX := 2;
  // если кнопка "влево", смещение для объекта 2
  if keypressed(37) then UnitMas[1].UDispX := -2;
  // если кнопка "вверх", смещение для объекта 2
  if keypressed(38) then UnitMas[1].UJump := true else UnitMas[1].UJump := false;
Вот сам гвоздь программы:
Код:
// общий механизм позиционирования

          // перемещение объекта по-горизонтали
          UMoveX := UMoveX + UDispX;
          // условие перехода на следующую клетку, cell - размер клетки
          if (UMoveX > (cell div 2)) or (UMoveX < -(cell div 2))  then
            begin
              // восстанавливаем проход в клетку
              MapMas[UOldPosX,UOldPosY].GMove := 0;
              // текущая позиция меняется (на единицу)
              UPosX := UPosX + (UDispX div 2);
              // записываем в клетку запрет на проход
              MapMas[UPosX,UPosY].GMove := 1;
              // запись текущей клетки
              UOldPosX := UPosX;
              // смещение
              if UDispX < 0 then UMoveX := (cell div 2) - 2;
              if UDispX > 0 then UMoveX := -(cell div 2) + 2;
            end;
          // обнуление смещения
          UDispX := 0;

          // расчет смещения (от скорости)
          UDispY := Round(USpeedY);
          // перемещение объекта по-вертикали
          UMoveY := UMoveY + UDispY;
          // условие перехода на клетку ниже, cell - размер клетки
          if (UMoveY > (cell div 2)) or (UMoveY < -(cell div 2)) then
            begin
              if UDispY < 0 then                // смещение вверх
                begin
                  // восстанавливаем проход в клетку
                  MapMas[UOldPosX,UOldPosY].GMove := 0;
                  // текущая позиция меняется (на единицу)
                  UPosY := UPosY - 1;
                  // запись текущей клетки
                  UOldPosY := UPosY;
                  UMoveY := (cell div 2) - 2;
                end;
              if UDispY > 0 then                // смещение вниз
                begin
                  // восстанавливаем проход в клетку
                  MapMas[UOldPosX,UOldPosY].GMove := 0;
                  // текущая позиция меняется (на единицу)
                  UPosY := UPosY + 1;
                  // запись текущей клетки
                  UOldPosY := UPosY;
                  UMoveY := -(cell div 2) + 2;
                end;
            end;
Продолжение следует ...
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 07.02.2009, 00:17   #15
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Подробно по универсальной системе (2)

Продолжение ...

Вот так идет отрисовка:
Код:
// отрисовка объекта в буфер (тоже бессовестным образом)
          BitBuf.Canvas.Draw(UPosX*cell             // точные координаты на экране по-X
                             +(cell div 2)          // плюс смещение на центр клетки
                             -(UW div 2)            // минус смещение на полширины объекта
                             +UMoveX,               // плюс смещение на пикселы (движение)
                             UPosY*cell             // точные координаты на экране по-Y
                             +(cell div 2)          // плюс смещение на центр клетки
                             -(UH div 2)            // минус смещение на полвысоты объекта
                             +UMoveY,               // плюс смещение на пикселы (движение)
                             UTexture);

          // отрисовка точных координат в массиве карты (не обязательное и бессовестное)
          BitBuf.Canvas.Draw(UPosX*cell, UPosY*cell, UTexPos);
Что касается обработки столкновений, это просто не выполнить, я написал несколько условий, они банальны и просты по сути, но все варианты не предусматривают, очевидно применение кругового опроса клеток карты, но это посложнее будет, я не стал убивать время, попробуй сам, если что помогу. А это то что есть:
Код:
// проверка на столкновение справа по уровню 0
          if ((MapMas[UPosX+(UW div cell),UPosY].GMove = 1)
              and (UMoveX >= (UW div 2 - cell))) or (UPosX > 38) then
            begin
              if UDispX > 0 then UDispX := 0       // нет смещения
            end;

          // проверка на столкновение слвева по уровню 0
          if ((MapMas[UPosX-(UW div cell),UPosY].GMove = 1)
              and (UMoveX <= -(UW div 2 - cell))) or (UPosX < 1) then
            begin
              if UDispX < 0 then UDispX := 0       // нет смещения
            end;

          // проверка на столкновение справа
          if ((MapMas[UPosX+(UW div cell),UPosY-(UH div cell)].GMove = 1)
              and (UMoveX >= (UW div 2 - cell))) or (UPosX > 38) then
            begin
              if UDispX > 0 then UDispX := 0       // нет смещения
            end;

          // проверка на столкновение слвева
          if ((MapMas[UPosX-(UW div cell),UPosY-(UH div cell)].GMove = 1)
              and (UMoveX <= -(UW div 2 - cell))) or (UPosX < 1) then
            begin
              if UDispX < 0 then UDispX := 0       // нет смещения
            end;

          // проверка на "пол под ногами"
          if (MapMas[UPosX+1,UPosY+1].GMove <> 1) and (MapMas[UPosX-1,UPosY+1].GMove <> 1) then
            begin
              USpeedY := USpeedY + G;              // скорость по-Y нарастает
            end
          else
            begin
              USpeedY := 0;                        // скорость на ноль
              UMoveY := (cell div 2) - (UH div 2); // смещение на низ
              // если нужно прыгать, то скорость прыжка
              if UJump then USpeedY := -6;
            end;

          // проверка на "потолок"
          if (MapMas[UPosX+1,UPosY-1].GMove = 1) or (MapMas[UPosX-1,UPosY-1].GMove = 1) then
            begin
              USpeedY := 2;              // скорость вниз от удара
              USpeedY := USpeedY + G;    // скорость по-Y нарастает
            end;

Исходник в архиве.
Вложения
Тип файла: zip Аркада.zip (11.0 Кб, 14 просмотров)
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 07.02.2009 в 00:25.
Beermonza вне форума Ответить с цитированием
Старый 07.02.2009, 01:35   #16
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

Большое вам спасибо за столь ясный и обстоятельный ответ, или хотя бы за то что не пожалели своего времени. Но при беглом просмотре (!) (сейчас уже довольно поздно) сразу возникает пару вопросов:

1)
Цитата:
// текстура точного позиционирования (не обязательна)
постарался это делать исправить самым бессовестным образом ) просто закомментировав. но объект маленький квадратик перестал двигаться..


Код:
With UnitMas[1] do                        // объект 2
    begin
   {   UTexture := TBitmap.Create;
      UTexture.LoadFromFile('pers2.bmp');   // текстура
      UW := UTexture.Width;                 // ширина
      UH := UTexture.Height;      }          // высота
      UTexPos := TBitmap.Create;
      UTexPos.LoadFromFile('perspos2.bmp'); // текстура позиции
      UPosX := 38;                          // позиция по-X
      UOldPosX := UPosX;
      UOldPosY := UPosY;
    end;
Кто же из двух кубиков "главный герой"? я так понял что большой?

2) Еще не понятно как увеличить объект в нашем случаи игрок, но не размер клетки, т. е фон как был 20 на 20 так он и должен быть, а игрок скажем 70 на 70? (постораюсь разобраться сам)

3) еще один момент: например самая нижняя полка, идете туда синим игроком и упираетесь в нее, далее не отпуская клавишу (стрелку) лево нажимаете стрелку верх и он заскакивает под полку и по моему прекрасно себя там чувствует) не смотря на то что там "1". Но это все мелочи..

А вообще есть чему поучиться, конечно, еще раз спасибо.
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Старый 07.02.2009, 14:54   #17
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Не стоит благодарности, мы все чему-то у кого-то учились, это все в порядке вещей, тем более на форуме все как кореша.

По вопросам:
1) Да, главный - большой, ...просто отправь в комментарий вот эту строчку в отрисовке:
Код:
BitBuf.Canvas.Draw(UPosX*cell, UPosY*cell, UTexPos);
...из модели не убирай, оно еще пригодится, когда будешь работать над столкновениями.
2) Размер увеличивается банально просто - меняем размер bmp-файла и он сам "освоится" в игре. К сожалению пока не отработана система столкновений не все проходит гладко, но перемещение стабильное и правильное.
3) На этом я вообще не заострял внимание, пролез и пролез, сродни Марио как пыж влетел в узкий проход и только прыжками может продвигаться присев )

Версия просто показательно-обучающая. Очень легко ставить объекты, создавать карты, подгружать новые по ходу игры, если немного разобраться с условиями коллизий, то можно легко имитировать поведение знаменитого персонажа из древней 8-битной игрушки "Черный Плащ", он снизу прыжком цепляется за полочку, еще один прыжок и он на полке. Как-то вот так.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 07.02.2009, 17:27   #18
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Не стоит благодарности, мы все чему-то у кого-то учились, это все в порядке вещей, тем более на форуме все как кореша.
Без комментарий, как говориться пять баллов.

Цитата:
2) Размер увеличивается банально просто - меняем размер bmp-файла и он сам "освоится" в игре. К сожалению пока не отработана система столкновений не все проходит гладко, но перемещение стабильное и правильное.
Это первое что пришло мне в голову, но вот те полки, что выше самого игрока - срабатывают на столкновение, а вот на рис....

Цитата:
3) На этом я вообще не заострял внимание, пролез и пролез, сродни Марио как пыж влетел в узкий проход и только прыжками может продвигаться присев )
Собственно поэтому это мелочи, хотя про Марио совсем как то забыл.


И последняя проблема что меня беспокоит это то что не получается читать "карту" с массива. пытался использовать конструкцию которая использовалась ранее


Код:
var
  f: TextFile;
  x,y: integer;
begin
  sx:=0; sy:=0;
  AssignFile(f,'1.txt');
  Reset(f);
  for y:=1 to 16 do
    for x:=1 to 31 do
    begin
      if x<31 then
        read(f,map[x,y])
      else
        readln(f,map[x,y]);
      if map[x,y]='2'then
      begin
        map[x,y]:='0';
        xp:=x*30; yp:=y*20;
      end;
   
    end;
  CloseFile(f);
Естественно вместо map[x,y], MapMas[x,y] не подставишь, ибо вы, на сколько понимаю свой тип объявили, а как его прикрутить к выше указанному коду, что то не могу сообразить..
Изображения
Тип файла: jpg 1.jpg (28.1 Кб, 103 просмотров)
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Старый 07.02.2009, 20:09   #19
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Сразу по поводу рисуночка в архиве, будет что-угодно пока нет четкой системы коллизий )
По поводу заполнения карты, мой тип содержит пакованные записи, одна из них - TBitmap текстура, другая - Byte проходимость. Нужно после записи массива MapMas[x,y] написать точечку, будет два варианта, соответственно нужно выбрать GMove - это проходимость. Соответственно если нужно записать стену, то вот так:
Код:
MapMas[x,y].GMove := 1;
Обрати внимание, в выше указанной загрузке массив строкового типа, у меня числового, вот немножко не помню переделает Delphi автоматом байт данных файла в число, если код байта является числом... попробуй.

Послесловие... вопросов может быть сколько-угодно, для того и нужен форум, и в частности отдельная тема.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 07.02.2009 в 20:13.
Beermonza вне форума Ответить с цитированием
Старый 07.02.2009, 20:53   #20
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

Цитата:
Обрати внимание, в выше указанной загрузке массив строкового типа, у меня числового, вот немножко не помню переделает Delphi автоматом байт данных файла в число, если код байта является числом... попробуй.
На этом этапе (в смысле я вижу что там char) проблем нет собственно, что делал я:

Код:
var 
  f: file of byte;
begin

 AssignFile(f,'1.txt');
  Reset(f);
    for y:=1 to 28 do
    for x:=1 to 39 do
    begin
        read(f,mapmas[x,y].GMove);
  if mapmas[x,y].GMove=1 then
              MapMas[x,y].GTexture := brg;
          MapMas[x,y].GMove := 1;
         counts:=counts+1;
      if mapmas[x,y].GMove=0 then
      begin
 MapMas[x,y].GTexture := wall;
              MapMas[x,y].GMove := 0;
      end;
    end;

  CloseFile(f);
Понимаю что не правильно, т. к нет нечего.
(точнее что есть я показываю в рис.)
И вот вопрос тогда как должен выглядеть файл, с которого читаем сейчас он имел вид:

00000000000000000000000000000000000 00..n
00000000000000011111000000000000000 00..n
..............n

Что-то сомневаюсь в правильности..
Изображения
Тип файла: jpg 2.jpg (82.2 Кб, 103 просмотров)
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
collision detection challengerr Gamedev - cоздание игр: Unity, OpenGL, DirectX 5 10.01.2009 20:53
Нужна помощь!!)) ТРОЯН=) Паскаль, Turbo Pascal, PascalABC.NET 2 29.12.2008 21:42
Нужна помощь BreeZe Помощь студентам 1 14.05.2007 21:38