Bölüm 3 — Amaç ve Kapsam
Genel Amaç
Bu bölümün temel amacı, deltaTime ile cihazdan bağımsız hareketi kurmak; dizi koleksiyonlarını oyun verisine bağlamak ve klavye girdisiyle kontrol iskeletini oluşturarak sonraki çarpışma ve durum makinesi konularına zemin hazırlamaktır. Bölüm boyunca her ana başlık kendi içinde amaç, öğrenme çıktıları, örnek kod ve değerlendirme sorularıyla tamamlanır; böylece bir sonraki bölüme geçmeden önce ölçülebilir kazanımlar elde edilir.
Kapsam
Bu bölüm şu ana başlıklar altında ele alınmaktadır:
Ana Başlık 1: deltaTime ile Zaman Tabanlı Hareket
Ana Başlık 2: Dizi Temelleri: Tanım, Erişim ve push/pop
Ana Başlık 3: Sabit Kapasite ve Paralel Dizilerle Mini Sahne
Ana Başlık 4: Klavye Girdisi
Ana Başlık 1. deltaTime ile Zaman Tabanlı Hareket
Amaç: deltaTime ile frame hızından bağımsız hareketi öğreterek taşınabilir animasyon kurmak.
Öğrenme Çıktıları:
- Frame başına sabit adım sorununu açıklar.
- deltaTime birimini ve kullanımını uygular.
- Hızı saniye başına birim olarak yazar.
- Hareketli top örneğinde zaman tabanlı güncelleme kurar.
Anahtar Sözcükler: deltaTime, zaman tabanlı hareket, hız, taşınabilirlik
Giriş
FPS ve frameRate bilindikten sonra asıl çözüm gelir: hareketi frame sayısına değil geçen süreye bağlamak. deltaTime son frame’den bu frame’e geçen milisaniyeyi verir; x += hiz * (deltaTime / 1000) ifadesi hızı “birim / saniye” yapar. Böylece 30 FPS ve 60 FPS’te top benzer gerçek hızda ilerler.
Bu ana başlık sorunu, formülü ve hareketli top örneğini işler. Sonraki diziler ve klavye kontrolü, bu zaman modelinin üzerine çoklu varlık ve girdi ekler. Bundan sonra gelen alt başlıklarda önce veri modeli, sonra hamle kuralı, en sonda çizim ve etkileşim kurulur. Her yeni fonksiyon mümkün olduğunca küçük bir örnekte çalıştırılır; böylece hatanın kaynağı daha kolay bulunur. Anlatımda önce ilgili yapının ne işe yaradığı açıklanır, ardından kod satır satır okunur. Terimler ilk geçtikleri yerde kısa bir tanımla verilir; gerekirse tablo veya görsel ile desteklenir. Örnek sketch’ler tek bir mekaniğe odaklanır; böylece yan konular okumayı dağıtmaz. Parametreleri değiştirip yeniden çalıştırmak, kuralın sınırını görmenin en hızlı yoludur. Bu ana başlığın çıktısı, sonraki oyunda yeniden kullanılabilecek bir iskelet oluşturur.
1.1. Frame Başına Hareketin Sorunu
Frame başına sabit piksel ekleme (topX = topX + 3) sezgiseldir; fakat hız frame sayısına bağlıdır:
Tablo 1.
| Makine | Yaklaşık FPS | Saniyede +3 ile kayma (60 frame varsayımı vs 30) |
|---|---|---|
| Hedef 60 FPS | ~60 | 60 × 3 = 180 piksel/saniye |
| Hedef 30 FPS | ~30 | 30 × 3 = 90 piksel/saniye |
Aynı kod, farklı frame hızında farklı oyun hızı üretir. Oyuncu deneyimi makineden makineye değişir; fizik tabanlı veya ağ üzerinden senkronize oyunlarda bu kabul edilemez.
Bu etki, hızlı hareket eden nesnelerde daha da görünür olur. Örneğin bir mermi veya ok, frame başına 15 piksel ilerleyen bir formülle hareket ettiriliyorsa, 30 FPS'te saniyede 450 piksel, 60 FPS'te saniyede 900 piksel kat eder — iki kat fark, çarpışma testlerinin bile farklı sonuç vermesine yol açabilir: yüksek FPS'te mermi ince bir engelin üzerinden "atlayarak" geçebilir, düşük FPS'te ise engelle çarpışabilir. Bu tür tutarsızlıklar, oyunun zorluk seviyesini geliştiricinin niyeti dışında değiştirir ve hata ayıklamayı zorlaştırır: bir hata bazı bilgisayarlarda gözlenirken bazılarında hiç ortaya çıkmayabilir.
Çözüm: hareketi frame sayısına değil, geçen süreye bağlamak. p5.js her draw() çağrısında bir önceki frame'den bu yana geçen süreyi milisaniye cinsinden deltaTime değişkeninde sunar.
Tanım: deltaTime — Bir önceki draw() çağrısından bu yana geçen süre (milisaniye). p5.js tarafından otomatik güncellenir; sketch içinde atanması gerekmez.
1.2. deltaTime ile Zaman Tabanlı Hareket
Hızı saniye başına piksel (pixels per second) olarak tanımlamak yaygın bir yöntemdir. Örneğin top saniyede 120 piksel sağa gitsin.
Kritik birim: p5.js’te deltaTime milisaniyedir (ms), saniye değil. 1 saniye = 1000 ms olduğu için formüle sokmadan önce saniyeye çevrilir:
Kod 1.
dtSaniye = deltaTime / 1000 // ör. 16.7 / 1000 ≈ 0.0167 skonumDegisimi = HIZ * dtSaniye // ör. 120 * 0.0167 ≈ 2 px bu frame'deTek satırda yazımı: HIZ * deltaTime / 1000 — / 1000 “ms → saniye” adımıdır; hız birimi (piksel/saniye) ile çarpmak için şarttır.
Tablo 2.
| Değişken | Örnek değer | Anlam |
|---|---|---|
HIZ |
120 | Saniyede 120 piksel |
deltaTime |
~16.7 (ms) | Son frame süresi — henüz saniye değil |
deltaTime / 1000 |
~0.0167 (s) | Aynı süre, saniye cinsinden |
HIZ * deltaTime / 1000 |
~2 piksel | Bu frame'de kayma |
60 FPS'te frame başına ~2 piksel, 30 FPS'te frame başına ~4 piksel olur; saniyede toplam yine ~120 piksel kalır.
Dikkat — sık tuzak: x = x + 100 * deltaTime yazmak (/ 1000 yok) yanlış birimle çarpmaktır. deltaTime ≈ 16.7 iken bir frame’de 100 * 16.7 ≈ 1670 piksel eklenir — top saniyede ~100 değil, on binlerce piksel “uçar”. Doğru olan 100 * deltaTime / 1000 (veya önce let dt = deltaTime / 1000, sonra x = x + 100 * dt).
Birim özeti: HIZ → piksel/saniye; deltaTime / 1000 → saniye; çarpım → piksel. Frame süresi kısalınca (FPS yüksek) frame başına eklenen piksel azalır, frame sayısı artar; süre uzayınca tersi olur — saniyedeki toplam aynı kalır. Bu, deltaTime hareketinin frame hızından bağımsız olmasının temelidir.
Okunabilir alışkanlık:
Kod 2.
let dt = deltaTime / 1000; // bir kez saniyeye çevirtopX = topX + HIZ * dt;Kod bloğu: Aynı top — deltaTime ile hareket.
Kod 3.
let topX = 50;let topY = 150;const TOP_YARICAP = 25;const HIZ = 120; // piksel / saniye function setup() { createCanvas(500, 300); noStroke(); frameRate(60);} function draw() { background(30, 35, 50); let dt = deltaTime / 1000; // ms → saniye topX = topX + HIZ * dt; // HIZ * deltaTime / 1000 ile aynı if (topX > width + TOP_YARICAP) { topX = -TOP_YARICAP; } fill(255, 200, 80); ellipse(topX, topY, TOP_YARICAP * 2, TOP_YARICAP * 2); fill(255); textSize(14); textAlign(LEFT, TOP); text("FPS: " + nf(frameRate(), 0, 1), 10, 10);}HIZ * deltaTime / 1000 tek satırda da yazılabilir; önce dt almak birimi görünür kılar.
Dikkat: deltaTime çok büyük olabilir: tarayıcı sekmesi arka plana alındığında veya bilgisayar uykuya geçtiğinde draw() duraklar; geri dönüldüğünde iki frame arasındaki süre birkaç saniyeye çıkabilir. Bazı oyunlarda üst sınır konur:
Kod 4.
let dt = min(deltaTime, 50) / 1000;topX = topX + HIZ * dt;Tek frame'de en fazla 50 ms sayılır; aksi halde top bir anda ekrandan fırlayabilir. Bu kitabın basit örneklerinde doğrudan deltaTime yeterlidir; tarayıcı sekmesi arka planda uzun süre kalırsa dönüşte ani sıçrama gözlemlenebilir — bu beklenen davranıştır.
Karşılaştırma tablosu (HIZ = 120, yaklaşık değerler):
Tablo 3.
| Yöntem | 60 FPS (dt≈16.7 ms) | 30 FPS (dt≈33.3 ms) | Saniyede toplam |
|---|---|---|---|
topX + 3 |
+3 px/frame | +3 px/frame | 180 px vs 90 px |
topX + 120 * dt/1000 |
+2 px/frame | +4 px/frame | ~120 px (her iki FPS) |
1.3. Hareketli Top Örneği
Aşağıdaki sketch, yatay hareketin yanı sıra dikey salınım ekler; sin() önceki bölümlerde tanıtılmıştır. Hareket güncellemesi deltaTime ile yapılır; çizim aynı draw() içinde kalır.
Oyun kuralları (basit demo):
- Top sürekli sağa hareket eder; tuval dışına çıkınca soldan tekrar girer.
- Dikey konum sinüs eğrisiyle salınır.
- Ekranda anlık FPS gösterilir.
Kod 5.
let topX = 0;const TOP_YARICAP = 22;const HIZ_X = 150; // yatay: piksel / saniyeconst SALINIM_GENISLIGI = 40;const SALINIM_HIZI = 2; // salınım faz hızı (radyan/saniye yaklaşık kullanım) let zaman = 0; // birikimli saniye (salınım fazı için) function setup() { createCanvas(560, 320); noStroke(); frameRate(60);} function draw() { background(25, 32, 48); let dtSaniye = deltaTime / 1000; topX = topX + HIZ_X * dtSaniye; zaman = zaman + dtSaniye; if (topX > width + TOP_YARICAP) { topX = -TOP_YARICAP; } let topY = height / 2 + sin(zaman * SALINIM_HIZI) * SALINIM_GENISLIGI; fill(255, 190, 70); ellipse(topX, topY, TOP_YARICAP * 2, TOP_YARICAP * 2); fill(220); textSize(14); textAlign(LEFT, TOP); text("FPS: " + nf(frameRate(), 0, 1), 12, 12); text("deltaTime: " + nf(deltaTime, 0, 1) + " ms", 12, 32);}Bu örnekte zaman değişkeni her frame'de dtSaniye kadar artırılarak birikimli bir saat gibi çalışır; sin(zaman * SALINIM_HIZI) ifadesi bu saate göre −1 ile +1 arasında salınan bir değer üretir ve SALINIM_GENISLIGI ile çarpılarak piksel cinsinden dikey ofsete dönüştürülür. zaman frame sayısına değil geçen gerçek süreye bağlı olduğu için, salınımın hızı da FPS'ten bağımsızdır — tıpkı yatay harekette olduğu gibi. Eğer bu değişken yerine frameCount (önceki bölümlerde tanıtılan, her frame bir artan sayaç) kullanılsaydı, salınım da frame hızına bağımlı hâle gelir ve yukarıda anlatılan tutarsızlık dikey eksende tekrarlanırdı.
setup() içinde frameRate(30) denendiğinde topun yatay hızı gözle aynı kalmalı; yalnızca hareketin akıcılığı (frame sayısı) değişir. Bu, deltaTime kullanımının amacını doğrular.
Deney önerisi: Aynı sketch'te topX = topX + 5 satırını geçici olarak geri getirin; frameRate(60) ve frameRate(30) arasında topun saniyede kat ettiği yolu gözlemleyin. Ardından HIZ * deltaTime / 1000 formülüne dönün — fark belirginleşir. Bu karşılaştırma, oyun geliştirmede «neden deltaTime?» sorusunun pratik yanıtıdır.
Sıra Sizde: Web Editor’de iki toplu karşılaştırma sketch’i yazın (yukarıdaki hareketli top örneğini temel alabilirsiniz).
İstenenler:
- İki top:
topAframe başına sabit (topAX = topAX + 4),topBzaman tabanlı (topBX = topBX + HIZ * deltaTime / 1000, ör.HIZ = 240). - Tuval dışına çıkınca her ikisi de soldan yeniden girsin; farklı renklerle çizin.
- Ekranda
frameRate()ve kısa bir etiket (A: frame,B: deltaTime) gösterin. setupiçindeframeRate(60)veframeRate(30)’u sırayla deneyin (veya1/2tuşuyla hedef FPS değiştirin). Hangisinin yatay temposu değişiyor, hangisi aynı kalıyor? Bir–iki cümleyle not edin.- (Bonus)
guncellevecizişlerini ayrı fonksiyonlara bölün;drawyalnızca arka plan + çağrı yapsın.
Yapay Zekâ Etkileşimi: İki tempo — sen yaz, YZ ölçüm / cilâ eklesin Tahmini etkinliği tamamlama süresi: 35–45 dakika.
Amaç: Frame vs deltaTime farkını çalışan kodla göstermek; ölçüm (saniye başına piksel) ve küçük bir cilâyı YZ’den isteyip çıktıyı eleştirel okumak.
Adım 1 — Sizin kodunuz: Sıra Sizde’deki iki toplu sketch’i kendiniz yazıp çalıştırın (frameRate 30/60 deneyi dahil). YZ’ye henüz tüm oyunu yazdırmayın.
Adım 2 — YZ’den ölçüm yardımcısı: Sketch’inizi yapıştırıp şunu isteyin:
Örnek istem — saniyede kaç piksel?
"Bu p5.js sketch’te iki top var (biri +4/frame, biri HIZ * deltaTime/1000). Mekaniği bozma. Her iki top için son 1 saniyede kat edilen yatay yolu ölçüp ekranda göster (ör. birikimli dx / geçen süre). frameRate(30) ve frameRate(60) iken A ve B için beklenen farkı kısa tabloyla da yaz. Class kullanma; kısa yorum ekle."
Adım 3 — Kontrol: Ölçülen değerler tablodaki sezgiyle uyuyor mu? A’nın saniyedeki yolu FPS ile değişiyor mu, B’ninki yaklaşık sabit mi? YZ deltaTime’ı yanlışlıkla iki kez mi böldü / 1000’i unuttu mu?
Adım 4 — İsteğe bağlı makyaj: Oyun hissi için YZ’ye (yine tam sketch ile) kısa bir cilâ isteyin — ör. tuşla 30/60 geçişi, min(deltaTime, 50) tavanı, hafif iz. Sonra «neleri değiştirdin, bu ders düzeyinde madde madde açıkla» deyin. Anlamadığınız satırda devam sorusu sorun; şu anki düzeyde ağır gelen parçayı sadeleştirmesini isteyin.
Yapay Zekâ Etkileşimi: Clamp’li deltaTime Tahmini süre: 15–20 dakika.
Amaç: Patolojik büyük deltaTime’ı sınırlamak.
Adım 1: Sekme sonrası deltaTime’ın çok büyümesi senaryosunu yazın.
Adım 2: Yapay zekâdan min(deltaTime, 50) benzeri clamp iskeleti isteyin.
Adım 3: Kendi top örneğinde clamp’li ve clampsiz farkı gözlemleyin.
Pekiştirme: kavramı mini senaryoya bağlama
- Veri: Hangi değişkenler durumu tutuyor?
- Güncelleme: Her frame veya olayda ne değişiyor?
- Çizim: Görünenler hangi alanlardan geliyor?
- Kural: Oyuncu eylemi hangi koşulla kabul/red?
Eksik adımı (sınır, başlangıç değeri, tek seferlik olay) şimdi tamamlamak, sonra büyük sketch içinde aramaktan kolaydır.
Sıra Sizde: Bu ana başlıkta öğrenilenleri sonraki konuya bağlayan tek cümlelik bir köprü yazın: “Şimdi X biliyorum; bundan sonra Y için buna ihtiyacım var.” Cümle kurulamıyorsa eksik kalan alt başlıktaki örnek bir kez daha çalıştırılır.
Bu noktada kurulan kalıbın tek cümlelik bir oyun kuralına bağlanması, kavramın yerleşip yerleşmediğini gösterir; kural yazılamıyorsa ilgili alt başlığa dönülüp örnek bir kez daha çalıştırılır. Küçük bir parametre değişikliğinin çıktıyı nasıl etkilediğini not etmek, sonraki ana başlıktaki birleşik örneğe geçişi kolaylaştırır.
Özet
Sabit x += n FPS’e bağımlıdır; deltaTime ile çarpılan hız ise zamana bağlıdır. Birimler önemlidir: deltaTime milisaniye olduğu için çoğu örnekte 1000’e bölünür. Çok büyük deltaTime (sekme sonrası) teleporta yol açmasın diye üst sınır (clamp) düşünülebilir.
Zaman tabanlı hareket, çarpışma ve klavye ile birleşince mini oyunlar farklı cihazlarda tutarlı oynanır. Bu ana başlık Temel Kavramlar kitabında animasyon taşınabilirliğinin anahtarını verir.
Değişikliğin görünür sonucu, sayıların anlamının değişmesidir. Sabit adım yazımında 5 değeri «her frame beş piksel» demektir ve gerçek hız donanıma göre oynar; zaman tabanlı yazımda aynı hız 300 gibi bir değerle «saniyede üç yüz piksel» olarak ifade edilir. Bu nedenle mevcut bir sketch zaman tabanlı hâle getirilirken bütün hız sabitlerinin yeniden ölçeklenmesi gerekir. Aynı çarpan, hız dışındaki zamana bağlı büyüklüklere de uygulanır: sayaçlar, geri sayımlar ve ömür değerleri de saniye cinsinden tutulur.
Ölçüt basittir: aynı sketch farklı FPS değerlerinde çalıştırıldığında topun tuvali kat etme süresi değişmiyorsa hareket zaman tabanlıdır. Değişiyorsa bir yerde frame sayısına bağlı bir güncelleme kalmış demektir. Aynı ölçüt, hareketin yanı sıra animasyon adımları ve düşman üretim aralıkları için de geçerlidir; zamana bağlanmamış tek bir sayaç bile oyunun temposunu donanıma bağımlı kılar.
Neler Öğrendik?
Soru 1
deltaTime tipik olarak neyi verir?
A) Son frame’den bu yana geçen süreyi (ms)
B) Tuval rengini
C) Dosya adını
D) DNS adresini
E) Git remote’u
Soru 2
x += hiz * (deltaTime/1000) neden tercih edilir?
A) Hareketi gerçek zamana bağlamak için
B) setup’ı silmek için
C) HTML’i kapatmak için
D) Sesi açmak için
E) CSS yazmak için
Soru 3 Frame başına sabit piksel eklemenin riski nedir?
A) Farklı FPS’te farklı gerçek hız
B) Dizinin zorunlu silinmesi
C) Renk körlüğü
D) EPUB bozulması
E) Yazıcı hatası
Soru 4 Hız değişkenini “birim / saniye” tutmanın yararı nedir?
A) deltaTime ile çarpınca anlamın net kalması
B) Klavyenin kapanması
C) Matematiğin kalkması
D) Sunucu zorunluluğu
E) SQL zorunluluğu
Neler Öğrendik Yanıt Anahtarı
Soru 1: Doğru Cevap: A
- Çözüm: p5.js deltaTime ms cinsindendir.
- İlgili Konu: 1.2. deltaTime
Soru 2: Doğru Cevap: A
- Çözüm: Zaman tabanlı entegrasyon.
- İlgili Konu: 1.2. Zaman Tabanlı Hareket
Soru 3: Doğru Cevap: A
- Çözüm: FPS düşünce sabit adım yavaşlar.
- İlgili Konu: 1.1. Frame Başına Hareketin Sorunu
Soru 4: Doğru Cevap: A
- Çözüm: Birim tutarlılığı okunabilirlik sağlar.
- İlgili Konu: 1.3. Hareketli Top Örneği
Yararlanılan Kaynaklar
Bu içerik aşağıdaki kaynaklardan derlenerek hazırlanmıştır:
- McCarthy, L., Reas, C., & Fry, B. (2015). Make: Getting Started with p5.js. Maker Media.
- Nystrom, R. (2014). Game Programming Patterns. gameprogrammingpatterns.com — Game Loop bölümü.
- Nystrom, R. (2014). Game Programming Patterns. Genever Benning. https://gameprogrammingpatterns.com/
- Nystrom, R. (2014). Game loop. In Game Programming Patterns. https://gameprogrammingpatterns.com/game-loop.html
- p5.js Foundation. (n.d.). deltaTime. p5.js Reference. https://p5js.org/reference/p5/deltaTime/
- p5.js Foundation. (n.d.). frameRate. p5.js Reference. https://p5js.org/reference/p5/frameRate/
- Shiffman, D. (n.d.). Code! Programming with p5.js. The Coding Train. https://thecodingtrain.com/tracks/code-programming-with-p5-js
Ana Başlık 2. Dizi Temelleri: Tanım, Erişim ve push/pop
Amaç: Dizi kavramını, indeksle erişimi ve push/pop/length işlemlerini oyun verisi bağlamında öğretmek.
Öğrenme Çıktıları:
- Diziyi sıralı koleksiyon olarak tanımlar.
- İndeks ile eleman okur ve yazar.
- for ile dizi dolaşır.
- push, pop ve length kullanımını uygular.
Anahtar Sözcükler: dizi, indeks, length, push, pop, paralel dizi
Giriş
Şimdiye kadar çoğu örnekte tekil değişkenler yeterliydi: bir x, bir skor, bir hedef. Oyunlar büyüdükçe aynı türden birçok değer birlikte yönetilir — birden fazla balon konumu, birden fazla engel, tahmin geçmişi. Bunları x1, x2, x3 diye çoğaltmak bakımı bozar; dizi (array) aynı türdeki değerleri tek isim altında, sırayla tutar.
JavaScript’te dizi köşeli parantezle yazılır; elemanlar 0’dan başlayan indekslerle okunur. length uzunluğu verir; push sona ekler, pop sondan çıkarır. Dolaşma çoğu zaman for ile yapılır. Bu ana başlık dizinin sözdizimini ve temel mutasyonlarını kurar; sabit kapasiteli yığın benzeri kullanım ve paralel dizilerle mini sahne bir sonraki ana başlıkta gelir. Bundan sonra gelen alt başlıklarda önce veri modeli, sonra hamle kuralı, en sonda çizim ve etkileşim kurulur. Her yeni fonksiyon mümkün olduğunca küçük bir örnekte çalıştırılır; böylece hatanın kaynağı daha kolay bulunur. Anlatımda önce ilgili yapının ne işe yaradığı açıklanır, ardından kod satır satır okunur. Terimler ilk geçtikleri yerde kısa bir tanımla verilir; gerekirse tablo veya görsel ile desteklenir. Örnek sketch’ler tek bir mekaniğe odaklanır; böylece yan konular okumayı dağıtmaz.
2.1. Dizi Kavramı ve Tanımlama
Tanım: Dizi (array) — Köşeli parantez [] ile tanımlanan, indeksle erişilen sıralı veri koleksiyonudur.
Kod 1.
let skorlar = [10, 25, 40]; // Sayı dizisilet renkler = [255, 120, 80]; // RGB bileşenlerilet mesajlar = ["dogru", "yuksek", "dusuk"]; // Metin dizisilet bosDizi = []; // Boş diziTablo 1.
| İfade | Anlam |
|---|---|
[] |
Boş dizi oluşturur |
[a, b, c] |
Başlangıç elemanlarıyla dizi |
dizi[0] |
İlk eleman (indeks 0) |
dizi.length |
Eleman sayısı |
Dikkat: İndeksler 1'den değil 0'dan başlar. skorlar[1] ikinci elemanı verir; skorlar[3] üç elemanlı dizide tanımsızdır (undefined).
Dikkat — boş slot (hole): Olmayan bir indekse yazmak diziyi “delikli” uzatabilir:
Kod 2.
let a = [1];a[3] = 44;// a.length → 4; a[1] ve a[2] boş (empty); okununca undefinedKonsolda çoğu zaman Array(4) [ 1, <2 empty slots>, 44 ] benzeri görünür. Bu, bilerek yazılan BOS / -1 işaretinden farklıdır: empty slot’ta hücre hiç doldurulmamıştır. push veya 0, 1, 2… sırasıyla atama boşluk bırakmaz; oyun listelerinde bu delikleri oluşturmayın.

