Box2D ile Joint İşlemi

Öncelikle Box2d nedir, ne için kullanılır gibi soruları cevapladıktan sonra örneğe geçeceğim.

Box2D Flash oyunlar için bir 2D rigid body simülasyon fizik motoru(physics engines) kütüphanesidir. Yazılım geliştiriciler yaptıkları oyunların gerçekciliğini arttırması ve fizik kurallarına uygun ve inandırıcı olması için bu ve bu gibi benzer fizik motoru kütüphaneleri kullanırlar.  C++ dili ile yazılmıştır. Tüm prefixleri b2 ile başlar. Daha önce bu ve buna benzer kütüphaneler ile çalışmadıysanız dökümantasyonu okuyarak başlamanızı tavsiye ederim. Temel olarak bilinmesi gerekenler Örn.

b2World – Herşey bu oluşturduğumuz class içince olur ve gerçekleşir sizin bir world’ünüz var ve tüm işler burda olur. Eklem(Joint), simülasyon adımlarını tutan classtır.

b2Vec2 – Yer çekimi tanımlamalarında kullanılır x ve y değerlerin vektörel olarak tutan bir classtır.

 

Flash ve Box2d farklılıkları.

Flash

Her şey pixeldir Örn.

mySprite. x = 200;
mySprite. y = 200;

Box2d

Her şey metredir

myBody.x = 5.0;
myBody.y = 8.0;

30 pixel = 1 Metre
3×3 = 300 x 300;

Sanırım açıklayıcı olmuştur :)

ve b2BodyDef
b2AABB
Shape
Polygon
Vertex
debugdraw

gibi detaylar ile dolu dediğim gibi dökümantasyonu ile yola başlayın.

Gelelim örneğimiz box2d’nin en ilginç özelliklerinden biri eklemler yani (joint)lerdir. Oldukça uzun ve çok önemli bir konudur bu örnekle umarım anlatabilirim giriş seviyesinde de olsa.

Şu anda, Box2D altı farklı ortak tipleri bulunmaktadır. Distance, Gear, Mouse, Prismatic, Pulley and Revolute joint. Bu yazıda, Distance joint ile çalışacağız. İki nesnemizi bir yerden bağlayıp aynı mesafede durmasını ve mouse ile hareket ettirerek kontrol edeceğiz.

 

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	import flash.events.MouseEvent;
	public class distance_joint extends Sprite {
		var mouseJoint:b2MouseJoint;
		var mousePVec:b2Vec2 = new b2Vec2();
		var bd:b2BodyDef;
		var the_circle:b2CircleDef = new b2CircleDef();
		var the_box:b2PolygonDef = new b2PolygonDef();
		var the_joint:b2DistanceJointDef = new b2DistanceJointDef();
		public function distance_joint() {
			// world setup
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);
			var gravity:b2Vec2=new b2Vec2(0.0,10.0);
			var doSleep:Boolean=true;
			m_world=new b2World(worldAABB,gravity,doSleep);
			// debug draw
			var m_sprite:Sprite;
			m_sprite = new Sprite();
			addChild(m_sprite);
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			var dbgSprite:Sprite = new Sprite();
			m_sprite.addChild(dbgSprite);
			dbgDraw.m_sprite=m_sprite;
			dbgDraw.m_drawScale=30;
			dbgDraw.m_alpha = 1;
			dbgDraw.m_fillAlpha=0.5;
			dbgDraw.m_lineThickness=1;
			dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit;
			m_world.SetDebugDraw(dbgDraw);
			// ground
			the_box.SetAsBox(9,0.5);
			the_box.density = 0;
			the_box.friction = 0.4;
			the_box.restitution = 0.1;
			bd = new b2BodyDef();
			bd.position.Set(8.5, 13);
			var ground:b2Body = m_world.CreateBody(bd);
			ground.CreateShape(the_box);
			ground.SetMassFromShapes();
			// circle
			the_circle.radius = 2;
			the_circle.density = 1.0;
			the_circle.friction = 0.4;
			the_circle.restitution = 0.3;
			bd = new b2BodyDef();
			bd.position.Set(6, 2);
			var circle:b2Body = m_world.CreateBody(bd);
			circle.CreateShape(the_circle);
			circle.SetMassFromShapes();
			// square
			the_box.SetAsBox(1.5,1.5);
			the_box.density = 1.0;
			the_box.friction = 0.4;
			the_box.restitution = 0.1;
			bd = new b2BodyDef();
			bd.position.Set(2, 2);
			var box:b2Body = m_world.CreateBody(bd);
			box.CreateShape(the_box);
			box.SetMassFromShapes();
			// joint (işte Joint yaptığımız yer)
			the_joint.Initialize(circle, box, new b2Vec2(6,2),new b2Vec2(2,2));
			the_joint.collideConnected = true;
			var joint:b2DistanceJoint = m_world.CreateJoint(the_joint)as b2DistanceJoint;
			// listeners
			stage.addEventListener(MouseEvent.MOUSE_DOWN, createMouse);
			stage.addEventListener(MouseEvent.MOUSE_UP, destroyMouse);
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
		}
		public function createMouse(evt:MouseEvent):void {
			var body:b2Body=GetBodyAtMouse();
			if (body) {
				var mouseJointDef:b2MouseJointDef=new b2MouseJointDef;
				mouseJointDef.body1=m_world.GetGroundBody();
				mouseJointDef.body2=body;
				mouseJointDef.target.Set(mouseX/30, mouseY/30);
				mouseJointDef.maxForce=30000;
				mouseJointDef.timeStep=m_timeStep;
				mouseJoint=m_world.CreateJoint(mouseJointDef) as b2MouseJoint;
			}
		}
		public function destroyMouse(evt:MouseEvent):void {
			if (mouseJoint) {
				m_world.DestroyJoint(mouseJoint);
				mouseJoint=null;
			}
		}
		public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body {
			var mouseXWorldPhys = (mouseX)/30;
			var mouseYWorldPhys = (mouseY)/30;
			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 k_maxCount:int=10;
			var shapes:Array = new Array();
			var count:int=m_world.Query(aabb,shapes,k_maxCount);
			var body:b2Body=null;
			for (var i:int = 0; i < count; ++i) {
				if (shapes[i].GetBody().IsStatic()==false||includeStatic) {
					var tShape:b2Shape=shapes[i] as b2Shape;
					var inside:Boolean=tShape.TestPoint(tShape.GetBody().GetXForm(),mousePVec);
					if (inside) {
						body=tShape.GetBody();
						break;
					}
				}
			}
			return body;
		}
		public function Update(e:Event):void {
			m_world.Step(m_timeStep, m_iterations);
			if (mouseJoint) {
				var mouseXWorldPhys=mouseX/30;
				var mouseYWorldPhys=mouseY/30;
				var p2:b2Vec2=new b2Vec2(mouseXWorldPhys,mouseYWorldPhys);
				mouseJoint.SetTarget(p2);
			}
		}
		public var m_world:b2World;
		public var m_iterations:int=10;
		public var m_timeStep:Number=1.0/30.0;
	}
}
Sorry, either Adobe flash is not installed or you do not have it enabled

