If you're seeing this message, it means we're having trouble loading external resources on our website.

Bağlandığınız bilgisayar bir web filtresi kullanıyorsa, *.kastatic.org ve *.kasandbox.org adreslerinin engellerini kaldırmayı unutmayın.

Ana içerik

Vektör hareketi

Tüm bu vektör matematiğiyle ilgili şeyler bilmemiz gereken bir şeye benziyor, ama neden? Kod yazmamıza nasıl yardımcı olacak? Aslında biraz sabıra ihtiyacımız olacak. PVector sınıfının kullanımının mükemmelliğinin ortaya çıkması biraz zaman alacak. Bu, yeni bir veri yapısı öğrenirken, sıklıkla rastlanılan bir durumdur. Örneğin, bir diziyi ilk öğrendiğinizde, birden fazla şey için birkaç değişken olması yerine dizi kullanmak çok daha uzun bir iş gibi görünür. Ama, yüz, veya bin, veya on bin şey gerektiğinde, bu plan hemen devreden çıkar. Aynı şey PVector için de geçerli olabilir. Şu an çok iş gibi görünen bir şey, sonradan çok işimize yarayacak. Ve bunun için fazla beklememiz gerekmeyecek, ödülünüz bir sonraki bölümde gelecektir.

Hız

Ancak, şimdilik, basitliğe odaklanmak istiyoruz. Vektör kullanarak hareket programlama hangi anlama gelir? Bunun başlangıcını zıplayan top örneğinde görmüştük. Ekrandaki bir nesnenin bir konumu (herhangi bir anda nerede olduğu) ve hızı (bir andan bir sonraki ana nasıl hareket etmesi gerektiğinin yönergesi) vardır. Hız konuma eklenir:
location.add(velocity);
Ve sonra nesneyi o konumda çizeriz:
ellipse(location.x,location.y,16,16);
Bu, Hareket 101'dir:
  • Hızı konumla toplayın
  • Nesneyi konumda çizin
Zıplayan top örneğinde, bunların hepsi ProcessingJS'nin draw fonksiyonunun içinde oluyordu. Şimdi yapmak istediğimiz ise, hareket için gereken tüm bu mantığı bir nesne nin içinde depolamaktır. Bu şekilde, ProcessingJS programlarımızın tümünde hareket eden nesneleri programlamak için bir temel oluşturabiliriz.
Bu durumda, ekranın etrafında hareket eden bir şeyi tanımlayan genel bir Mover nesnesi oluşturacağız. Onun için, aşağıdaki iki soruyu düşünmeliyiz:
  • Bir hareketçinin ne tür verileri vardır?
  • Bir hareketçinin ne tür işlevselliği vardır?
Hareket 101 algoritması, bize bu soruların cevaplarını verir. Bir Mover nesnesinin iki parça verisi bulunur: konum ve huz, bunların ikisi de PVector nesneleridir. Bu özellikleri uygun rastgele değerlerle başlatan yapıcı fonksiyonu yazmakla başlayabiliriz:
var Mover = function() {
  this.position = new PVector(random(width), random(height));
  this.velocity = new PVector(random(-2, 2), random(-2, 2));
};
İşlevselliği de aynı ölçüde basittir. Mover'ın hareket etmesi ve görülmesi gerekir. Bu ihtiyaçları update() ve display() isimli yöntemler şeklinde uygularız. Hareket mantığı kodunu update()'e koyacağız ve nesneyi display()'de çizeceğiz.
Mover.prototype.update = function() {
  this.position.add(this.velocity);
};

