Ok Atma (Deneysel)

Bu yazıda flash’da oyun tarzı uygulamalar geliştirmede yardımcı olan bazı tekniklerle deneysel bir uygulama yapacağız. Öncelikle yapacağımız şeyin son halini gösterelim: (tıklayıp sürükleyin ve bırakın)

Sahneye tıklayınca mouse ucunda ok ve yayın oluştuğunu, oku yalnız belirli bir alana kadar çekip bırakabildiğimizi, okun seyri esnasındaki hızının da bu çekime bağlı olduğunu, oka yerçekimi etkisi, okun rotasyonu, okun duvara sapmanması vs. gibi durumlara dikkat ediniz. Şimdi bu uygulamayı ve bahsettiğim bu etkileri nasıl yaptığımızı açıklayayım:

1. Öncelikle sahneye bir ok, yay ve duvar şeklinde klipler ekleyelim ve bunlara sırasıyla ok_mc, yay_mc ve duvar_mc adlarını verelim. Kütüphanedeki okun linkage kısmına da ‘ok’ diyelim(şekil-1). Ayrıca dikkat etmemiz gereken bir şey de; okun registration point noktasını kuyruğu, yayın da tutulacak kısmı olması gerekiyor(şekil-2).

[şekil-1] [şekil-2]

2. Şimdi kod yazmaya başlayalım. Kodumuz dört bloktan oluşuyor, ilk olarak değişkenlerimizi yazıyoruz: (Açıklamalar kodlarla aynı satırda)

var hip:Number   /*hipotenüs uzunluğu, yani mouseun yaydan uzaklığı*/
var gerim:Number=ok_mc.width-10   /*okun çekilme mesafesi(genişliğinin 10 eksiği kadar çekilsin)*/
var artX:Number   /*mouse'un gerim uzunluğunu geçmesi durumundaki okun x konum artışı*/
var artY:Number   /*mouse'un gerim uzunluğunu geçmesi durumundaki okun y konum artışı*/
var birak:Boolean=false   /*oku bırakma durumu (false, yani ok bırakılmamış)*/
var duv:Boolean=false   /*okun duvara değme durumu (false, yani ok duvara saplanmamış)*/
var hizX:Number   /*okun x hızı*/
var hizY:Number   /*okun y hızı*/
var gr:Number=0   /*yer çekim miktarı*/
var brk_yon:Number   /*okun soldan sağa mı sağdan sola mı bırakıldığı durumu - bu daha sonra açıklanacak-*/

3. Bu kodları ekledikten sonra ok ve yayın ilk aşamada (tıklama olmadığı zaman) görünmemesini sağlıyoruz:

ok_mc.visible=false
yay_mc.visible=false

4. Şimdi sahneye tıklanma ve tıklamayı bırakma esnasında yapılacakları yazıyoruz;

stage.addEventListener(MouseEvent.MOUSE_DOWN,tik)   /*sahneye tıklamada çağırılacak fonksiyon atanıyor*/
function tik (e:MouseEvent){   /*fonksiyonu yazıyoruz*/
gr=0   /*tıklama esnasında önceki yerçekimi değerini sıfırlıyoruz*/
birak=false   /*bırakma yok*/
duv=false   /*duvara temas yok(bunlar daha sonra kullanılacak)*/
yay_mc.x=mouseX;yay_mc.y=mouseY   /*yayı mouse koordinatlarına getiriyoruz*/
ok_mc.visible=true   /*oku görünür yaptık*/
yay_mc.visible=true   /*yayı görünür yaptık*/
}
 
