Ana Başlık 4. Fare Girdisi ve Daire Tıklama Oyunu
Amaç: Fare konumu, tıklama ve dist ile etkileşim kurarak Daire Tıklama mini oyununu adım adım kodlamak.
Öğrenme Çıktıları:
- mouseX, mouseY ve mouseIsPressed ile fare durumunu okur.
- dist ile iki nokta mesafesini hesaplar.
- mousePressed olayında tek tıklama mantığı kurar.
- Daire Tıklama oyununu modüler adımlarla tamamlar.
Anahtar Sözcükler: mouseX, mouseY, mousePressed, dist, etkileşim, mini oyun
Giriş
Önceki ana başlıkta değişkenler ve if/else ile programın karar verme iskeleti kuruldu. Gerçek bir mini oyunda bu kararlar çoğunlukla oyuncu girdisine bağlanır: fare hedefe yakın mı, tıklama hedefi vurdu mu, skor artmalı mı?
p5.js fare konumunu mouseX / mouseY ile, basılı olup olmadığını mouseIsPressed veya mousePressed() olayı ile verir. İki nokta arası uzaklık dist ile ölçülür; böylece “daireye tıklandı mı?” sorusu geometrik bir koşula dönüşür. Tek tıklamada skorun birden fazla artmaması için olay fonksiyonu ile sürekli basılı tutma ayrımı kritiktir.
Bu ana başlık fare, metin ve mesafe araçlarını birleştirir; ardından Daire Tıklama oyununu adım adım tamamlar. Çoklu hedefler ve diziler sonraki bölümlerde gelecektir. 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.
4.1. Fare Girdisi, Metin, Mesafe ve Etkileşim
Bu bölümde sırayla: fare konumu, ekrana yazı, iki nokta arası mesafe ve bunların if/else ile birleştirilmesi ele alınır. Her alt adımda yalnızca o ana kadar tanıtılmış kavramlar kullanılır.
Fare konumu ve tuş durumu
p5.js, fare girdisini yerleşik değişkenler ve fonksiyonlarla sunar. width ve height tuval boyutları tuval ve koordinat sistemi alt başlığında tanıtılmıştır; fare konumu bu aralıkta piksel cinsinden okunur.
Tablo 1.
| Ad | Tür | Açıklama | Örnek değer |
|---|---|---|---|
mouseX |
number | Fare imlecinin X konumu (0 … width−1) | createCanvas(500,400) ve imleç ortadaysa → yaklaşık 250 |
mouseY |
number | Fare imlecinin Y konumu (0 … height−1) | imleç üst kenardaysa → 0 |
mouseIsPressed |
boolean | Fare tuşu basılı mı? | tuş basılı → true; bırakıldı → false |
mousePressed() |
fonksiyon | Tuşa basıldığı an (tek frame) | her basışta bir kez çalışır |
mouseReleased() |
fonksiyon | Tuş bırakıldığı an (tek frame) | her bırakışta bir kez çalışır |
mousePressed() ve mouseReleased(), setup() ve draw() gibi p5.js olay fonksiyonlarıdır: p5.js, fare olayı gerçekleştiğinde bu isimdeki fonksiyonu otomatik çağırır. Genel fonksiyon tanımı 4. ana başlıkta ayrıntılı işlenecektir.
Ekrana metin yazma
Skor veya mesaj göstermek için p5.js metin komutları kullanılır. text() Ana Başlık 1'deki çizim tablosunda ve 3.1’deki string örneğinde geçmiştir; burada textSize ve textAlign ile birlikte özetlenir:
Tablo 2.
| Komut | Açıklama |
|---|---|
text(metin, x, y) |
(x, y) noktasını referans alarak metin yazar |
textSize(boyut) |
Yazı boyutunu piksel cinsinden ayarlar |
textAlign(hizaX, hizaY) |
(x, y) noktasının metnin hangi köşesine / kenarına denk geleceğini seçer |
textAlign, (x, y) koordinatlarını silmez; o noktanın metne göre bağlantı yerini değiştirir. Yatayda LEFT sol kenarı, CENTER ortayı, RIGHT sağ kenarı (x, y) üzerine oturtur. Dikeyde TOP üstü, CENTER ortayı, BOTTOM altı bağlar. Varsayılan genelde sola ve alta yakındır; skor gibi köşe yazıları için textAlign(LEFT, TOP) ile (15, 15) sol-üst köşeye oturur. Ekran ortası mesajında textAlign(CENTER, CENTER) ve text(..., width / 2, height / 2) kullanılır — aynı (x, y) verilse bile hizalama değişince yazı kaymış gibi görünür.
Kod bloğu: Metin çizimi örneği.
Kod 1.
function draw() { background(240); fill(0); textSize(24); textAlign(LEFT, TOP); // (15, 15) = metnin sol-üst köşesi text("Skor: 0", 15, 15);}İki nokta arası mesafe (dist)
Tanım: dist(x1, y1, x2, y2) — p5.js'in yerleşik fonksiyonu; iki nokta arasındaki Öklid mesafesini sayı olarak döndürür. Matematikteki karşılığı sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) ifadesidir (kare alma, farkın kendisiyle çarpılmasıdır); burada sqrt da p5.js'te yerleşiktir, isterseniz mesafeyi dist yerine bu ifadeyle kendiniz de yazabilirsiniz. İlerleyen bölümlerde iki dairenin birbirine değmesi bu mesafe ile yarıçap toplamı karşılaştırılarak test edilecektir.
Daire içinde tıklama algılamak için merkez ile fare konumu arası mesafe hesaplanır; mesafe yarıçaptan küçükse nokta daire içindedir.

Görsel 1 noktanın daire içinde olup olmadığını özetler: merkezden nokta uzaklığı (dist) yarıçaptan küçükse içeride, aksi halde dışarıdadır.
Fare yakınlığına göre renk (birleşik örnek)
Aşağıdaki örnek, 3.3’teki if/else yapısına mouseX, mouseY ve dist() eklenmiş halidir; bu üç kavram artık tanıtılmıştır.
Kod bloğu: Fare daireye yaklaştıkça renk değişen çizim.
Kod 2.
function draw() { background(240); let merkezX = 200; let merkezY = 200; let yaricap = 50; let mesafe = dist(mouseX, mouseY, merkezX, merkezY); if (mesafe < yaricap) { fill(50, 200, 80); // Yeşil — fare dairenin içinde (tam kenar hariç) } else { fill(200, 50, 50); // Kırmızı — fare uzakta } noStroke(); ellipse(merkezX, merkezY, yaricap * 2, yaricap * 2);}mousePressed() ile tek tıklama
mouseIsPressed draw() içinde sürekli kontrol edildiğinde tuş basılı tutulduğu sürece true döner. Skor gibi tek seferlik sayılması gereken olaylarda mousePressed() genellikle daha uygundur.
Tablo 3.
| Yöntem | Ne zaman true? | Skor riski |
|---|---|---|
mouseIsPressed |
Tuş basılı tutulduğu her frame'de (draw ~60/sn) | Tek tıklama birden fazla sayılabilir |
mousePressed() |
Tuşa basıldığı tek frame'de | Skor genelde bir kez artar |
Kod bloğu: mousePressed() ile tek tıklama yakalama.
Kod 3.
let tiklandi = false; function mousePressed() { tiklandi = true;} function draw() { background(220); if (tiklandi) { fill(0, 180, 0); textSize(20); textAlign(LEFT, TOP); text("Tiklandi!", 150, 200); }}Daire Tıklama oyununda klavye girdisi (keyIsDown, keyPressed()) kullanılmaz; klavye girdisi ilerleyen bölümlerde sistematik ele alınacaktır.
4.2. Adım Adım: Daire Tıklama Oyunu
Daire Tıklama (Circle Clicker), ekranda beliren hedef daireye tıklayarak skor toplamayı amaçlayan basit bir refleks oyunudur. Bu oyun yalnızca değişken ve if/else bilgisiyle kodlanabilir; döngü veya dizi gerektirmez.
Oyun kuralları:
- Ekranda rastgele konumda bir hedef daire görünür.
- Oyuncu daireye tıkladığında skor 1 artar; daire yeni rastgele konuma taşınır.
- Belirli skora (örneğin 10) ulaşıldığında oyun kazanılır.
- Daireye tıklanmazsa skor değişmez.
- Oyun bitince yeni tur için sayfa yenilenir veya sketch yeniden çalıştırılır (bu örnekte ayrı menü yoktur).
Bu mini oyun öğretim amaçlıdır; benzer «hedefe tıkla / isabet al» mekaniğini denemek için kaynaklardaki çevrim içi örneklerden yararlanılabilir.
Aşağıdaki sıra, mousePressed() içindeki karar adımlarını özetler:
mousePressed()tetiklenir.oyunBittitrue ise → işlem yapılmaz (return).- Fare ile hedef arası mesafe hesaplanır (
dist). - Mesafe yarıçaptan küçük değilse → skor değişmez.
- Mesafe yarıçaptan küçükse → skor 1 artar.
- Skor hedefe ulaştıysa →
oyunBitti = true; aksi halde hedefe yeni rastgele konum atanır.
Adım 1: Değişkenleri tanımla
Kod 4.
let hedefX; // Hedef dairenin X konumulet hedefY; // Hedef dairenin Y konumulet hedefYaricap = 40;let skor = 0;const HEDEF_SKOR = 10;let oyunBitti = false;Adım 2: setup() — tuval ve ilk hedef konumu
Bu adımda p5.js’in iki parametreli random kullanımı ilk kez sistematik tanıtılır (önceki ana başlıklarda konum atamak için kullanılmamıştı).
Tanım: random(min, max) — p5.js fonksiyonu; min ile max arasında (üst sınır max dahil değil) rastgele ondalıklı bir sayı döndürür. Örnek: random(10, 50) yaklaşık 10 ile 50 arasında bir değer üretir; 50’ye eşit olma garantisi yoktur. Tek parametreli random(max) ise 0 ile max arasında değer üretir; parametresiz random() 0 ile 1 arasındadır. Bu oyunda merkez koordinatı için iki parametreli biçim kullanılır.
Kod 5.
function setup() { createCanvas(500, 400); // İlk hedef konumu — random(min, max) bu adımda tanıtıldı hedefX = random(hedefYaricap, width - hedefYaricap); hedefY = random(hedefYaricap, height - hedefYaricap);}Hedef ellipse(hedefX, hedefY, hedefYaricap * 2, …) ile merkezden çizilir. Merkez sol kenara (0) veya sağ kenara (width) çok yaklaşırsa şeklin bir kısmı tuval dışına taşar; oyuncu eksik görünen bir hedefe tıklamaya çalışır. Bu yüzden X için alt sınır hedefYaricap, üst sınır width - hedefYaricap seçilir (Y için height ile aynı mantık): merkez her zaman kenardan en az bir yarıçap içeride kalır ve elips bütünüyle görünür.
Adım 3: draw() — çizim ve oyun durumu
Kod 6.
function draw() { background(25, 30, 50); // Koyu arka plan if (!oyunBitti) { // Hedef daire fill(255, 180, 0); noStroke(); ellipse(hedefX, hedefY, hedefYaricap * 2, hedefYaricap * 2); } else { // Kazanma ekranı fill(255); textSize(32); textAlign(CENTER, CENTER); text("Kazandınız!", width / 2, height / 2); } // Skor göstergesi (her durumda) fill(255); textSize(20); textAlign(LEFT, TOP); text("Skor: " + skor, 15, 15);}!oyunBitti ifadesi "oyun bitmediyse" anlamına gelir. ! operatörü boolean değeri tersine çevirir. textSize() ve textAlign() bu alt bölümde (2.4) özetlenmiştir; text() daha önce tanıtılmıştır.
Adım 4: mousePressed() — tıklama kontrolü
Tanım: return — Bulunulan fonksiyonun geri kalanını çalıştırmadan çıkmasını sağlar. Oyun bittiyse tıklamaların yoksayılması için kullanılır.
Kod 7.
function mousePressed() { if (oyunBitti) { return; // Oyun bittiyse aşağıdaki satırlar çalışmaz } let mesafe = dist(mouseX, mouseY, hedefX, hedefY); if (mesafe < hedefYaricap) { skor = skor + 1; if (skor >= HEDEF_SKOR) { oyunBitti = true; } else { hedefX = random(hedefYaricap, width - hedefYaricap); hedefY = random(hedefYaricap, height - hedefYaricap); } }}Hedef vurulduğunda skor bir artar; hedef skora ulaşılmadıysa random() ile yeni konum atanır. return sayesinde oyun bittikten sonra yapılan tıklamalar işlenmez.
Adım 5: Tam kod (birleştirilmiş)
Kod bloğu: Daire Tıklama oyununun tam kodu.
Kod 8.
let hedefX;let hedefY;let hedefYaricap = 40;let skor = 0;const HEDEF_SKOR = 10;let oyunBitti = false; function setup() { createCanvas(500, 400); hedefX = random(hedefYaricap, width - hedefYaricap); hedefY = random(hedefYaricap, height - hedefYaricap);} function draw() { background(25, 30, 50); if (!oyunBitti) { fill(255, 180, 0); noStroke(); ellipse(hedefX, hedefY, hedefYaricap * 2, hedefYaricap * 2); } else { fill(100, 255, 100); textSize(32); textAlign(CENTER, CENTER); text("Tebrikler! 10 puana ulaştınız.", width / 2, height / 2); } fill(255); textSize(20); textAlign(LEFT, TOP); text("Skor: " + skor + " / " + HEDEF_SKOR, 15, 15);} function mousePressed() { if (oyunBitti) { return; } let mesafe = dist(mouseX, mouseY, hedefX, hedefY); if (mesafe < hedefYaricap) { skor = skor + 1; if (skor >= HEDEF_SKOR) { oyunBitti = true; } else { hedefX = random(hedefYaricap, width - hedefYaricap); hedefY = random(hedefYaricap, height - hedefYaricap); } }}Bu kod p5.js Web Editor'e yapıştırılıp doğrudan çalıştırılabilir. Oyun, if/else ve değişken kavramlarının bir arada kullanıldığı ilk tam örnektir; çoklu hedefler sonraki ana başlıklarda ele alınır.
Sıra Sizde: Daire Tıklama’da skorun bir basışta birden fazla artmaması için mousePressed ile draw içindeki mouseIsPressed farkını kendi cümlelerinizle açıklayın. Yanlış tasarımda ne olurdu?
Sıra Sizde: Yukarıdaki Daire Tıklama kodunu biraz daha karmaşık hale getirin. Çemberin dışına tıklandığında skor 3 puan azalsın. Skor sıfırın altına düşerse oyunu bitirin (oyunBitti = true) ve ekranda «Üzgünüm, oyunu kaybettiniz» mesajını gösterin. İpucu: mousePressed içinde mesafe < hedefYaricap dalına bir else ekleyin; draw içinde hem kazanma hem kaybetme mesajını skor ile ayırt edin.
Sıra Sizde: Hedef konumunda random(hedefYaricap, width - hedefYaricap) (ve Y için benzeri) kullanıyoruz. Neden daha “basit” görünen random(hedefYaricap, width) veya random(0, width) yazmadık? Kendi cümlelerinizle yorumlayın. Ardından: bu iki alternatiften birini kullansaydık oyunda görünüm ve tıklanabilirlik açısından ne değişirdi? (İsterseniz Web Editor’de kısa süre deneyip gözlemleyin.)
Yapay Zekâ Etkileşimi: Nokta Elipsin İçinde mi? Tahmini etkinliği tamamlama süresi: 20–25 dakika.
Amaç: Bir noktanın elips içinde olup olmadığını kontrol eden p5.js kodunu yazmak ve arkasındaki matematiği (Öklid mesafesi / yarıçap karşılaştırması) adım adım anlamak. (Bu ana başlıktaki hedef, genişlik ve yüksekliği eşit bir ellipse ile çizilir; o durumda merkez–nokta mesafesi yarıçapla karşılaştırılır.)
Adım 1: Merkezi (hedefX, hedefY), yarıçapı hedefYaricap olan bir elips ve fare noktası (mouseX, mouseY) düşünün.
Adım 2: Tercih ettiğiniz yapay zekâya şu istemi verin:
Örnek İstem: "p5.js'te (mouseX, mouseY) noktasının bir elipsin içinde olup olmadığını kontrol eden kısa bir kod yaz; genişlik ve yükseklik eşit olsun (dist veya sqrt kullanabilirsin; kendi fonksiyonunu tanımlama). Ardından formülü terim terim açıkla: mesafe < yarıçap karşılaştırması geometrik olarak neden doğru sonuç verir?"
Adım 3: İlk yanıt çoğu zaman yalnızca kod verir veya matematik kısmı yüzeysel kalır. İstediğiniz bilgiyi alana kadar sohbeti sürdürün; örneğin: "Aynı testi dist kullanmadan sqrt ile yaz; Pisagor bağıntısıyla bağını göster." veya "Genişlik ve yükseklik farklı olduğunda test nasıl değişir; kısa kod ve gerekçe yaz." Yapay zekâ bazen mesafeyi function noktaIcindeMi(...) gibi sizin tanımladığınız bir fonksiyon içine koyar — fonksiyon tanımlamayı henüz görmediğiniz için bunu geri çevirin: "Fonksiyon tanımlamadan, yalnızca setup/draw/mousePressed ve yerleşik dist veya sqrt ile daha basit yaz." Yapay zekânın ilk cevabı her zaman yeterli değildir — kodu ve matematiği birlikte netleştirene kadar soruyu ilerletin.
Adım 4: Aldığınız kodu ve açıklamayı bu ana başlıktaki dist(mouseX, mouseY, hedefX, hedefY) < hedefYaricap ifadesiyle ve Görsel 1 ile karşılaştırın.
Yapay Zekâ Etkileşimi: Dokunmatik Ekranda Dokunma Tahmini etkinliği tamamlama süresi: 15–20 dakika.
Amaç: Bilgisayarda fare tıklaması yerine dokunmatik ekranda sketch’e dokunmanın nasıl algılanacağını öğrenmek.
Adım 1: Bu ana başlıktaki fare örneklerini (mouseX, mousePressed) hatırlayın.
Adım 2: Yapay zekâya sorun:
Örnek İstem: "p5.js sketch'imi dokunmatik ekranda kullanacağım. mousePressed / mouseX yerine dokunmayı nasıl algılarım? Kısa örnek ver; fare ile farkını bir paragrafta yaz."
Adım 3: Yanıttaki API adlarını (ör. touches, touchStarted) p5.js Reference’ta doğrulayın. Dokunmatik cihazda nasıl kolay deneyebileceğinizi de yapay zekâya sorun — örneğin: "p5.js Web Editor sketch'imi telefonda veya tablette kolayca nasıl açıp dokunarak denerim? Güvenli ve pratik yolları kısaca yaz." Ardından önerilen adımlardan birini uygulayın.
Özet
Fare etkileşimi, önceki ana başlıkta kurulan koşullu mantığı doğrudan oyuncu eylemine bağlar. p5.js’te mouseX ve mouseY imlecin tuval üzerindeki konumunu her frame günceller; mouseIsPressed tuş basılı tutulduğu sürece her frame doğru değerini alırken mousePressed() yalnızca basma anında bir kez çalışan bir olay fonksiyonudur. Bu ayrım, skor artışı gibi tek seferlik sayılması gereken işlemlerin draw içinde tekrarlanarak hatalı biçimde çoğalmasını önler. Aynı bölümde metin araçları da toparlanır: text mesajı yazar, textSize yazı boyutunu belirler, textAlign ise verilen noktanın metnin hangi kenarına oturacağını seçer.
dist(x1, y1, x2, y2) iki nokta arasındaki Öklid mesafesini döndürür; bu değer hedef dairenin yarıçapıyla karşılaştırıldığında “tıklama daireye isabet etti mi?” sorusu geometrik bir koşula dönüşür. Daire Tıklama oyunu bu araçları tek bir sketch’te birleştirir: hedefin konumu random(min, max) ile kenardan en az bir yarıçap içeride seçilir, mousePressed() içinde isabet sınanır, skor bir artar ve hedef yeni bir rastgele konuma taşınır. Hedef skora ulaşıldığında oyunBitti bayrağı devreye girer ve return sonraki tıklamaları etkisiz kılar. Kaçırmada puan kaybı ve skorun sıfırın altına düşmesiyle kaybetme gibi kurallar Sıra Sizde etkinliklerinde genişletilir.
Böylece mini oyun, dizilere ve çoklu nesne yapılarına geçmeden önce girdi–karar–geri bildirim döngüsünü pekiştirir.
Neler Öğrendik?
Soru 1 Daireye tıklanıp tıklanmadığını anlamak için en uygun araç hangisidir?
A) Yalnızca frameCount
B) dist ile merkez–imleç mesafesini yarıçapla karşılaştırmak
C) background rengini okumak
D) Yalnızca keyIsDown
E) console.log zorunluluğu
Soru 2 Skorun bir tıklamada birden fazla artmasını önlemek için ne yapılır?
A) Artışı mousePressed içinde tutmak
B) Artışı yalnızca background içinde yazmak
C) frameRate(1) zorunlu kılmak
D) createCanvas’ı draw içine almak
E) Değişken kullanmamak
Soru 3
mouseX / mouseY neyi verir?
A) Tuval boyutunu
B) İmlecin tuval üzerindeki konumunu
C) Yalnızca son tıklanan noktayı kalıcı saklar
D) Klavye kodunu
E) FPS değerini
Soru 4 Daire Tıklama iskeletinde hedef yenileme tipik olarak ne zaman yapılır?
A) Yalnızca dosya kaydedilirken
B) İsabet sonrası yeni rastgele konum atanırken
C) setup hiç çalışmazken
D) Yalnızca EPUB üretilirken
E) CSS yüklenirken
Neler Öğrendik Yanıt Anahtarı
Soru 1: Doğru Cevap: B
- Çözüm: Mesafe ≤ yarıçap ise geometrik isabet vardır.
- İlgili Konu: 4.1. Fare Girdisi, Metin, Mesafe ve Etkileşim
Soru 2: Doğru Cevap: A
- Çözüm: draw içinde mouseIsPressed ile artış tekrarlanabilir; olay tek seferliktir.
- İlgili Konu: 4.1. Fare Girdisi, Metin, Mesafe ve Etkileşim
Soru 3: Doğru Cevap: B
- Çözüm: p5.js imleç koordinatlarını bu sistem değişkenlerinde tutar.
- İlgili Konu: 4.1. Fare Girdisi, Metin, Mesafe ve Etkileşim
Soru 4: Doğru Cevap: B
- Çözüm: İsabet sonrası hedef yeni konuma taşınır.
- İlgili Konu: 4.2. Adım Adım: Daire Tıklama Oyunu
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.
- Microsoft. (n.d.). Visual Studio Code. https://code.visualstudio.com/
- p5.js Foundation. (n.d.). dist(). p5.js Reference. https://p5js.org/reference/p5/dist/
- p5.js Foundation. (n.d.). mouseX. p5.js Reference. https://p5js.org/reference/p5/mouseX/
- p5.js Foundation. (n.d.). p5.js Web Editor. https://editor.p5js.org/
- p5.js Foundation. (n.d.). random(). p5.js Reference. https://p5js.org/reference/p5/random/
- Shiffman, D. (n.d.). Code! Programming with p5.js. The Coding Train. https://thecodingtrain.com/tracks/code-programming-with-p5-js
- Sweigart, A. (2017). Invent Your Own Computer Games with Python (4th ed.). No Starch Press. (Benzer mini oyun örnekleri için.)
- The Coding Train. (n.d.). Games [Öğretici parkur]. https://thecodingtrain.com/tracks/games/