Node.js Dersleri : Bölüm 5 - Node.js ve Socket.io ile Multiplayer Çizim
Şimdi farkettim de 1 aydır iş yoğunluğundan yeni yazı yazamaz olmuşum. Hele hele node.js konusunda baya olmuş :) Bu sefer biraz hızlandırılmış biraz da sert bir ders hazırladım. Bu dersimizde; node.js, socket.io ve node-static kullanarak nasıl çoklu kullanıcılı çizim aplikasyonu hazırlarız bunu anlatacağım. Dersin içeriği aslında node.js ile birlikte canvas nasıl çalışır, nasıl kullanılır'a kadar gidiyor haliyle rahat kafada bu dersi okuyun derim :D
Şimdiye kadar; Node.js nedir, Nasıl site yapılır, Nasıl chat sistemi yapılır derslerini anlattım. Eğer okumadıysanız kesinlikle öncelikle onlara bakın. Şimdi ise herşeyi harmanlayıp bir çizim aplikasyonu yapacağız. Bu aplikasyonda; kullanıcı login olduğunda kendine özel bir renk belirlenecek, istediği şekilde çizim yapabilecek, ayrıca diğer kullanıcılar bağlandığında aynı ekranda çizime devam edebilecekler. Ayrıca en güzel özellik olarak isterse telefondan girerse bu işlemleri aynen desktopta olduğu gibi telefonda yapabilecek. (ki tabii burada bir parantez açayım çünkü android galaxy s3'te denediğimde biraz ağır çalıştı kabul ediyorum :) canvas-socket konusunda android biraz ağır kalıyor.)
Şimdi öncelikle projemin son haline bu github sayfasından ulaşabilirsiniz. İstediğiniz gibi inceleyip denersiniz. Zaten kodların içinde satır satır neyin ne işe yaradığı, ne yaptığı hakkında bilgiler bulunuyor. Tabii lütfen kodu ticari işlerde kullanmazsanız ve sitenizde paylaşırken de isim verirseniz çok mesut ve bahtiyar olurum. ;)
Öncelikle her zamanki gibi bir klasör açıyoruz ve administrator modda açtığımız command prompt'umuzu aynı klasöre götürüyoruz. Sonrasında ise "npm install socket.io" diyerek kurulumlarımıza başlıyoruz (eğer npm diye birşey yok hacı diyen bir hata alırsanız nodejs'in sitesine girip yeni versiyonu yükleyin. Eskisinde destek sağlamayabiliyor). Kurulum bittikten sonra ise "npm install node-static" diyerek node-static library'imizi kuruyoruz. Şimdiye kadar express kullanan ben için bu node-static aslında çok rahat geldi. Şöyle ki; node-static'in yaptığı tek şey belirttiğiniz adresteki statik dosyalarına kolayca link üzerinden ulaşmanızı sağlıyor. Yani express'teki gibi birçok kodla uğraşmanıza gerek kalmıyor. Ayrıca express'in 3 versiyonunda socket.io ciddi problemli :( . Bir şekilde çalıştırmayı becerebiliyorsunuz ancak randımanlı olmuyor nedense. Maalesef ki community tarafından yürütülen library'lerde böyle problemler olabiliyor. Node-static kurulumunu da hallettikten sonra öncelikle klasörünüzün içinde "assets" adında bir klasör açıyorsunuz. Burada statik dosyalarımızı tutacağız. Sonrasında ise ana klasörde "app.js" dosyamızı yani serverside js dosyamızı yaratıyoruz. Ve kodlamamıza başlıyoruz; (Tavsiyem github sayfamdan kodu alıp çalışmanız çünkü gösterimi burada zor olduğundan localinizde çalışarak daha rahat edersiniz.)
Her satırın ne iş yaptığını dosyada kısaca anlattım. Zaten bir önceki dersimi eğer okuduysanız bu kod size çok kolay gelecektir. (olay client-side tarafında dönüyor bu sefer :)) Burada yeni olarak;
var file = new static.Server('./');
file.serve(req, res);
kısımları var. İlk satırda node-static library'imize nereden itibaren statikleri okuması gerektiğini gösteriyoruz. "./" kısmı ana klasörden okumasını sağlatıyor. İkinci kısımda ise statik dosya okumalarının node-static üzerinden yürütülmesini sağlıyoruz. Bunun dışındakiler zaten daha önceki derslerimde belirttiğim şeyler. (evet okumadıysanız öncekilere bir göz atın :D)
Bunu app.js dosyamıza kopyaladıktan sonra geliyoruz asıl iş olan statik dosyalarımıza. Öncelikle kısaca canvas nedir, ne işe yarar, ne yapılır konusu ile başlayayım. Canvas; html 5 ile hayatımıza giren, üzerinde javascript ile birlikte grafiksel işlemler yapmamıza olanak sağlayan html elemanı. İster çizim yapın, ister yazılar yazın, ister resim ekleyin, ister karakterler yaratın. Ne gibi delilikler yapılabiliceğini google'da "Canvas html5 examples" aratarak çok rahat bulabilirsiniz :) Benim en çok beğendiğim örnek ise http://www.chromeexperiments.com/arcadefire/ adresindeki ilk html5 klip. Tabii bu projemizde yaptıklarımız örneklerin %1 diyebiliriz :)
Kısaca canvas hakkında bilgi verdiğime göre koda geçebilirim. (kodu bu github sayfasından görebilirsiniz) Kodu anlatırken tasarımda kolaylık olsun diye "Modernizr" ve "Normalize.css" kullandım. İkisi de opsiyoneldir yani ister kullanın ister hiç bulaşmayın :) Index.html ve global.css dosyalarında çok basit bir kod yazıyoruz. Sadece işlemlerimizi kolayca gerçeleştirelim diye. Index.html'de dikkat etmeniz gerekenler;
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<canvas id="cizimEkrani" width="2500" height="2500"></canvas>
Bu iki satırda yaptığım; ilkinde telefonlardan girildiğinde browser'ın standard görüntü sağlamasını ve görüntüyü büyültme-küçültme gibi işlemlerin devre dışı kalmasını sağlıyorum. Böylelikle çizim sırasında görüntü problemleri oluşmuyor haliyle touch event'ları daha düzgün çalışıyor. İkinci satırda ise canvas elemanımızı yaratıyorum. 2500x2500 vermemin sebebi ise her ekranda oturabilecek şekilde görüntü oluşturmak. Eğer canvas'ınızı ekran boyutuna göre düzenlerseniz görüntüde bozukluklar ve karşı kullanıcılara doğru değerleri verememe gibi problemler oluşuyor. Bu yüzden büyük boyut belirtip, css'te de html tag'ına "overflow:hidden;" verdim ki nereden açılırsa açılsın scroll çıkmasın ama görüntü düzgün gelsin.
Şimdi ise global.js dosyamıza geçiyoruz. Burada yaptıklarımı global.js dosyasında satır satır aslında anlattım. Bu yüzden önemli kısımları anlatacağım ki ne siz sıkılın ne de ben yazı tekrarı yapayım :)
$('#cizimEkrani')[0].getContext('2d') : Ayarlar kısmında bulunan bu kod; canvas ekranımızda işlemler yapmamızı sağlıyor. Bu kod çalıştırıldığı vakit bize canvas üzerindeki bütün event ve property'leri dönüyor. Burdan gelen bilgilerle çizimlerimizi sağlıyor veya üzerindeki çizimlerin detaylarına ulaşabiliyoruz.
event.targetTouches : Bu property sayesinde kısaca telefondan/tabletten gelip gelmediğini anlayabiliyoruz. Bu property bize touch bilgilerini dönüyor ve böylelikte aynı mouse'un bilgilerini kullanır gibi touch bilgilerini kullanmamıza olanak sağlıyor. Yanına verdiğiniz rakama göre touch sayısını kontrol edebiliyorsunuz ve istediğiniz takdirde multi-touch bir sistem yapabiliyorsunuz.
CizimYap() : Bu fonksiyonun içi tamamen önemli diyebilirim :) "beginPath()" ile çizime başlıyoruz. "moveTo()" ile başlangıç noktamızı belirliyoruz. "LineTo()" ile gideceğimiz noktayı gösterip, "lineWidth" ile çizgi kalınlığını ayarlıyoruz. "strokeStyle" ile rengimizi ayarladıktan sonra "stroke()" ile son vuruşu yapıyoruz. Buradaki bir diğer noktada getContext'ten gelen bilgiler üzerinde çalıştığımız nokta. Dikkat edin canvas değil, canvas'tan gelen getContext üzerinde çalışıyoruz. Bunu şöyle düşünebilirsiniz; Canvas bizim masamız, getContext kısmı ise masamızın üzerindeki defterimiz. Basit olarak böyle anlatılabilir :)
touchstart, touchmove, touchend : Kısa ve net; Dokunmatik event'lar :) Aynı mouse event'ları gibi çalışsalar da tek fark yukarıda belirttiğim targetTouches kısmı.
Global.js'de işlemler ise kod sırasıyla;
Öncelikle modernizr ile canvas özelliği desteklenip desteklenmediği kontrol ediliyor.
Ayarlar objesinde her zaman kullanacağımız bilgiler ekleniyor. Böylelikle temiz kod yazıyoruz :D
cizimYap fonksiyonu ile cizimlerimizi gerçekleştiriyoruz.
telefonMu fonksiyonu ile sayfaya telefon-tablet tarafından girilip girilmediği test ediliyor.
bilgiGonder fonksiyonu ile socket tarafından server'ımıza kullanıcının yaptığı bütün çizim aktiviteleri yollanıyor. Server'dan da diğer bütün kullanıcılara bilgiler hemen yollanıyor.
Canvas üzerinde "mouse" ve "touch" eventlarımızı yaratıyoruz ve bizim yazdığımız kodların default olarak çalışmasını sağlıyoruz ki diğer türlü yaptığımız işlemler düzgün çalışmayabilir.
En son ise socket'ten gelen bilgilerle ne yapılacağını yazıyoruz. İlk olarak datanın yeni bir çizim başlangıcı mı olduğunu kontrol ediyoruz. Sonrasında ise çizimin başladı mı kontrolünü yapıp çizimi ekrana yansıtıyoruz.
Aşağıdaki ekranda ise bütün kodları görebilirsiniz (tabii daha önce de dediğim gibi localinizde çalışmanızda fayda var.)
Artık node.js üzerinde çizimlerimizi çoklu kullanıcılı yapabiliyoruz. Yazıda belirttiğim gibi bu github sayfasından bütün projeye ulaşabilirsiniz. Derslerin devamında planım database konularına girmek. Tabii zaman vermeyeceğim bu sefer, işler yüzünden uzayabiliyor :)