Mover.prototype.display = function() {
  stroke(0);
  strokeWeight(2);
  fill(127);
  ellipse(this.position.x, this.position.y, 48, 48);
};
Nesne yönelimli programlama sizin için yeniyse, buradaki bir özellik biraz karışık gelebilir. Ne de olsa, bölümün başında PVector'ü ayrıntılı bir şekilde tartıştık PVector nesnesi, konum nesnesi ve hız nesnesini yapmak için şablondur. O zaman başka bir nesnenin, Mover nesnesinin içinde ne arıyorlar? Aslında, bu en normal şeydir. Nesne, sadece veri (ve işlevsellik) tutan bir şeydir. Bu veriler sayılar, dizeler, diziler veya başka nesneler olabilir! Bu derste, bunları tekrar tekrar göreceğiz. Örneğin, Parçacık dersinde, bir parçacık sistemi tanımlamak için bir nesne yazacağız. ParticleSystem nesnesinin verileri bir dizi Particle nesnesi olacak…ve her bir Particle nesnesinin verileri birkaç PVector nesnesi olacak!
Mover nesnesini nesne pencerenin kenarına ulaştığında ne yapması gerektiğini belirten bir fonksiyonu koyarak bitirelim. Şimdilik basit bir şey yapalım, ve kenarlarından saralım:
Mover.prototype.checkEdges = function() {

  if (this.position.x > width) {
    this.position.x = 0;
  } 
  else if (this.position.x < 0) {
    this.position.x = width;
  }

  if (this.position.y > height) {
    this.position.y = 0;
  } 
  else if (this.position.y < 0) {
    this.position.y = height;
  }
};
Artık Mover nesnesi bittiğine göre, ana programda neler yapmamız gerektiğine bakabiliriz. Önce yeni Mover oluşumunu bildiriyoruz ve başlatıyoruz:
var mover = new Mover();
Sonra, draw'da uygun fonksiyonlar çağırırız:
draw = function() {
  background(255, 255, 255);

  mover.update();
  mover.checkEdges();
  mover.display(); 
};
İşte bunun çalışan örneği. Sayılarla oynamayı, kodları yorumlamayı ve neler olduğunu görmeyi deneyin:

İvme

Tamam. Bu noktada, iki şeyi anlamamız gerekir: (1) PVector'un ne olduğu ve (2) konum ve hareketini izlemek için PVector'u nesnenin için kullanmak. Bu mükemmel bir ilk adımdır ve hafif bir alkışı hak eder. Alkışlar ve çığlık atan hayranlardan önce, biraz büyük bir adım daha atmamız gerekir. Sonuçta, Hareket 101 örneğini izlemek oldukça sıkıcırdır—çember hiç hızlanmaz, yavaşlamaz, ve dönmez. Daha ilginç, etrafımızdaki gerçek dünyada görülen hareket için, Mover nesnemize bir PVector daha eklememiz gerekir—ivme.
Burada kullandığımız ivmenin tam tanımı: hızın değişim oranıdır. Bu tanımı biraz düşünelim. Bu yeni bir kavram mı? Pek değil. Hız, konumun değişme oranı olarak tanımlanır. Esasında, bir “damlama” etkisi geliştiriyoruz. İvme hızı etkiler, hızda konumu etkiler (kısa bir önseme olarak, bu noktanın bir sonraki bölümde daha da önem kazanacağını söyleyebiliriz, çünkü bu bölümde kuvvetlerin ivmeyi, bunun da hızı, hızın da konumu nasıl etkilediğini göreceğiz). Kod olarak, bu şöyle okunur:
velocity.add(acceleration);
location.add(velocity);
Alıştırma olarak, bu noktadan sonra, kendimiz için bir kural oluşturalım. Bu derslerin kalanındaki her bir örneği hız ve konum değerine (başlatma hariç) dokunmadan yazalım. Başka bir deyişle, hareketi programlamak için şimdiki hedefimiz: İvmeyi hesaplamak için bir algoritma bulma ve damlama etkisinin sihrini göstermesine izin verme. (Aslında, bu kuralı kırmak için nedenler bulursunuz, ama hareket algoritmasının arkasındaki ilkeleri göstermek de önemlidir.) Onun için, ivmeyi hesaplama yolları bulmamız gerekiyor:
  1. Sabit ivme
  2. Tamamen rastgele bir ivme
  3. Fareye doğru ivme
