Inverse Lerp (+Lerp) - by Furkan Karabudak - Game Maker Turkiye

Inverse Lerp  (+Lerp) by Furkan Karabudak

GMS1 & GMS2

Bugün sizlerle GameMaker'da olmayan, ancak yeri geldiğinde çok işinize yarayabilecek bir fonksiyon olan InverseLerp fonksiyonunu kendi yazdığım script halinde paylaşacağım.

Peki ne bu InverseLerp ?

InverseLerp'in ne olduğunu anlamak için öncelikle gelin lerp 'i anlayalım beraber. Lerp, Linear interpolation yapmamızı sağlayan bir fonksiyondur ve GameMaker'da standart olarak mevcuttur. Lerp şu alanlarda kullanılır diye anlatamam çünkü bir çok yerde oldukça işinize yarayabilir. Bunun yerine kullanıldığı alanlardan sadece birkaç tanesini örnek vererek kafanızda daha iyi canlanmasını sağlayabilirim. Ancak bundan önce, gelin tanımına, işleyiş mantığına ve nasıl kullanılacağına bir değinelim.

lerp(a, b, amount);

Parametre Açıklama
 a  Birinci Değer
 b  İkinci Değer
 amount  İnterpolasyon Miktarı

Lerp iki sayı değeri arasında, belirlenen interpolasyon miktarına göre bir değer tutar. Yani a ile b değerleri arasında bir değer tutar. Bunu örnekler ile daha rahat açıklayabileceğimi düşünüyorum.

variable = lerp(0,10,0);     Burada interploasyon miktarı 0 olduğu için ilk değer döndürülür. Yani variable'ın değeri ilk parametre olan 0 olacaktır.

variable = lerp(0,10,1);     Burada ise interpolasyon miktarı 1 olduğu için ikinci değer döndürülür. Yani variable'ın değeri ikinci parametre olan 10 olacaktır.

variable = lerp(0,10,0.5);     Burada ise interpolasyon 0.5 olduğu için yarımdır, yani iki değerin tam ortasını tutacaktır. Dolayısıyla variable'ın değeri 0 ile 10'un tam ortası olan 5 olacaktır.

variable = lerp(23,78,0.25); Burada ise interpolasyon 0.25 ve 23 ile 78 sayılarının arasında 23'e daha yakın olacak şekilde olacaktır. Dolayısıyla variable değeri 36.75 olacaktır.

(23+(23+78)/2)/2 = 36.75

Lerp fonksiyonunun genel formulü şu şekildedir.

a + ((b - a) * amount)

Peki Lerp İle Neler Yapabiliriz ?

 

Lerp'ü en çok yumuşak geçişlerde ve yumuşatılmış animasyonlarda kullanıyoruz. Yandaki GIF'e bakarak bu yumuşatma işlemini çok daha iyi anlayabilirsiniz.

 

Şimdi ise bu yumuşatma işlemi ile hangi efektleri ve animasyonları yapabileceğimize bir bakalım.

 

 

 

 

 

 

 

Şimdi ise şu sıralar uğraştığım kendi mobil oyunumun ana menüsünden bir sahne göstereceğim.

 Yukarıda Lerp'i tek sefer çalıştırdığımız için tek bir değer elde etmiştik. Peki Lerp'i bu şekilde animasyon yapmak için nasıl kullacağız ?

 Bunun için kodu step event yada onun gibi sürekli tetiklenen bir event'a yazmanız gerekiyor.

 İlk parametreyi değişkenininiz olarak ayarlarsanız ve bunu step event'a koyarsanız, değişkeniniz yumuşatılmış bir şekilde ilk değerinden ikinci parametrenin değerine doğru yaklaşacaktır. Yaklaştıkça artış/azalış miktarı da yavaşlayacak, ve değişken değeriniz ikinci parametrenin değerine ulaştığı anda artış/azalış duracaktır.

 Diyelim ki  bir objemiz olsun ve x ekseninde önceki pozisyonu olan 100'den 450'ye yumuşak bir animasyon ile hareket etmesini istiyorsunuz. Tek yapmanız gereken aşağıdaki gibi bir kullanım yapmak olacaktır:

    x = lerp(x, 450, 0.1);

 Yukarıdaki gibi bir kullanım yaparsanız istediğinizi elde edebilirsiniz. Tabi üçüncü parametreye animasyonun hızının ne olmasını istiyorsanız ona göre bir değer yazmalısınız. 0 ile 1 arasında değer yazmanız önerilir. Yazdığınız değer büyüküdçe animasyon hızınız artar, küçüldükçe animasyon yavaşlar.

Tabi bu fonksiyonu yalnızca bu amaçla değil hayal gücünüze göre ihtiyaç duyabileceğiniz her alanda kullanabilirsiniz. Aşağıda birkaç farklı örnek kullanım yaptım.

image_alpha = lerp(image_alpha, 0.75, 0.05);       image_xscale = lerp(image_xscale, 3, 0.3);