stage.addEventListener(MouseEvent.MOUSE_UP,brk)   /*sahneye tıklama bitince çağırılacak fonksiyon atanıyor*/
function brk (e:MouseEvent){   /*fonksiyonu yazıyoruz*/
yay_mc.gotoAndPlay(2)   /*yay_mc nin içinde tıklamayı bıraktığımız esnada sarsılması için kısa bir titreme asnimasyonu yapmıştım. 6 karelik bu animasyonun ilk karesine stop() komutu verdim, ikinci kareye de oku bırakınca çıkacak sesi ekledim. Burada tıklama olunca ikinci kareye gidip oynamasını söylüyoruz.(bunu ok için de yapmıştık onu da aşağıda göreceğiz)*/
birak=true   /*bırakma var*/
hizX=(ok_mc.x-yay_mc.x)/3*2   /*okun x hızı, ok ve yayın x konumları arasındaki uzaklığın 3/2 katı olsun*/
hizY=(ok_mc.y-yay_mc.y)/3*2   /*okun y hızı, ok ve yayın y konumları arasındaki uzaklığın 3/2 katı olsun*/
brk_yon=mouseX-yay_mc.x   /*bırakma yönü. Eğer ok sağa doğru atılmışsa bu değer negatif, sola doğru atılmışsa pozitif çıkacak. Bunu okun rotasyon yönünü bulmada kullanacağız*/
}

5. Bu aşamada yukarıda bırakma ve duvara saplanma durumlarına false ve true dediğimiz ‘birak’ ve ‘duv’ isimli boolean’lerin değişmesiyle yani okun bırakılıp bırakılmadığı ve duvara saplanıp saplanmadığı durumlarını değerlendireceğimiz sürekli çalışacak olan enterframe fonkisyonumuzu yazalım.(açıklamalardan dolayı kodlar biraz karışık göründü..)

addEventListener(Event.ENTER_FRAME,calis)   /*sürekli çalışacak fonksiyonu tanımlıyoruz*/
function calis(e:Event){   /*fonksiyonu çağırıyoruz*/
 
if(!birak && !duv){   /*eğer bırakma ve duvara saplanma durumu yoksa. Burada iki durum söz konusudur, ya mouse'un yaya uzaklığı gerimden büyüktür ya da küçüktür.(bunun için aşağıdaki açıklama kısmına bakınız)*/
hip=Math.sqrt(Math.pow((mouseX-yay_mc.x),2)+Math.pow((mouseY-yay_mc.y),2))   /*hipotenüs uzaklığını yani mouse'un yaya olan uzaklığını hesapladık*/
 
if(hip<=gerim){   /*eğer okla yay arası uzaklık gerimden küçük veya eşitse;*/
ok_mc.x=mouseX;ok_mc.y=mouseY   /*okun yeri mouse olsun*/
}else{   /*değilse;*/
artX=gerim*(mouseX-yay_mc.x)/hip   /*(bunun için sayfa sonundaki açıklama kısmına bakınız)*/
ok_mc.x=yay_mc.x+artX   /*okun yeni x konumu*/
artY=gerim*(mouseY-yay_mc.y)/hip   /*(bunun için sayfa sonundaki açıklama kısmına bakınız)*/
ok_mc.y=yay_mc.y+artY   /*okun yeni y konumu*/}
ok_mc.rotation=yay_mc.rotation = Math.atan2(ok_mc.y-yay_mc.y,ok_mc.x-yay_mc.x)*(180/Math.PI)   /*burada okun ve yayın rotasyoununu okun yatayla yaptığı açıya göre belirleyerek bunu derece cinsine çevirdik.*/}
 
if(birak){   /*bırakma varsa*/
gr-=5   /*yer çekimi etkisi*/
ok_mc.x=ok_mc.x-hizX   /*okun x konumunun her birimde azalacak miktarı*/
ok_mc.y=ok_mc.y-hizY-gr/15   /*okun y konumunu her birimde azalacak miktarı. Bu y koordinatı olduğu için yer çekimi etkisini de katıyoruz işin içine*/
 
if(brk_yon>=0){   /*oku sola doğru atmışsak(bu yukarıda açıklanmıştı)*/
ok_mc.rotation+=gr/80}   /*ok sağdan sola doğru yer çekimi ile orantılı olarak dönsün*/
else{ok_mc.rotation-=gr/80}   /*değilse tam tersi olsun*/}
 
if(ok_mc.hitTestObject(duvar_mc)&& duv==false && birak==true){   /*eğer ok ile duvar temas etmişse -hittest- ve bırakma varsa*/
ok_mc.visible=false   /*oku gösterme(bu okun yerine kütüphaneden çağıracağımız bir oku koyacağız)*/
duv=true   /*duvarla temas var*/
 
var yeni_mc:ok=new ok();   /*kütüphaneden ok ismini verdiğimiz klibi çağrmak için yeni_mc'yi tanımlıyoruz*/
yeni_mc.x=ok_mc.x   /*çağrılan yeni oku eski ok'un duvarla değme anındaki konumun oturtmak için x değerini ona eşitliyoruz*/
yeni_mc.y=ok_mc.y   /*y değerini eşitliyoruz*/
yeni_mc.rotation=ok_mc.rotation   /*ve eski okla yani okun aynı konumda ve aynı rotasyonda olması için rotasyonlarını da eşitliyoruz*/
addChild(yeni_mc);   /*yeni_mc'yi sahneye ekliyoruz*/
yeni_mc.gotoAndPlay(2)   /*saplanma esnasında tıpkı yaydaki gibi bir titreşimin olması için okun içinde bir animasyon yaptım, bu animasyonun ilke karesine stop() komutu ikinci karesine ise saplanma esnasında çıkacak sesi ekledim, burada bu aniaasyonu başlatıyoruz*/
	}
}