Görsel 1 her elemanın indeks numarasını (0, 1, 2) ve skorlar[i] erişimini kutularla gösterir. Dördüncü kutu yoktur — skorlar[3] tanımsızdır.
Bilgi: JavaScript dizileri başlangıç düzeyinde farklı türleri aynı listede tutabilir ([1, "iki", true]). Oyun kodunda genellikle tek tür tutulması okunabilirliği artırır.
Dizi okuma izlemesi: let renkler = [255, 120, 80]; tanımı için indeks ve değer eşleşmesi şöyledir:
Tablo 2.
| İndeks | renkler[indeks] |
Anlam |
|---|---|---|
| 0 | 255 | Kırmızı bileşen |
| 1 | 120 | Yeşil bileşen |
| 2 | 80 | Mavi bileşen |
| 3 | undefined |
Dizide karşılığı yoktur |
fill(renkler[0], renkler[1], renkler[2]) ifadesi bu üç bileşeni sırayla okuyarak fill(255, 120, 80) ile aynı sonucu verir; dizi, ilgili renk bileşenlerini tek isim altında taşımayı sağlar.
Sıra Sizde: let skorlar = [10, 25, 40]; için kâğıda yazın:
skorlar[0]veskorlar[2]nedir?skorlar[3]neden sorunlu?skorlar.lengthkaçtır? Son geçerli indeks hangisidir?forile üç skoru alt alta yazdıracak döngünün koşulunu bir satırda yazın (i < …).
2.2. Dizi Elemanlarına Erişim, Dolaşma ve Paralel Diziler
Eleman okuma ve yazma:
Kod 3.
let tahminler = [7, 12, 5];tahminler[0] = 8; // İlk elemanı 8 yaplet ortanca = tahminler[1]; // 12Kod bloğu: for döngüsüyle dizi elemanlarını ekrana yazma.
Kod 4.
let tahminler = [7, 12, 5, 9]; function setup() { createCanvas(400, 300);} function draw() { background(240); fill(30); textSize(18); textAlign(LEFT, TOP); for (let i = 0; i < tahminler.length; i = i + 1) { let metin = (i + 1) + ". tahmin: " + tahminler[i]; text(metin, 20, 20 + i * 28); }}i < tahminler.length koşulu, indeksin dizi sınırları içinde kalmasını sağlar. length eleman sayısını verdiği için son geçerli indeks length - 1'dir.
Tablo 3.
| i | tahminler[i] | Ekrandaki satır |
|---|---|---|
| 0 | 7 | 1. tahmin: 7 |
| 1 | 12 | 2. tahmin: 12 |
| 2 | 5 | 3. tahmin: 5 |
| 3 | 9 | 4. tahmin: 9 |
Dizideki tek bir eleman güncellenebilir: tahminler[2] = 99; yalnızca üçüncü elemanı değiştirir. Son geçerli indeks dizi.length - 1'dir; bu sınırın dışına yazmak beklenmedik sonuçlara yol açabilir.
Paralel diziler — aynı indeks, bir nesne
Tek bir daire için x ve y iki değişken yeter. Ekranda birden fazla hedef varsa her biri için X ve Y gerekir. Bunları iki dizide, aynı indekste tutmak pratik bir çözümdür: hedefXListesi[i] ile hedefYListesi[i] aynı hedefin koordinatlarıdır. Bu modele paralel dizi denir. (İleride nesne veya 2B dizi alternatifleri gelecek; şimdilik paralel dizi yeterlidir.)
Hatırlatma — ellipse: ellipse(x, y, genislik, yukseklik) merkez (x, y) olan bir elips çizer. Genişlik ve yükseklik çaptır (yarıçapın iki katı). Daire için genişlik = yükseklik; oval için ikisi farklıdır. circle(x, y, cap) ise yalnızca daire içindir.
Kod bloğu: Konum listesinden birden fazla hedef çizimi.
Kod 5.
let hedefXListesi = [80, 200, 320];let hedefYListesi = [100, 150, 200];const YARICAP = 25; function setup() { createCanvas(400, 300); noStroke();} function draw() { background(25, 30, 45); fill(255, 200, 50); for (let i = 0; i < hedefXListesi.length; i = i + 1) { ellipse(hedefXListesi[i], hedefYListesi[i], YARICAP * 2, YARICAP * 2); }}Aynı i hem X hem Y’yi okur; döngü bir turda bir hedef çizer.

Görsel 2 hedefXListesi[i] ve hedefYListesi[i] çiftinin tuvalde aynı hedef dairesine karşılık geldiğini gösterir.
Sıra Sizde: Aşağıdaki sahnede biz (oyuncu) ve düşmanlar var. Bizim konumumuz tek bir noktadır — bizX, bizY iki değer yeter, dizi gerekmez. Ama düşmanlar çok olduğu için konumları paralel dizilerde tutulur: dusmanX[] ve dusmanY[]. Aynı indeks bir düşmanı verir: (dusmanX[i], dusmanY[i]). Boş / ölü slotta hem X hem Y -1’dir; döngüde atlanır (sahnede çizilmez).
Kod 6.
let bizX = 200, bizY = 150;let dusmanX = [60, 340, -1, 260, 150];let dusmanY = [60, 80, -1, 240, 200]; // [2] ikisi de -1 → yok
Kağıda yazın:
dusmanX.lengthkaçtır? Sahnede gerçekten kaç düşman var (-1slotunu saymayın)?(dusmanX[0], dusmanY[0])neresi? İndeks[2]neden sahnede yok?- Bize en yakın düşman hangi indeks?
forile-1olanları atlayıpdist(bizX, bizY, dusmanX[i], dusmanY[i])(veya uzaklık karesi) ile en küçüğü bulun.
2.3. push(), pop() ve length
Tanım: push() — Dizinin sonuna eleman ekler; length bir artar.
Tanım: pop() — Dizinin son elemanını çıkarır ve o değeri döndürür; length bir azalır.
Tablo 4.
| Metot / özellik | Etki | Örnek | Sonuç |
|---|---|---|---|
push(değer) |
Sona ekler | liste.push(42) |
liste [10, 20] iken → [10, 20, 42] |
pop() |
Sondan çıkarır | liste.pop() |
liste [10, 20, 42] iken → 42 döner; liste [10, 20] |
length |
Eleman sayısı | liste.length |
[10, 20] iken → 2 |

