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.