Проект glVehicles не заброшен! Согласен, известий не было давно, демками не пополнялась длительное время. И вот недавно я взял себя в руки и решил сконструировать что-нибудь полноценное, играбельное. Ведь, как мне показалось, многих отталкивает debug-отрисовка физических объектов. Всем хочется сразу красивых спрайтов и "рюшечек". Рисовать самому или просить кого-то сделать несколько спрайтов для бесплатной демки с открытым кодом - как-то не хотелось. Наткнулся на этот арт и сразу родилась идея для демки. Сделалось быстро, а вот написать это сообщение, руки дошли только сейчас. |
Придумался мне платформер, где главный герой - квадратик, смешно скачет, прыгает, карабкается. В ходе разработки демки показались стильными "залипания" на стенах, которые в конечном итоге переродились в способ пропрыгивания по вертикальным стенкам. Fun, fun, fun...
В динамике это выглядит так:
Немного пробегусь по коду...
По сути самое важное, что добавилось, так это проверка на наличие контакта со стенами. Сама проверка, конечно же, находится в callback'е физики:
procedure OnProceedContactCallBack(AContactData: Pb2_ContactListenerCallBackData); cdecl;
где можно найти саму проверку на контакт с игроком:
if(UserDataB = frmDemo9.fPlayer)then if (UserDataA <> nil) and not (TObject(UserDataA) is TStar) then begin if AContactData^.ContactType = 0 then frmDemo9.fPlayerContacts := frmDemo9.fPlayerContacts + 1 else if AContactData^.ContactType = 2 then frmDemo9.fPlayerContacts := frmDemo9.fPlayerContacts - 1; frmDemo9.fContactTime := cst_ContactTime; end;
Сама отрисовка объектов происходит наипримитивнейшим образом, а именно пробегаемся по списку всех физических объектов и "кастуем" по типу объекту из UserData... вот как это происходит в OnDirectRender():
for i := 0 to fb2BodyList.ObjectsCount - 1 do begin obj := fb2BodyList.GetObjectByIndex(i); if obj.GetBodyUserData = nil then continue; if obj.GetBodyUserData = fNormalBlock then begin pos := fViewer.Buffer.WorldToScreen(obj.Position); fNormalBlock.Position.x := pos[0] + 1; fNormalBlock.Position.y := fViewer.Height - pos[1] - 3; fNormalBlock.Render(rci); end; if (obj.GetBodyUserData = fDynamicBox) or (obj.GetBodyUserData = fPlayer) then begin ... end; if obj.GetBodyUserData = fLeftRampBlock then begin ... end; if obj.GetBodyUserData = fRightRampBlock then begin ... end;
Код, конечно, можно было и почище сделать, объединив похожие блоки в один. Но это просто демка, показывающая возможности Delphi, GlScene и Box2d. Ни на какие титулы "идеального кода" не претендуем :)
Вот и все... Вообще, само поведение блока мне понравилось, и, возможно, буду доводить эту дему "до ума", из этого вполне может выйти неплохая мини-игрушка.
Так что качаем или апдейтимся, компилируем, запускаем и тестим! Для меня главное - отзывы по поводу управления: насколько удобно или неудобно карабкаться и прыгать...
А где следующий пост?
ОтветитьУдалитьНедавно приступил к изучению box2d. Скачал исходники с репозитория. Так как использую другой граф. движок, то у Вас взял только b2Physics.pas.
ОтветитьУдалитьОтрисовка debug проходит на ура, т.к. отрисовываются полигончики. Но вот с отрисовыванием примитивов по координатам и углу поворота незаладилось. Если координаты и совпадают, то углы поворота какие стремные. У Вас нет случаем простейшего примерчика на чистом ogl?
Антон, привет!
ОтветитьУдалитьЯ на чистом ogl к сожалению не программирую.
Если хочешь, можешь скинуть мне свою демку с багом - я по возможности посмотрю, может чем-то смогу помочь.
Вообще, для Delphi также существует трансляция box2d, можно посмотреть здесь:
http://box2d.org/forum/viewtopic.php?f=17&t=4764
Вроде там есть рабочий тест-бед.