|
|
|||||
Регистрация: Feb 2014
Сообщений: 56
|
Физика двигателя.
Здравствуйте, уважаемые форумчане.
Волнует вопрос по физическому двиглу nape. В box2d, есть физика колеса\двигателя. Если мощность не позволяет, то машинка начнёт заезжать на горку с явным напрягом, в обратном случае без напряга. Можно описать скорость, момент силы, etc... Но box2d медлен по сравнению с nape. Есть необходимость использовать nape, но никак не могу сделать колесо с двигателем. В nape есть момент силы относительно двух радиусов, но мощность\скорость регулировать невозможно, машинка получается не физичной. Уважаемые, прошу ответов, рекомендаций по существу вопроса. |
|
|||||
У MotorJoinnt есть параметр rate, вот он является мощностью, применив к колесу получаем чувствительность к нагрузке - http://napephys.com/samples.html#swf-Constraints
Пример машинки на Nape - https://github.com/DaVikingCode/Citr...le/nape/Car.as |
|
|||||
Регистрация: Feb 2014
Сообщений: 56
|
Но тем самым увеличим скорость, как же ограничивать скорость, увеличивая мощность..
|
|
|||||
вы уже пробовали?
rate - это не скорость |
|
|||||
Регистрация: Feb 2014
Сообщений: 56
|
Вложен проект.
При изменении rate, меняется скорость, на препятствие заезжает независимо хорошо от rate, но с разной постоянной скоростью. Rate меняю в move(); package { import Links.m_space; import flash.Boot; import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import nape.constraint.MotorJoint; import nape.constraint.PivotJoint; import nape.dynamics.InteractionFilter; import nape.geom.Vec2; import nape.phys.Body; import nape.phys.BodyType; import nape.phys.Material; import nape.shape.Circle; import nape.shape.Polygon; import nape.shape.Shape; import nape.space.Space; import nape.util.BitmapDebug; [SWF(width = 1024, height = 708)] public class Main extends Sprite { private var WIDTH :Number = 1024; private var HEIGHT:Number = 708; private var stick :Body; private var wheel_1 :Body; private var wheel_2 :Body; private var motorJoint1 :MotorJoint; private var pivotJoint1 :PivotJoint; private var pivotJoint2 :PivotJoint; private var stick2 :Body; private var wheel_3 :Body; private var wheel_4 :Body; private var motorJoint2 :MotorJoint; private var pivotJoint3 :PivotJoint; private var pivotJoint4 :PivotJoint; private var debug :BitmapDebug; private var mat_ground:Material = new Material(0, 5, 5, 5, 0.5); private var mat_wheel:Material = new Material(0, 5, 5, 5, 0.99); private var filter:InteractionFilter = new InteractionFilter(0x10000, 0x10001); public function Main():void { new Boot(); m_space = new Space(new Vec2(0, 900)); // Создание мира debug = new BitmapDebug(WIDTH, HEIGHT); debug.drawConstraints = true; addChild(debug.display); createBox(); createBodies(); createJoint(); addEventListener(Event.ENTER_FRAME, enterFrameListener); stage.addEventListener(KeyboardEvent.KEY_DOWN, move); stage.addEventListener(KeyboardEvent.KEY_UP, stand); } private function createBox():void { var w:Number = 15; var regions:Body = new Body(BodyType.STATIC); // Основная коробка regions.shapes.add(new Polygon(Polygon.rect(0, HEIGHT-w, WIDTH, w), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, 0, WIDTH, w), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, 0, w, HEIGHT),mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(WIDTH-w, 0, w, HEIGHT),mat_ground)); // Горизонтальные перегородки regions.shapes.add(new Polygon(Polygon.rect(400, 584/3, 399, 15), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, (584/3)*2, 600, 15),mat_ground)); regions.space = m_space; } private function createBodies():void { var pentagonBody:Body = new Body(BodyType.STATIC); pentagonBody.position.setxy(WIDTH/2, HEIGHT-50); var pentagonShape:Shape = new Polygon(Polygon.regular(200, 75, 3, -100)); pentagonShape.body = pentagonBody; pentagonBody.space = m_space; stick = new Body(BodyType.DYNAMIC); stick.shapes.add(new Polygon(Polygon.rect(100, HEIGHT-50, 100, 10), Material.steel(), filter)); stick.mass = 512; stick.align(); stick.space = m_space; wheel_1 = new Body(BodyType.DYNAMIC); wheel_1.shapes.add(new Circle(25, new Vec2(100, HEIGHT-35), Material.steel(), filter)); wheel_1.align(); wheel_1.mass = 75; wheel_1.space = m_space; wheel_2 = new Body(BodyType.DYNAMIC); wheel_2.shapes.add(new Circle(25, new Vec2(198, HEIGHT-35), Material.steel(), filter)); wheel_2.align(); wheel_2.mass = 75; wheel_2.space = m_space; stick2 = new Body(BodyType.DYNAMIC); stick2.shapes.add(new Polygon(Polygon.rect(WIDTH-200, HEIGHT-50, 100, 10), Material.steel(), filter)); stick2.mass = 512; stick2.align(); stick2.space = m_space; wheel_3 = new Body(BodyType.DYNAMIC); wheel_3.shapes.add(new Circle(25, new Vec2(WIDTH-200, HEIGHT-35), mat_wheel, filter)); wheel_3.align(); wheel_3.mass = 75; wheel_3.space = m_space; wheel_4 = new Body(BodyType.DYNAMIC); wheel_4.shapes.add(new Circle(25, new Vec2(WIDTH-102, HEIGHT-35), mat_wheel, filter)); wheel_4.align(); wheel_4.mass = 75; wheel_4.space = m_space; } private function createJoint():void { // CART 1 ========== motorJoint1 = new MotorJoint(stick, wheel_1, 0, 1); motorJoint1.ignore = true; motorJoint1.active = true; motorJoint1.space = m_space; pivotJoint1 = new PivotJoint(stick, wheel_1, new Vec2(-50, 0), new Vec2()); pivotJoint1.ignore = true; pivotJoint1.active = true; pivotJoint1.space = m_space; pivotJoint2 = new PivotJoint(stick, wheel_2, new Vec2(50, 0), new Vec2()); pivotJoint2.ignore = true; pivotJoint2.active = true; pivotJoint2.space = m_space; // CART 2 ========== motorJoint2 = new MotorJoint(stick2, wheel_4, 0, 1); motorJoint2.ignore = true; motorJoint2.active = true; motorJoint2.space = m_space; pivotJoint3 = new PivotJoint(stick2, wheel_3, new Vec2(-50, 0), new Vec2()); pivotJoint3.ignore = true; pivotJoint3.active = true; pivotJoint3.space = m_space; pivotJoint4 = new PivotJoint(stick2, wheel_4, new Vec2(50, 0), new Vec2()); pivotJoint4.ignore = true; pivotJoint4.active = true; pivotJoint4.space = m_space; } private function move(e:KeyboardEvent):void { if(e.keyCode == Keyboard.RIGHT) { motorJoint2.active = true; motorJoint2.rate = 50; motorJoint2.ratio = 15; } if(e.keyCode == Keyboard.LEFT) { motorJoint2.active = true; motorJoint2.rate = -50; motorJoint2.ratio = 15; } if(e.keyCode == Keyboard.D) { motorJoint1.active = true; motorJoint1.rate = 50; motorJoint1.ratio = 15; } if(e.keyCode == Keyboard.A) { motorJoint1.active = true; motorJoint1.rate = -50; motorJoint1.ratio = 15; } } private function stand(e:KeyboardEvent):void { if(e.keyCode == Keyboard.RIGHT) { motorJoint2.active = false; } if(e.keyCode == Keyboard.LEFT) { motorJoint2.active = false; } if(e.keyCode == Keyboard.D) { motorJoint1.active = false; } if(e.keyCode == Keyboard.A) { motorJoint1.active = false; } } private function enterFrameListener(e:Event):void { m_space.step(1/60, 100, 60); debug.clear(); // Очищаем debug.draw(m_space); // выводим на экран debug.flush(); // Обновляем } } } Последний раз редактировалось Freeman; 14.09.2015 в 20:32. |
|
|||||
уменьшил трение качения, стало с трудом закатываться
весь код копирую, так как много там всего менять пытался package { //import Links.m_space; import flash.Boot; import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import nape.constraint.MotorJoint; import nape.constraint.PivotJoint; import nape.dynamics.InteractionFilter; import nape.geom.Vec2; import nape.phys.Body; import nape.phys.BodyType; import nape.phys.InertiaMode; import nape.phys.Material; import nape.shape.Circle; import nape.shape.Polygon; import nape.shape.Shape; import nape.space.Space; import nape.util.BitmapDebug; [SWF(width = 1024, height = 708)] public class Main extends Sprite { private var WIDTH :Number = 1024; private var HEIGHT:Number = 708; private var stick :Body; private var wheel_1 :Body; private var wheel_2 :Body; private var motorJoint1 :MotorJoint; private var pivotJoint1 :PivotJoint; private var pivotJoint2 :PivotJoint; private var stick2 :Body; private var wheel_3 :Body; private var wheel_4 :Body; private var motorJoint2 :MotorJoint; private var pivotJoint3 :PivotJoint; private var pivotJoint4 :PivotJoint; private var debug :BitmapDebug; private var mat_ground:Material = new Material(0, 5, 5, 5, 0.1); private var mat_wheel:Material = new Material(0, 5, 5, 5, 0.1); private var filter:InteractionFilter = new InteractionFilter(0x10000, 0x10001); private var m_space:Space; public function Main():void { new Boot(); m_space = new Space(new Vec2(0, 2900)); // Создание мира debug = new BitmapDebug(WIDTH, HEIGHT); debug.drawConstraints = true; addChild(debug.display); createBox(); createBodies(); createJoint(); addEventListener(Event.ENTER_FRAME, enterFrameListener); stage.addEventListener(KeyboardEvent.KEY_DOWN, move); stage.addEventListener(KeyboardEvent.KEY_UP, stand); } private function createBox():void { var w:Number = 15; var regions:Body = new Body(BodyType.STATIC); // Основная коробка regions.shapes.add(new Polygon(Polygon.rect(0, HEIGHT-w, WIDTH, w), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, 0, WIDTH, w), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, 0, w, HEIGHT),mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(WIDTH-w, 0, w, HEIGHT),mat_ground)); // Горизонтальные перегородки regions.shapes.add(new Polygon(Polygon.rect(400, 584/3, 399, 15), mat_ground)); regions.shapes.add(new Polygon(Polygon.rect(0, (584/3)*2, 600, 15),mat_ground)); regions.space = m_space; } private function createBodies():void { var pentagonBody:Body = new Body(BodyType.STATIC); pentagonBody.position.setxy(WIDTH/2, HEIGHT-50); var pentagonShape:Shape = new Polygon(Polygon.regular(200, 75, 3, -100)); pentagonShape.body = pentagonBody; pentagonBody.space = m_space; stick = new Body(BodyType.DYNAMIC); stick.shapes.add(new Polygon(Polygon.rect(100, HEIGHT-50, 100, 10), Material.steel(), filter)); stick.mass = 512; stick.align(); stick.space = m_space; wheel_1 = new Body(BodyType.DYNAMIC); wheel_1.shapes.add(new Circle(25, new Vec2(100, HEIGHT-35), Material.steel(), filter)); wheel_1.align(); wheel_1.mass = 75; wheel_1.space = m_space; wheel_2 = new Body(BodyType.DYNAMIC); wheel_2.shapes.add(new Circle(25, new Vec2(198, HEIGHT-35), Material.steel(), filter)); wheel_2.align(); wheel_2.mass = 75; wheel_2.space = m_space; stick2 = new Body(BodyType.DYNAMIC); stick2.shapes.add(new Polygon(Polygon.rect(WIDTH-200, HEIGHT-50, 100, 10), Material.steel(), filter)); stick2.mass = 512; stick2.align(); stick2.space = m_space; wheel_3 = new Body(BodyType.DYNAMIC); wheel_3.shapes.add(new Circle(25, new Vec2(WIDTH-200, HEIGHT-35), mat_wheel, filter)); wheel_3.align(); wheel_3.mass = 575; wheel_3.space = m_space; wheel_4 = new Body(BodyType.DYNAMIC); wheel_4.shapes.add(new Circle(25, new Vec2(WIDTH-102, HEIGHT-35), mat_wheel, filter)); wheel_4.align(); wheel_4.mass = 75; wheel_4.space = m_space; } private function createJoint():void { // CART 1 ========== motorJoint1 = new MotorJoint(stick, wheel_1, 0, 0.9 );/// motorJoint1.ignore = true; motorJoint1.active = true; motorJoint1.space = m_space; pivotJoint1 = new PivotJoint(stick, wheel_1, new Vec2(-50, 0), new Vec2()); pivotJoint1.ignore = true; pivotJoint1.active = true; pivotJoint1.space = m_space; pivotJoint2 = new PivotJoint(stick, wheel_2, new Vec2(50, 0), new Vec2()); pivotJoint2.ignore = true; pivotJoint2.active = true; pivotJoint2.space = m_space; // CART 2 ========== motorJoint2 = new MotorJoint(m_space.world, wheel_4, 0,0.9); motorJoint2.ignore = true; motorJoint2.active = true; motorJoint2.space = m_space; pivotJoint3 = new PivotJoint(stick2, wheel_3, new Vec2(-50, 0), new Vec2()); pivotJoint3.ignore = true; pivotJoint3.active = true; pivotJoint3.space = m_space; pivotJoint4 = new PivotJoint(stick2, wheel_4, new Vec2(50, 0), new Vec2()); pivotJoint4.ignore = true; pivotJoint4.active = true; pivotJoint4.space = m_space; } private function move(e:KeyboardEvent):void { if(e.keyCode == Keyboard.RIGHT) { motorJoint2.active = true; motorJoint2.rate = 5; } if(e.keyCode == Keyboard.LEFT) { motorJoint2.active = true; motorJoint2.rate = -5; } if(e.keyCode == Keyboard.D) { motorJoint1.active = true; motorJoint1.rate = 50; } if(e.keyCode == Keyboard.A) { motorJoint1.active = true; motorJoint1.rate = -50; } } private function stand(e:KeyboardEvent):void { if(e.keyCode == Keyboard.RIGHT) { motorJoint2.active = false; } if(e.keyCode == Keyboard.LEFT) { motorJoint2.active = false; } if(e.keyCode == Keyboard.D) { motorJoint1.active = false; } if(e.keyCode == Keyboard.A) { motorJoint1.active = false; } } private function enterFrameListener(e:Event):void { m_space.step(1/60, 100, 60); debug.clear(); // Очищаем debug.draw(m_space); // выводим на экран debug.flush(); // Обновляем } } } |
|
|||||
Регистрация: Feb 2014
Сообщений: 56
|
Всё равно как-то непонятно, как сделать адекватную машинку.
Класс Car так не смог добавить в мир, чтобы потестить управление, после чего изучить, если адекватная.. Очень неоднозначно всё как-то %] |
|
|||||
Ну я тоже не понял почему не учитывается импульс от колеса к стику. Может из за ignore = true;
Класс Car работает только с движком Citrus, его обязательно надо запускать в контексте CitrusEngine. Там кстати в этом классе тоже непонятно работает, там тупо дается горизонтальный velocity телу машинки, но при этом учитывается движение в гору. В вашем случае еще можно попробовать давать телу машинки горизонтальный импульс или силу в направлении движения, технически это тоже должно учитывать угол подъема и массу машинки. Например в случае с трением качения оно как то неадекватно учитывает вес. |
|
|||||
Регистрация: Feb 2014
Сообщений: 56
|
Нужны именно колёса.. Применить Box2D импульс не получается к nape... Надежда на чистый nape. Как бы не играл с параметрами, всё фигня какая-то.(
|
|
|||||
|
Часовой пояс GMT +4, время: 23:13. |
|
« Предыдущая тема | Следующая тема » |
|
|