Burada bir kurala uymak istedim (Öyle bir fonksiyon adı yaz ki açıklama satırı yazmana gerek kalmasın( Comment ) ) Clean Code kitabından.

Örneğimize gelecek olursak aslında kodlardan da anlaşılacağı gibi oldukça kolay ve anlaşılır. Kodlar arasında bazı açıklamalar yapmak gerekirse.

Kısaca
debugdraw() – Sümulasyonlarımızı test etmek için kullanabiliriz diyebilirim.
b2Body – Kadtı cisimleri temsil etmek için kullanılan bir classtır. Ve sadece katı cisimleri yönetir.
b2BodyDef – Katı cisimlerin konumlarını belirlemek için kullanılır. Bunu tanımladıktan sonra konum belirtebilirz.
define = Tanımlamak
definition = Tanım
collision = Çarpışma
Shape = Şekil Daire veya Çokgen
Polygon ve b2PolygonDef tanımlamak için b2Polygon oluşturduktan sonra body oluşturmamız gerek.
Vertex = Köşe kenar veya Tepe diyebilirim
Density = Yoğunluk = Yoğunluğun 0 olması demek herhangi bir çarpışmadan etkilenmeyecek demektir. Zemin için kullanılır.
Friction = Sürtünme
Restitution = Sıçrama efekti için kullanılır değeri ise 0 veya 1’dir. 1 sıçrar aynı zamanda esneklik katar.

Ortak mesafe değişkeni the_joint

Joint başlatılıyor. Joint etkilenen birinci body, ikinci eklem ve ikinci bir noktayı bağlamak için ilk body noktası: Initialize (), dört parametre alır.

collideConnected true ayarlandığında, joint tarafından bağlı olarak birbirleri ile çarpışabilirler. Aksi takdirde üst üste olurlar.

Son olarak da oluşturduğumuz world’e joint ekliyoruz.

Temel olarak bunları bildikten sonra yukarıdaki kodları biraz daha rahat anlayabileceğinizi düşünüyorum.

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

ActionScript ve PHP SDK Kullanarak Facebook Uygulaması Oluşturmak

