LUA Script Dilini Kullanmak

LUA Script Dilini Kullanmak

Bu dökümanda LUA script dilinin C/C++ programları ile kullanımı üzerinde duracağız. Doğrudan örneklerle dilin kullanımı ve programlarımıza entegrasyonunun gerçekleştirimini açıklayacağım. Script dilleri hakkında bilgiye sahip değilseniz sitemizde yer alan "Script Dilleri" isimli dökümana göz atmanızı tavsiye ederim.

LUA script dili birçok oyun projesinde de kullanılan, açık kaynak kodlu, kullanımı basit, yalın ve hızlı çalışan bir dildir. Bu dil serbest olarak kullanılabilmektedir. LUA ilgili programları, kütüphaneleri, dökümaları ve örnekleri içeren dağıtım paketlerine LUA resmi sitesindeki linkleri kullanarak erişebilirsiniz. ( LUA resmi sitesi: [ www.lua.org ] ) Bu dökümanda sisteminize LUA kütüphanelerini kurduğunuz ve derleyici ayarlarını yaptığınız varsayılacaktır. Kütüphaneyi düzgün bir biçimde kuramadıysanız dökümanın en alt kısmında linki verilen örnek proje kütükleri içerisinde işler halde bulunan LUA liblerine ulaşabilirsiniz.

LUA script dili temel olarak iki şekilde kullanılabilir. Herhangi bir text editörü ile yazdığınız scriptleri LUA interpreter i yardımı ile çalıştırabilirsiniz. Veya LUA kütüphanesini programlarınıza ekledikten sonra programın içerisinden gerekli yordamları çağırarak LUA komutlarını uygulatabilir, script kütüklerini işletebilirsiniz. Bu ikinci kullanım şekli ilkine göre daha ilgi çekicidir. Birkaç ayarlamadan sonra LUA scriptleri içerisinden programınız içerisindeki yordamları çağırabilir böylelikle programınızın işleyişine dışarıdan scriptler vasıtasıyla yön verebilirsiniz.

LUA script dilinin yazım şekli genel olarak pascal' ı anımsatmaktadır ve oldukça yalın bir görünüme sahiptir. Dil tüm programlama dillerinde bulunan döngü kullanım şekillerine, değişken, dizi tanımlama, if ifadelerine, fonksiyon tanımlamalarına izin vermektedir. LUA içerisinde geniş olarak string, girdi/çıktı, ve matematiksel fonksiyonlar hazır halde bulunmaktadır. LUA dağıtımı ile birlikte gelen örnekler ve referans dökümanına göz atarak kısa zamanda dil kurallarını ve fonksiyonelliğini öğrenebileceğinizi tahmin ediyorum. Şimdi dökümanımızın esas amacı olan LUA yı programlarımız içerisinde kullanma konusunu inceleyelim.

İlk olarak yapmanız gereken "liblua.lib" ve "liblualib.lib" isimli kütüphaneleri derleyici ayarlarından programınıza eklemek. Daha sonra aşağıdaki şekilde gerekli include ları yapmalısınız. C++ yerine C programları yazanlar extern ifadesini kullanmayabilirler.

extern "C" {
    #include <lua.h>
    #include <lualib.h>
    #include <lauxlib.h>
    #include <luadebug.h>
}

LUA script dilini kullanırken yapacağınız tüm yordam çağırımlarında girdi parametresi olarak kullanmanız gereken bir handler vardır. Bu yapı bir çeşit context görevi görmektedir. Şimdilik buna fazla kafanızı takmayın. Şu şekilde bir tanımlama yapmanız gerekmekte.

static lua_State *L = NULL;

Daha önce LUA scriptleri içerisinden programlarımızda bulunan fonkisiyonları çağırabileceğimizi söylemiştik. Bu işlemi gerçekleştirebilmek için yordamlarımızı LUA 'ya tanıtmamız gerekir. Aynı zamanda bu yordamların LUA sistemi tarafından belirlenmiş bir tipi var. Yani yordamımız aynı zamanda bu tipe de uymak zorunda. Uymamız gereken yordam tipi şu şekildedir:

int yordam_adi (lua_State *L);

Bu yordamımızı LUA ya tanıtmadan önce bir adet eşleştirme tablosu oluşturmalıyız. Bu tablo yardımı ile LUA scriptleri içerisinden hangi kelimeyi (fonksiyon ismini) kullanarak fonksiyonumuzun çağırılabileceğini belirtiyoruz. Örneğin aşağıdaki biçimde tanımlanmış bir yordamımız olsun.

