28 Aralık 2009 Pazartesi

Yerine Tetikleyiciler - 'Instead Of' Triggers (MS SQL)

Microsoft SQL Server'da Instead of trigger'ların bize sağladığı en önemli avantaj, güncellenemeyen view'lerin güncellenebilir yapılmasıdır. Bu yazıda da güncellenemeyen bir view'e instead of insert trigger yazarak view'e insert yapılmasını sağlayacağız.

İlk olarak tablolarımızı oluşturmamız gerekiyor. Bir önceki yazıda (Linq) kullandığımız tabloları kullanacağız. İster elle oluşturabilirsiniz isterseniz de aşağıdaki sql sorgusunu veritabanınızda çalıştırabilirsiniz. Toplam 3 adet tablomuz bulunmakta, kısaca açıklamak gerekirse, student tablomuzda öğrenci verileri tutulmaktadır.

Bir öğrencinin istediği kadar ders alabilmesi için student_course_join tablomuz bulunmaktadır ve doğal olarak dersleri kayıt ettiğimiz bir de course tablosu bulunmaktadır.

19 Aralık 2009 Cumartesi

Hala Linq Kullanmıyor musunuz?

.Net için ufak bir uygulama geliştirirken, bu uygulamada veritabanı bağlantısını Sql Data Client ile sağlıyordum, dolayısıyla oluşturduğum her yeni dosyada kodlamaya başlamadan önce "using System.Data.SqlClient;" satırını eklemek zorundaydım. Oysa "using System.Linq;" satırı hazır olarak geliyordu. Bende Microsoft'ta çalışanların elbet bir bildiği vardır diye düşündüm ve kodlamayı yarım bırakarak google'a "linq tutorial" yazıp arattım.

Yeni şeyler öğrenmek her zaman insana zor gelir, ancak linq öğrendikten sonra, neden daha önce bakmadım diye kendime sordum. Çünkü her seferinde bağlantı açıp kapamak, sql sorguları yollayıp sonuçları okumak gibi işlemler linq ile çok kolay.

Bu yazıda çok basit bir uygulamayı linq kullanarak nasıl daha basit hale getirilebileceğini göreceksiniz.Bu uygulamada bir tane öğrenci tablomuz, bir tane de ders tablomuz olacak ve her öğrencinin istediği kadar ders seçebilmesi için de bunları bağlayan bir join tablomuz olacak.

İlk olarak tabloları oluşturmak için, "SQL Serve Management Studio Express"i başlatıyoruz. "Deneme" adında bir veritabanı yaratıp,  aşağıdaki tabloları oluşturuyoruz. Tablo isimlerini ingilizce olarak yazıyorum, eğer türkçe oluşturursak kod içerisinde ingilizce-türkçe karışık bir notasyon oluşacaktır.

26 Kasım 2009 Perşembe

Basit PHP Kurulumu

Eğer php ile çalışıyorsanız, bilgisayarınıza attığınız her formattan sonra apache, php, mysql, phpmyadmin gibi araçları kurmak sizi de sıkmış olmalı. Daha önce bir yazıda apache, php ve mysql'in nasıl kurulduğunu anlatmıştım, ancak bu işlemin bir alternatifi varken aynı işlemleri tekrar tekrar yapmak gereksiz ve sıkıcı olabilir. İşte bu yüzden, yine bir format sonrası, internette kısa bir araştırma yaptıktan sonra XAMPP'i buldum.

XAMPP, geliştirme sırasında kullanma ihtimaliniz yüksek olan bir çok araç barındırmaktadır. Windows paketinde apache, openssl, mysql, php, phpmyadmin, webalizer, geoip vb. programlar/araçlar içermekte. Ayrıca XAMPP çeşitli platformlarda da bulunmaktadır. Bu platformlar, Linux, Windows, Mac OS X ve Solaris.

Windows için son versiyonunu http://sourceforge.net/projects/xampp/files/ adresinden bulabilirsiniz. Bu sayfadaki kurulum dosyasını indirdikten sonra, bir kaç basit adımda kurulumu tamamlıyoruz.

xampp1

xampp2

Daha fazla bilgi için http://www.apachefriends.org/en/xampp.html adresini inceleyebilirsiniz.

18 Kasım 2009 Çarşamba

Unreal 3 Artık Ücretsiz mi ?

udk-logo

Önce Unity şimdi de Unreal Development Kit

Epic Games'in Unreal 3 Motorunu bilmeyeniniz yoktur. 2009 yılında Next-Gen sıfatıyla bir çok AAA kalitesinde oyun yayınlandı ve bu oyunların birçoğu unreal 3 motoruyla oluşturuldu. Bunlardan birkaçı; Gears of War, Wheel Man, Army of Two, BioShock, Mass Effect, Mirror's Edge, Turok, X-Men Origins: Wolverine ...

Tahmin edebileceğiniz gibi bu motoru kullanmanın da bir bedeli var, yani vardı, artık hobi veya öğrenme amaçlı kullanıcılar bu araça (UDK - Unreal Development Kit) kolaylıkla sahip oluyor.

5 Kasım 2009 Perşembe

Bedava Unity

1
Başka yerlerde de dikkatinizi çekmiş olabilir, Unity Technologies, yakın bir zamana kadar sattığı 'Unity Indie' adlı video oyunu oluşturma aracının ismini sadece 'Unity' olarak değiştirerek kendi sitesinden bedava olarak indirmeye sundu.

2

Bu aracı 60 gün içinde satın alan kişiler için para iadesi hakkına veya pro sürümüne indirimli olarak sahip olma seçeneğinine sahip olacak.

3

Unity'nin özellikleri ilk bakışta pro versiyonuna göre kısıtlı gelebilir, ancak 'Web Deployment' özelliği ve düzgün bir editörünün olması büyük bir artı. Eğer kısa zamanda, son teknolojiyi değil de, eski makinalarda da çalışabilecek bir oyun oluşturmak istiyorsanız, unity tam size göre :)