Facebook oyunları üzerinde çalıştığım için bu yazıda facebook ile nasıl haberleşilir PHP SDK nasıl kullanılır gibi bilgilere deyineceğim. Facebook ile etkileşim sağlayacak bir çok ActionScript API’ileri vardır. Fakat ben en basit yöntem ile nasıl olacağını anlatacağım. Kendi Facebook geliştirici anahtarımı (key) embed etmeden göstereceğim. Peki ne yapacağım sırayla Flash ile Facebook API kullanmak için (Facebook […]

ActionScript 3.0 ile Pong Oyunu – 5

Adım 5. Çarpışma (Collision) Şimdiye kadar, topun dışarıya taşmaması için sahne içinde kalmasını yaptık ve playerPaddle nesnemizi fare ile kontrol edilebilir hale getirdik ardından topun pozisyonuna bağlı olarak aşağı yukarı hareket eden cpuPaddle nesnemizi programladık. Şimdi ise top nesnemizi paddle nesnelerimiz tarafından engelleme özelliği ekleyeceğiz. Hit Test Flash ile sahnedeki iki objeyi çarpıştırmak istersek bunu hitTestObject() ile yaparız. Her nesnenin etrafında […]

ActionScript 3.0 ile Pong Oyunu – 4

Pong oyunumuzun 4. adımına geldik  1. , 2. ve 3. adımları okuyup uyguladıktan sonra 4.adımdan devam edebilirsiniz. Adım 4: Bilgisayar tarafından “cpuPaddle”  kontrolü. Bu bölüm bence son derece öğretici ve oldukça kısa ve oldukça önemli, Çünkü oyun programlamanın en önemli konularından birisini işleyeceğiz. AI (Artificial Intelligence) Yapay Zeka konusu. Yapay Zeka Bilgisayar tarafından bir şeyler kontrol etmek ve belirli koşullara […]

ActionScript 3.0 ile Pong Oyunu – 3

Pong oyunumuzun 3. kısımındayız. Bu kısma başlamadan önce 1. ve 2. kısmı okuyabilirsiniz. Adım 3: Sol tarafta bulunan Paddle nesnemizin kontrolünü programlayacağız. Oyunumuzun 2. kısmında top nesnemizi sahnemiz sınırları içinde hareketlerini tamamlamıştık şimdi ise sol tarafta bulunan “playerPaddle” adındaki nesnemizi mouseY  = yani mouse hareketinin y eksenine bağlayacağız.   mouseY  y – konumunda olması gerek Sahnemizin sınırları […]

ActionScript 3.0 ile Pong Oyunu – 2

Pong oyunumuzun 2. kısmındayız Adım 2 : Basit oyun döngüsü ve “Ball” hareketlerini programlamak Öncelikle, oyunumuzda 2 adet Paddle nesnemiz için her birine farklı Instance name vermemiz gerekir nesnelere erişebilmemiz için. Soldaki  Paddle nesnemizin ismini “playerPaddle” olarak yazıyoruz, sağdaki ise “cpuPaddle” ismini veriyoruz ve kayıt ediyoruz. Tamamdır, şimdi ActionScript panelini açıyoruz (Window -> Actions) kullanarak paneli açabiliriz. Burada […]

ActionScript 3.0 ile Pong Oyunu

1972 yılında Atari Pong sürümü ile video oyun endüstrisine öncülük etmiştir. Eğer klasik oyunlar düşünüyorsanız, Pong listenin  hemen hemen her zamanen üstündedir. Yani Flash ile yapacağınız oyunlar arasında Pong oyun örneği listenizde olmalıdır. Bu blog yazımda, baştan sona tam bir Pong oyunu yapacağız. Bu oyun örneğimde yeni başlayanlar ve oyun geliştirmek isteyenler için tasarladım OOP ile yazmadım […]

Actionscript 3.0 ile Facebook SDK Kullanımı

Facebook’ta bir uygulamayı veya oyunu geliştirmek ve dağıtmak, arkadaşlar, fotoğraflar ve diğer bilgileri hakkında ayrıntılı bilgi almak için Facebook API ile çalışmak gerekir. Facebook Graph API üzerinden bu görevleri gerçekleştirmek için kullanabileceğiniz birkaç resmi SDK bulunmaktadır. Bu yazımda actionscript 3.0 ile javascript SDK kullanarak detaylara değineceğim. Başlarken öncelikle bu üç Facebook JavaScript API çağırmamız gerekli. FB.init – Facebook […]

ActionScript 3.0 ile Trigonometriye Giriş

Bu Blog postumla beraber bir sonraki blog postum ActionScript ile trigonometri örnekleri anlatmayı düşünüyorum. Öncelikle Trigonometri nedir, Açı nedir, Radyan ve Derece nedir gibi genel bir giriş yaptıktan sonra uygulama örneklerine geçmeyi düşünüyorum. Trigonometri Adından da anlaşılacağı gibi temel olarak üçgen ve üçgenlerin kenarları ile olan ilişkilerini inceleyen bir matematik dalıdır. Bildiğiniz gibi üçgenlerin üç kenarı […]

ActionScript 3.0 ve Nodejs ile Socket Programlama

Socket bağlantıları belirlenen bir port numarası üzerinden sunucuya bilgi yollamak ve almak için kullanılır. Tabi bu sistem normal dosya gönderme ve alma sistemleri gibi çalışmaz. Aradaki en büyük normal bağlantıları istenilen bilgiyi aldıktan sonra bağlantıyı kapatırlar. Socket bağlantılarında ise veri alışverişinden sonra bağlantı kopartılmaz. Bu bağlantılar ya sunucu tarafındaki iletişimin kesilmesi ya da Flash Player […]