int f_topla (lua_State *L) {
    int arg1 = luaL_check_number(L,1);
    int arg2 = luaL_check_number(L,2);
    lua_pushnumber(L,arg1+arg2);
    return 1;
}

Bu yordamın LUA scriptleri içerisinden "topla" şeklinde çağırılmasını istiyorsak aşağıdaki tabloyu oluşturmalıyız.

const struct luaL_reg mylib[] = {
    {"topla", f_topla}
};

Daha sonra birkaç yordam çağırarak LUA sistemini başlatmamız gerekiyor.

// LUA sistemini hazırla
L = lua_open(0);

// standart LUA fonksiyonlarını içeren kütüphaneleri aktif hale getir.
lua_baselibopen(L);
lua_iolibopen(L);
lua_strlibopen(L);
lua_mathlibopen(L);
lua_dblibopen(L);

// kendi oluşturduğumuz yordamı içeren kütüphaneyi LUA sistemine tanıt
luaL_openl(L, mylib);

Bu aşamaları hatasız olarak tamamladıktan sonra artık LUA scriptlerini programımız içerisinden çalıştırabilecek duruma gelmiş bulunuyoruz. LUA scriptini değişik şekillerde çalıştırabilirsiniz. Örneğin bir string içerisine scripti yazıp daha sonra lua_dostring() yordamı ile bunu işletebilirsiniz.

const char *script = "write(\"merhaba...\")";
lua_dostring(script);

Veya scriptinizi bir kütük içerisine yazıp lua_dofile() yordamını kullanabilirsiniz.

lua_dofile("c:/script/lua/ornekler/ornek1.lua");

Biraz önce f_topla() isimli bir yordam yazmış ve bu yordamı LUA sistemine "topla" ismi ile kayıt etmiştik. Bu yordam 2 sayıyı toplayıp sonucu geri dönürmek gibi bir işi gerçekleştiriyor. Bu yordamı kullanan aşağıdaki LUA scriptini bir editör yardımı ile yazın ve ornek.lua olarak kaydedin.

sonuc = 0;
for i = 1,10 do
    sonuc = topla(sonuc,i);
end
write(format("%d",sonuc));


Daha sonra programınız içerisinden bu scripti işletin:

lua_dofile("ornek.lua");

Gördüğünüz gibi fonksiyonumuz lua scripti içerisinden çağırıldı ve görevini yerine getirdi. Bu yöntem ile programınız içerisinden istediğiniz yordamları LUA scriptlerinin kullanımına açabilirsiniz. Fonksiyonumuzun gerçekleştirimde biraz karışık görünen kısımlarda LUA sistemi kullanılarak parametre alışverişi gerçekleştiriliyordu. İsterseniz fonksiyonumuzu satır satır açıklayalım.

int f_topla (lua_State *L) {
    // luaL_check_number fonksiyonu çağırılarak LUA sistemindeki yığıtta bulunan bir değeri elde edebiliyoruz.
    // LUA sistemi bir yordamı çağırırken gönderilen parametreleri sırası ile yığıta atar.
    // bizim fonksiyonumuz topla(a,b) biçiminde iki parametre ile çağırılacağı için yığıta sırası ile
    // a ve b değerleri atılmaktadır. Bu değerleri aşağıdaki kodu kullanarak yığıttan alıyoruz.

    int arg1 = (int) luaL_check_number(L,1);             // ilk sayı değerini al
    int arg2 = (int) luaL_check_number(L,2);        
     // ikinci sayı değerini al

    // arg1 ve arg2 değerlerini toplayıp geri döndürmemiz lazım. Bir değeri sisteme geri döndürmek için
    // tekrar yığıtı kullanmalıyız. Fakat bu sefer yığıta geri göndermek istediğimiz değeri koymamız gerekiyor.
    // lua_pushnumber() yordamı ile yığıta bir sayı değerini koyabiliyoruz.

    lua_pushnumber(L,arg1+arg2);

    // topla fonksiyonu geriye bir parametre döndürdüğü için return 1; diyoruz. LUA fonksiyonları
    // geriye birden fazla parametre gönderebilirler. Eğer fonksiyonun geri dönüş değeri olmasaydı
    // return 0; dememiz gerekirdi.
    return 1;
}

Gördüğünüz gibi aslında çokta zor olmayan bir dizi işlem tamamlanarak LUA scriptleri ile bağlantı kurulup veri alışverişi yapılabiliyor. Örneğimizde parametre olarak sayı aldık ve geriye sayı döndürdük. Yığıttan string almak için ise luaL_check_string() yordamını aynı şekilde kullanabiliriz. Geriye string döndürmek için yığıta bir string ifadesi koymamız gerekir. Bunu da lua_pushstring() yordamı ile yapabiliriz. LUA referans dökümanlarını inceleyerek değişik kullanım şekillerini öğrenebilirsiniz.

