14 февраля 2010 в 15:23
Blitz3d уроки - 7. Родительская зависимость
В этой главе мне бы хотелось рассказать о том что такое привязки, и что с ними можно делать. Начнём сразу с примера. Да возьмём один из прошлых – помните, когда мы поворачивали кубик?
Graphics3D 640,480,16,1 SetBuffer BackBuffer() lit=CreateLight() cub=CreateCube() ScaleEntity cub,1,.5,2 cam=CreateCamera() PositionEntity cam,0,5,-10 pln=CreatePlane() tex=LoadTexture("Picture.bmp") ScaleTexture tex,10,10 EntityTexture pln,tex PositionEntity pln,0,-1,0 Repeat If KeyDown(200) MoveEntity cub,0,0,.1 If KeyDown(208) MoveEntity cub,0,0,-.1 If KeyDown(203) TurnEntity cub,0,1,0 If KeyDown(205) TurnEntity cub,0,-1,0 UpdateWorld RenderWorld Flip Until KeyHit(1) End
В общем-то ничего не изменилось, мы только поставили плоскость внизу, и (зачем-то) создали камеру ПОСЛЕ создания куба.
Хорошо, теперь кое-что изменим. Представим, например, что мы делаем какую-нибудь игру с видом от третьего лица. Тогда нам надо, чтобы камера двигалась вместе с кирпичом – вернее сзади него. Сделайте вот что - замените простую строчку создания камеры на:
cam=CreateCamera(cub)
Какая-то хитрая строчка… вроде ничего не изменилось, кроме того, что мы поставили в скобки переменную созданного нами куба. В этом и весь фокус! Когда мы создаём какой-то объект, и в скобках ничего не указываем, объект создаётся свободным, а если мы что-то укажем – объект становится зависимым от другого объекта, указанного в скобках – в данном случае это куб. Немного расскажу об этой зависимости:
Значит так, во-первых свободный, непривязанный ни к чему объект создаётся в точке 0,0,0 относительно мировой системы координат. Объект же, привязанный таким образом к другому объекту - родителю, создаётся в той точке, где находится его родитель. Второе – все команды которые писались раньше относительно мировой системы координат – теперь пишутся относительно системы координат родителя т.е. в данном случае если бы камера не была привязана к кубу, команда PositionEntity cam,0,5,-10 означала бы поставить объект cam в точку с координатами 0,5,-10. А так как она привязана к кубу, камера ставится в точку 0,5,-10 относительно куба (т.е. центр куба для камеры считается точкой 0,0,0). Получается, что камера располагается сзади и немного сверху относительно куба. И куда мы этот куб перед этим бы не поставили, как бы не повернули – всё равна камера бы поставилась именно таким образом. И, наконец, самое главное: Все движения и повороты, которые применяются к родителю автоматически применяются к зависимым от него объектам – то есть они как будто бы привязаны к родителю. Например, если мы подвинем родителя, все зависимые от него объекты также подвинутся. Если повернём – все зависимые объекты относительно него повернутся! Но не наоборот! Как бы мы не вертели не крутили и не двигали зависимые объекты, родителю будет на это всё глубоко параллельно…
Надеюсь понятно объяснил. Хотелось бы только отметить: если всё же нам нужно будет поместить, передвинуть или повернуть зависимый объект относительно мировой системы координат, то это делается очень просто – в конце добавляется True (что значит, что команда совершается ГЛОБАЛЬНО – то есть относительно мировой системы координат.). Например, если нам камеру надо будет поставить в точку 5,5,-20 относительно мировой системы координат, а не относительно мировой системы родителя - мы просто пишем PositionEntity cam,5,5,-20,True ! И всё! И связь всё равно от этого не потеряется!
Запустите программу, и вы увидите, что камера стоит ровно, и следит за кубом. А он ездит (это видно по плоскости, которая пролетает внизу – вот зачем она была нужна!). Чтобы показать, что движение зависимых объектов никак не влияет на родителей, добавим ещё две строчки в цикл:
If KeyDown(30) MoveEntity cam,0,0,.1 If KeyDown(44) MoveEntity cam,0,0,-.1
В них, как вы видите, условие – если нажата кнопка A – двигать камеру вперёд, а если нажата Z – назад. Куб остаётся на месте!
Полный код:
Graphics3D 640,480,16,1 SetBuffer BackBuffer() lit=CreateLight() cub=CreateCube() ScaleEntity cub,1,.5,2 cam=CreateCamera(cub) PositionEntity cam,0,5,-10 pln=CreatePlane() tex=LoadTexture("Picture.bmp") ScaleTexture tex,10,10 EntityTexture pln,tex PositionEntity pln,0,-1,0 Repeat If KeyDown(200) MoveEntity cub,0,0,.1 If KeyDown(208) MoveEntity cub,0,0,-.1 If KeyDown(203) TurnEntity cub,0,1,0 If KeyDown(205) TurnEntity cub,0,-1,0 If KeyDown(30) MoveEntity cam,0,0,.1 If KeyDown(44) MoveEntity cam,0,0,-.1 UpdateWorld RenderWorld Flip Until KeyHit(1) End
Ну, мы раскрыли секрет игр, сделанных от третьего лица! Но использование привязок не ограничивается «следящей» камерой. О том, что ещё можно сделать с привязками, я расскажу в следующей главе.
6 января 2014 в 23:51
Здравствуйте! У меня вот какая ситуация случилась. До того как я камеру прикрепил к кирпичу, у меня в этой строчке ScaleEntity cub,1,.5,2 все работало правильно... т.е. кирпич тех размеров которые заданы. А когда в строке объявления камеры в скобках вписываю cub, то в этой строке ScaleEntity cub,1,.5,2 координата "y" изменяет ширину рисунка на текстуре ( у меня картинка в кирпичек, так вот ширина этих кирпичиков увеличивается или уменьшается в зависимости от величины y). Если убираю cub из скобок, все как и должно быть. Почему так, не подскажите?
Да, кстати спасибо за материл!!!
6 января 2014 в 23:52
Спасибо за материал!!!
авторизуйтесь
или войдите через