физика в играх ЕВГЕНИЙ КОРНЮШЕНКО Спецвыпуск: Хакер, номер #064, стр. 064-020-6 Листинг 1. opal::Solid* platformSolid = gSimulator->createSolid(); 2. platformSolid->setStatic(true); 3. opal::BoxShapeData boxShape; 4. boxShape.dimensions = gGroundDimensions; 5. platformSolid->addShape(boxShape); В приведенном куске кода создаем объект в виде прямоугольной коробки, который служит в качестве земли. В первой строчке создаем твердое тело в нашем симуляторе (это твердое тело будет обрабатываться именно данным симулятором и никаким другим). Во второй строчке делаем тело статическим, то есть таким, которое не может менять свою позицию (обладает бесконечной массой), но может взаимодействовать с другими физическими телами. Как правило, в играх такие статические тела используются для симуляции неподвижных объектов локаций, таких как земля, стены и т.д. В третьей строчке создаем экземпляр структуры boxShape, которая описывает трехмерный прямоугольник (бокс). В четвертой строчке устанавливаем его размеры по трем осям, а в пятой — устанавливаем этот прямоугольник в качестве объема для нашей земли, вызвав метод addShape. Заметь, что можно добавлять сколько угодно разных фигур (Shapes), описывая таким образом сложный объем. В OPAL, помимо боксов, в качестве объема можно использовать сферы, цилиндры, плоскости и многоугольники, причем и выпуклые, и невыпуклые. Все фигуры имеют, помимо специфичных для каждой фигуры параметров (как dimensions в нашем примере), ряд общих полей: Листинг Matrix44r offset; Material material; Поле offset задает смещение фигуры относительно центра твердого тела, поле material задает свойства материала фигуры. В OPAL'е материал имеет следующие свойства: hardness — от 0 до 1. Показывает, насколько допустимо перекрытие объемов тел. friction — от 0 до 1, трение движения. Чем больше это значение, тем быстрее будет останавливаться движущееся тело. bounciness — от 0 до 1, упругость. Чем больше значение, тем больше энергии будет поглощаться при соударении. density — плотность материала. На основании этого параметра и объема фигуры вычисляется масса фигуры. Листинг основной цикл программы (вернее, те его части, которые представляют интерес в контексте рассматриваемого вопроса) while (!gQuit) { opal::real dt = (opal::real)timer.getElapsedSeconds(); gQuit = processInput(); if (!gPaused) { gSimulator->simulate(dt); } } Нам интереснее всего вот эта строчка: Листинг gSimulator->simulate(dt); В метод simulate передаем единственный параметр — время, которое прошло в «физическом мире». Именно внутри этого вызова происходит расчет столкновений и расчет взаимодействия физических объектов, происходит обновление позиций, скоростей и т.д. Листинг gSimulator->destroy(); Заключительная строчка программы вызывает метод destroy объекта-симулятора, тем самым освобождая все ресурсы, занятые им, и уничтожая все физические объекты, созданные через методы симулятора, подобные createSolid. |