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

——————————————————————————————-
Yazarı Takip Edin (Bilal):
Tüm Yazılar | Twitter.com/3bilal | Facebook.com/3bilal

VN:F [1.9.11_1134]
Rating: 9.0/10 (10 votes cast)
Ok Atma (Deneysel), 9.0 out of 10 based on 10 ratings

18 Responses to “Ok Atma (Deneysel)”

  1. avatar Selçuk diyor ki:

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

  2. avatar Ercüment Ekinci diyor ki:

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

  3. avatar Giray Bal diyor ki:

    Flash ve Fizik
    Çok kaliteli bir konu.

  4. avatar alio diyor ki:

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

  5. avatar 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. avatar Bilal 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. avatar alio diyor ki:

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

  8. avatar 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. avatar Bilal 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. avatar 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. avatar Bilal 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. avatar kenasuka diyor ki:

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

  13. avatar Bilal diyor ki:

    teşekkürler kenasuka.

  14. avatar D3niz diyor ki:

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

  15. avatar ern diyor ki:

    spr bişi. ama kolayca hazırlayabilirsiniz demene kızdım. neresi kolay bunun

  16. avatar Bilal diyor ki:

    sondaki göz uygulaması için demişim onu :)

  17. avatar Mahmut Aydın diyor ki:

    Tek kelime ile başarılı bir çalışma.

  18. avatar dizüstü diyor ki:

    güzelmiş anlatım

Leave a Reply

*