|
|
|||||
Регистрация: Jan 2009
Сообщений: 25
|
Передвижение мира
Доброго времени!
Пытаюсь написать визуализацию компании (схема с ответвлениями). Использую для физики Box2d . В центре сцены статический объект с привязанным к нему мувиклипом от него идут связи с другими динамическими объектами. Пример прикреплён. В дальнейшем при клике на любой динамический объект будет ещё ответвления со связями ИТП. Получается некое подобие графической карты. Вопрос в том чтобы организовать скроллинг всей этой карты мышкой при клике на свободную область. Координаты чего надо менять (пересчитывать)? Форум я читал, но если честно я так и не понял что к чему, сильно не пинайте box2d изучаю ровно 3 дня, но уже голова кругом. Сильно не пинайте. Сам движок я изучал по достаточно неплохим туториалам с сайта http://redefy.net. Увы там описано не всё. Во сам скрипт: package { /* Классы Box2d */ import adobe.utils.CustomActions; import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2CircleShape; import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Collision.Shapes.b2Shape; import Box2D.Common.b2Color; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2Fixture; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2World; import Box2D.Dynamics.Joints.*; import flash.display.MovieClip; /* import Box2D.Dynamics.Joints.b2LineJoint; import Box2D.Dynamics.Joints.b2MouseJoint; import Box2D.Dynamics.Joints.b2MouseJointDef; import Box2D.Dynamics.Joints.b2JointDef; import Box2D.Dynamics.Joints.b2DistanceJoint; import Box2D.Dynamics.Joints.b2DistanceJointDef; import Box2D.Dynamics.Joints.b2FrictionJointDef; import Box2D.Dynamics.Joints.b2JointEdge; */ import flash.display.Graphics; /* Классы встроенные во Flash */ import flash.display.Shape; import flash.display.Graphics; import flash.display.Bitmap; import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; /* Пользовательские классы */ /** * @author Andrey Averin */ [SWF(width = "800", height = "600", framerate = "60", backgroundColor = 0xFFFFFF)] // с какими параметрами запускается сам ролик public class Main extends Sprite { private var world:b2World; //Создаём мир private var meters:int = 30; // один метр будет равен 30 пикселям private var velocityIterations:int = 10; private var positionIterations:int = 10; private var timeStep:Number = 1.0 / 24.0; private var isMouseDown:Boolean = false; private var debugSprite:Sprite = new Sprite(); private var logo:Sprite = new logoMC(); public function Main():void // Конструктор { graphics.beginFill(0xc7c7c7); graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); addChild(debugSprite); // логотип logo.x = logo.width - 77; logo.y = logo.height - 30; createWorld(); // создаёт мир box2d //createWallStage(); // создаёт стены мира (не уверен что они нужны) createBodies(); createDebugDraw(); // метод включает дебаг для объектов box2d addEventListener(Event.ENTER_FRAME, update); stage.scaleMode = StageScaleMode.NO_SCALE; stage.addEventListener(MouseEvent.MOUSE_DOWN, flagCheck); stage.addEventListener(MouseEvent.MOUSE_UP, flagCheck); stage.addEventListener(Event.RESIZE, onResizeStage); // Отрисовываем стены при измнении размера флеш ролика stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel); } private function onResizeStage(e:Event):void { // Здесь будет перерисовываться границы из твёрдых тел //var bb:b2Body; //тело for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext() ) { //if (bb.GetType() == b2Body.b2_staticBody) { if (bb.GetUserData()) { //world.DestroyBody(bb); var data:Array = bb.GetUserData(); var clip:MovieClip = data[0]; trace(clip); } } //this.createBodies(); //trace(stage.x); } private function handleMouseWheel(e:MouseEvent):void { // прокрутка мыши trace(stage.width); } private function createWorld():void { // метод создания мира var gravity:b2Vec2 = b2Vec2.Make(0.0, 0.0); var sleepingBody:Boolean = true; world = new b2World(gravity, sleepingBody); } private function createWallStage():void { //создадим статические тела по границам сцены чтобы наши тела не вылетали за нее // очищаем мир от статических тел /* var bb:b2Body; //тело for (bb = world.GetBodyList(); bb; bb = bb.GetNext() ) { if (bb.GetType() == b2Body.b2_staticBody) { world.DestroyBody(bb); } } */ var body:b2Body; //тело var bodyDef:b2BodyDef; //геометрические настройки тела var bodyShapePoligon:b2PolygonShape; var wallThickness:Number = 2; // толщина стен, ( он же width ) //left /* bodyDef = new b2BodyDef(); //создаем b2BodyDef геометрические свойства тела bodyDef.type = b2Body.b2_staticBody; // bodyDef.active = true; bodyDef.position.Set(wallThickness/meters/2, stage.stageHeight/meters/2); //устанавливаем позицию тела на сцене bodyShapePoligon = new b2PolygonShape(); bodyShapePoligon.SetAsBox(wallThickness/meters/ 2, stage.stageHeight / meters / 2); body = world.CreateBody(bodyDef); //создаем тело body.CreateFixture2(bodyShapePoligon); //right bodyDef = new b2BodyDef(); //создаем b2BodyDef bodyDef.position.Set((stage.stageWidth-wallThickness/2)/meters, stage.stageHeight/meters/2); //устанавливаем позицию тела на сцене body = world.CreateBody(bodyDef);//создаем тело body.CreateFixture2(bodyShapePoligon); //down bodyDef = new b2BodyDef(); //создаем b2BodyDef bodyDef.position.Set(stage.stageWidth/2/meters, (stage.stageHeight-wallThickness/2)/meters); bodyShapePoligon = new b2PolygonShape(); bodyShapePoligon.SetAsBox(stage.stageWidth/meters/ 2, wallThickness / meters / 2); //устанавливаем позицию тела на сцене body = world.CreateBody(bodyDef); //создаем тело body.CreateFixture2(bodyShapePoligon); //up bodyDef = new b2BodyDef(); //создаем b2BodyDef bodyDef.position.Set(stage.stageWidth/2/meters, wallThickness/2/meters); //устанавливаем позицию тела на сцене body = world.CreateBody(bodyDef); //создаем тело body.CreateFixture2(bodyShapePoligon); */ } private function createBodies():void { // Создание тел на сцене var body:b2Body; var bodyA:b2Body; var bodyDef:b2BodyDef; var bodyShapePoligon:b2PolygonShape; var bodyShapeCircle:b2CircleShape; var fixture:b2FixtureDef; var jointDef:b2JointDef; //определение соединения //var jointDef:b2DistanceJointDef; //определение соединения //var joint:b2DistanceJoint; //соединение // Главный спрайт компании BodyA var company:Sprite = new companyMC(); var userdadaStaticStore:Array = new Array(company); // массив присоедияемых к телу данных bodyDef = new b2BodyDef(); bodyDef.position.Set(stage.stageWidth / meters / 2, stage.stageHeight / meters / 2); bodyDef.userData = userdadaStaticStore; bodyA = world.CreateBody(bodyDef); bodyShapePoligon = new b2PolygonShape(); bodyShapePoligon.SetAsBox((company.width /2) / meters, (company.height /2 - 10) / meters); bodyA.CreateFixture2(bodyShapePoligon); var i:int; for (i = 0; i < 5; i++) { var connectionLine:Sprite = new Sprite(); // линия соединитель connectionLine.graphics.lineStyle(1, 0xc7c7c7, 1); addChild(connectionLine); var clip:Sprite = new humanMC(); // тело компаньона clip.x = clip.x + Math.random() * 500; clip.y = clip.y + Math.random() * 500; addChild(clip); // рисуеми тело bodyDef = new b2BodyDef(); //bodyDef.position.Set((Math.random() * 700 +50) / meters, 100 / meters / 2); bodyDef.position.Set(clip.x / meters, clip.y / meters); bodyDef.type = b2Body.b2_dynamicBody; bodyDef.fixedRotation = true; // запрещаем вращение //bodyDef.linearVelocity.Set(Math.random() * 10, Math.random() * 10); bodyDef.linearVelocity.Set(5, 5); var userdadaStore:Array = new Array(clip, connectionLine); // массив присоедияемых к телу данных //userdadaStore[0] = clip; //userdadaStore[1] = ConnectionLine; //bodyDef.userData = clip; bodyDef.userData = userdadaStore; body = world.CreateBody(bodyDef); bodyShapePoligon = new b2PolygonShape(); //bodyShapePoligon.SetAsBox((Math.random() * 25 + 5) / meters, (Math.random() * 25 + 5) / meters); bodyShapePoligon.SetAsBox( ( (clip.width - 15) / meters)/2, ( (clip.height - 15) / meters)/2); fixture = new b2FixtureDef(); //fixture.density = Math.random() * 9 + 1; // fixture.shape = bodyShapePoligon; body.CreateFixture(fixture); jointDef = new b2FrictionJointDef(); //создаем определение соединения первым способом b2FrictionJointDef(jointDef).bodyA = bodyA; //первое тело b2FrictionJointDef(jointDef).bodyB = body; //второе тело b2FrictionJointDef(jointDef).localAnchorA = new b2Vec2(-0.3, 0); //якорная точка первого тела b2FrictionJointDef(jointDef).localAnchorB = new b2Vec2(-0.3, 0); //якорная точка второго тела b2FrictionJointDef(jointDef).maxForce = 1000; //максимальная сила b2FrictionJointDef(jointDef).maxTorque = 0; //максимальный крутящмй момент world.CreateJoint(jointDef); //создаем и добавляем соединение в мир } addChild(company); } private function clickChecker(e:Event):void { trace(e.target.body); } private function createDebugDraw():void { var debugDraw:b2DebugDraw = new b2DebugDraw(); debugDraw.SetSprite(debugSprite); debugDraw.SetDrawScale(30.0); debugDraw.SetFillAlpha(0.4); debugDraw.SetLineThickness(1.0); debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit); world.SetDebugDraw(debugDraw); world.DrawDebugData(); } private function update(e:Event):void { // Метод обновления мира for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext() ) { if (bb.GetUserData()) { var data:Array = bb.GetUserData(); // забираем массив данных привязанных к телу box2d //trace(data[1]); // тут происходит привязка мувиклипов к телам box2d (без этого никак) data[0].x = bb.GetPosition().x * meters; // по оси X data[0].y = bb.GetPosition().y * meters; // по оси Y data[0].rotation = bb.GetAngle() * (180 / Math.PI) % 360; // здесь включется вращение тела если разрешено вращение for (var jj:b2JointEdge = bb.GetJointList(); jj; jj = jj.next){ //trace(jj.joint.GetAnchorA().x, jj.joint.GetAnchorA().y); //trace(bb.GetUserData()); // линии соединители (обработка координат) if(data.length > 1){ data[1].graphics.clear(); data[1].graphics.lineStyle(1, 0x88000, 1); data[1].graphics.moveTo(jj.joint.GetAnchorA().x * meters, jj.joint.GetAnchorA().y * meters); data[1].graphics.lineTo(jj.joint.GetAnchorB().x * meters, jj.joint.GetAnchorB().y * meters); } } } } UpdateMouseWorld(); MouseDrag(); world.Step(timeStep, velocityIterations, positionIterations); world.ClearForces(); world.DrawDebugData(); } private function flagCheck(e:MouseEvent):void { switch(e.type) { case "mouseDown": isMouseDown = true; break; case "mouseUp": isMouseDown = false; break; } } ////////////////////////////////////////////////////////////////////////// private var m_mouseJoint:b2MouseJoint; static public var mouseXWorldPhys:Number; static public var mouseYWorldPhys:Number; static public var mouseXWorld:Number; static public var mouseYWorld:Number; public function UpdateMouseWorld():void{ mouseXWorldPhys = mouseX/meters; mouseYWorldPhys = mouseY/meters; mouseXWorld = mouseX; mouseYWorld = mouseY; } public function MouseDrag():void{ if (isMouseDown && !m_mouseJoint){ var body:b2Body = GetBodyAtMouse(); if (body != null){ // перемещение одного елемента var md:b2MouseJointDef = new b2MouseJointDef(); md.bodyA = world.GetGroundBody(); md.bodyB = body; md.target.Set(mouseXWorldPhys, mouseYWorldPhys); md.collideConnected = true; md.maxForce = 3000; m_mouseJoint = world.CreateJoint(md) as b2MouseJoint; body.SetAwake(true); } else { // перемещение группы елементов } } if (!isMouseDown){ if (m_mouseJoint){ world.DestroyJoint(m_mouseJoint); m_mouseJoint = null; } } if (m_mouseJoint){ var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys); m_mouseJoint.SetTarget(p2); } } private var mousePVec:b2Vec2 = new b2Vec2(); public function GetBodyAtMouse(includeStatic:Boolean = false):b2Body { mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001); aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001); var body:b2Body = null; var fixture:b2Fixture; function GetBodyCallback(fixture:b2Fixture):Boolean{ var shape:b2Shape = fixture.GetShape(); if (fixture.GetBody().GetType() != b2Body.b2_staticBody || includeStatic){ var inside:Boolean = shape.TestPoint(fixture.GetBody().GetTransform(), mousePVec); if (inside){ body = fixture.GetBody(); return false; } } return true; } world.QueryAABB(GetBodyCallback, aabb); return body; } } } |
|
|||||
Перемещать нужно спрайт с графикой, и только. Мир трогать не надо. В нем координаты всегда будут относительно 0:0, так же как и внутренние координаты спрайта с графикой. Но сам спрайт будет двигаться и на физику не влиять
|
|
|||||
Регистрация: Jan 2009
Сообщений: 25
|
Цитата:
Help pls (( оч надо - разъясните тупарю. |
Часовой пояс GMT +4, время: 18:34. |
|
« Предыдущая тема | Следующая тема » |
|
|