Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > API приложений и сред

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 19.07.2013, 17:59
n_drey вне форума Посмотреть профиль Отправить личное сообщение для n_drey Найти все сообщения от n_drey
  № 1  
Ответить с цитированием
n_drey
 
Аватар для n_drey

Регистрация: Jan 2009
Сообщений: 25
По умолчанию Передвижение мира

Доброго времени!
Пытаюсь написать визуализацию компании (схема с ответвлениями).
Использую для физики Box2d . В центре сцены статический объект с привязанным к нему мувиклипом от него идут связи с другими динамическими объектами. Пример прикреплён. В дальнейшем при клике на любой динамический объект будет ещё ответвления со связями ИТП. Получается некое подобие графической карты.
Вопрос в том чтобы организовать скроллинг всей этой карты мышкой при клике на свободную область.
Координаты чего надо менять (пересчитывать)?
Форум я читал, но если честно я так и не понял что к чему, сильно не пинайте box2d изучаю ровно 3 дня, но уже голова кругом. Сильно не пинайте.

Сам движок я изучал по достаточно неплохим туториалам с сайта http://redefy.net. Увы там описано не всё.

Во сам скрипт:
Код AS3:
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;
		}
	}
 
 
 
 
}
Тыкните пожалуйста в нужную сторону, как реализовать скроллинг карты. На сколько я понимаю координаты мира менять нельзя.
Вложения
Тип файла: swf vizualization.swf (155.9 Кб, 51 просмотров)

Старый 19.07.2013, 18:35
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 2  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Перемещать нужно спрайт с графикой, и только. Мир трогать не надо. В нем координаты всегда будут относительно 0:0, так же как и внутренние координаты спрайта с графикой. Но сам спрайт будет двигаться и на физику не влиять

Старый 19.07.2013, 18:59
n_drey вне форума Посмотреть профиль Отправить личное сообщение для n_drey Найти все сообщения от n_drey
  № 3  
Ответить с цитированием
n_drey
 
Аватар для n_drey

Регистрация: Jan 2009
Сообщений: 25
Цитата:
Сообщение от caseyryan Посмотреть сообщение
Перемещать нужно спрайт с графикой, и только. Мир трогать не надо. В нем координаты всегда будут относительно 0:0, так же как и внутренние координаты спрайта с графикой. Но сам спрайт будет двигаться и на физику не влиять
То есть мне надо будет пробегать по списку всех объектов на сцене и сдвигать их на определённые координаты? Или я чего то не допонимаю ((( Что в моём коде получается спрайт с графикой? Прочитал кучу статей, так и не понял реализацию ((((
Help pls (( оч надо - разъясните тупарю.

Создать новую тему Ответ Часовой пояс GMT +4, время: 18:34.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 18:34.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.