4

Unity ile neler yapılabileceğini görmek için kendi sitesine veya http://blurst.com/'a bakabilirsiniz.
(Blurst 2008 yılında kurulumuş olan, miniclip benzeri bir oyun portalı. Ancak birçok oyun portalından farklı olarak sitede bulunan oyunlar unity ile oluşturulmuş. Adobe Director'a göre daha esnek olan unity sayesinde internet sayfasında oynanabilen, 3 boyulu ve yenilikçi oyunlar geliştirmişler.)

5

Lisans karşılaştırmalarına buradan, unity'nin özelliklerine ise buradan ulaşabilirsiniz.

20 Ekim 2009 Salı

Battlefield Heroes

Battlefield Hereos, EA Games'in internet üzerinden bedava olarak dağıttığı, çok oyunculu bir TPS oyunu. En son yayınlanan trailer'ını aşağıda bulabilirsiniz.



Battlefield heroes uzun zamandır internetten bedava olarak dağıtılıyormuş ancak ben henüz gördüm. Aslında oyunu oynama sebebim, ilk olarak ücretsiz olmasıydı, ancak denedikten sonra oyun oldukça zevkli geldi. İlk yüklediğimde uzun bir süre başından kalkamadım.

screen-6-f

Oyundan biraz bahsetmek gerekirse, oyunun kendine göre bir havası var. Grafikler çizgi film stilinde. Oynanış bakımından ilk oynayanlar için biraz kullanışsız gelebilir ama biraz vakit harcadıktan sonra kontrollere alışıyorsunuz. Oynanabilirliği de çok yüksek olmadığını söyleyebilirim. İlk denemelerinizde canınızı biraz sıkılabilir, kontrollere ve oyuna alışmak biraz zaman alıyor.

Oyunu bilgisayarınıza kurmak için https://www.battlefieldheroes.com/playnow adresine gitmeniz gerekiyor. Burada firefox ya da internet explorer kullanıyorsanız sizden bir plug-in kurmanızı istiyor. Bu plugini kurtuktan sonra, adrese yapıcağınız ziyaretlerde, otomatik olarak güncelleştirmeler kontrol edilip oyun başlatılıyor.

1

11 Ekim 2009 Pazar

Adobe Director ile Basit Bir Oyun

Bu eğitselde, basit olarak, adobe director kullanarak nasıl bir oyun yapılacağını göreceksiniz. İnternet üzerinden satılan ve oldukça ünlü olan "MarbleBall"a benzer bir oyun oluşturacağız. Kısaca gerekli adımları sıralamak gerekirse;
1 - Oyun için modellerin hazırlanması ve uygun bir formatta export edilmesi.
2 - Menu ve bölümlerin bitiş ekranları için gerekli flash dosyalarının hazırlanması.
3 - Hazırlanan dosyaların director'a import edilmesi ve ardından küçük bir script yazılmasıyla oyunun tamamlanması.

Birinci Bölüm: 3dsMax ile modellerin hazırlanması

Yapıcağımız oyun sadece öğrenim amaçlı olduğundan grafiklere fazla önem vermiyoruz. Topun ilerleyebileceği bir sahne hazırlıyoruz (Aşağıdaki gibi)

director_2

Burada dikkat edilmesi gereken, isimlendirmedir. Sahnenizi tamamladıktan sonra, oluşturduğunuz topa 'ball' ismini verin. Geriye kalan, topun üzerinde gezmesi gereken geometrilerin hepsini seçin ve onları gruplandırın.

director_3

Bu grubu 'levelgeo' olarak adlandırın.

Oyunumuzda bir seviyenin tamamlanması için, topun bir yere ulaşması gerekiyor. Biz de bu yeri bir kutu ile belirtiyoruz.

director_4

Bu kutunun ismine 'levelfin' adını veriyoruz.

Artık oyun için bir sahnemiz var. Şimdi bunu director'a import edebilmek için '.w3d' formatında export ediyoruz. Dosyaya 'level1.w3d' adını veriyoruz. Küçük bir hatırlatma, bu eğitselin sonunda, oluşturduğumuz tüm dosyaları bulabilirsiniz.

İkinci Bölüm: Flash ile gerekli menü ve ekranların hazırlanması

Kullanıcının rahatça oynunuzu oynaması için oyunun düzgün bir menüsü olmalı. Menüyü director'da da hazırlayabilirsiniz fakat bu işlem flash'a göre daha uzun ve daha zordur. Arayüz oluştururken flash'ı kullanmak daha akıllıca olacaktır.

Yeni bir flash dosyası (ben A.S 2 kullandım) oluşturun ve 'menu.fla' olarak kaydedin. Menünüzün sığabileceği bir çözünürlük seçin, ben 640x480 seçtim. Bundan sonra düzgün bir menü oluşturun. Bu eğitselde az da olsa flash bildiğinizi varsayıyorum. Ben aşağıdaki gibi bir menü oluşturdum.

director_5

Burada rastgele dikdörtgenler çizdim, özel birşey yok. Sadece 'yüksek puanlar' ve 'kim yaptı bunu' butonları için iki tane movieclip oluşturdum (resimde sağda). Bu butonlara tıklanınca bu movieclip'ler menünün önüne geliyor. 'Tamam'a tıklanınca da geri gidiyor. Bunun için ufak bir script yazdım. İlk frame'e bu moviecliplerin gitmesi için aşağıdaki scripti ekledim.

{code type=php}
_root.creditsbox._x = 10000;
_root.scorebox._x = 10000;
{/code}

Yine bu scripti her movieclip'teki 'Tamam' butonlarına ekledim. Menüdeki tuşlara tıklandığında da bu moviecliplerin ekrana gelmesi içinde aşağıdaki scripti ekledim.
İlki 'Kim Yaptı Bunu' butonu için, ikinciside 'Yüksek Puanlar' için, zaten script'tende belli oluyor.

{code type=php}
on(press)
{
_root.creditsbox._x = 107.6;
_root.creditsbox._y = 147.1;
}

on(press)
{
_root.scorebox._x = 107.6;
_root.scorebox._y = 112.1;
}
{/code}

Son olarak da 'Yeni Oyun' butonuna basıldığında bizim director'a haber vermemiz gerekiyor. Bunun için 'Yeni Oyun' butonuna aşağıdaki scripti ekliyoruz.

{code type=php}
on(press)
{
getURL("event:triggerNewGame");
}
{/code}

Bu ne demek oluyor hemen açıklıyorum. Director içinde 'triggerNewGame' diye bir fonksiyon oluşturursanız, bu butona basıldığında otomatik olarak director'da o fonksiyon çağırılacaktır.

İkinci olarak level tamamlandığında da kullanıcıyı bir ekranla karşılamalıyız. Bunun için 'fin.fla' adında bir flash dosyası oluşturuyoruz. Yine bir arayüz oluşturup kullanıcının bu ekranı geçmesi için bir buton koyuyoruz. Tekrar director'a mesaj gönderebilmesi için ona da küçük bir script ekliyoruz.

{code type=php}
on(press)
{
getURL("event:triggerOk");
}
{/code}

director_6

Bu durumda menümüzde hazırlanmış oldu. Şimdi ise son bölüme geçiyoruz. Burada oluşturduğumuz herşeyi birleştirip bir oyun haline getireceğiz.

Üçüncü Bölüm: Bir araya getiriyoruz

Adobe Director'u başlatın. Yeni bir dosya oluşturun ve 'clumsyball' olarak kaydedin. Bu aşamadan sonra isterseniz sürükle bırakla, isterseniz import seçeneğiyle oluşturduğumuz dosyaları director'un içine atın.

director_7

Stage'e import ettiğimiz 'menu'yü ekliyoruz. Ekledikten hemen sonra 'Property Inspector'den hem 'start frame'ini hem de 'end frame'ini 1 yapıyoruz.

director_8

Daha sonra flash sekmesinde, scale seçeneğini 'no scale' yapıyoruz.

director_9

Daha sonra stage'e 'level1'i ekliyoruz. Ekledikten sonra yine property inspector'den boyutunu 640x480 olarak ayarlıyoruz, bu sefer start ve end frame'ini 2 yapıyoruz.

director_10

Son olarak da 'fin'i ekliyoruz. Onunda start ve end frame'ini 3 yapıyoruz. Flash sekmesinden de 'no scale' seçeneğini seçmeyi unutmayın.

Gerekli tüm ayarlamaları yaptık, şimdi ise script yazmaya başlayabiliriz. Stage'e eklemeden önce scriptlerimizi oluşturuyoruz. Sağ altta bulunan 'Behavior Inspector'den 'New Behavior' seçeneğini seçiyoruz.

director_11

Director'da scriptler 'Behavior' olarak adlandırılmıştır. İlk behavior'umuza 'menu_behavior' adını veriyoruz. Bu kodu menüye ekleyeceğiz. Burada daha önce flash'ı oluştururken belirttiğimiz 'triggerNewGame' fonksiyonunu tanımlıyoruz. Bu fonksiyonda çok önemli bir kod yok, sadece 2.frame'e gitmesini söylüyoruz. on exitFrame'de ise, bu frameden ayrılmamasını sağlıyoruz aksi taktirde menüde işlem yapamadan bir sonraki frame'e geçer.

{code type=css}
on triggerNewGame
beep
go to frame 2
end

on exitFrame
go to frame 1
end
{/code}

İkinci olarak, oyun tamamlandığındaki frame için bir behavior ekliyoruz. Bunun da adı 'fin_behavior' olsun. Yine daha önce flash'da belirttiğimiz 'triggerOk' fonksiyonunu tanımlıyoruz. 'exitFrame'de bu frame'den ayrılmaması için bir kod yazıyoruz. Bir öncekiyle aynı işi yapıyor ancak farklı şekilde, sadece gösterim amaçlı.

{code type=css}
on exitFrame
_movie.go(_movie.frame)
end

on triggerOk
beep
go to frame 1
end
{/code}

Şimdi ise en önemli kısıma geldik. 2. frame için kod yazmaya başlıyoruz. Ama bu behavior'u eklemeden önce cast'e bir media element eklemeliyiz. Bunun için insert->media element->Physics'i seçiyoruz. Oyunumuzdaki tüm çarpışma kontrolünü ve simülasyonu bu obje(PhysX) yapıcak.

director_12

Son olarak, oyundaki işlemlerin yapılması için bir behavior daha ekliyoruz. Eklediğimiz bu behavior'a 'game_behavior' ismini verip aşağıdaki kod'u ekliyoruz. Tüm açıklamalar kodun üzerinde yapılmıştır.

{code type=css}
-- Basit bir marbleball oyunu
-- bu property'ler ok tuşlarını tutmak için kullanılıyor
property pLeftArrow, pRightArrow, pDownArrow, pUpArrow

-- level'ımızı tutan property
property p3Dmember
-- ball geometrimize erişmemize yarayan değişken
property pBall

-- sahne kamerası
property pCam
-- level geometrimizi tutan property
property terrain
-- levelfin kutusu için property
property pFin

-- Physx ile ilgili olan değişkenler
-- fizik objemizi tutuan değişken
property pDirPhyz
-- adım zamanı ve alt adımlar
property pTimeStep,pSubSteps
-- levelgeo için rigid body
property rterrain
-- ball için rigid body
property rBall
-- fin kutusu için rigid body
property rFin

-- kameranın yeni pozisyonunu hesaplarken kullandığımız
-- geçici bir değişken
property t
-- kameranın ile top arasındaki mesafenin vektörü
property distvec
-- top'un ilk pozisyonu
property first_pos


-- bu ilk kez çağırılacak olan fonksiyondur.
on beginSprite me
-- her seferinde member'a erişmek zorunda kalmamak için
-- bir değişkene atıyoruz.
p3Dmember = member("level1")
p3Dmember.resetWorld()

--PhysX içinde aynısını yapıyoruz, ve istediğimiz değişkenleri
-- belirtiyoruz.
pDirPhyz = member("phsyX")
pTimeStep = 0.025
pSubSteps = 5
-- Phsyx ile level'ımızı bağlıyoruz.
pDirPhyz.Init(p3Dmember, vector(1,1,1),#equal, pTimeStep, pSubSteps )

-- çeşitli parametreleri physx'e veriyoruz.
-- ağırlık, kontak toleransı, sürtünme katsayısı,
-- lineer ve açısal sönümleme ve iade (bir yüzeye çarpması durumunda
-- eski enerjisinin ne kadarına sahip olacağı)
pDirPhyz.gravity = vector(0,0,-80)
pDirPhyz.contacttolerance = 0.2
pDirPhyz.friction = 1
pDirPhyz.lineardamping = 1
pDirPhyz.angulardamping = 1
pDirPhyz.restitution = 0.1

-- top'umuzu bir değişkene atıyoruz.
pBall = p3Dmember.model("Ball")

-- sahnemizdeki kamerayı bir değişkene atıyoruz.
pCam = p3Dmember.camera[1]
-- uzaklık vektörümüzü hesaplıyoruz.
-- kameranın konum vektörü - topun konum vektörü
distvec = pCam.transform.position - pBall.transform.position
-- topun ilk konumunu kaydediyoruz, eğer kişi, topu aşağıya düşürürse
-- top buraya konumlandırılacak.
first_pos = pBall.transform.position

-- aslında terrain ile çok alakası olmasada böyle bir isim
-- uygun görmüşüm :)
-- level geometrimiz için bir değişken oluşturuyoruz.
terrain = p3Dmember.model("levelgeo")

-- physx de olan değişikliklerin 3d dünyamıza yansıması için
-- ikisinede modifier ekliyoruz.!!!
pBall.addmodifier(#meshdeform)
terrain.addmodifier(#meshdeform)

-- levelgeo için bir rigid body oluşturuyoruz. Zaman zaman
-- konkav olabileceği için sorun çıkmaması için bu şekli konkav
-- olarak tanımlıyoruz. ayrıca sabit bir geometri olduğundan
-- statik olarak tanımlıyoruz.
rterrain = pDirPhyz.createRigidBody(terrain.name,terrain.name,\
#concaveshape,#static)

-- Top için bir rigid body oluşturuyoruz. Bu sefer top bir küre
-- olduğundan ötürü konveks bir şekle sahip olacaktır. Ayrıca
-- topu hareket ettirmek istediğimizden onu dinamik olarak
-- tanımlıyoruz.
rBall = pDirPhyz.createRigidBody(pBall.name,pBall.name,\
#convexshape,#dynamic)
-- kütlesini 100 olarak belirliyoruz.
rBall.mass = 100

-- levelfin geometrisini bir değişkene atıyoruz.
pFin = p3Dmember.model("levelfin")
-- bunada bir modifier ekliyoruz.
pFin.addmodifier(#meshdeform)
-- bu değişkenden de bir rigid body oluşturuyoruz (konveks ve statik)
rFin = pDirPhyz.createRigidBody(pFin.name,pFin.name,#convexshape,#static)

-- topun levelfin geometrisine çarpması halinde level'ın tamamlanması lazım
-- bu yüzden bir çarpışma callback'i ekliyoruz.
-- collisionCallback fonksiyonunu daha sonra tanımlıyoruz.
pDirPhyz.registercollisioncallback(#collisionCallback, me)
-- ve son olarak callback'leri aktif hale getiriyoruz.
pDirPhyz.enablecollisioncallback()
-- böylelikle 3d ve fizik dünyamını kullanıma hazırlamış olduk.
end

-- klavyede bir tuşa basıldığında bu fonksiyon çağırılacaktır.
-- bizde bu sayede ok tuşlarımızın durumlarını güncelliyoruz.
on keyDown
if keypressed(123) then pLeftArrow = TRUE
if keypressed(124) then pRightArrow = TRUE
if keypressed(125) then pDownArrow = TRUE
if keypressed(126) then pUpArrow = TRUE
end

-- aynı şekilde herhangi bir tuş bırakılırsa da bu fonksiyon
-- çağırılacaktır.
on keyUp
if keypressed(123)<>TRUE then pLeftArrow = FALSE
if keypressed(124)<>TRUE then pRightArrow = FALSE
if keypressed(125)<>TRUE then pDownArrow = FALSE
if keypressed(126)<>TRUE then pUpArrow = FALSE
end

-- döngümüzü bu fonksiyonla belirliyoruz. Frameden her çıkmaya çalıştığında
-- gerekli işlemlerimi yaptırıyoruz ve aynı frame'e geri döndürüyoruz.
on exitFrame
-- topu hareket ettirdiğimiz fonksiyonu çağırıyoruz.
ballMove
-- kameranın yeni pozisyonunu hesaplıyoruz.
t = pCam.getWorldTransform()
-- kameranın hareket eden topa göre yeni pozisyonunu hesaplıyoruz.
t.position = distvec + pBall.transform.position
-- yumuşak bir geçiş için bu yeni pozisyon ile
-- eski pozisyonu arasında interpolayson yapmasını istiyoruz.
pCam.transform.interpolateTo(t, 100)
-- physx'e bir adım daha hesaplamasını söylüyoruz.
pDirPhyz.simulate()
-- tekrar bulunduğumuz frame'e dönmesini belirtiyoruz.
_movie.go(_movie.frame)
end

on ballMove
-- basılan tuşlara göre topun rigid body'sine kuvvet uygula
if(_key.keyPressed("s")) then
rBall.applyLinearImpulse(vector(0,-400,0))
end if
if (_key.keyPressed("w")) then
rBall.applyLinearImpulse(vector(0,400,0))
end if
if (_key.keyPressed("a")) then
rBall.applyLinearImpulse(vector(-400,0,0))
end if
if (_key.keyPressed("d")) then
rBall.applyLinearImpulse(vector(400,0,0))
end if
if (_key.keyPressed(" ")) then
--rBall.applyLinearImpulse(vector(0,0,300))
end if

-- eğer top aşağıda düştüyse, ilk pozisyonuna
-- götürmeye çalış
if pBall.transform.position.z < -30 then
rBall.attemptMoveTo(first_pos)
end if
end

-- Daha önce belirttiğimiz collison callback
-- fonksiyonunun tanımı
on collisionCallback me,colReport
-- çarpışan her cisim için kontrol yap.
repeat with k = 1 to colReport.count
rb1 = colReport[k].ObjectA
rb2 = colReport[k].ObjectB
-- eğer çarpışan objelerin biri top, diğeri levelfin ise
-- level tamamlanmıştır.
if ((rb1.name contains "ball") and ( rb2.name contains "levelfin")) then
-- oyun bitince uyarı ver ve bir sonraki frame'e geç
beep
go to frame 3
end if
end repeat
end

-- son olarak temizlik yap.
on endSprite me
if pDirPhyz.isInitialized = 1 then
pDirPhyz.destroy()
end if
end
{/code}

Dosyamızı kaydediyoruz. Normalde bu tip oyunlarda topa kuvvet yerine tork uygulanır ancak tork uygulamak için biraz daha işlem yapmamız gerekiyor. Bu yüzden örneği basit tutmak amacıyla topa kuvvet uyguluyoruz. Şimdi ise behavior'ları stage'e ekliyoruz. Bunun için ilgili frame'e gelip, behavior'u stage'e sürüklüyoruz. Son durumda 'score' aşağıdaki gibi görünmeli.

director_13

Oyunumuz neredeyse hazır. Bitirmeden önce file->publish settings'e giriyoruz. Resimdeki gibi ayarlamaları yapıyoruz. Oyunumuzu internette yayınlamak için html ve dcr formatında oluşturulmasını istiyoruz ve tam ekran olması için de html sekmesinde boyutunu %100 yapıyoruz.

director_14

director_15

Ayarları kaydettikten sonra da file menüsünden publish diyoruz. Artık oyunumuzu tamamlamış olduk. Oyunun dosyalarını aşağıdaki linkten indirebilirsiniz.

rarclumsyball.rar (166 kb)
dcrOyunu oynamak için tıklayın

4 Ekim 2009 Pazar

Onlive - Yenilikçi Bir Oyun Hizmeti

OnLive teknolojisi daha önce 2009 yılının mart aynıda bir GDC'da tanıtılmıştı. Yakın bir zamanda ise onlive.com'da beta test için kayıt bölümü açıldı. Ancak bunun için amerikada yaşamanız gerekiyor.

Onlive Nedir?

Onlive bilgisayarınızla veya televizyona bağlanan bir mikro-konsol aracılıyla oyun oynamanıza yarayan bir hizmettir. Bu hizmetin en ilginç özelliği ise, oynadığınız oyundaki hiç bir işlemin istemci tarafından yapılmaması. Bu sayede ekran kartı olmayan bir laptopta crysis oynayabilirsiniz.

Bilgisayarınızda, tarayıcınıza yüklediğiniz 1mb'lık bir plugin ile bu hizmeti başlatıyorsunuz. Uygulamanın başlamasıyla bilgisayarınız ile onlive sunucuları arasında bir bağlantı açılıyor ve sürek olarak bir video akışı sağlanıyor. Menüye girdiğinizde, oyunları listeden seçip, trailer'larını veya diğer oyuncuların oyunlarını izleyebiliyorsunuz. Oyunu oynayabilmeniz için onu ya satın almanız ya da kiralamanız gerekmekte. Bu işlemden sonra oyunu oynamaya başlıyorsunuz. Herhangi bir bekleme olmadan oyun başlıyor.

Aynı zamanda eğer bir televizyonunuz varsa, onlive'ın mikro konsolunuda satın alabilirsiniz. Bu konsol, bir ele sığabilecek kadar küçük ve üzerinde HDMI, optik çıkış,ses çıkışı, ethernet girişi ve 2 adet usb portu bulunmaktadır.

1

Herkes gibi sizin de aklınızda şu soru oluşmuştur. Peki ama internet videolarında büyük bir gecikme süresi var.

Onlive'ın geliştiricileri daha önce quicktime oluşturulmasında da rol almışlar ve geliştirdikleri yeni algoritma sayesinde gecikme sürelerini 1ms'ye kadar düşürdüklerini idda ediyorlar. Youtube videolarında yaklaşık olarak 500ms. Bir kere bağlantı kurulduğunda bir daha bekleme veya indirme gibi bir durumla karşılaşmıyorsunuz. Ekrandaki görüntüler sürekli olarak sunucundan bilgisayarınıza gönderiliyor.

2

Tabii ki bu hizmetten yaralanabilmeniz için stabil bir internet bağlantınız olmalı. Eğer bana standart definiton (SD) yeter diyorsanız 1.5 Mbps'lık bir bağlantı hızı gerekmekte, ancak oyunları High Definition (HD) olarak oynamak isterseniz bağlantı hızınız 5 Mbps civarında olmalı.

Beta testi daha yeni açılmış oluğundan deneme fırsatım olmadı, ancak izlediğim video'lardan crysis'in ortalama bir laptopta gayet akıcı olarak oynanabildiğini gördüm.

3

Bu hizmetin yatırım maliyeti çok yüksek ancak tutulma olasılığı birkaç nedenden dolayı bana yüksek geliyor, öncelikle geliştiriciler için oldukça avantajlı. Tek bir platform için geliştirme yapılıyor, yani başka platformlara port etme gibi bir sorun yok. En önemlisi korsan kullanımın önüne geçilmiş olunuyor. Her ne kadar yatırım maliyeti yüksek olsa da günümüzde korsan kullanım yüzünden oluşan kayıplar çok yüksek.

4

Eğer oturduğunuz yerden kalkamayacak kadar tembelseniz sizin için de avantajlı bir hizmet çünkü CD/DVD almak için mağzaya gitmenize gerek yok ve yine aldığınız bu CD/DVD'leri konsolunuza takmak zorunda kalmayacaksınız :) Ancak sunuculardan yararlanmak için sürekli olarak para dökmeniz gerekecek. Büyük ihtimalle oyun bilgisayarı almaktan daha ucuza gelecektir.

Beta testleri başladı, ancak onlive hizmetinin ne zaman başlayacağı tam olarak bilinmiyor, yaklaşık 7 yıllık gizli bir proje olduğundan, bu süre birkaç ayda olabilir birkaç yılda. Merakla bekliyoruz.

29 Eylül 2009 Salı

Yeni Blog

artık bu blog'a daha fazla yazı eklemeyeceğim, onun yerine başka bir blog başlattım. Bu blogdaki tüm yazılar orada da var. Aslında devamı gibi. Yeni blogum artık hem ingilizce hem de türkçe olacak. Çok az post olmasından dolayı şu an için ingilizcesine ulaşılamıyor ama zaman içerisinde o da çalışır hale gelicektir. Hemen gitmek için;
Sonradan gelen düzenleme;
Sürekli güncellemeydi, spamdi derken blog'umu tekrar blogspot'a taşımış bulunmaktayım.

5 Eylül 2009 Cumartesi

Yol Bulma (Path Finding)

İnternette path finding ile ilgili bir makale okudum, önemli birkaç konuya değiniyordu, bu yüzden ben de bu makaleyi biraz özetleyerek türkçe olarak aktarmaya karar verdim. Umarım yardımcı olur. Bu makalenin orjinalini bu adreste bulabilirsiniz.

Oyunlarda hala yol bulma ile ilgili ciddi problemler bulunmaktadır, aşağıdaki video'da çeşitli oyunlardaki çeşitli hatalar gösterilmiştir.


Video'da görüldüğü gibi, bir çok oyundaki yol bulma algoritmaları her durumda doğru sonuç vermemektedir. Ancak bu sorunların çoğu, yol bulma işleminin way-point'ler ile hesaplanmasından kaynaklanmaktadır.

(Waypoint, gezilebilinen alanları tanımlamak için konan noktalardır. Buna 'yol noktaları' diyebiliriz.)

Waypoint'ler Neden Yol Bulmak için Uygun Değildir ?

Aşağıda tipik bir waypoint örneği bulunmakta.

Stormwind
[World of Warcraft'daki Stormwind City]

Stormwind_waypoints
[Waypointlerin konulmuş hali]

Gezilebilir alanları (yolları) way-pointlerle belirtebildiğimiz gibi konveks poligonlarla da ifade edebiliriz. Bu AI'a yol hakkında daha fazla bilgi ve daha düzgün karar verme olanağı verir. Bu şekildeki geometriler "navigation mesh" olarak adlandırılmıştır.

Stormwind-NavMesh

1. Bazı alanlarda, çok yüksek miktarda waypoint kullanmamız gerekebilir.

Geniş, açık alanlarda, AI'ın düzgün bir hareket yakalaması için çok fazla poligon gerekebilir.

Aşağıdaki resim, World of Warcraft'taki "Halaa" ismindeki kasabadan. NPC'lerin açık kısımlarda rahatça hareket etmesi isteniyor.

Halaa

Açık alanlar için çok fazla waypoint koymamız gerekiyor. Ancak bu sayı bile yeterli değil, waypointlerimizi daha da arttırmazsak, karakterlerimiz hareket ederken zig-zaglar çizerek ilerleyecektir.

Halaa_waypoints2

Diğer yandan, navigation mesh ile tanımlama yaparsak, çok daha az poligon kullanarak işimizi bitirmiş oluruz.

Halaa_navmesh2

Bu sayede daha az arama yaparak, yol bulma işleminin hızını da arttırabilirisiniz.

2. Karakterler ilerlerken zig-zaglar çizerek ilerleyebilir.

Waypoint'ler belirlediğiniz zaman, karakteriniz bu waypointlerin üzerinde hareket edecektir. Bu yüzden, büyük ihtimalle seçtiğiniz herhangi iki nokta arasında, düzgün waypointler bulunmayacağından, karakteriniz zig-zaglar çizerek hareket edecektir.

Karakterimizin A'dan B'ye gittiğiniz düşünelim.

Halaa_ab

Burada da sarı ile gösterilmiş olan yol, A'dan B'ye giden en ideal waypoint'leri göstermektedir.

Halaa_waypoints2_AB

Bu noktalar ile daha yumuşak olarak bir eğri oluşturmayı da düşünebilirsiniz, fakat waypointler etrafındaki objelerle ilgili bir bilgi barındırmadığından, eğrinin istenmeyen bir noktadan geçip geçmeyeceğini hesaplamanız zor olabilir.

Ancak, navigation mesh kullansaydık, en doğru yolu bulmamız daha kolay olacaktı. Aşağıda ise aynı işlemin navigation mesh ile yapılmış hali bulunmakta.

Halaa_navmesh2_AB

Bu durumda ise, karakterlerin dolaşabileceği alanın tümünü bildiğimizden dolayı, hesapladığımız yolu istediğimiz gibi yumuşatabiliriz. Aynı şekilde, aşağıdaki resimde, kırmızı olarak işaretlenen yol waypoint kullanıldığında ortaya çıkarken, mavi ile gösterilen yol ise navigation mesh kullandığımızda oluşturuluyor. (Tabii ki mavi olan yol programcının kullandığı algoritmaya göre değişir.)

Stormwind-NavMesh-with_splines

3. Waypointler kullandığımızda yolu, dinamik olarak değişen çevreye göre, değiştirmemiz daha zordur.

Eğer çevre dinamik olarak değişiyorsa ve sizin o bölgede yeterli sayıda waypointiniz yoksa, yol bulma işlemi başarısız olabilir. Aşağıdaki resimde yol üzerinde bir kutu olduğunu düşünelim. Bu durumda çok az waypoint bulunduğundan, karakter kutunun yanından düzgün bir şekilde dolaşamayacaktır.

Stormwind_waypoints_and_crate

Ancak, navigation mesh kullanırsak, çevre hakkında da bilgi sahibi olduğumuzdan, çeşitli yöntemlerle daha uygun bir yol bulabiliriz.

Stormwind-NavMesh-avoidance-cropped

4. Waypoint'ler farklı hareket tipleri olan karakterler için düzgün sonuç vermez.

Genişliği, yüksekliği, dönüş şekli ve bunun gibi bir çok parametrenin değiştiği durumlarda waypoint sistemi düzgün çalışmayabilir. Örnek olarak, aşağıdaki resimde bir panzer ile bir kişinin olduğunu düşünelim. Kişi, kum torbalarının yanından kolaylıkla yürüken, bir panzer bunu yapamaz.

bf42_piece

Kırmızı çizgi kişinin, mavi çizgi ise panzerin yolunu göstermektedir.

bf42_piece_paths

Waypoint'lerin düzgün çalışması için farklı waypoint grupları belirtebilirsiniz. Ancak bu işlem çok vakit isteyebilir. Bunların yanında waypointleri birleştirip panzerin nerede dolaşabileceğini hesaplayabilirsiniz ki, bu durumda waypointlerinizle bir navigation mesh oluşturmuş olursunuz.

bf42_piece_mesh

Yukarıdaki resimde gördüğünüz gibi, gezilebilinen alanların köşeleri belirli. Bu durumda, her farklı karakteriniz için bir yarıçap belirtebilirsiniz. Örnek olarak bir kişinin yarıçapı 1m, panzerin ise 5m olarak belirlenebilir.

bf42_piece_mesh_with_extents

Aynı zamanda farklı tipte karakterler için farklı hareket stilleri belirtebilirsiniz. Örnek olarak bir motorsiklet köşeleri daha yuvarlak alırken, bir insan köşeli dönüşler yapabilir.

motorcycle

Yukarıdaki resimde, motorsiklet kırmızı yolu izleyebilirken, sarı yolu izleyemez.

5. Waypointler karakterlerinizin, yol bulma dışındaki işlemleri için yeterli veri barındırmaz.

Bazı zamanlarda, yol bulma için kullanılan verilerin, AI'a nasıl davranacağını veya hareket edeceğini hesaplamada yardım etmesi gerekir. Örnek olarak bir karakterin belirli bir yola değilde, bir düşmana göre yer değiştirdiğini düşünelim. Bir canavar tarafından kovalanan köylü, kendine göre bir algoritmayla kaçmaya başlayacaktır. Eğer siz waypoint kullandıysanız, karakteriniz bu waypointleri kullanarak sağa sola koşamaz veya atlayamaz. Bu durum navigation mesh ile giderilebilir. Yani her nokta için, o noktanın uygun olup olmadığını hesaplayabilirsiniz. Bu işi, fizik motorunuz da sizin yerinize yapabilir, ancak navigation mesh kullanarak daha az sistem kaynağı tüketen bir AI sistemi yazabilirsiniz.

swordsman2

Hala ikna olmayanlar, makalenin orjinalinde yer alan soru/cevap kısmını inceleyebilirsiniz. http://www.ai-blog.net/archives/000152.html

29 Ağustos 2009 Cumartesi

Video Oyunları Orkestrası - Video Games Orchestra

GDnet'in facebook sayfasında karşılaştım, böyle bir orkestra varmış. Youtube sayfalarını da inceledim, eski oyunları oynamışlığınız varsa kesinlikle bir ara ziyaret etmelisiniz. Hepsini izlemek isterseniz http://www.youtube.com/user/VGOOnline#play/all adresine tıklayınız. Bende birkaç tane seçtim sizin için, iyi seyirler :)

Super Mario Medley (5/8/2009 @ IGC East '09)


Donkey Kong Medley (3/5/2009 @ BPC) Laptop hoparlörleri ile dinliyorsanız pek bişey duyamayabilirsiniz.


Super Mario Galaxy: Wind Garden (5/8/2009 @ IGC East '09)



Chrono Trigger Medley (5/8/2009 @ IGC East '09)


Linkler
Anasayfa:
http://www.vgo-online.org/
Youtube Sayfası:
http://www.youtube.com/user/VGOOnline#play/all

9 Ağustos 2009 Pazar

Bilgisayarın IP'sinden Bağlandığı Ülke Nasıl Bulunur ?

Web sitenize giren kullanıcıların hangi ülkeden bağlandığını öğrenmek isteyebilirsiniz, böylelikle onlara uygun bir sayfa veya karşılama metni gösterebilirsiniz. Bu yazıda, geo ip veritabanı kullanarak, bunu nasıl yapılacağını anlatacağım.

Öncelikle işe veritabanı için gerekli csv dosyasını indirmekle başlıyoruz. Csv dosyasını http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip adresinden indirebilirsiniz.

İndirme işlemi tamamlandıktan sonra, bu dosyayı uygun bir veritabanına aktarmamız gerekiyor. Herhangi bir veritabanı oluşturun, ya da hali hazırdaki bir veritabanını kullanın. Daha sonra bu veritabanında bir tablo yaratın. Bu tablonun ismi 'geoip' olabilir. Uygun bir tablo oluşturmak için, aşağıdaki kodu çalıştırabilirsiniz.

CREATE TABLE IF NOT EXISTS `geoip` (
`start_ip` char(15) NOT NULL,
`end_ip` char(15) NOT NULL,
`start` int(10) unsigned NOT NULL,
`end` int(10) unsigned NOT NULL,
`cc` char(2) NOT NULL,
`cn` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Şimdi bu tabloya, indirdiğimiz csv'deki verileri yükleyeceğiz. Bunun için, indirdiğiniz csv dosyasının yerini bilmeniz gerekiyor. Aşağıdaki SQL sorgusunu

çalıştırdığınızda csv dosyası veritabanına yüklenecektir.

LOAD DATA LOCAL INFILE [dosyanın yolu] INTO TABLE [tablo adı] FIELDS TERMINATED BY [kolon ayıracı] ENCLOSED BY [kapatma işareti] LINES TERMINATED BY [satır ayıracı];

Yukarıdaki koddan tam anlaşılmayabilir. Ben kendi durumum için doldurduğumda aşağıdaki sonucu elde ediyorum.

LOAD DATA LOCAL INFILE 'c:\\GeoIPCountryWhois.csv' INTO TABLE geoip FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

Tablomuz hazır olduğuna göre, küçük bir php script'i ile ip'lerin hangi ülkeye ait olduğunu bulabilirsiniz.

<?php
$pth = "localhost";
$user = "root";
$psw = "123456";
$dbname = "country";

$con = mysql_connect($pth,$user,$psw);

if (!$con)
{
     die("Veritabanı bağlantısı sağlanamıyor: " . mysql_error());
}

mysql_select_db($dbname, $con);

// IPden Ülke kodunu ve ismini array olarak döndüren fonksiyon.
function getCountry($ip) {

          $ip = explode(".",$ip);
          
          $result = 16777216 * $ip[0] + 65536 * $ip[1] + 256 * $ip[2] + $ip[3];
          
          $sql = "SELECT cc, cn FROM geoip WHERE ".$result." BETWEEN start AND end";
          $result = mysql_query($sql);
          $country[0] = mysql_result($result,0,"cc");
          $country[1] = mysql_result($result,0,"cn");
          if(empty($ccode)) $ccode = "default";
          return $country;
}

$myip = $_SERVER['REMOTE_ADDR'];
$myip = "85.100.153.122"; // eğer localhostta çalıştırısanızi 127.0.0.1 döneceğinden, herhangi bir ülke bulunmayacaktır.
                // O yüzden örnek olarak bir ip adresi yazıyorum buraya, scripti kullanırken silmeyi unutmayın.
echo "IP Address = <b>".$myip."</b><br>n";
$code = getCountry($myip);
echo "Code = <b>".$code[0]."</b><br>n";
echo "Country = <b>".$code[1]."</b><br>n";

?>

27 Temmuz 2009 Pazartesi

3G Şakası


Bugün Avea 3G fiyatlarını açıkladı. Ancak bu fiyatlar dünya standartlarının çok üstünde. Ayrıca kotasız bir tarifede yok. Ücretlendirmeler şöyle;
  • Görüntülü Konuşma ücreti her yöne dakikası 10 kuruş/1 kontör olacak.
  • Cepten TV izlemek abonelik ücretine dahil olacak ve fiyatlar 5 TL'den başlayacak.
  • Belirli bir video, film seçip indirmenin ücreti ise 3,5 TL.
  • Cep telefonu için 100 MB kotalı bağlantı 8 TL
  • 2GB Kotalı bağlantı ise 35 TL.
  • Bilgisayar bağlantıları içinse 3G internet hızının maliyeti, 2GB 35 TL. 6GB 55 TL.
Birçok kişi 3G'nin TTNET ADSL hizmetine bir seçenek olacağını umut ediyordu. Ancak bu fiyatlarla normal kullanımın bile pahalı olduğunu söyleyebiliriz.

Diğer operatörlerde fiyatların çok oynamayacağını düşünüyorum. 3 gün sonra tüm operatörler tarifelerini açıklamış olacaklar.

Güncelleme:

Turkcell'inde fiyatlarıda çok farklı değil, işte fiyatlar.
  • 1 GB internet bağlantısı aylık 29TL, 4 GB 39TL, 8GB ise 69 TL.
  • Haftalık kullanmak isterseniz, 1 GB internet 19 TL.
  • Cepten internete girmek isterseniz, 100 MB 9 TL / 65 Kontör

23 Temmuz 2009 Perşembe

Ogre ile Küçük Bir Deneme

Önceki yazıda ogre ile uğraştığımdan bahsetmiştim. Deneme amaçlı bir oyun yazmaya çalıştım. Her projede kullanabileceğim bir kod oluşturmak istedim, ancak yeniden yazılması gerekiyor.

Kısaca anlatmam gerekirse, 3000x3000 lik bir düzlemde kamera, ağaçlar, kutular, çimler ve zombiler rastgele yerleştiriliyor. Daha sonra sizden oyundaki zombileri öldürmeniz isteniyor :). Oyunda Ogre'nin haricinde NxOgre eklentisini kullandım.


Linkler
NxOgre:
http://www.nxogre.org/
NxOgre Forum:
http://www.ogre3d.org/addonforums/viewforum.php?f=6