Görsel 4 push(9) öncesi ve sonrası diziyi yan yana gösterir; altta for döngüsünün her indekste hangi değeri okuduğu özetlenir.
Kod bloğu: Tahmin geçmişine ekleme.
Kod 7.
let tahminGecmisi = []; function mousePressed() { let yeniTahmin = floor(random(1, 11)); // 1–10 arası tam sayı tahminGecmisi.push(yeniTahmin);}floor() p5.js'te ondalıklı sayıyı aşağı yuvarlayarak tam sayı üretir; random(1, 11) 1 ile 11 arasında (11 hariç) değer verir.
Tanım: floor() — Verilen sayıyı aşağı yuvarlayan p5.js fonksiyonu; tam sayı elde etmek için random() ile birlikte kullanılır.
Dikkat: pop() boş dizide undefined döndürür. Oyun mantığında dizinin boş olup olmadığı length === 0 ile kontrol edilebilir.
pop() iz örneği: let liste = [10, 20, 42];
Tablo 5.
| Adım | İşlem | liste içeriği |
Dönüş |
|---|---|---|---|
| Başlangıç | — | [10, 20, 42] |
— |
| 1 | liste.pop() |
[10, 20] |
42 |
| 2 | liste.pop() |
[10] |
20 |
| 3 | liste.pop() |
[] |
10 |
| 4 | liste.pop() |
[] |
undefined |
Son satırda dizi boşken pop() güvenli çalışır ancak anlamlı değer vermez; oyun mantığında «son tahmini geri al» gibi özellikler eklenecekse önce length > 0 kontrolü yapılır.
Bilgi — yığın (stack): push ve pop yalnızca «diziyi büyüt / küçült» değil; birlikte kullanıldığında dizi yığın (stack) gibi davranır. Kural LIFO’dur (last in, first out — son giren ilk çıkar): en son eklenen eleman ilk çıkarılır. JavaScript’te ayrı bir Stack sınıfı şart değildir; sıradan bir dizi + push/pop çoğu zaman yeter.
Yığın, programlamada temel bir yapıdır: fonksiyon çağrıları makinede bir çağrı yığını üzerinde tutulur; derleyiciler ve yorumlayıcılar bu modeli kullanır. Oyun geliştirmede de sık görülür — birkaç tanıdık örnek:
Tablo 6.
| Bağlam | Yığın ne tutar? | push / pop hissi |
|---|---|---|
| Geri al (Undo) | Son hamleler / fırça darbeleri | Ctrl+Z ≈ pop; çizim editörleri, Super Mario Maker seviye düzenleyicisi, birçok bulmaca oyunu |
| Ekran / menü yığını | Açık menü katmanları | Duraklat → Ayarlar → Kontroller; kapatınca bir üst menüye dönüş (pop) — konsol RPG ve aksiyon oyunlarında klasik |
| Kart / deste | Destenin üstü | Solitaire ve benzeri kart oyunlarında desteden çekmek ≈ üstten pop; yeni kart koymak ≈ push |
| Envanter «son alınan» | Son eklenen eşyalar | Bazı envanter / crafting akışlarında «son ekleneni geri ver» veya kısa geçmiş |
Aşağıdaki mini kule örneğinde GERİ AL ile son kuleyi kaldırmak da aynı fikirdir: geçmiş bir yığındır.
Bilgi: push() çağrısının kendisi de bir değer üretir: eklemeden sonraki yeni eleman sayısını döndürür. let yeniUzunluk = tahminGecmisi.push(7); satırında yeniUzunluk, güncellenmiş tahminGecmisi.length ile aynı değeri taşır. Örneklerde dönüş değeri kullanılmaz, push yalnızca ekleme etkisi için çağrılır; ancak dönüş değerinin var olduğunu bilmek, ileride benzer metotlarla karşılaşıldığında şaşırtıcı olmayacaktır.
Kod bloğu: Dizide en büyük değeri bulma (skor listesi, can değerleri…).
Kod 8.
function enBuyuk(degerler) { if (degerler.length === 0) { return 0; } let maks = degerler[0]; for (let i = 1; i < degerler.length; i = i + 1) { if (degerler[i] > maks) { maks = degerler[i]; } } return maks;}enBuyuk(skorlar) çağrısı listedeki en yüksek skoru verir; for + karşılaştırma örüntüsü birçok özet istatistikte tekrarlanır.
Kod bloğu: Mini kule savunma — haritaya tıkla, kule kur (push); geri al henüz yok (Sıra Sizde’de pop).
Kod 9.
let kuleX = [];let kuleY = []; function setup() { createCanvas(400, 300);} function draw() { background(210, 230, 205); // yesil harita // Once buton — metinler ustune binmesin diye saginda / altinda fill(150, 60, 60); rect(0, 0, 72, 36); fill(255); textAlign(CENTER, CENTER); textSize(12); text("GERİ AL", 36, 18); fill(40); textSize(13); textAlign(LEFT, TOP); text("Haritaya tıkla: kule kur", 80, 6); text("GERİ AL: son kuleyi kaldır", 80, 22); text("Kule sayısı: " + kuleX.length, 12, 44); for (let i = 0; i < kuleX.length; i = i + 1) { fill(70, 110, 200); circle(kuleX[i], kuleY[i], 26); // kule govdesi fill(255); circle(kuleX[i], kuleY[i], 10); // namlu }} function mousePressed() { if (mouseX < 72 && mouseY < 36) { // GERİ AL — Sıra Sizde'de pop eklenecek } kuleX.push(mouseX); kuleY.push(mouseY);}Her tıklama harita konumunu her iki diziye push eder; kuleler ekranda birikir. Sol üst GERİ AL kutusuna tıklamak şu hâliyle kaldırma yapmaz; dahası tıklama alttaki push satırına da ulaştığı için o noktaya yeni bir kule eklenir. Kaldırma mantığı ve bu istenmeyen ekleme Sıra Sizde’de birlikte düzeltilir.
Sıra Sizde: Yukarıdaki mini kule savunma kodunu temel alın. GERİ AL’a tıklanınca son kurulan kuleyi kaldırın (kule savunmada yanlış yere konan kuleyi geri almak gibi).
İstenenler:
- Kâğıtta:
kuleX = [10, 20],kuleY = [30, 40]iken bir kule kurun →push(50, 60), sonra bir geri al — diziler nasıl kalır? mousePressediçinde GERİ AL dalına:length > 0ise her iki dizidepop(yalnızca birinde değil — paralel dizi!).- Çalıştırıp birkaç kule kurup geri alın; ekrandaki kule sayısı
kuleX.lengthile uyumlu olsun.
İpucu: Yalnızca if bloğunun içine pop yazmak yetmez — mousePressed içinde en az bir değişiklik daha gerekir; yoksa GERİ AL’a basınca istenmeyen bir push de tetiklenebilir.
Yapay Zekâ Etkileşimi: Dizi Dolaşma Bug’ı Tahmini süre: 15–20 dakika.
Amaç: Off-by-one hatalarını tanımak.
Adım 1: i <= dizi.length yazan hatalı bir döngü düşünün; ne olur yazın.
Adım 2: Yapay zekâya bu bug’ı ve düzeltmesini sorun; kendi gerekçenizle karşılaştırın.
Adım 3: Kısa bir diziyle editörde hem hatalı hem doğru sınırı deneyin.
Özet
Dizi, köşeli parantezle tanımlanan ve indeksle erişilen sıralı bir veri koleksiyonudur; let sayilar = [10, 20, 30] üç elemanlı bir listedir. İndeksler sıfırdan başladığı için sayilar[0] ilk elemanı verir ve son geçerli indeks length - 1 olur; bu sınırın dışına çıkan bir okuma undefined üretir. Dolaşma döngüsünün koşulu bu yüzden çoğu zaman i < dizi.length biçiminde yazılır. Var olmayan bir indekse yazmak diziyi boş hücrelerle uzatabilir; bu boşluklar, oyun listelerinde bilinçli olarak konan işaret değerlerinden farklıdır.
Aynı türden birden çok nesnenin özellikleri paralel dizilerde tutulabilir: iki ayrı listede aynı indeks aynı düşmanın x ve y koordinatını gösterir, kullanılmayan hücre ise bir işaret değeriyle atlanır. Tek bir for döngüsü her turda ilgili indeksin iki değerini birden okuyarak sahnedeki nesneleri çizer. Bu model, ileride gelecek nesne ve iki boyutlu dizi alternatiflerinin ön adımıdır.
push diziyi sonundan büyütür, pop son elemanı çıkarıp değerini döndürür ve length her iki işlemde de güncellenir; boş dizide pop çağrısı undefined verdiği için önce uzunluk denetlenir. İkisi birlikte kullanıldığında dizi, son giren ilk çıkar kuralıyla çalışan bir yığın gibi davranır; geri alma, menü katmanları ve kart destesi bu davranışın tanıdık örnekleridir. Sabit kapasiteli kullanım ve mini sahne örneği bir sonraki ana başlıkta bu temele dayanır.
Neler Öğrendik?
Soru 1 JavaScript dizilerinde ilk elemanın indeksi nedir?
A) 1
B) 0
C) -1
D) length
E) undefined
Soru 2
dizi.push(5) ne yapar?
A) İlk elemanı siler
B) 5’i dizinin sonuna ekler
C) Tuvali temizler
D) FPS’i 5 yapar
E) setup’ı yeniden çalıştırır
Soru 3
for (let i = 0; i < dizi.length; i++) neden yaygındır?
A) Çünkü length dışı indekslere güvenli sınır çizer
B) Çünkü rengi değiştirir
C) Çünkü HTML siler
D) Çünkü ses açar
E) Çünkü DNS ister
Soru 4 Paralel diziler ne anlama gelir?
A) İki dizinin aynı indekste ilişkili özellik tutması
B) İki tarayıcının zorunlu açılması
C) Yalnızca string birleştirme
D) CSS grid
E) Git branch
Neler Öğrendik Yanıt Anahtarı
Soru 1: Doğru Cevap: B
- Çözüm: JS dizileri 0 tabanlıdır.
- İlgili Konu: 2.1. Dizi Kavramı ve Tanımlama
Soru 2: Doğru Cevap: B
- Çözüm: push sona ekler.
- İlgili Konu: 2.3. push(), pop() ve length
Soru 3: Doğru Cevap: A
- Çözüm: length döngü üst sınırıdır.
- İlgili Konu: 2.2. Dizi Elemanlarına Erişim, Dolaşma ve Paralel Diziler
Soru 4: Doğru Cevap: A
- Çözüm: Aynı i indeksi aynı varlığı bağlar.
- İlgili Konu: 2.2. Dizi Elemanlarına Erişim, Dolaşma ve Paralel Diziler
Yararlanılan Kaynaklar
Bu içerik aşağıdaki kaynaklardan derlenerek hazırlanmıştır:
- McCarthy, L., Reas, C., & Fry, B. (2015). Make: Getting Started with p5.js. Maker Media.
- MDN Web Docs. (n.d.). JavaScript Guide. Mozilla. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
- Mozilla Developer Network. (n.d.). Array. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
- p5.js Foundation. (n.d.). floor. p5.js Reference. https://p5js.org/reference/p5/floor/
- p5.js Foundation. (n.d.). keyPressed. p5.js Reference. https://p5js.org/reference/p5/keyPressed/
- Shiffman, D. (n.d.). Code! Programming with p5.js. The Coding Train. https://thecodingtrain.com/tracks/code-programming-with-p5-js
Ana Başlık 3. Sabit Kapasite ve Paralel Dizilerle Mini Sahne
Amaç: push/pop olmadan sabit kapasiteli dizi kullanımını ve paralel dizilerle çoklu nesne sahnesini öğretmek.
Öğrenme Çıktıları:
- Sabit kapasite + tepe indeksi modelini açıklar.
- Paralel dizilerle birden fazla nesneyi günceller.
- Mini sahnede dizi tabanlı animasyon kurar.
- Dizi verisini oyun kuralına (ör. tahmin / balon) bağlar.
Anahtar Sözcükler: sabit kapasite, tepe, paralel dizi, mini sahne, çoklu nesne
Giriş
Dizi temelleri ve push/pop bilindikten sonra iki pratik yol ayrımı belirir. Birincisi dinamik liste: eleman gelince uzar, gidince kısalır. İkincisi sabit kapasite: dizi boyutu baştan ayrılır, “kaç eleman canlı?” bilgisi ayrı bir tepe/sayaçta tutulur. Bazı oyun iskeletlerinde ikinci model, bellek ve döngü sınırını öngörülebilir kılar.
Paralel diziler aynı indekste konum, hız veya renk gibi özellikleri birlikte taşır. Bu ana başlık sabit kapasite fikrini somutlaştırır ve paralel dizilerle küçük bir sahne kurar. Sayı tahmin veya balon örneği, dizinin yalnızca veri deposu değil oyun kuralının taşıyıcısı olduğunu gösterir. Sonraki bölümlerdeki klavye ve çarpışma, bu çoklu nesne alışkanlığının üzerine binecektir. Bundan sonra gelen alt başlıklarda önce veri modeli, sonra hamle kuralı, en sonda çizim ve etkileşim kurulur. Her yeni fonksiyon mümkün olduğunca küçük bir örnekte çalıştırılır; böylece hatanın kaynağı daha kolay bulunur. Anlatımda önce ilgili yapının ne işe yaradığı açıklanır, ardından kod satır satır okunur. Terimler ilk geçtikleri yerde kısa bir tanımla verilir; gerekirse tablo veya görsel ile desteklenir. Örnek sketch’ler tek bir mekaniğe odaklanır; böylece yan konular okumayı dağıtmaz.
3.1. Sabit kapasite: diziyi push / pop olmadan yığın gibi kullanmak
Motivasyon: push ve pop hazır metotlardır; onları bilmek işi kısaltır. Ama yığın mantığı metotlara bağlı değildir: «sona ekle / sondan çıkar» davranışını indeks ve atama ile de kurabilirsiniz. Bu, hem «metotları henüz bilmiyorum» durumunda bir çıkış yolu sunar hem de dizinin nasıl çalıştığını (slot, indeks, doluluk) daha görünür kılar. Birçok dilde ve özellikle makineye yakın ortamlarda hazır push/pop yoktur; sabit boyutta dizi + tepe indeksi klasik çözümdür.
push / pop dizinin gerçek uzunluğunu değiştirir. Alternatif yaklaşım: ihtiyaç duyulacak en fazla eleman sayısını (MAKS) baştan belirlemek; diziyi o uzunlukta oluşturup boş slotları özel bir değerle (BOS, -1, "" …) kodlamak; ekleme ve çıkarmayı push() / pop() çağırmadan slotlara yazarak yapmak. Böylece dizi yığın (stack) gibi kullanılır: length sabit kalır, doluluk bir tepe indeksiyle (veya BOS tarayarak) izlenir.
Fikir:
- Üst sınırı sabitle (
MAKS). - Diziyi
MAKSuzunluğundaBOSile doldur (geçerli veriden ayırt edilebilir olmalı). - «Ekle» (
pushbenzeri) =yigin[tepe] = deger; tepe++—push()yok. - «Çıkar» (
popbenzeri) =tepe--;değeri oku; slotaBOSyaz —pop()yok.
Kod 1.
const MAKS = 5;const BOS = -1; // geçerli tahmin 1–10 olduğu için -1 «boş» demektir let yigin = [BOS, BOS, BOS, BOS, BOS]; // length her zaman 5let tepe = 0; function yiginEkle(deger) { if (tepe >= MAKS) { return false; // yer yok } yigin[tepe] = deger; tepe = tepe + 1; return true;} function yiginCikar() { if (tepe === 0) { return BOS; // boş } tepe = tepe - 1; let eski = yigin[tepe]; yigin[tepe] = BOS; return eski;}Tablo 1.
| Adım | İşlem | yigin |
tepe |
|---|---|---|---|
| Başlangıç | — | [-1, -1, -1, -1, -1] |
0 |
| 1 | yiginEkle(7) |
[7, -1, -1, -1, -1] |
1 |
| 2 | yiginEkle(3) |
[7, 3, -1, -1, -1] |
2 |
| 3 | yiginCikar() → 3 |
[7, -1, -1, -1, -1] |
1 |
Bu modelde yigin.length her zaman MAKS kalır; dolu eleman sayısı tepe ile aynıdır. Ekrana yazarken yalnızca dolu slotlar çizilir:
Kod 2.
for (let i = 0; i < tepe; i = i + 1) { text(yigin[i], 20, 40 + i * 20);}tepe tutmak istemezseniz «ilk BOS slota yaz / sondan ilk dolu slotu boşalt» diye de tarayabilirsiniz; sonuç aynı fikirdir, yalnızca doluluk hesabı döngüyle yapılır.
Tablo 2.
| Yaklaşım | Boyut | Boş yer | Ne zaman uygun? |
|---|---|---|---|
push / pop |
length değişir |
Eleman yoksa slot yoktur | Uzunluk baştan bilinmiyor; geçmiş listesi |
Sabit kapasite + BOS (+ tepe) |
length === MAKS sabit |
Slot var, değer BOS |
Envanter, can, sabit düşman havuzu, yığın/geri al |
Bilgi — JavaScript’te dinamik dizi: Bu kitapta kullandığımız JavaScript / p5.js dizileri dinamiktir: push ile büyür, pop ile küçülür; length çalışma sırasında değişebilir. Bu yüzden «doğru boyutu baştan seçmek» JS’te çoğu zaman zorunluluk değil, tasarım tercihidir (örneğin envanterde tam 5 slot istiyorsanız).
Dikkat — bazı dillerde boyut sabit kalır: C, C++ sabit dizileri, Pascal dizileri veya gömülü / makineye yakın ortamlarda dizi boyutu çoğu zaman tanım anında belirlenir ve sonradan büyütülemez. Boyutu çok küçük seçmek taşmaya (overflow) ve hatalı bellek yazımına yol açabilir; çok büyük seçmek ise kullanılmayan slotlar yüzünden bellek israfına yol açar. Bu yüzden o dünyada «ihtiyacı doğru tahmin etmek» kritik bir mühendislik kararıdır. Sabit kapasite + tepe modeli, hem o kısıtı yansıtır hem de JS’te bile «maksimum N» kuralını açıkça kodlar.
Bilgi: 2.3’teki yığın fikri burada da aynıdır — fark yalnızca sözdizimidir: push/pop yerine tepe ve BOS ile LIFO davranışı elle kurulur. Gerçek oyun motorlarında da «maksimum N kayıtlı geri al» veya «en fazla N açık menü» gibi üst sınırlar sıkça sabittir; taşmayı engellemek için kapasite baştan kesilir.
Dikkat: Boş işaretçisi geçerli bir oyun değeriyle çakışmamalıdır. Tahmin aralığı 1–10 iken BOS = -1 uygundur; skor 0 da anlamlıysa 0 boş anlamına gelemez. String listelerinde sıkça "" veya "BOS" kullanılır.
Kule kurma ve skor geçmişi gibi örnekler push / pop ile yazılır (kısa ve okunaklıdır). Sabit slot / yığın modeli, metot bilmeden yığın kurmak, «maksimum N yer» kuralını gömmek veya sabit boyutlu dizi zorunluluğu olan dilleri anlamak için bilinmelidir.
Ne isteniyor? (kısa): push / pop kullanmadan «aynı işi başka sözdizimiyle yaz» demek değil. Yukarıdaki sabit slot + tepe modeli zaten yiginEkle / yiginCikar ile duruyor. Sıra Sizde’de bu modeli çalışan bir mini sketch’te göreceksiniz; sizin göreviniz listenin görselini Görsel 1’deki gibi slot kutularına çevirmek.