camera_set_view_pos(oCamera.camera, lerp(camera_get_view_x(oCamera.camera), oPlayer.x, 0.4), lerp(camera_get_view_y(oCamera.camera), oPlayer.y, 0.4));

Artık Lerp'i anlamış olduğunuzu düşünüyorum. Lerp zaten gamemaker'da bulunan bir fonksiyondu. Ancak InverseLerp GameMaker'da bulunmuyor, bu yüzden ben de buna kendimce bir çözüm buldum.

Peki ne bu InverseLerp ? (Evet bu kez gerçek)

 InverseLerp adından da anlaşılacağı üzere Lerp fonksiyonunun tam tersidir. Lerp'i step event'ta kullandığınızda ilk parametre ikinci parametreye yaklaşıyordu ancak yaklaştıkça bu yaklaşma hızı yavaşlıyor ve en son iki parametre birbirine eşit olduğu anda duruyordu. InverseLerp de bunun tam tersi, ilk parametre yine ikinci parametreye sürekli olarak yaklaşıyor, ancak uzakken bu yaklaşma hızı çok yavaş başlıyor, ve Lerp'in aksine, ilk parametre ikinciye yaklaştıkça yavaşlamak yerine gittikçe hızlanıyor. İlk parametre ikinciye eşit olduğu anda gene duruyor.

Kullanımı

Benim scripti yazma şeklimden kaynaklı olarak, lerp'i kullandığınızdan azıcık farklı olarak, bunu bir if bloğunun içine koyarak kullanmamız gerekiyor. Genel kullanım kalıbı aşağıdaki gibi:

if inverseLerpChecker(-"deger1"-(string), -deger2-, -parametre1'in başlangıç değeri-)

{

    deger1 = inverseLerp(deger1, deger2, amount);

}

Unutmayın !!! if şartındaki inverseLerpChecker fonksiyonu birinci parametrenin değeri ikinciye ulaştığında artış/azalış işlemini durdurmak içindir ve ilk parametre'nin ismini her zaman çift tırnak içerisinde (") string olarak yazmalısınız.

inverseLerp içerisine birinci parametre kısmına başalngıç değerini, ikinci parametre kısmına ise hedef değeri yazın. Amount kısmına ise interpolation miktarını yazacaksınız. Ancak burada Lerp alışkanlıklarınız sizi yanıltmasın. Lerp'te hatırlayacağınız üzere genel olarak 0 ile 1 arasında değerler kullanmayı tercih ediyorduk. Burada ise işler biraz daha farklı. Burada animasyonunuzun düzgün görünmesi için genel anlamda amount'a ne yazacağınızı söyleyemem. Sadece bazı değerler için önerdiğim amount miktarlarını söyleyebilirim. Siz de kullandığınız iki değer arasındaki farkın büyüklüğüne göre, benim verdiğim örneklere bakarak karar verebilirsiniz.

değer 1 = 0 ; değer 2 = 1 ; amount = 300 ;

değer 1 = 0 ; değer 2 = 100 ; amount = 0.05 ;

değer 1 = 100 ; değer 2 = 2000 ; amount = 0.001 ;

Yukarıda da göreceğiniz üzere, iki değer arasındaki fark arttıkça amount değerini küçültmeniz gerekir. İki değer arasındaki fark azaldıkça amount'u büyütmeniz gerekir. Örnek olarak bu sayıları baz aldıktan sonra kullandığınız sayılara göre kullanmanız gereken amount değerine deneyerek kendiniz karar vermeniz gerekir.

Örnek Kullanım

if inverseLerpChecker("deger1",2000,100)
    
deger1 = inverseLerp(deger1,2000,0.001);


 


 

 

 

 

Scriptler

 

Bu fonksiyonu kullanmak için aşağıdaki başlıkların isminde script oluşturup içlerine altlarındaki ilgili kodları yapıştırmanız gerekiyor.

 

 

inverseLerpChecker

///@description inverseLerpChecker(a_name_string,b,a_start_val)
///@param a_name_string
///@param b
///@param a_start_val

var a_name = argument[0];
var bb = argument[1];
var a_start = argument[2];

var diff = sign(bb - a_start);

var aa = variable_instance_get(id,a_name);

if diff > 0
{
    if aa > bb
        variable_instance_set(id,a_name,bb);

    if aa < bb return true;
    
if aa >= bb return false;
}
else
{
    if aa < bb
        variable_instance_set(id,a_name,bb);
        
    
if aa > bb return true;
    
if aa <= bb return false;
}

inverseLerp

///@description inverseLerp(a,b,amount)
///@param a
///@param b
///@param amount

var aa = argument[0];
var bb = argument[1];
var tt = argument[2];

return aa + 1 / ((bb-aa)*tt)


Script Programcısı & Yazan : Furkan Karabudak

Herhangi bir sorunuz, öneriniz, probleminiz vs. olduğu durumlarda buraya tıklayarak Discord sunucumuza katılabilir ve beni etiketleyebilirsiniz. @Furkan Karabudak 


 

Benzer İçerikler :