Kodlarımız bu kadar. Yukarıdaki işlemleri yapıp bu kodları sırayla eklersek uygulamamız sorunsuz çalışır. Şimdi yukarıda bazı kodların izahında yönlendirdiğimiz açıklamalara bakalım;

Açıklama:

artX=gerim*(mouseX-yay_mc.x)/hip
ok_mc.x=yay_mc.x+artX

Bu işlemde oku belli bir miktardan fazla çektiğimiz zaman okun mouse konumunu almayı bıraktığını ve sadece yay ile mouse arasında belli bir uzaklıkta bu düzlemde kaldığını görüyoruz yani oku çekmeyi sınırlıyoruz. Aşağıda bu sınırlama ve sınırlamanın olmadığı durumlar swf olarak gösterilmiştir. Solda sınırlamanın olmadığı, sağda olduğu durum verilmiştir:

Bunu yapabilmek için işin içine biraz daha geometri katacağız. Aşağıdaki şekil-3 üzerinden şöyle bir yorum getirebiliriz: Bizim bulmaya çalışltığımız şey; mouse gereğinden fazla uzaklaşsa bile hep belirli bir mesafe uzaklıkta kalmasını istediğimiz kırmızı noktanın koordinatları.

[şekil-3]

Bu grafiğe göre mouse ve yayı birleştiren doğru üzerinde benzer üçgenler teoremleri esaslı şöyle bir bağlantı kuruyoruz,

gerim/hip=artX/(mouseX-yay_mc.x)

buradan da artX’i yalnız bırakıp şöyle bir formülize sistem kurabiliriz;

artX=gerim*(mouseX-yay_mc.x)/hip

aynı yöntemle de artY’yi buluyoruz;

artY=gerim*(mouseY-yay_mc.y)/hip

Şimdi artX ve artY değerlerini bulduğumuza göre bunları yay_mc’nin koordinatlarına eklersek kırmızı noktanın yani ok_mc nin koordinatlarını bulmuş oluruz.
Bu yöntem oldukça faydalı olmakla beraber bazı uygulamaların da esasını oluşturan geometrik bir yöntemdir.

# Size bu yazıya bonus olarak aşağıdaki takip eden göz uygulamasını da veriyorum. Bunun da mantığı üstteki durum gibidir. Bu uygulamayı yukarıda bahsettiğim geometrik esaslara dayanarak kolayca hazırlayabilirsiniz.