Kod bloğu: Mini envanter — tıkla ekle / sol üstten çıkar (push/pop yok).
Kod 3.
const MAKS = 5;const BOS = ""; let envanter = [BOS, BOS, BOS, BOS, BOS]; // length her zaman 5let tepe = 0;let esyalar = ["kilic", "iksir", "anahtar", "kalkan", "harita"]; function setup() { createCanvas(520, 200); textAlign(CENTER, CENTER);} function draw() { background(245); fill(40); textSize(14); textAlign(LEFT, TOP); text("Sol tık: eşya ekle | Sol üst kutu: çıkar | length = " + envanter.length, 12, 10); text("tepe = " + tepe, 12, 32); // Sol üst: çıkar fill(120, 80, 80); rect(0, 160, 40, 40); fill(255); textAlign(CENTER, CENTER); textSize(11); text("ÇIKAR", 20, 180); // Şimdilik yalnızca metin listesi — Sıra Sizde'de bunu Görsel 1 gibi slotlara çevireceksiniz textAlign(LEFT, TOP); textSize(14); fill(30); for (let i = 0; i < MAKS; i = i + 1) { let yazi = envanter[i]; if (yazi === BOS) { yazi = "(boş)"; } text("[" + i + "] " + yazi, 60, 70 + i * 20); }} function mousePressed() { if (mouseX < 40 && mouseY > 160) { yiginCikar(); return; } // Sıradaki eşyayı ekle (döngüsel) let ad = esyalar[tepe % esyalar.length]; yiginEkle(ad);} function yiginEkle(deger) { if (tepe >= MAKS) { return false; } envanter[tepe] = deger; tepe = tepe + 1; return true;} function yiginCikar() { if (tepe === 0) { return BOS; } tepe = tepe - 1; let eski = envanter[tepe]; envanter[tepe] = BOS; return eski;}Sketch’i çalıştırın: birkaç kez tıklayın, ÇIKAR ile geri alın. Konsolda veya ekranda envanter.length’in hep 5 kaldığını görün — push/pop olmadığı için dizi büyüyüp küçülmez; doluluk tepe ile izlenir.
Sıra Sizde: Yukarıdaki mini envanter kodunu temel alın. draw içindeki metin listesini kaldırıp Görsel 1’e benzer 5 yan yana dikdörtgen slot çizin.
İstenenler:
- Dolu slot (
envanter[i] !== BOS): dolu kutu + eşya adı. - Boş slot: soluk / kesik çizgili çerçeve + «BOS» (veya boş bırakın).
tepeindeksinin altına küçük bir üçgen veya ok koyun (sonraki boş slotu göstersin;tepe === MAKSiken en sağda veya «dolu» yazın).yiginEkle/yiginCikarvemousePressedmantığına dokunmayın — yalnızca çizimi değiştirin.envanter.lengthhâlâ 5 olmalı.
3.2. Paralel dizilerle mini sahne — balonlar
2.2’de paralel diziler ve ellipse hatırlatması yapıldı; 2.3’te push / pop ile liste büyüyüp küçüldü. Bu alt başlıkta ikisini birleştirip oval balon sahnesi kurulur: konum için balonX / balonY, boyut için ayrı balonRX / balonRY (yatay ve dikey yarıçap) — hepsi aynı indekste.
Hatırlatma: ellipse(x, y, genislik, yukseklik) — genişlik = 2 * rx, yükseklik = 2 * ry. Daire istiyorsanız rx === ry (veya circle); Görsel 2’deki gibi oval balonlar için rx ile ry farklıdır.
Sık karşılaşılan dizi hataları:
Tablo 3.
| Belirti | Olası neden | Çözüm |
|---|---|---|
undefined ekranda |
Geçersiz indeks (d[3] üç elemanlı dizide) |
i < dizi.length koşulunu kontrol et |
| Döngü hiç çalışmıyor | i <= length sınır aşımı |
i < length kullan |
push sonrası liste görünmüyor |
draw() içinde dolaşma yok |
for ile ekrana yazdır |
| Tüm balonlar üst üste / garip boyut | Paralel dizide indeks kayması | Aynı i ile X, Y, RX, RY oku |
| Bir balon «kaybolmuş» gibi | Yalnızca bir diziye push / pop |
Ekleme-çıkarma tüm paralel dizilerde birlikte |
Dikkat: Paralel dizilerde push yalnızca bir listeye uygulanırsa listeler farklı uzunlukta kalır. balonX.push(mouseX) yapıp balonY / balonRX / balonRY unutulursa döngü undefined okur. Ekleme ve çıkarma her listede birlikte yapılmalıdır.
Sıra Sizde: Paralel dizilerle bir balon sahnesi çizin. Hedef görünüm:

İstenenler:
balonX,balonY,balonRX,balonRY(isteğe bağlı renk dizisi) — aynı indekste bir balon.foriçindeellipse(balonX[i], balonY[i], balonRX[i] * 2, balonRY[i] * 2)(ip için kısa birlinebonus).- Kâğıtta: yalnızca
balonX.push(...)yapıp diğer üç diziyi unutan bir arkadaşın ekranında ne bozulur? Bir cümleyle yazın.
Örnek Olay: Kule yığını Tahmini etkinliği tamamlama süresi: 20–25 dakika.
Senaryo: Mini kule sketch’inde üç kule kurulmuş, sonra bir kez GERİ AL’a basılmıştır. Dizilerde ne kalır, ekranda kaç kule görünür?
Tartışma Soruları:
kuleX[0]hangi kuleyi temsil eder — ilk mi, son mu?- GERİ AL neden her iki dizide
popister? length === 0ikenpopçağırmak neden risklidir?
Yapay Zekâ Etkileşimi: Balon Patlat — sen yaz, YZ yardımcı fonksiyon yazsın Tahmini etkinliği tamamlama süresi: 45–60 dakika.
Amaç: Oyun mekaniğini (siz yazın); nokta–elips testi, çakışmasız yeni balon ve uyumlu renk gibi yardımcı fonksiyonları YZ’den isteyin; en sonda çalışan oyunu YZ ile makyajlayın (patlama / belirme efektleri). Boş slot / -1 yok — ekleme push, silme splice (veya sondaysa pop).
splice (kısa): dizi.splice(i, 1) indeksi i olan elemanı çıkarır (length bir azalır). pop() yalnızca sondan çıkarır; ortadaki balonu patlatmak için splice gerekir. Paralel dizilerde aynı i için her listede splice(i, 1) çağrılır.
Oyun fikri (kısa): Oval balonlar (balonX, balonY, balonRX, balonRY; isteğe bağlı balonR, balonG, balonB). Tıklama bir balonun içindeyse o indeks tüm dizilerden splice ile çıkar, skor artar. Değilse YZ’nin ürettiği yardımcılarla yeni, diğerlerine değmeyen bir balon push edilir.
Adım 1 — Sizin kodunuz (oyun mekaniği): Web Editor’de şunları kendiniz yazın:
- Paralel diziler + birkaç başlangıç balonu (elle sabit değerler yeterli)
setup/draw: arka plan, skor,for+ellipse(+ isteğe bağlı ip)mousePressedakışı (iskelet):- Tıklanan noktayı hangi balon içeriyor? → (Adım 2’deki
noktaElipsIcindeMiile bakın; indeksi bulun) - Bulunduysa: tüm paralel dizilerde
splice(i, 1);skor = skor + 1 - Bulunamadıysa:
yeniBalonOlustur(...)sonucunu dört (veya yedi) diziyepushedin
- Tıklanan noktayı hangi balon içeriyor? → (Adım 2’deki
- Class / nesne alanı kullanmayın; veri paralel dizilerde kalsın
Adım 2 — YZ’den üç yardımcı fonksiyon: Aşağıdaki istemleri ayrı ayrı (veya tek seferde üç fonksiyon diye) verin. Dönüş için dizi kullanın — bu ana başlıkta nesne literal ({ x: … }) henüz yok; [x, y, rx, ry] yeter ([0]→x, [1]→y, [2]→rx, [3]→ry).
Örnek istem A — nokta elips içinde mi?
"p5.js için fonksiyon yaz: noktaElipsIcindeMi(px, py, cx, cy, rx, ry) → boolean. (px,py) noktası, merkezi (cx,cy), yatay yarıçap rx, dikey yarıçap ry olan elipsin içinde mi? Elips denklemi kullan. Kısa yorum ekle. Class / nesne literal yok."
Örnek istem B — çakışmasız yeni balon:
"Fonksiyon: yeniBalonOlustur(balonX, balonY, balonRX, balonRY, tuvalW, tuvalH). Rastgele konum ve rx/ry üret; balon tamamen tuval içinde kalsın; mevcut balonlardan hiçbirine değmesin (elips–elips veya güvenli daire yaklaşımı). Birkaç deneme yapsın; yer bulamazsa null dönsün. Dönüş: dizi [x, y, rx, ry] — nesne literal kullanma. Parametre olarak mevcut paralel dizileri ve tuval boyutlarını alsın."
Örnek istem C — uyumlu renk (isteğe bağlı):
"Fonksiyon: uyumluBalonRengi() → [r, g, b] (0–255). Pastel / birbirine uyumlu canlı renkler üretsin (ör. sabit doygunluk, rastgele ton). color() nesnesi yerine sayı dizisi dön."
Adım 3 — Birleştirme (siz): YZ fonksiyonlarını sketch’e yapıştırın. mousePressed içinde örneğin:
Kod 4.
// iskelet — indeksi siz bulun, splice / push siz yazınlet vurus = -1;for (let i = 0; i < balonX.length; i = i + 1) { if (noktaElipsIcindeMi(mouseX, mouseY, balonX[i], balonY[i], balonRX[i], balonRY[i])) { vurus = i; break; }}if (vurus >= 0) { // tüm paralel dizilerde splice(vurus, 1); skor++} else { let b = yeniBalonOlustur(balonX, balonY, balonRX, balonRY, width, height); if (b !== null) { // b[0]..b[3] → push; renk için uyumluBalonRengi() }}Adım 4 — Kontrol / eleştirel bakış:
noktaElipsIcindeMigerçekten elips mi kullanıyor, yoksa yalnızcadistile daire mi?yeniBalonOlusturtuval kenarlarını ve mevcut balonları dikkate alıyor mu? Dönüş gerçekten[x,y,rx,ry]mi?- Siz
splice/push’u tüm paralel dizilerde birlikte mi yaptınız? - Renk fonksiyonu varsa
fill(r, g, b)ile mi bağladınız?
Oyun mekanik olarak çalışıyorsa (patlat / ekle / skor) Adım 5’e geçin. İsterseniz süzülme (balonY[i] = balonY[i] - 0.5) gibi ufak bir mekaniği de kendiniz ekleyebilirsiniz.
Adım 5 — Makyaj (YZ): Mantık bittikten sonra çalışan sketch’in tamamını yapıştırıp görsel + ses cilasını YZ’ye bırakın. Amaç oyunu yeniden yazmak değil; patlama / belirme hissi ve kısa geri bildirim sesleri katmak.
Örnek istem — efektli makyaj (+ ses + açıklama): "Aşağıdaki p5.js Balon Patlat sketch’im çalışıyor (paralel diziler, splice/push, skor). Mekaniği bozma; class kullanma; paralel dizi modelini koru.
Yapılacaklar:
- Balon patlayınca hemen splice etme — kısa kaybolma animasyonu (küçülme ve/veya alfa; parçacık/halka bonus olabilir).
- Yeni balon eklenince büyüme veya fade-in ile belirsin.
- Patlamada ve yeni balon eklenince kısa ses efekti (p5.sound veya basit sentez / Oscillator; Web Editor’de çalışacak şekilde; dosya yoksa sentez tercih et).
Ayrıca yanıtında şunları iste:
A) Önce sözel olarak: balon patlatma için kaç farklı efekt türü düşünülebilir? (ör. küçülerek kaybolma, alfa solma, parçacık saçılma, genişleyen halka, titreme…) Her türü 1–2 cümleyle anlat.
B) Her tür için bu sketch’e uygun, kısa örnek kod parçası yaz (hepsini birden uygulamana gerek yok; birini seçip tam koda entegre et, diğerlerini örnek olarak göster).
C) En sonda: benim orijinal koda göre neleri değiştirdin / ekledin listesini yaz. Her maddeyi bu ders düzeyinde açıkla (dizi, for, push/splice, fonksiyon — henüz bilmediğimiz class/nesne jargonundan kaçın).
Kod:"
(Ardından kendi sketch’inizi yapıştırın.)
YZ’nin önerdiği animasyon için çoğu zaman ekstra diziler gerekir (ör. balonOlcek, balonAlfa veya «patlıyor» durumu). Bunları eklerken indekslerin hâlâ birlikte push / splice edildiğini kontrol edin. Ses için ek kütüphane / userStartAudio() gibi satırlar gelebilir — Play’e bastıktan sonra ilk tıklamada sesin açılması normaldir. Efekt abartılıysa sadeleştirin; skor ve tıklama mantığı bozulmamalı.
Adım 6 — Önce fikir, sonra (isterseniz) kod: YZ’nin Adım 5’teki «neleri değiştirdim» listesini okuyun. Anlamadığınız bir satır varsa devam sorusu sorun (ör. «Şu eklediğin balonAlfa dizisini, bu dersteki paralel dizi diliyle tekrar açıkla.»).
Ardından oyunu daha ileri taşımak için önce yalnızca fikir isteyin — henüz kod istemeyin:
Örnek istem — başka nasıl makyajlarız? (yalnızca fikir) "Bu Balon Patlat oyununu (paralel diziler, patlat/ekle, skor) daha eğlenceli yapmak için 6–8 makyaj / cilâ fikri öner. Görsel, ses, arayüz ve hafif oyun hissi karışık olsun. Her fikir için kısa sözel açıklama ve zorluk (kolay/orta) yaz. Kod yazma; yalnızca fikir kataloğu."
Beğendiğiniz bir (veya birkaç) fikri uygulamaya dökmek isterseniz, mevcut sketch’inizi yapıştırıp uygun bir prompt yazın; yapılan makyajın kodunu sizin şu anki bilgi düzeyinizde açıklamasını isteyin. Anlamadığınız noktalarda devam soruları sorun.
Örnek istem — seçilen fikri uygula + açıkla: "Şu makyaj fikrini mevcut koda ekle: [fikri buraya yaz]. Mekaniği bozma. Bitince: (1) eklediğin/değiştirdiğin yerleri madde madde listele, (2) her maddeyi dizi, for, push/splice, fonksiyon dilinde, yeni başlayan düzeyinde açıkla. Kod:"
Hatırlatma: YZ bazen bu derste henüz görmediğiniz yapılara (ör. daha ileri animasyon, ses API’si, alışık olmadığınız sözdizimi) kayabilir. Bir parçayı «şu anki düzeyimde anlamıyorum, daha basit anlat veya o kısmı sadeleştir» diyerek geri itmek doğaldır; her satırı hemen kavramak zorunda değilsiniz. Anladığınız katmanı tutup, kalanını sonraki konulara bırakabilirsiniz.
Yapay Zekâ Etkileşimi: Paralel Diziden Nesneye Tahmini süre: 15–20 dakika.
Amaç: Paralel dizilerin nesne literaline eşlenmesini görmek.
Adım 1: x[i], y[i], r[i] için bir nesne şekli ({x,y,r}) tasarlayın.
Adım 2: Yapay zekâdan paralel dizi ↔ nesne dizisi dönüşüm iskeleti isteyin; henüz sınıf kullanmayın.
Adım 3: Hangi modelin bu aşamada daha okunur olduğunu bir cümleyle not edin.
Özet
Sabit kapasitede dizi, baştan istenen sayıda eleman içerecek biçimde (ör. [BOS, BOS, BOS, BOS]) tanımlanır; canlı eleman sayısı tepe benzeri bir değişkenle izlenir. Ekleme tepeye yazar ve tepeyi artırır; silme tepeyi azaltır — push/pop yerine indeks aritmetiği vardır. Bu model, nesne havuzu düşüncesine de köprüdür.
Paralel x[], y[], r[] dizileri aynı i ile bir balonu veya hedefi tanımlar. draw içinde i < tepe (veya length) kadar dolaşıp güncelleme ve çizim yapılır. Mini sahne, diziyi görünür oyun davranışına bağlar: çoklu konum, basit kural, okunabilir döngü. Bu alışkanlık olmadan sonraki çarpışma ve klavye kontrollü çoklu varlıklar zorlaşır.
İki modelin maliyeti farklıdır. Dinamik listede silme işlemi kalan elemanları kaydırdığı için indeksler değişir; döngü içinde eleman çıkarmak, atlanan eleman gibi ince hatalara yol açar. Sabit kapasitede ise dizi hiç küçülmez, yalnızca tepe değeri oynar; bu yüzden indeksler kararlıdır ve döngü sınırı her frame'de aynı biçimde okunur. Kapasitenin dolması ayrı bir karardır: yeni eleman ya reddedilir ya da en eskisinin üzerine yazılır. Bu seçim, oyunun kuralına göre baştan belirlenir.
Neler Öğrendik?
Soru 1
Sabit kapasite modelinde tepe tipik olarak neyi tutar?
A) Tuval rengini
B) Canlı / geçerli eleman sayısına giden sınırı
C) DNS adresini
D) CSS sınıfını
E) EPUB kapak adını
Soru 2
Paralel x ve y dizilerinde aynı indeks ne anlama gelir?
A) İki farklı oyunun skoru
B) Aynı varlığın ilişkili özellikleri
C) Rastgele iki tarayıcı
D) Zorunlu ses kanalı
E) Git commit
Soru 3
Mini sahnede diziyi draw içinde dolaşmanın amacı nedir?
A) Her varlık için güncelleme ve çizimi tekrarlamak
B) setup’ı silmek
C) HTML’i kapatmak
D) Renk körlüğü testi
E) Yazıcıya göndermek
Soru 4
push/pop yerine sabit kapasite seçmek ne sağlar?
A) Üst sınırın ve döngünün öngörülebilir kalması
B) Matematiğin kalkması
C) Farein kapanması
D) Zorunlu 3B
E) Sunucu kurulumu
Neler Öğrendik Yanıt Anahtarı
Soru 1: Doğru Cevap: B
- Çözüm: tepe canlı aralığı işaret eder.
- İlgili Konu: 3.1. Sabit kapasite
Soru 2: Doğru Cevap: B
- Çözüm: Aynı i aynı nesneye aittir.
- İlgili Konu: 3.2. Paralel dizilerle mini sahne
Soru 3: Doğru Cevap: A
- Çözüm: Frame başına tüm canlılar işlenir.
- İlgili Konu: 3.2. Paralel dizilerle mini sahne
Soru 4: Doğru Cevap: A
- Çözüm: Kapasite baştan bellidir.
- İlgili Konu: 3.1. Sabit kapasite
Yararlanılan Kaynaklar
Bu içerik aşağıdaki kaynaklardan derlenerek hazırlanmıştır:
- McCarthy, L., Reas, C., & Fry, B. (2015). Make: Getting Started with p5.js. Maker Media.
- MDN Web Docs. (n.d.). JavaScript Guide. Mozilla. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
- Mozilla Developer Network. (n.d.). Array. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
- p5.js Foundation. (n.d.). floor. p5.js Reference. https://p5js.org/reference/p5/floor/
- p5.js Foundation. (n.d.). keyPressed. p5.js Reference. https://p5js.org/reference/p5/keyPressed/
- Shiffman, D. (n.d.). Code! Programming with p5.js. The Coding Train. https://thecodingtrain.com/tracks/code-programming-with-p5-js
Ana Başlık 4. Klavye Girdisi
Amaç: Klavye olaylarını (keyIsDown, key, keyPressed()) öğreterek oyuncu kontrollü hareket sağlamak.
Öğrenme Çıktıları:
- Klavye girdisinin oyun döngüsündeki yerini açıklar.
keyIsDown()ile sürekli basılı tuş kontrolü yapar.keyPressed()ile tek seferlik tuş olayını yakalar.keyvekeyCodedeğişkenlerini ayırt eder; tuş kodlarının ASCII/Unicode ile ilişkisini açıklar.deltaTimeile klavye kontrollü hareket kodlar.
Anahtar Sözcükler: klavye girdisi, keyIsDown, keyPressed, key, keyCode, oyuncu kontrolü, ASCII, Unicode
Giriş
Önceki ana başlıkta top deltaTime ile kendi kendine hareket ediyordu; oyuncu yalnızca izliyordu. Oyunlarda karakter, araç veya imleç çoğu zaman klavye (ve fare) ile yönlendirilir. Klavyenin en tanıdık kullanımı tek seferlik olaydır: bir tuşa basıldığı anda tek bir iş yapılır, örneğin R ile tur yeniden başlatılır. Gerçek zamanlı kontrolde ise tuş basılı tutulduğu sürece hareket devam etmelidir: WASD veya ok tuşlarıyla kareyi gezdirmek buna tipik örnektir.
p5.js, fare girdisinde olduğu gibi klavye için de iki katman sunar: draw() içinde her frame okunan durum (keyIsDown) ve tuşa basıldığı anda bir kez çalışan olay fonksiyonu (keyPressed). Bu ana başlıkta her iki yöntem sistematik biçimde ele alınacak; hareket deltaTime ile birleştirilerek önceki ana başlıktaki frame bağımsız hız korunacaktır.
Bu iki katmanlı yaklaşım, klavyenin fiziksel doğasından kaynaklanır: bir tuş, oyuncu parmağını kaldırana kadar "basılı" kalır ve bu süre boyunca aynı tuşa ait sayısız draw() çağrısı gerçekleşebilir. Programın bu süreklilikten haberdar olması için her frame'de tuşun anlık durumunu sorgulaması gerekir; bu da keyIsDown() fonksiyonunun görevidir. Buna karşılık "tuşa basıldı" bilgisinin yalnızca bir kez işlenmesi istenen durumlar da vardır — bir menüde seçim yapmak, bir mermi ateşlemek gibi; bu tür senaryolarda p5.js'in tuş basışını olay olarak bildirdiği keyPressed() daha uygundur. İki katmanı doğru yerde kullanmak, klavye kontrollü bir oyunun hem tepkisel hem öngörülebilir olmasını sağlar.
Türkiye'de okul laboratuvarlarında QWERTY klavye yaygındır; WASD ve ok tuşları birlikte desteklenirse farklı alışkanlıklara sahip oyuncular aynı sketch'i kullanabilir. Tuval odaklıyken tuşlar sketch'e gider — önizleme paneline bir kez tıklamak gerekir; aksi halde girdi tarayıcıya veya editöre yönlenebilir.
4.1. Klavye Olayları ve p5.js Örüntüsü
Tanım: Klavye girdisi — Oyuncunun tuş basmasıyla programa ilettiği kontrol bilgisidir.
p5.js'te yerleşik olay fonksiyonları (önceki bölümlerde setup, draw, mousePressed ile tanıtılan örüntü):
Tablo 1.
| Fonksiyon | Ne zaman çalışır | Tipik kullanım |
|---|---|---|
keyPressed() |
Tuşa basıldığı frame'de bir kez | Zıplama, ateş, menü seçimi, tur yenileme |
keyReleased() |
Tuş bırakıldığı frame'de bir kez | Tuş bırakılınca eylem tetikleme (ör. şarj biriktirip bırakınca ateş etme) |
draw() + keyIsDown() |
Tuş basılı olduğu sürece her frame | Sürekli yürüme, hızlanma |
Bilgi: keyPressed adını taşıyan fonksiyon, p5.js'in otomatik çağırdığı yerleşik olay adıdır; setup ve draw gibi tam yazım gerekir. Kendi fonksiyon adınız farklı olursa p5.js o kodu tuş olayı için çalıştırmaz.
Fare ile karşılaştırma (önceki bölümler):
Tablo 2.
| Girdi | Sürekli (basılı tutma) | Tek seferlik olay |
|---|---|---|
| Fare | mouseIsPressed, mouseX / mouseY |
mousePressed() |
| Klavye | keyIsDown(...) |
keyPressed() |
4.2. keyIsDown ile Sürekli Hareket
Tanım: keyIsDown(key) — p5.js fonksiyonu; verilen tuş o frame'de basılıysa true, değilse false döndürür. draw() içinde çağrılır.
Ok tuşları için p5.js sabitleri kullanılabilir: LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW. Harf tuşlarında keyIsDown sayı ister: 65 (A), 68 (D).
Kod bloğu: Ok tuşlarıyla yatay hareket — deltaTime ile hız.
Kod 1.
let kareX = 200;let kareY = 150;const KARE_BOYUT = 40;const HIZ = 180; // piksel / saniye function setup() { createCanvas(500, 300); noStroke();} function draw() { background(35, 40, 55); let dt = deltaTime / 1000; if (keyIsDown(RIGHT_ARROW)) { kareX = kareX + HIZ * dt; } if (keyIsDown(LEFT_ARROW)) { kareX = kareX - HIZ * dt; } fill(100, 200, 255); rect(kareX, kareY, KARE_BOYUT, KARE_BOYUT);}Birden fazla if kullanıldığında koşullar bağımsızdır; çapraz hareket (ör. sağ + yukarı) aynı frame'de birleşebilir. else if yalnızca tek yön seçilecekse uygundur.
Çapraz hareket ve hız: Sağ ve yukarı aynı anda basılıyken kare hem X hem Y değişir; frame başına kat edilen mesafe HIZ * dt ile her eksende ayrı uygulanır. Köşegen hareket biraz daha hızlı görünebilir (Pisagor bağıntısı); rekabetçi oyunlarda hız normalize edilir. Örneklerde basit bağımsız if blokları kullanılır; çapraz hızı eşitlemek istenirse X ve Y bileşenleri birim vektöre göre ölçeklenip (normalize edilip) tekrar HIZ ile çarpılır.
Tablo 3.
| Tuş kombinasyonu | X değişimi | Y değişimi | Görsel etki |
|---|---|---|---|
| Yalnızca RIGHT | + | 0 | Yatay |
| Yalnızca UP | 0 | − | Dikey |
| RIGHT + UP | + | − | Çapraz sağ-üst |
Dikkat: Tuş kodunu yalnızca keyPressed() içinde okursanız basılı tutma ile sürekli hareket üretilemez; draw() döngüsünde keyIsDown gerekir.
Bu hata sık görülür çünkü keyPressed() sezgisel olarak "tuşla ilgili her şeyin buraya yazılacağı" fonksiyon gibi algılanabilir. Ancak keyPressed() yalnızca tuşa basılma anında bir kez tetiklenir; oyuncu tuşu birkaç saniye basılı tutsa da fonksiyon gövdesi tek seferlik çalışır. Bu nedenle keyPressed() içine kareX = kareX + HIZ * dt gibi bir satır yazmak, karenin yalnızca her basışta bir kez ve sabit miktarda ilerlemesine yol açar — akıcı hareket değil, adım adım sıçrama görünür. Sürekli hareket her zaman draw() içindeki bir koşulla, yani keyIsDown() ile sağlanmalıdır.
Dikey hareket için UP_ARROW ve DOWN_ARROW aynı örüntüyle eklenir:
Kod 2.
if (keyIsDown(DOWN_ARROW)) { kareY = kareY + HIZ * dt; } if (keyIsDown(UP_ARROW)) { kareY = kareY - HIZ * dt; }4.3. keyPressed ve Tek Seferlik Eylemler
Turu yeniden başlatan R tuşu, keyPressed() ile şu biçimde yazılır:
Kod 3.
function keyPressed() { if (key === "r" || key === "R") { // turu sıfırla }}Tanım: key — Basılan tuşun karakter değerini tutan p5.js değişkeni ( 'a', 'R', ' ' boşluk vb.). Yalnızca olay fonksiyonu çalıştığı frame'de anlamlıdır.
keyPressed() ile mousePressed() aynı mantığı izler: olay bir kez tetiklenir. Zıplama, tek atış veya menüde seçim gibi "her basışta bir eylem" senaryolarına uygundur.
Kod bloğu: Boşluk tuşuna basınca karenin rengini değiştirme (toggle).
Kod 4.
let kareRengi; function setup() { createCanvas(400, 300); kareRengi = color(100, 200, 255);} function draw() { background(30); fill(kareRengi); rect(width / 2 - 30, height / 2 - 30, 60, 60);} function keyPressed() { if (key === " ") { if (red(kareRengi) > 200) { kareRengi = color(100, 200, 255); } else { kareRengi = color(255, 120, 80); } }}red() p5.js renk bileşenini okur; renk kavramı önceki bölümlerdeki fill(r, g, b) ile uyumludur.
Bilgi: Tek seferlik eylem için draw() içinde keyIsDown + bayrak değişkeni kullanmak yerine doğrudan keyPressed() tercih edilir; kod niyeti daha net iletilir.
Alternatif olarak draw() içinde keyIsDown ile birlikte bir "önceki durum" bayrağı tutulup tek seferlik eylem simüle edilebilir (tuş bu frame basılı, önceki frame basılı değildi ise eylemi çalıştır). Bu teknik bazı ileri senaryolarda (örneğin aynı frame'de birden çok girdi kaynağını birleştirirken) gerekebilir; ancak ek bir değişken ve karşılaştırma gerektirdiği için kodu karmaşıklaştırır. p5.js'in kendisi bu karşılaştırmayı keyPressed() aracılığıyla otomatik yaptığından, basit ve orta düzey oyunlarda doğrudan keyPressed() tercih edilmelidir.
keyReleased(): Tuş bırakıldığı anda bir kez çalışır. keyPressed() basma anını, keyIsDown() basılı tutmayı, keyReleased() ise bırakma anını yakalar. Örneğin SPACE basılıyken şarj dolup bırakılınca ateş etmek için keyIsDown ile şarj, keyReleased ile ateş ayrılabilir.
Kontrol şeması örneği (uzay gemisi):
Tablo 4.
| Tuş | Yöntem | Eylem |
|---|---|---|
| Ok / WASD | keyIsDown + draw() |
Sürekli hareket |
| SPACE | keyPressed() |
Tek mermi |
| R | keyPressed() |
Tur sıfırlama |
| ESC | keyPressed() |
Menüye dön (önceki bölümlerin 4. ana başlığı) |
4.4. key ve keyCode
Bazı tuşların tek karakterle temsil edilmesi zordur veya ok tuşları farklı klavyelerde farklı karakter üretebilir. Bu durumda keyCode kullanılır.
Tanım: keyCode — Basılan tuşun sayısal kodu. Ok tuşları için p5.js sabitleri keyCode ile eşleşir.
key ve keyCode arasındaki fark, "hangi karakter" ile "hangi fiziksel tuş" sorularının ayrımına dayanır. Harf ve rakam tuşlarında key doğrudan okunabilir bir karakter döndürür ('a', '5'); bu, ekrana metin yazdırma veya karakter karşılaştırma için pratiktir. Ok tuşları, SHIFT, CTRL gibi tuşlarda ise yazdırılabilir bir karakter yoktur — bu tuşlar keyCode üzerinden sayısal bir kimlikle temsil edilir. p5.js, sık kullanılan ok tuşları için LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW adlı sabitleri önceden tanımlayarak bu sayısal kodları ezberlemeyi gereksiz kılar; geliştirici keyCode === 37 yazmak yerine keyCode === LEFT_ARROW yazabilir, kod hem okunur hem hataya daha az açık olur.
37 nereden geliyor? ASCII, Unicode ve tuş kodları
keyCode === 37 yazıldığında 37 «rastgele bir sabit» değildir; bilgisayarların karakter ve tuşları sayılarla temsil etme geleneğinden gelir. «Bu sayı tablonun neresinde?» sorusu için üç katmanı ayırmak yeterlidir.
1. ASCII (American Standard Code for Information Interchange)
Erken bilgisayarlarda harf, rakam ve bazı denetim karakterleri 0–127 aralığında numaralandırıldı. 0–31 denetim kodlarıdır (görünmez); 32–126 yazdırılabilir karakterlerdir. Görsel 1 bu yazdırılabilir aralığı gösterir; renkler rakam, büyük harf ve küçük harf bloklarını ayırır.

Tablo 5.
| Aralık | ASCII / Unicode | Anlam |
|---|---|---|
| 48 … 57 | '0' … '9' |
Rakamlar |
| 65 … 90 | 'A' … 'Z' |
Büyük harfler |
| 97 … 122 | 'a' … 'z' |
Küçük harfler |
| 32 | boşluk | Space |
Harf ve rakam gibi yazdırılabilir tuşlarda key değişkeni doğrudan bu karakteri verir ('A', 'w'). JavaScript’te bir karakterin numarasını görmek için charCodeAt kullanılabilir: 'A'.charCodeAt(0) → 65.
Bilgi: Tam ASCII listesi ve tarihçesi için ASCII (Wikipedia) veya ASCII Table kaynaklarına bakılabilir. Bu kitaptaki Görsel 1, oyun kodunda en çok kullanılan yazdırılabilir dilimi özetler.
Yazdırılamayan (denetim) karakterler: \n, \t
Görsel 1’de görünmeyen 0–31 aralığı denetim kodlarıdır; ekranda bir «harf» gibi basılmaz, ama programda kaçış dizisi (escape sequence) ile yazılır. Oyun ve arayüz metinlerinde en sık kullanılan ikisi:
Tablo 6.
| Yazım (string içinde) | ASCII | Adı | Ne yapar? |
|---|---|---|---|
\n |
10 | LF (line feed) | Yeni satır (satır sonu) |
\t |
9 | TAB (sekme) | Yatay sekme; genelde birkaç boşluk kadar ilerler |
(boşluk tuşu) |
32 | Space | Görünür boşluk (yazdırılabilir) |
JavaScript string’inde backslash (\) «sonraki karakter özel anlam taşır» demektir: "Merhaba\nDunya" içinde \n iki karakter (\ ve n) gibi yazılır ama bellekte tek satır-sonu karakterine dönüşür.
p5.js text() bu kaçışları işler; HUD (skor / can) gibi çok satırlı yazılar için \n pratiktir:
Kod 5.
function draw() { background(30); fill(255); textSize(18); textAlign(LEFT, TOP); text("Skor: 3\nCan: 5", 24, 40); // iki satır text("A\tB\tC", 24, 100); // sekme ile aralık}
Görsel 2 solda string içindeki kaçışları, sağda tuvalde oluşan satır kırılmasını ve sekme boşluğunu gösterir.
Bilgi: console.log("skor\t" + skor) konsolda sütun gibi hizalama için de \t kullanır. Tuvalde sütunlar kritikse \t yazı tipine göre farklı genişlik verebilir; o zaman ayrı text(..., x, y) çağrıları veya sabit x ofsetleri daha öngörülebilirdir.
Dikkat: Kaynak kodda girinti için kullanılan boşluk ve Tab da aynı ASCII karakterleridir (32 ve 9). Bunlar string içindeki \n / \t ile karıştırılmamalıdır: biri editörde satırı içeri almak, diğeri metin içeriğinde satır kırmak / sekme koymaktır. Girintinin okunabilirlikteki rolü önceki bölümlerde if ve for bloklarıyla birlikte vurgulanır.
2. Unicode
ASCII yalnızca Latin alfabesinin dar bir dilimini kapsar. Unicode, dünyadaki yazı sistemlerini (Türkçe ğ, ş, emoji, vb.) tek bir numara uzayında toplayan daha geniş standarttır. Unicode’un ilk 128 kodu ASCII ile aynıdır; yani 'A' hem ASCII’de hem Unicode’da 65’tir. Bu kitapta oyun girdileri çoğunlukla Latin harf ve ok tuşlarıyla sınırlıdır; yine de metinleri bilgisayarın «harf = sayı» diye sakladığını bilmek, ileride dosya, ağ veya farklı dillerle çalışırken işe yarar.
Bilgi: Unicode’un resmi özeti: The Unicode Standard. Karakter arama için Unicode Character Table kullanışlıdır. JavaScript kaynak dosyaları UTF-8 ile saklandığında Unicode karakterler metin içinde kullanılabilir.
Dikkat: JavaScript (ve dolayısıyla p5.js sketch’leri) Unicode destekler; teknik olarak let skorŞuAn = 0; veya function çizTop() { … } gibi Türkçe karakterli tanımlayıcılar çoğu modern tarayıcıda çalışır. Yine de bu kitaptaki örneklerde ve önerilen alıştırmalarda değişken / fonksiyon adlarında ASCII harfler (skorSuAn, cizTop) tercih edilir: (1) farklı editör ve yazı tipi kombinasyonlarında karakter bozulması riski azalır; (2) İngilizce kaynaklar ve hata mesajlarıyla eşleşmek kolaylaşır; (3) takım çalışmasında klavye düzeni farkları az sorun çıkarır. Oyuncuya gösterilen metinlerde (text("Skor: " + skor), "Kazandınız!") Türkçe karakter kullanmak ise doğaldır ve teşvik edilir — kısıt tanımlayıcı adlarındadır, ekran yazılarında değil.
3. keyCode ve ok tuşları (37, 38, 39, 40)
Dikkat: Ok tuşlarının ASCII kodu yoktur. ASCII (ve Görsel 1) yazdırılabilir / denetim karakterleri içindir (A, %, satır sonu…). Sol oka basınca metin kutusuna % yazılmaz; key de genelde tek bir yazdırılabilir harf vermez. Oklar «karakter» değil, özel tuştur.
O zaman 37 nereden geliyor? Tarayıcıların eski klavye API’sinin (p5.js’in keyCode ile yansıttığı) ayrı bir tuş-numara listesinden. Bu liste ASCII tablosu değildir; tesadüfen sol oka 37 denmiştir. Aynı şekilde yukarı 38, sağ 39, aşağı 40’tır:
Tablo 7.
| Tuş | keyCode (sayı) |
p5.js sabiti | ASCII’de karşılığı? |
|---|---|---|---|
| Sol ok | 37 | LEFT_ARROW |
Yok (← diye bir ASCII karakteri yok) |
| Yukarı ok | 38 | UP_ARROW |
Yok |
| Sağ ok | 39 | RIGHT_ARROW |
Yok |
| Aşağı ok | 40 | DOWN_ARROW |
Yok |
«Ama ASCII 37 = % değil mi?» Evet — ama o başka bir sözlükteki 37’dir. İki farklı numaralandırma aynı rakamı kullanabilir; bu bir çakışma veya çelişki değil, tesadüftür. (İki farklı apartmanda «daire 37» olması gibi: aynı numara, farklı binalar.) Sol ok ≠ %. % tuşuna basınca key === "%" olur; sol oka basınca keyCode === LEFT_ARROW (yani 37) bakılır — farklı olaylar.
Bu yüzden keyCode === 37 ile keyCode === LEFT_ARROW aynı karşılaştırmadır; LEFT_ARROW yalnızca o tuş kimliğinin okunabilir adıdır. Harf tuşlarında keyCode çoğu ortamda büyük harfin ASCII/Unicode numarasına yakındır (ör. A → 65); yine de harf kontrolünde key === "w" / key === "W" daha doğrudan ve güvenilirdir. Ok, SHIFT, ENTER gibi özel tuşlarda keyCode (veya LEFT_ARROW sabiti) kullanılır — ASCII tablosundan ok aramayın; orada yoktur.
Dikkat: Ok / SHIFT sayılarını ezberlemeyin; ASCII’den «okun kodu» diye satır aramayın. Kodda her zaman LEFT_ARROW / RIGHT_ARROW / UP_ARROW / DOWN_ARROW yazın. console.log(keyCode) yalnızca merak veya hata ayıklama içindir.
Dikkat: LEFT / RIGHT / UP / DOWN sabitleri hizalama içindir (textAlign(LEFT) …) ve değerleri string’dir ('left'). keyIsDown(LEFT) bu yüzden «Number bekleniyor, string geldi» uyarısı üretir ve ok tuşunu yakalamaz. Oklar için LEFT_ARROW kullanın. keyIsDown harf için de sayı ister: keyIsDown(65) (A), 68 (D), 87 (W), 83 (S).
Tablo 8.
| Tuş | p5.js sabiti | Tipik kullanım |
|---|---|---|
| Sol ok | LEFT_ARROW |
keyIsDown(LEFT_ARROW) veya keyCode === LEFT_ARROW |
| Sağ ok | RIGHT_ARROW |
keyIsDown(RIGHT_ARROW) |
| Yukarı | UP_ARROW |
keyIsDown(UP_ARROW) |
| Aşağı | DOWN_ARROW |
keyIsDown(DOWN_ARROW) |
| Harf | keyCode sayısı | keyIsDown(65) (A); olaylarda key === "w" |
Kod bloğu: keyPressed() içinde ok tuşu ile mesaj — önceki bölümlerde tanıtılan console.log() ile tuşa basıldığı alt konsolda görülür (tuvalde değil).
Kod 6.
function keyPressed() { if (keyCode === UP_ARROW) { console.log("Yukari ok"); } if (key === "w" || key === "W") { console.log("W tusu"); }}WASD ve ok tuşlarını aynı hareket için birleştirmek yaygındır:
Kod 7.
if (keyIsDown(LEFT_ARROW) || keyIsDown(65)) { kareX = kareX - HIZ * dt; } if (keyIsDown(RIGHT_ARROW) || keyIsDown(68)) { kareX = kareX + HIZ * dt; }4.5. Klavye ile Kontrol Edilen Kare
Aşağıdaki sketch, ok tuşları ve WASD ile hareket eden bir kareyi tuval sınırları içinde tutar. Hareket deltaTime ile hesaplanır; ekranda basılı tuş bilgisi gösterilir.
Kontrol özeti:
- Ok veya WASD: sürekli hareket
- R: konumu merkeze sıfırla (tek seferlik
keyPressed) - Fare konumu bilgi metninde gösterilir (önceki bölümler girdisi ile birlikte)
Kod 8.
let oyuncuX;let oyuncuY;const BOYUT = 44;const HIZ = 200; function setup() { createCanvas(560, 360); noStroke(); oyuncuX = width / 2 - BOYUT / 2; oyuncuY = height / 2 - BOYUT / 2;} function draw() { background(28, 32, 48); let dt = deltaTime / 1000; if (keyIsDown(LEFT_ARROW) || keyIsDown(65)) { oyuncuX = oyuncuX - HIZ * dt; } if (keyIsDown(RIGHT_ARROW) || keyIsDown(68)) { oyuncuX = oyuncuX + HIZ * dt; } if (keyIsDown(UP_ARROW) || keyIsDown(87)) { oyuncuY = oyuncuY - HIZ * dt; } if (keyIsDown(DOWN_ARROW) || keyIsDown(83)) { oyuncuY = oyuncuY + HIZ * dt; } oyuncuX = constrain(oyuncuX, 0, width - BOYUT); oyuncuY = constrain(oyuncuY, 0, height - BOYUT); fill(90, 180, 255); rect(oyuncuX, oyuncuY, BOYUT, BOYUT); fill(220); textSize(14); textAlign(LEFT, TOP); text("Ok / WASD: hareket | R: merkeze sifirla", 12, 12); text("Fare: " + floor(mouseX) + ", " + floor(mouseY), 12, 32);} function keyPressed() { if (key === "r" || key === "R") { oyuncuX = width / 2 - BOYUT / 2; oyuncuY = height / 2 - BOYUT / 2; }}Tanım: constrain(deger, min, max) — p5.js fonksiyonu; değeri verilen alt ve üst sınır arasında tutar. Kare tuval dışına taşmaz. Bu, tuval sınır çarpışmasının pratik kısayoludur; bir sonraki ana başlıkta sınır testinin if ile açık yazımı ve sekme tepkisi ayrıca ele alınır.
Tanım: color(r, g, b) — p5.js fonksiyonu; Önceki bölümlerdeki RGB modeliyle (0–255 bileşenler) renk değeri üretir ve değişkende saklanabilir. red(), green(), blue() bu değerden ilgili bileşeni okur. Doğrudan fill(r, g, b) ile aynı sayı aralığı kullanılır; fark, rengin bir kez üretilip yeniden kullanılabilmesidir.
Tanım: floor(n) — Ondalıklı sayıyı aşağı yuvarlayarak tam sayıya indirger; ekranda koordinat göstermek için kullanılmıştır (önceki bölümler, diziler ana başlığındaki floor(random(...)) örneğiyle aynı işlev).
Tuval odaklıyken tuşlar sketch'e gider; tarayıcı sekmesinin odak dışı kalması durumunda girdi alınmayabilir — önizleme paneline tıklamak gerekir.
Hata ayıklama ipuçları:
Tablo 9.
| Sorun | Olası neden | Denenecek |
|---|---|---|
| Tuşlar hiç çalışmıyor | Tuval odak dışı | Önizlemeye tıkla |
| Hareket çok yavaş/hızlı | HIZ veya deltaTime |
HIZ * dt formülünü kontrol et |
| R tuşu yanıt vermiyor | keyPressed tanımsız |
Fonksiyon adının doğru yazıldığını doğrula |
| Kare ekrandan çıkıyor | constrain eksik |
Sınır satırını ekle |
| Çapraz hareket beklenenden hızlı | X ve Y aynı anda değişiyor | Basit oyunlarda sorun oluşturmaz; hız normalize edilerek düzeltilebilir |
| Bir tuş bazen çalışıyor bazen çalışmıyor | Klavye düzeni (harf/sembol) farkı | keyCode veya büyük/küçük harf kontrolünü gözden geçir |
Bu tablo, klavye kontrollü bir sketch'te karşılaşılan sorunların çoğunun ya odak (tuvalin girdi almaması) ya da hangi p5.js aracının (durum mu, olay mı) kullanıldığıyla ilgili olduğunu gösterir. Hata ayıklarken ilk soru her zaman "bu davranış sürekli mi yoksa tek seferlik mi olmalı?" olmalıdır; yanıt keyIsDown ile keyPressed arasındaki seçimi belirler.
Yapay Zekâ Etkileşimi: Kontrol Şeması Tasarlama Tahmini etkinliği tamamlama süresi: 25–30 dakika.
Amaç: Klavye girdisini oyun eylemleriyle eşleştirmek.
Adım 1: Basit bir oyun fikri seç (ör. uzay gemisi, top, kare).
Adım 2: Hangi tuşların sürekli (keyIsDown), hangilerinin tek seferlik (keyPressed) olacağını tabloya yaz.
Adım 3: Yapay zekâ sohbet robotuna şu istemi gir: "p5.js için [oyun] kontrol tablom: [tablo]. Her tuş için keyIsDown mu keyPressed mi kullanmalıyım? Kısa gerekçe ver."
Adım 4: Öneriyi yukarıdaki kare örneğiyle karşılaştır.
Yapay Zekâ Etkileşimi: Klavye Girdisi Tahmini etkinliği tamamlama süresi: 20–25 dakika.
Adım 1: keyIsDown (sürekli) ile keyPressed (tek sefer) farkını tabloya yazın.
Adım 2: Ok tuşları için LEFT_ARROW kullanımını not edin.
Adım 3: Yapay zekâ sohbet robotuna sorun: «p5.js keyIsDown keyPressed keyCode ne zaman kullanılır?»
Adım 4: Yanıtı bu ana başlıktaki kontrol tablosu ile karşılaştırın.
Sıra Sizde: Bir oyunda sürekli basılı tutulan hareket (WASD) ile tek seferlik eylem (SPACE ile ateş / zıplama) için hangi klavye API’sini seçerdiniz? İkisini tablo gibi iki satırda yazın.
Özet
Klavye girdisi, oyuncunun gerçek zamanlı kontrolünü sağlar. p5.js'te iki temel katman ayırt edilir: keyIsDown() tuş basılıyken her frame true döndüğü için draw() içinde sürekli hareket üretir; keyPressed() ise basış anında bir kez çalışır. Sürekli harekette hız deltaTime ile çarpılarak Bölüm 2 Ana Başlık 4'teki frame bağımsız tempo korunur; çapraz hareket için bağımsız if blokları birleşir. WASD ve ok tuşları birlikte desteklenebilir; böylece farklı alışkanlıklara sahip oyuncular aynı sketch'i kullanır. Ok tuşları için LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW sabitleri; keyIsDown ile harf tuşları için 65 / 68 gibi keyCode sayıları kullanılır. keyPressed() zıplama, ateş, tur yenileme ve renk değiştirme gibi tek seferlik eylemler için uygundur. key harf ve sembol tuşlarını, keyCode ok tuşları gibi özel tuşları tanımlamada kullanılır; key === "r" veya keyCode === LEFT_ARROW gibi koşullar olay gövdesinde yazılır. Yazdırılabilir karakterler ASCII (ve onu kapsayan Unicode) numaralarıyla saklanır ('A' → 65); ok tuşları ise ASCII’de yoktur — keyCode 37/38/39/40 gibi özel sayılardır ve p5.js bunları LEFT_ARROW / UP_ARROW / RIGHT_ARROW / DOWN_ARROW sabitleriyle adlandırır. Ham sayı yerine sabiti kullanmak okunabilirliği artırır. Denetim karakterleri \n (satır sonu) ve \t (sekme) string içinde kaçış dizisi olarak yazılır; text() ile çok satırlı HUD üretilebilir. constrain() ile nesne tuval sınırları içinde tutulur — bu, konumu sınırda kilitleyen bir engellemedir; duvara çarpınca yön değiştiren sekme tepkisi sonraki ana başlıkta açık if ve hız tersine çevirme ile ele alınır. Fare ile karşılaştırıldığında sürekli basılı tutma mouseIsPressed / keyIsDown, tek seferlik olay ise mousePressed() / keyPressed() eşleşmesine karşılık gelir.
Neler Öğrendik?
Soru 1 Sürekli yürüme hareketi için en uygun yapı hangisidir?
A) Yalnızca keyPressed() içinde konum artırmak
B) draw() içinde keyIsDown() ile konum güncellemek
C) Yalnızca setup() içinde keyIsDown() kullanmak
D) background() ile tuş okumak
E) createCanvas() her frame çağırmak
Soru 2
key === "r" ifadesi ne zaman anlamlıdır?
A) Her frame otomatik true olur
B) keyPressed() veya keyReleased() çalıştığında basılan tuşu kontrol eder
C) Yalnızca fare tıklanınca
D) Tuval genişliğini verir
E) Dizi uzunluğunu döndürür
Soru 3
[Kod okuma] HIZ = 200, deltaTime ≈ 16.7 ms iken aşağıdaki blok bir frame'de kareX değerini yaklaşık ne kadar artırır?
Kod 9.
if (keyIsDown(RIGHT_ARROW)) { kareX = kareX + HIZ * deltaTime / 1000;}A) 200 piksel
B) Yaklaşık 3.3 piksel
C) 16.7 piksel
D) 0 piksel
E) 1000 piksel
Soru 4
constrain(oyuncuX, 0, width - BOYUT) satırının amacı nedir?
A) FPS artırmak
B) Oyuncu konumunu tuval sınırları içinde tutmak
C) Klavye olayını silmek
D) Diziye eleman eklemek
E) R tuşunu devre dışı bırakmak
Neler Öğrendik Yanıt Anahtarı
Soru 1: Doğru Cevap: B
- Çözüm: Basılı tutma
draw()döngüsündekeyIsDownile okunur;keyPressedyalnızca bir frame tetiklenir. - İlgili Konu: 4.2. keyIsDown ile Sürekli Hareket
Soru 2: Doğru Cevap: B
- Çözüm:
keyolay anındaki karakter tuşunu verir; sürekli okuma içinkeyIsDownkullanılır. - İlgili Konu: 4.4. key ve keyCode
Soru 3: Doğru Cevap: B
- Çözüm: 200 × 0.0167 ≈ 3.3 piksel; hız saniye başına tanımlıdır.
- İlgili Konu: 4.2. keyIsDown ile Sürekli Hareket
Soru 4: Doğru Cevap: B
- Çözüm:
constraindeğeri min–max aralığına sıkıştırır; kare ekran dışına çıkmaz. - İlgili Konu: 4.5. Klavye ile Kontrol Edilen Kare
Yararlanılan Kaynaklar
Bu içerik aşağıdaki kaynaklardan derlenerek hazırlanmıştır:
- ASCII. (n.d.). In Wikipedia. https://en.wikipedia.org/wiki/ASCII
- asciitable.com. (n.d.). ASCII Table. https://www.asciitable.com/
- McCarthy, L., Reas, C., & Fry, B. (2015). Make: Getting Started with p5.js. Maker Media.
- MDN Web Docs. (n.d.). Identifiers — Lexical grammar. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers
- Microsoft. (n.d.). Visual Studio Code. https://code.visualstudio.com/
- Nystrom, R. (2014). Game Programming Patterns. Genever Benning. https://gameprogrammingpatterns.com/
- p5.js Foundation. (n.d.). constrain. p5.js Reference. https://p5js.org/reference/p5/constrain/
- p5.js Foundation. (n.d.). keyCode. p5.js Reference. https://p5js.org/reference/p5/keyCode/
- p5.js Foundation. (n.d.). keyIsDown. p5.js Reference. https://p5js.org/reference/p5/keyIsDown/
- p5.js Foundation. (n.d.). keyPressed. p5.js Reference. https://p5js.org/reference/p5/keyPressed/
- p5.js Foundation. (n.d.). p5.js Web Editor. https://editor.p5js.org/
- Shiffman, D. (n.d.). Code! Programming with p5.js. The Coding Train. https://thecodingtrain.com/tracks/code-programming-with-p5-js
- Unicode Consortium. (n.d.). The Unicode Standard. https://www.unicode.org/standard/standard.html
- unicode-table.com. (n.d.). Unicode Character Table. https://unicode-table.com/
Bölüm 3 — Ek Sorular
Her ana başlık için 10 çoktan seçmeli değerlendirme sorusu. Bölüm sonu sınav veya pekiştirme amaçlıdır.
Ana Başlık 1 için 10 Soru
SORU 1: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 2: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 3: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 4: Hız değişkenini “birim / saniye” tutmanın yararı nedir?
A) deltaTime ile çarpınca anlamın net kalması
B) Klavyenin kapanması
C) Matematiğin kalkması
D) Sunucu zorunluluğu
E) SQL zorunluluğu
Doğru cevap: A
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 1.4
SORU 5: «deltaTime ile Zaman Tabanlı Hareket» bağlamında hangisi daha iyi bir sonraki adım geliştirmedir?
A) Konu dışı bir CSS animasyonu eklemek
B) Mevcut sketch’e ölçülebilir bir kural (skor, sınır, durum) eklemek
C) Tuvali silip boş bırakmak
D) setup’ı tamamen kaldırmak
E) Rastgele sözdizimi hatası bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme mevcut öğrenilen API ile kural ekler. İlgili Konu: 1.uygulama
SORU 6: Aşağıdaki hangi seçenek tipik bir çeldirici bug senaryosudur?
A) dist ile isabet, ardından skoru bir kez artırmak
B) draw içinde koşulsuz skor artışı
C) createCanvas’ı setup içinde bir kez çağırmak
D) background ile frame temizlemek
E) keyIsDown ile sürekli hareket
Doğru cevap: B
Genel açıklama: Koşulsuz artış her frame şişer — görünür bug. İlgili Konu: 1.uygulama
SORU 7: Kod okuma: if (x > width) { x = 0; } ne yapar?
A) Y’yi sıfırlar
B) X tuval sağını aşınca sola sarar
C) FPS’i sıfırlar
D) Fareyi kilitler
E) Diziyi temizler
Doğru cevap: B
Genel açıklama: Yatay sarma (wrap) kalıbı. İlgili Konu: 1.uygulama
SORU 8: Bu ana başlıkta (deltaTime ile Zaman Tabanlı Hareket) hangi uygulama en uygundur?
A) Öğrenilen API’yi bilinçli yok sayıp rastgele hazır kütüphane çağırmak
B) Anlatılan kavramı küçük bir sketch’te görünür çıktıyla denemek
C) Konuyu yalnızca okuyup hiç kod yazmamak
D) Tuval boyutunu her frame rastgele değiştirmek
E) Hata ayıklamadan uzun kod kopyalamak
Doğru cevap: B
Genel açıklama: Seçenek konu başlığıyla örtüşür; diğerleri alandan kopuk. İlgili Konu: 1.uygulama
SORU 9: console.log ayıklamada asıl faydası nedir?
A) Tuval çözünürlüğünü artırır
B) Ara değerleri görüp yanlış varsayımı yakalamayı sağlar
C) Otomatik çarpışma ekler
D) draw’ı durdurur
E) Kaynakça üretir
Doğru cevap: B
Genel açıklama: Gözlemlenebilir ara durum. İlgili Konu: 1.uygulama
SORU 10: Bir fonksiyonu parametreli yazmanın faydası?
A) FPS’i kilitlemek
B) Aynı mantığı farklı argümanlarla yeniden kullanmak
C) setup’ı kaldırmak
D) HTML’i silmek
E) Rengi yasaklamak
Doğru cevap: B
Genel açıklama: Modülerlik ve yeniden kullanım. İlgili Konu: 1.uygulama
Ana Başlık 2 için 10 Soru
SORU 1: JavaScript dizilerinde ilk elemanın indeksi nedir?
A) 1
B) 0
C) -1
D) length
E) undefined
Doğru cevap: B
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 2.1
SORU 2: dizi.push(5) ne yapar?
A) İlk elemanı siler
B) 5’i dizinin sonuna ekler
C) Tuvali temizler
D) FPS’i 5 yapar
E) setup’ı yeniden çalıştırır
Doğru cevap: B
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 2.2
SORU 3: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 4: Paralel diziler ne anlama gelir?
A) İki dizinin aynı indekste ilişkili özellik tutması
B) İki tarayıcının zorunlu açılması
C) Yalnızca string birleştirme
D) CSS grid
E) Git branch
Doğru cevap: A
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 2.4
SORU 5: «Dizi Temelleri: Tanım, Erişim ve push/pop» bağlamında hangisi daha iyi bir sonraki adım geliştirmedir?
A) Konu dışı bir CSS animasyonu eklemek
B) Mevcut sketch’e ölçülebilir bir kural (skor, sınır, durum) eklemek
C) Tuvali silip boş bırakmak
D) setup’ı tamamen kaldırmak
E) Rastgele sözdizimi hatası bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme mevcut öğrenilen API ile kural ekler. İlgili Konu: 2.uygulama
SORU 6: Aşağıdaki hangi seçenek tipik bir çeldirici bug senaryosudur?
A) dist ile isabet, ardından skoru bir kez artırmak
B) draw içinde koşulsuz skor artışı
C) createCanvas’ı setup içinde bir kez çağırmak
D) background ile frame temizlemek
E) keyIsDown ile sürekli hareket
Doğru cevap: B
Genel açıklama: Koşulsuz artış her frame şişer — görünür bug. İlgili Konu: 2.uygulama
SORU 7: Kod okuma: if (x > width) { x = 0; } ne yapar?
A) Y’yi sıfırlar
B) X tuval sağını aşınca sola sarar
C) FPS’i sıfırlar
D) Fareyi kilitler
E) Diziyi temizler
Doğru cevap: B
Genel açıklama: Yatay sarma (wrap) kalıbı. İlgili Konu: 2.uygulama
SORU 8: Bu ana başlıkta (Dizi Temelleri: Tanım, Erişim ve push/pop) hangi uygulama en uygundur?
A) Öğrenilen API’yi bilinçli yok sayıp rastgele hazır kütüphane çağırmak
B) Anlatılan kavramı küçük bir sketch’te görünür çıktıyla denemek
C) Konuyu yalnızca okuyup hiç kod yazmamak
D) Tuval boyutunu her frame rastgele değiştirmek
E) Hata ayıklamadan uzun kod kopyalamak
Doğru cevap: B
Genel açıklama: Seçenek konu başlığıyla örtüşür; diğerleri alandan kopuk. İlgili Konu: 2.uygulama
SORU 9: console.log ayıklamada asıl faydası nedir?
A) Tuval çözünürlüğünü artırır
B) Ara değerleri görüp yanlış varsayımı yakalamayı sağlar
C) Otomatik çarpışma ekler
D) draw’ı durdurur
E) Kaynakça üretir
Doğru cevap: B
Genel açıklama: Gözlemlenebilir ara durum. İlgili Konu: 2.uygulama
SORU 10: Bir fonksiyonu parametreli yazmanın faydası?
A) FPS’i kilitlemek
B) Aynı mantığı farklı argümanlarla yeniden kullanmak
C) setup’ı kaldırmak
D) HTML’i silmek
E) Rengi yasaklamak
Doğru cevap: B
Genel açıklama: Modülerlik ve yeniden kullanım. İlgili Konu: 2.uygulama
Ana Başlık 3 için 10 Soru
SORU 1: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 2: Paralel x ve y dizilerinde aynı indeks ne anlama gelir?
A) İki farklı oyunun skoru
B) Aynı varlığın ilişkili özellikleri
C) Rastgele iki tarayıcı
D) Zorunlu ses kanalı
E) Git commit
Doğru cevap: B
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 3.2
SORU 3: Aşağıdaki yaklaşımlardan hangisi oyun sketch’inde daha sağlam bir geliştirmedir?
A) Konu dışı teknolojiye (biçim/dil dışı) sapıp temel kuralı atlamak
B) Öğrenilen p5.js API’si ile ölçülebilir bir oyun kuralı eklemek
C) draw içinde createCanvas tekrarlamak
D) Skoru her frame koşulsuz artırmak
E) Hata ayıklamadan uzun kodu olduğu gibi bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme, öğrenilen araçlarla kural eklemeyi hedefler; alandan kopuk şıklar elenir. İlgili Konu: Pekiştirme
SORU 4: push/pop yerine sabit kapasite seçmek ne sağlar?
A) Üst sınırın ve döngünün öngörülebilir kalması
B) Matematiğin kalkması
C) Farein kapanması
D) Zorunlu 3B
E) Sunucu kurulumu
Doğru cevap: A
Genel açıklama: Bu soru ana başlık kazanımını ölçer. İlgili Konu: 3.4
SORU 5: «Sabit Kapasite ve Paralel Dizilerle Mini Sahne» bağlamında hangisi daha iyi bir sonraki adım geliştirmedir?
A) Konu dışı bir CSS animasyonu eklemek
B) Mevcut sketch’e ölçülebilir bir kural (skor, sınır, durum) eklemek
C) Tuvali silip boş bırakmak
D) setup’ı tamamen kaldırmak
E) Rastgele sözdizimi hatası bırakmak
Doğru cevap: B
Genel açıklama: Geliştirme mevcut öğrenilen API ile kural ekler. İlgili Konu: 3.uygulama
SORU 6: Aşağıdaki hangi seçenek tipik bir çeldirici bug senaryosudur?
A) dist ile isabet, ardından skoru bir kez artırmak
B) draw içinde koşulsuz skor artışı
C) createCanvas’ı setup içinde bir kez çağırmak
D) background ile frame temizlemek
E) keyIsDown ile sürekli hareket
Doğru cevap: B
Genel açıklama: Koşulsuz artış her frame şişer — görünür bug. İlgili Konu: 3.uygulama
SORU 7: Kod okuma: if (x > width) { x = 0; } ne yapar?
A) Y’yi sıfırlar
B) X tuval sağını aşınca sola sarar
C) FPS’i sıfırlar
D) Fareyi kilitler
E) Diziyi temizler
Doğru cevap: B
Genel açıklama: Yatay sarma (wrap) kalıbı. İlgili Konu: 3.uygulama
SORU 8: Bu ana başlıkta (Sabit Kapasite ve Paralel Dizilerle Mini Sahne) hangi uygulama en uygundur?
A) Öğrenilen API’yi bilinçli yok sayıp rastgele hazır kütüphane çağırmak
B) Anlatılan kavramı küçük bir sketch’te görünür çıktıyla denemek
C) Konuyu yalnızca okuyup hiç kod yazmamak
D) Tuval boyutunu her frame rastgele değiştirmek
E) Hata ayıklamadan uzun kod kopyalamak
Doğru cevap: B
Genel açıklama: Seçenek konu başlığıyla örtüşür; diğerleri alandan kopuk. İlgili Konu: 3.uygulama
SORU 9: console.log ayıklamada asıl faydası nedir?
A) Tuval çözünürlüğünü artırır
B) Ara değerleri görüp yanlış varsayımı yakalamayı sağlar
C) Otomatik çarpışma ekler
D) draw’ı durdurur
E) Kaynakça üretir
Doğru cevap: B
Genel açıklama: Gözlemlenebilir ara durum. İlgili Konu: 3.uygulama
SORU 10: Bir fonksiyonu parametreli yazmanın faydası?
A) FPS’i kilitlemek
B) Aynı mantığı farklı argümanlarla yeniden kullanmak
C) setup’ı kaldırmak
D) HTML’i silmek
E) Rengi yasaklamak
Doğru cevap: B
Genel açıklama: Modülerlik ve yeniden kullanım. İlgili Konu: 3.uygulama
Ana Başlık 4 için 10 Soru
SORU 1: Sürekli yürüme hareketi için en uygun yapı hangisidir?
A) Yalnızca keyPressed() içinde konum artırmak
B) draw() içinde keyIsDown() ile konum güncellemek
C) Yalnızca setup() içinde keyIsDown() kullanmak
D) background() ile tuş okumak
E) createCanvas() her frame çağırmak
Doğru cevap: B
Genel açıklama: Basılı tutma draw() döngüsünde keyIsDown ile okunur. İlgili Konu: 2.2. keyIsDown ile Sürekli Hareket
SORU 2: Zıplama veya tek atışlı ateş gibi eylem için hangi olay fonksiyonu daha uygundur?
A) draw() içinde sürekli keyIsDown
B) keyPressed()
C) setup()
D) background()
E) createCanvas()
Doğru cevap: B
Genel açıklama: keyPressed() bir basışta bir kez tetiklenir; tekrarlayan hareket için uygun değildir. İlgili Konu: 2.3. keyPressed ve Tek Seferlik Eylemler
SORU 3: Ok tuşları için genelde hangi değişken kullanılır?
A) mouseX
B) keyCode
C) frameCount
D) deltaTime
E) push()
Doğru cevap: B
Genel açıklama: Ok tuşları gibi özel tuşlar keyCode ile (LEFT_ARROW, RIGHT_ARROW vb.) okunur. İlgili Konu: 2.4. key ve keyCode
SORU 4: [Kod okuma] HIZ = 200, deltaTime ≈ 16.7 ms iken aşağıdaki blok bir frame'de kareX değerini yaklaşık ne kadar artırır?
Kod 1.
if (keyIsDown(RIGHT_ARROW)) { kareX = kareX + HIZ * deltaTime / 1000;}A) 200 piksel
B) Yaklaşık 3.3 piksel
C) 16.7 piksel
D) 0 piksel
E) 1000 piksel
Doğru cevap: B
Genel açıklama: 200 × 0.0167 ≈ 3.3 piksel; hız saniye başına tanımlıdır. İlgili Konu: 2.2 (deltaTime ile birleşim)
SORU 5: constrain(oyuncuX, 0, width - BOYUT) satırının amacı nedir?
A) FPS artırmak
B) Oyuncu konumunu tuval sınırları içinde tutmak
C) Klavye olayını silmek
D) Diziye eleman eklemek
E) R tuşunu devre dışı bırakmak
Doğru cevap: B
Genel açıklama: constrain değeri min–max aralığına sıkıştırır; kare ekran dışına çıkmaz. İlgili Konu: 2.5. Klavye ile Kontrol Edilen Kare
SORU 6: key === "a" ifadesi ne zaman anlamlıdır?
A) Her frame otomatik true olur
B) keyPressed() veya keyReleased() çalıştığında basılan tuşu kontrol eder
C) Yalnızca fare tıklanınca
D) Tuval genişliğini verir
E) Dizi uzunluğunu döndürür
Doğru cevap: B
Genel açıklama: key olay anındaki karakter tuşunu verir; sürekli okuma için keyIsDown kullanılır. İlgili Konu: 2.3 ve 2.4
SORU 7: WASD ve ok tuşlarını birlikte desteklemek neden tercih edilir?
A) FPS düşürmek için
B) Farklı klavye alışkanlıklarına erişilebilir kontrol sunmak için
C) Diziyi silmek için
D) Çarpışma testini kapatmak için
E) Tuvali küçültmek için
Doğru cevap: B
Genel açıklama: İki kontrol şeması aynı hareketi farklı tuşlarla sağlar. İlgili Konu: 2.5. Klavye ile Kontrol Edilen Kare
SORU 8: [Kod okuma] Aşağıdaki kodda keyIsDown(LEFT_ARROW) || keyIsDown(65) ifadesi ne zaman true olur?
A) Yalnızca SPACE basılıyken
B) Sol ok veya A tuşundan en az biri basılıyken
C) Yalnızca fare tuval üzerindeyken
D) draw() hiç çalışmıyorken
E) setup() tamamlandıktan sonra bir kez
Doğru cevap: B
Genel açıklama: || en az bir koşul true ise true döner. İlgili Konu: 2.5
SORU 9: I. keyIsDown() her frame kontrol edilebilir.
II. keyPressed() tek basışta bir kez çalışır.
III. Klavye girdisi tuval odak dışındayken her zaman alınır.
Hangileri doğrudur?
A) Yalnız I
B) I ve II
C) Yalnız III
D) II ve III
E) I, II ve III
Doğru cevap: B
Genel açıklama: I ve II doğru. III yanlış; önizleme panelinin odakta olması gerekir. İlgili Konu: 2.1–2.3
SORU 10: Klavye ile hareket eden kare örneğinde hız neden deltaTime ile çarpılır?
A) Dizi indeksini hesaplamak için
B) Frame hızından bağımsız tutarlı hareket için (Ana Başlık 1)
C) Tuval rengini değiştirmek için
D) mousePressed() tetiklemek için
E) Kazanan kontrolü yapmak için
Doğru cevap: B
Genel açıklama: Ana Başlık 1'deki zaman tabanlı hareket klavye girdisiyle birleştirilir. İlgili Konu: 2.2 ve 2.5
Ana Başlık 1 — Açık Uçlu
A1. «deltaTime ile Zaman Tabanlı Hareket» konusundaki merkezi kavramı kendi cümlelerinizle açıklayın ve bunu somut bir mini oyun / sketch örneğine bağlayın.
A2. «deltaTime ile Zaman Tabanlı Hareket» için küçük bir varyasyon tasarlayın (yeni kural, sınır durumu veya görsel geri bildirim). Hangi fonksiyonlar değişir? Madde madde yazın.
A3. Bu ana başlıkta sık yapılan bir yanlış varsayımı (yanlış indeks, sıra, durum veya veri modeli) seçin; neden hatalı olduğunu ve doğru yaklaşımı iki–üç cümleyle yazın.
Ana Başlık 2 — Açık Uçlu
A1. «Dizi Temelleri: Tanım, Erişim ve push/pop» konusundaki merkezi kavramı kendi cümlelerinizle açıklayın ve bunu somut bir mini oyun / sketch örneğine bağlayın.
A2. «Dizi Temelleri: Tanım, Erişim ve push/pop» için küçük bir varyasyon tasarlayın (yeni kural, sınır durumu veya görsel geri bildirim). Hangi fonksiyonlar değişir? Madde madde yazın.
A3. Bu ana başlıkta sık yapılan bir yanlış varsayımı (yanlış indeks, sıra, durum veya veri modeli) seçin; neden hatalı olduğunu ve doğru yaklaşımı iki–üç cümleyle yazın.
Ana Başlık 3 — Açık Uçlu
A1. «Sabit Kapasite ve Paralel Dizilerle Mini Sahne» konusundaki merkezi kavramı kendi cümlelerinizle açıklayın ve bunu somut bir mini oyun / sketch örneğine bağlayın.
A2. «Sabit Kapasite ve Paralel Dizilerle Mini Sahne» için küçük bir varyasyon tasarlayın (yeni kural, sınır durumu veya görsel geri bildirim). Hangi fonksiyonlar değişir? Madde madde yazın.
A3. Bu ana başlıkta sık yapılan bir yanlış varsayımı (yanlış indeks, sıra, durum veya veri modeli) seçin; neden hatalı olduğunu ve doğru yaklaşımı iki–üç cümleyle yazın.
Ana Başlık 4 — Açık Uçlu
A1. Bir oyun için kontrol tablosu oluşturun: hangi tuşlar keyIsDown, hangileri keyPressed ile okunmalı? Gerekçe yazın.
Örnek yanıt unsurları: WASD sürekli; SPACE/R tek seferlik.
Değerlendirme: Tuş–olay eşlemesi tutarlı mı?
A2. constrain() ile manuel sınır if testi arasında ne zaman hangisini tercih edersiniz?
Örnek yanıt unsurları: constrain engelleme; sekme için açık if + hız tersi.
Değerlendirme: Ana Başlık 2–3 köprüsü kurulmuş mu?
A3. Tuval odak dışıyken klavye çalışmıyorsa kullanıcıya ne önerirsiniz?
Örnek yanıt unsurları: Önizleme paneline tıklama.
Değerlendirme: Pratik çözüm var mı?