Algoritma #1, sabit bir ivme, pek ilginç değildir, ama en basitidir ve kodumuza ivmeyi katmamıza yardımcı olacaktır.
Yapmamız gereken ilk şey, Mover yapıcısına ivmeyi temsil eden başka bir PVector özelliği eklemektir. Bunu (0,001,0,01)'den başlatırız ve sonsuza kadar bu değerde tutarız, çünkü şuanki algoritmamız sabit ivmedir. Şöyle düşünüyor olabilirsiniz, “Tanrım, bu değerler ne kadar küçük görünüyor!” Evet, doğru bunlar oldukça küçük. İvme değerlerimizin (piksel cinsinden) zamanla hızda birikeceğinin farkına varmak önemlidir, çizimimizin kare hızına göre yaklaşık saniyede otuz kere. Hız vektörünün büyüklüğünü makul bir aralıkta tutmak için, ivme değerlerimiz küçük başlamalı ve öyle kalmalıdır.
var Mover = function() {
  this.position = new PVector(width/2,height/2);
  this.velocity = new PVector(0, 0);
  this.acceleration = new PVector(-0{,}001, 0{,}01);
  this.topspeed = 10;  
};
Üstte dikkat ederseniz, hızı da 0'dan başlattık - çünkü program çalıştıkça, ivme sayesinde hızlandıracağımızı biliyorduk. Bunu update() yönteminde yapacağız:
Mover.prototype.update = function() {
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);  
};
Sürekli olarak hızı artırdığımız için, program çok uzun çalışırsa, hız değerlerimizin inanılmaz derecede büyümesi riski olur. Hızı bir maksimumla sınırlandırmak istiyoruz. Bunu, bir vektörü belirli bir büyüklükte sınırlayan PVector limit yöntemini kullanarak yapabiliriz.
Mover.prototype.update = function() {
  this.velocity.add(this.acceleration);
  this.velocity.limit(10);
  this.position.add(this.velocity);  
};
Bu, aşağıdakine dönüşür:
Hızın büyüklüğü nedir? 10'dan azsa, endişelenmeyin; olduğu gibi bırakın. Ancak, 10'dan fazlaysa, 10'a indirin!
Mover nesnesindeki değişikliklere acceleration ve limit()ile birlikte bakalım:
Şimdi, Algoritma #2'ye geçelim, tamamen rastgele bir ivme. Bu durumda, nesnenin yapıcısındaki ivmeyi başlatmak yerine, her döngüde, yani update() her çağrıldığında, yeni bir ivme seçmek istiyoruz.
Mover.prototype.update = function() {
  this.acceleration = PVector.random2D();
  this.velocity.add(this.acceleration);
  this.velocity.limit(10);
  this.position.add(this.velocity);  
};
Bu rastgele vektör normalize edilmiş olduğundan, iki teknikle ölçeklemeyi deneyebiliriz:
  1. ivmeyi sabit bir değerde ölçekleme:
    acceleration = PVector.random2D();
    acceleration.mult(0{,}5);
    
  1. ivmeyi rastgele bir değere ölçekleme:
    acceleration = PVector.random2D();
    acceleration.mult(random(2));
    
Bu açık bir nokta gibi görünse de, ivmenin sadece hareketli bir nesnenin hızlanması veya yavaşlamasıyla ilgili olmadığını, ancak büyüklük veya yönde hız değişimini kastettiğini anlamak çok önemlidir. İvme bir nesneyi yönlendirmek için kullanılır, ve bunu sonraki bölümlerde, ekranda hareket kararları veren nesneler programladıkça tekrar tekrar göreceğiz.

Bu "Doğal Simülasyonlar" dersi, Daniel Shiffman'ın"Kodun Doğası"'nın bir türevidir ve Creative Commons Yüklemesi-Ticari Olmayan 3,0 Dağıtıma Açık Lisansla kullanılmaktadır.

Tartışmaya katılmak ister misiniz?

Henüz gönderi yok.
İngilizce biliyor musunuz? Khan Academy'nin İngilizce sitesinde neler olduğunu görmek için buraya tıklayın.