Uygulamaların fla dosyalarını aşağıdaki bağlantılardan indirebilirsiniz.

Kaynak Dosyaları:
ok_atma.fla | goz.fla

Takip Edin:
Tüm Yazılar | Tüm Yazılar RSS | Twitter
——————————————————————————————-

VN:F [1.8.2_1042]
Rating: 9.0/10 (6 votes cast)
Ok Atma (Deneysel)9.0106

14 Responses to “Ok Atma (Deneysel)”

  1. Selcuk Selçuk diyor ki:

    Güzel anlatım…Bu tür derslerinin devamını bekliyorum…

  2. Ercüment Ekinci Ercüment Ekinci diyor ki:

    güzel ne kelime..harika bir ders…
    Tebrik ediyorum Fullusi..

  3. Giray Bal Giray Bal diyor ki:

    Flash ve Fizik
    Çok kaliteli bir konu.

  4. alio alio diyor ki:

    Çok güzel bir ders hatta harika :) tebrikler.

  5. alio alio diyor ki:

    yalnız kafama takılan birşey oldu. bazen ok’un sadece ucu saplanıyor bazen de yarısından fazlası saplanıyor.

    Bu herhangi bir kritere mi bağlı? rasgele oluyor gibi duruyor.

  6. Fullusi Fullusi diyor ki:

    Teşekkür ederim herkese, beğendiğinize sevindim.:)
    Alio, okun saplanması ok ve duvarın hittest anında gerçekleşiyor, bu nedenle bir miktar okun hızına yani okun her karede aldığı yola bağlı. ama rastgele de diyebiliriz çünkü ayarlanmış bir şey değil.:)

  7. alio alio diyor ki:

    Aslında ok’u tutup çekiriyoruz ya çekme şiddetine göre duvara saplansa daha güzel olur gibi :)

  8. Selman KURT Selman KURT diyor ki:

    Fullusi seni burda görmek ne güzel,
    Çok güzel ders olmuş eline sağlık, ayrıca her satırda yazdığın açıklamalar dersi daha anlaşılır hale getirmiş. Tebrikler,
    devamını bekleriz :)

  9. Fullusi Fullusi diyor ki:

    Alio haklısın, ama esasında çekimle yine biraz bağlantılı.
    Selman sağol, seni de burada görmek çok güzel..:)

  10. memet memet diyor ki:

    slm guzel bir paylasım emegine saglık yanlız ben ilk kez flash ogrenmeye kara verdim ve yukarda yapılanları hangi menu kullanarak yapmam gerek anlamadım ornegin linkage diye bir sey cıkmadı bende programı kullanmasını biilmiyorum yani once menuler hakkında nasıl bilgi alırım yardımcı olurmusunuz

  11. Fullusi Fullusi diyor ki:

    @memet Linkage, kliplerin kütüphanedeki bağlantı isimleridir. Kütüphaneden bir klip çağırmak için önce ona bir isim verir sonra kodlarda bu ismi kullanırız. Linkage verebilmek için ctrl+L ile, veya window menüsünden “Library” kutusunu açıyoruz ve istediğimiz klibe sağ tıklayıp şekil-1 deki işlemi yapıyoruz.
    Aslında bu yazı biraz orta düzeye yönelik bir yazıydı. O sebepten bazı temel kısımları okuyucu biliyordur öngörüsüyle atladım.. Bu site yeni olduğundan henüz her seviye ve konuda dersler yok ama internet sınırsız kaynak, mesela başlangıç düzeyi mevcut flashdersleri.com sitesine bakabilirsiniz..

  12. kenasuka kenasuka diyor ki:

    Flash yönü basit matematik yönü karışık bir uygulama.Çok güzel olmuş eline sağlık.

  13. Fullusi Fullusi diyor ki:

    teşekkürler kenasuka.

  14. D3niz D3niz diyor ki:

    Çok güzel bir anlatım olmuş. :)
    Teşekkürler.

Leave a Reply