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

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

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

Регистрация: Mar 2009
Сообщений: 51
Question Можно ли сделать просчет пересечения точнее?

Здравствуйте!

Я написал небольшое демо на box2D и меня беспокоит, что иногда можно уловчиться и перетащить один физический объект в другой. Причем сделать это довольно просто.

Можно ли сделать просчет пересечений точнее? В идеале, чтобы любое тело не могло пересекаться с другими.

Ссылка на на демо.

Код

Код AS3:
package  {
 
	//-----------------------------------
	import Box2D.Collision.b2AABB;
	import Box2D.Collision.Shapes.b2MassData;
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Collision.Shapes.b2Shape;
	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.b2MouseJoint;
	import Box2D.Dynamics.Joints.b2MouseJointDef;
	import flash.display.Sprite;
	import flash.events.Event;
	import General.Input;
	//-----------------------------------
 
	/**
	 * @langversion ActionScript 3
	 * @playerversion Flash 11.1.0
	 * @timecreation 07.03.2012 10:55
	 * ...
	 * @author artFintch
	 */
	public class App extends Sprite {
 
		private const PHYS_SCALE:Number = 30;
		private const TIME_STEP:Number = 1.0 / 30.0;
 
		private const _mVelocityIterations:int = 10;
		private const _mPositionIterations:int = 10;
 
		private var _mInput:Input;
		private var _mSprite:Sprite;
		private var _mWorld:b2World;
 
		private var _mouseXWorldPhys:Number;
		private var _mouseYWorldPhys:Number;
		private var _mouseXWorld:Number;
		private var _mouseYWorld:Number;
 
		private var _mMouseJoint:b2MouseJoint;
		private var _mousePVec:b2Vec2 = new b2Vec2();
 
		public function App() {
 
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
 
		}
 
		private function init(e:Event = null):void {
 
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			// entry point
 
			initWorld();
 
			//////
 
			addSomebody(10, 10, 50, 50);
			addSomebody(20, 40, 200, 200);
			addSomebody(60, 60, 400, 400);
 
			//////
 
			addEventListener(Event.ENTER_FRAME, updatePhysics, false, 0, true);
 
		}
 
		private function addSomebody(w:Number, h:Number, x:Number, y:Number):void {
 
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			var bodyShape:b2PolygonShape = new b2PolygonShape();
			var bodyDef:b2BodyDef = new b2BodyDef();
			var body:b2Body;
 
			bodyDef.type = b2Body.b2_staticBody;
			bodyDef.bullet = true;
			fixtureDef.density = 0.1;
			fixtureDef.friction = 10;
			fixtureDef.restitution = 0;
			bodyDef.fixedRotation = true;
			fixtureDef.shape = bodyShape;
 
			var sWidth:Number = stage.width;
			var sHeight:Number = stage.height;
 
			bodyDef.position.Set(x / PHYS_SCALE / 2, y / PHYS_SCALE / 2);
			bodyShape.SetAsBox(w / PHYS_SCALE, h / PHYS_SCALE);
			body = _mWorld.CreateBody(bodyDef);
			body.CreateFixture(fixtureDef);
 
			var massData:b2MassData = new b2MassData();
			massData.mass = 0.01;
			body.SetMassData(massData);
 
		}
 
		private function initWorld():void {
 
			_mSprite = new Sprite();
			addChild(_mSprite);
 
			_mInput = new Input(_mSprite);
 
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-1000.0, -1000.0);
			worldAABB.upperBound.Set(1000.0, 1000.0);
 
			var gravity:b2Vec2 = new b2Vec2(0.0, 0.0);
			var doSleep:Boolean = false;
 
			_mWorld = new b2World(gravity, doSleep);
			_mWorld.SetWarmStarting(true);
 
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			dbgDraw.SetSprite(_mSprite);
			dbgDraw.SetDrawScale(30.0);
			dbgDraw.SetFillAlpha(0.3);
			dbgDraw.SetLineThickness(1.0);
			dbgDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
			_mWorld.SetDebugDraw(dbgDraw);
 
			var wall:b2PolygonShape= new b2PolygonShape();
			var wallBd:b2BodyDef = new b2BodyDef();
			var wallB:b2Body;
 
			var width:Number = stage.stageWidth;
			var height:Number = stage.stageHeight;
 
			// Left
			wallBd.position.Set( 0 / PHYS_SCALE, height / PHYS_SCALE / 2);
			wall.SetAsBox(4 / PHYS_SCALE, height / PHYS_SCALE / 2);
			wallB = _mWorld.CreateBody(wallBd);
			wallB.CreateFixture2(wall);
			// Right
			wallBd.position.Set((width) / PHYS_SCALE, height / PHYS_SCALE / 2);
			wallB = _mWorld.CreateBody(wallBd);
			wallB.CreateFixture2(wall);
			// Top
			wallBd.position.Set(width / PHYS_SCALE / 2, 0 / PHYS_SCALE);
			wall.SetAsBox(width / PHYS_SCALE / 2, 4 / PHYS_SCALE);
			wallB = _mWorld.CreateBody(wallBd);
			wallB.CreateFixture2(wall);
			// Bottom
			wallBd.position.Set(width / PHYS_SCALE / 2, (height) / PHYS_SCALE);
			wallB = _mWorld.CreateBody(wallBd);
			wallB.CreateFixture2(wall);
 
		}
 
		private function updatePhysics(e:Event):void {
 
			_mSprite.graphics.clear();
 
			Input.update();
 
			updateMouseWorld()
			mouseDestroy();
			mouseDrag();
 
			_mWorld.Step(TIME_STEP, _mVelocityIterations, _mPositionIterations);
			_mWorld.ClearForces();
 
			_mWorld.DrawDebugData();
 
		}
 
		public function updateMouseWorld():void {
 
			_mouseXWorldPhys = (Input.mouseX) / PHYS_SCALE; 
			_mouseYWorldPhys = (Input.mouseY) / PHYS_SCALE; 
 
			_mouseXWorld = (Input.mouseX); 
			_mouseYWorld = (Input.mouseY); 
 
		}
 
		public function mouseDrag():void {
 
			// mouse press
			if (Input.mouseDown && !_mMouseJoint) {
 
				var body:b2Body = getBodyAtMouse(true);
 
				if (body) {
 
					if (body.GetType() != b2Body.b2_dynamicBody) body.SetType(b2Body.b2_dynamicBody);
 
					var md:b2MouseJointDef = new b2MouseJointDef();
					md.bodyA = _mWorld.GetGroundBody();
					md.bodyB = body;
					md.target.Set(_mouseXWorldPhys, _mouseYWorldPhys);
					md.collideConnected = true;
					md.maxForce = 10000.0;
 
					_mMouseJoint = _mWorld.CreateJoint(md) as b2MouseJoint;
 
				}
 
			}
 
			// mouse release
			if (!Input.mouseDown) {
 
				if (_mMouseJoint) {
 
					_mMouseJoint.GetBodyB().SetLinearVelocity(new b2Vec2(0, 0));
					_mMouseJoint.GetBodyB().SetType(b2Body.b2_staticBody)
					_mWorld.DestroyJoint(_mMouseJoint);
					_mMouseJoint = null;
 
 
				}
 
			}
 
			// mouse move
			if (_mMouseJoint) {
 
				var p2:b2Vec2 = new b2Vec2(_mouseXWorldPhys, _mouseYWorldPhys);
				_mMouseJoint.SetTarget(p2);
 
			}
 
		}
 
		public function mouseDestroy():void {
 
			// mouse press
			if (!Input.mouseDown && Input.isKeyPressed(68)) {
 
				var body:b2Body = getBodyAtMouse(true);
 
				if (body) {
 
					_mWorld.DestroyBody(body);
					return;
 
				}
 
			}
 
		}
 
		public function getBodyAtMouse(includeStatic:Boolean = false):b2Body {
 
			// Make a small box.
			_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;
 
			// Query the world for overlapping shapes.
			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;
			}
 
			_mWorld.QueryAABB(getBodyCallback, aabb);
 
			return body;
 
		}
 
	}
 
}
Помогите кто чем может)
Сам не могу разобраться(

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

Регистрация: Mar 2009
Сообщений: 51
to Ohcysp Regit

Цитата:
Ну что я могу сказать код ты зря приложил.
Почему?

Цитата:
А вообще не совсем я понимаю о чем ты говоришь, если о том что тело проскакивает одно через другое.
То маус очень большой форс задает телу из за чего одно и проскакивает через другое.
Попробуй с реальной моделью управления объектами, без мауса этого и такой ситуации в принципе не будет возникать.
Как минимум у меня таких проблем не возникает
Мне необходимо перетаскивать объекты мышью. Да, сила действительно большая, но иначе объект начинает болтаться.

Цитата:
Ну а более конкретно посмотри в сторону ConcatListener'a утверждать не буду но возможно в пресолв приходит событие даже если объекты проскакивают( ну и не только пресолв ). И ты можешь дополнительно "не дать объектам" проходить друг через друга
Попробую разобраться конечно. Но хотелось бы получить более подробный ответ.

Спасибо.

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

Теги
box2d , box2D столкновение тел
Опции темы
Опции просмотра

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

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


 


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


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