LUA scriptleri çeşitli yordamlar içerebilirler. Bu yordamlar scriptin içerisinden veya scripti çalıştıran program içerisinden direk olarak çağırılabilirler. Örneğin yukarıda gerçekleştirdiğimiz çalışmayı bu seferde tersten tekrarlayalım. LUA script dosyası içerisinde topla isimli bir yordam tanımlayalım.

function topla(a,b)
    return a + b;
end

Bu scripti ornek2.lua olarak kaydedelim. Şimdi bu scripti programımız içerisinden nasıl çağırabileceğimizi görelim:

// scripti işlet.. aslında burada script içerisindeki yordam LUA sistemine tanıtılıyor. kütük içerisinde işletilebilecek
// açıkta kod olmadığından herhangi bir işlem gerçekleştirilmiyor (kod, topla yordamı içerisinde bulunuyor)
lua_dofile("ornek2.lua");

// topla isimli yordamı çağıracağız
lua_getglobal(L,"topla");
// ilk parametre 13
lua_pushnumber(L,13);
// ikinci parametre ise 666
lua_pushnumber(L,666);
// bu şekilde topla yordamı çağırılıyor. iki parametre gönderdiğimiz ve geriye 1 değer döndüğü için
// lua_call(L,2,1) şeklinde bir çağırımda bulunduk
lua_call(L,2,1);

// Şimdi geriye dönen değeri yığıttan alalım.
int toplam = luaL_check_number(L,1);

Gördüğünüz gibi birkaç kalıba uyduğunuz taktirde kolaylık ile LUA script dilini programlarınız içerisinde kullanabiliyorsunuz. Dahası programınızı LUA scriptleri yardımı ile dışarıdan yönlendirebiliyorsunuz. LUA nın bu yönünün oyun programlarında kullanımına pratik bir örnek vermek için yılan oyunumuzu biraz değiştirerek yeni bir versiyonunu hazırladım. Bu sürümde:  yılanın hızını arttıran ,oyun alanına belirli bir renkte,isimde ve konumda cisim ekleyen ve ismi verilen cismi silen yordamlar eklendi. Ayrıca söz ettiğimiz şekilde bu yordamların LUA scriptleri içerisinden çağırılabilmesi için gerekli ayarlamalar yapıldı. Oyun her başladığı zaman ismi bilinen bir LUA yordamının çağırılması (OnLevelStart) ve her yılan-cisim çarpışması durumunda "OnCollision" isimli LUA yordamının çağırılması gerçekleştirildi. "level1.lua" isimli kütük içerisine bu bahsettiğimiz iki yordamın gerçekleştirimleri yazıldı. Bu gerçekleştirimleri değiştirerek oyunun işleyişine direk olarak etkide bulunabilirsiniz. Şu anki gerçekleştirimde oyun başlangıcında 10 adet kırmızı ve 1 adet yeşil cisim oyun alanına yerleştiriliyor (rasgele pozisyonlara). Yeşil cisimlere çarpıldığı zaman cismin yeri yine rastgele biçimde değiştiriliyor. Kırmızı cisimlere çarpıldığı zaman ise cismin yeri değiştirilirken aynı zamanda yılanın hızı bir miktar arttırılıyor.

LUA script dili ilginizi çekti ise mutlaka LUA kod dağıtımını indirip içinde gelen örnek ve dükümanları inceleyin. Dilin burada söz etmediğim birçok ileri seviye ve oldukça işe yarar özelliği bulunmakta. Örneğin programınız içerisinde tanımlı nesnelere LUA scriptleri içerisinden erişme ve nesneye yönelik yaklaşımları uygulamak bile mümkün olabiliyor. Her zamanki gibi bu döküman hakkında sormak istediğiniz soruları ve görüşlerinizi sitemiz forumları aracılığı ile bana iletebilirsiniz. Kendinize iyi bakın..

VC++ Örnek proje kütüklerine aşağıdaki link yardımı ile erişebilirsiniz.
[ Yılan Oyunu - LUA Örnek Script Sürümü ]

M.Deniz Aydınoğlu :: 2003 :: www.oyunyapimi.org




Bu yazının bulunduğu site: OyunYapimi.org
http://www.oyunyapimi.org

Bu yazı için adres:
http://www.oyunyapimi.org/modules.php?name=Sections&op=viewarticle&artid=24