Проект 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. Ни на какие титулы "идеального кода" не претендуем :)
Вот и все... Вообще, само поведение блока мне понравилось, и, возможно, буду доводить эту дему "до ума", из этого вполне может выйти неплохая мини-игрушка.
Так что качаем или апдейтимся, компилируем, запускаем и тестим! Для меня главное - отзывы по поводу управления: насколько удобно или неудобно карабкаться и прыгать...