Bölüm 1 · Sunum 6
Değişkenleri, koşulları ve fareyi birleştirip oynanabilir bir oyun yazacağız.
Şimdiye kadar sketch’lerimiz kendi kendine çalıştı. Bir oyunda ise kararlar oyuncuya bağlı: fare nerede, tıkladı mı?
| Ad | Tür | Ne verir? | Örnek |
|---|---|---|---|
mouseX | number | İmlecin x konumu (0 … width − 1) | 500 genişlikte tuvalin ortasında ≈ 250 |
mouseY | number | İmlecin y konumu (0 … height − 1) | Üst kenarda 0 |
mouseIsPressed | boolean | Fare tuşu şu an basılı mı? | Basılıyken true |
mousePressed() | fonksiyon | Tuşa basıldığı an çalışır | Her basışta bir kez |
mouseReleased() | fonksiyon | Tuş bırakıldığı an çalışır | Her bırakışta bir kez |
mousePressed() ve mouseReleased(), tıpkı setup() ve draw() gibi özeldir: olay gerçekleşince p5.js bu addaki fonksiyonu kendisi çağırır.Fareyi tuvalde gezdirin, sonra tuşu basılı tutun. mouseX ve mouseY her frame güncellenir.
mouseX ve mouseY ile: gözler sineği izlerFareyi tuvalde gezdirin. Dört yaratık da aynı iki sayıyı okuyor: mouseX ve mouseY. Göz bebeğinin hesabını şimdi anlamanız gerekmiyor.
| Komut | Ne yapar? |
|---|---|
text(metin, x, y) | (x, y) noktasını referans alarak metni yazar. |
textSize(boyut) | Yazı boyutunu piksel olarak ayarlar. |
textAlign(hizaX, hizaY) | (x, y) noktasının, metnin hangi köşesine ya da kenarına denk geleceğini seçer. |
LEFT sol kenar, CENTER orta, RIGHT sağ kenar.TOP üst, CENTER orta, BOTTOM alt.textAlign koordinatı değiştirmez; o noktanın metne nereden bağlanacağını değiştirir.
Köşe yazıları için textAlign(LEFT, TOP); ekran ortası mesajı için textAlign(CENTER, CENTER) ve width / 2, height / 2.
Elimizde dört sayı var: farenin x ve y’si, dairenin merkezi ve yarıçapı. Hangi soruyu sormalıyız?
Fareyi dairenin içine ve dışına götürün. Renkli çizgi merkezle fare arasındaki mesafe, mavi çizgi yarıçaptır; soru yalnızca hangisinin daha uzun olduğudur.
dist(): iki nokta arasındaki mesafedist(x1, y1, x2, y2)p5.js’in yerleşik fonksiyonu. İki nokta arasındaki düz mesafeyi (Öklid mesafesi) sayı olarak verir.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)). sqrt de yerleşiktir; isterseniz kendiniz yazabilirsiniz.Bir nesne yalnızca dist(fare, nesne) < 110 ise çiziliyor. Korku oyunlarındaki el feneri, strateji oyunlarındaki “savaş sisi” aynı sorunun cevabına bakar.
draw içine yazarsak?Bir kez tıkladınız. Skor kaç olur?
Tuvale birkaç kez tıklayın. Sonra tuşu basılı tutun: hangi sayaç fırlıyor?
draw saniyede 60 kez çalışır. Parmağınız düğmedeyken her frame “basılı mı?” sorusunun cevabı evettir.Gerçek oyunlarda da görülür: bir düğmeye bir kez bastığınızda menüde üç satır birden atlanıyorsa sebep büyük ihtimalle budur.
| Yöntem | Ne zaman? | Skor için |
|---|---|---|
mouseIsPressed | Tuş basılı tutulduğu her frame (saniyede ~60) | Tek tıklama birçok kez sayılır |
mousePressed() | Tuşa basıldığı tek an | Skor bir kez artar |
mousePressed() içine yazılır.mousePressed() ile tek tıklamayı yakalamaktiklandi bir bayrak: tıklama olunca true oluyor, draw ona bakıp yazıyı gösteriyor.
Çizmek süren bir iş: basılı olduğu her frame çizgi uzar. Renk seçmek tek seferlik bir olay: tıklama anında bir kez olur. Bu sketch’te background yalnızca setup’ta ve “Temizle”de çağrılıyor; çizgiler o yüzden kalıyor.
if / else. Döngü ya da dizi gerekmiyor.mousePressed() tetiklenir.setup ve draw’ın dışında: oyun boyunca yaşayacaklar.hedefX ve hedefY henüz boş; değerlerini setup verecek.HEDEF_SKOR değişmeyecek: const.oyunBitti bir bayrak: başta false.setup(): tuval ve ilk hedefrandom(min, max)min ile max arasında rastgele, ondalıklı bir sayı verir; max dahil değildir. random(10, 50) yaklaşık 10 ile 50 arasında bir değer üretir.
random(max) 0 ile max arasında, parametresiz random() 0 ile 1 arasında değer verir.random(0, width) yazmadık?Daha basit görünüyor. Hedefin merkezi tam 0’a ya da tam width’e denk gelirse ne olur?
ellipse merkezden çizer. Merkez kenara çok yaklaşırsa dairenin bir kısmı dışarıda kalır; oyuncu yarım bir hedefe tıklamaya çalışır.
hedefYaricap, üst sınır width - hedefYaricap. y için aynısı height ile.draw(): çizim ve oyun durumu!oyunBitti: “oyun bitmediyse”. Hedef daire yalnızca o zaman çizilir.if’in dışında: her durumda çizilir.textAlign: ortada ve sol üstte.mousePressed(): tıklama kontrolüreturnBulunulan fonksiyonun geri kalanını çalıştırmadan çıkmasını sağlar.keyIsDown ve keyPressed() kullanmadık. Klavye girdisini ilerleyen bölümlerde ele alacağız.Bu oyun, bir oyunun en temel döngüsünü gösteriyor: girdi → karar → geri bildirim.
Çekirdek aynı: dist ile isabet testi ve mousePressed. Üstüne üç küçük fikir eklendi. Bunları “Oyunu zorlaştırın” etkinliğinde kendiniz yazmayı deneyeceksiniz.
mousePressed ile draw içindeki mouseIsPressed arasındaki farkı anlatın. Yanlış tasarımda ne olurdu?random(hedefYaricap, width) ya da random(0, width) yazmadık? Bu ikisinden birini kullansaydık görünüm ve tıklanabilirlik nasıl değişirdi? Editörde deneyip gözleyin.mousePressed içindeki mesafe < hedefYaricap dalına bir else ekleyin. draw içinde iki mesajı skor ile ayırın.frameCount / 60.dist kullanmadan sqrt ile yaz; Pisagor bağıntısıyla ilişkisini göster.”dist(mouseX, mouseY, hedefX, hedefY) < hedefYaricap ifadesiyle karşılaştırın.mousePressed / mouseX yerine dokunmayı nasıl algılarım?”touches, touchStarted) p5.js referansından doğrulayın.dist(0, 0, 3, 4) kaç döndürür?Pisagor: 3² + 4² = 25, karekökü 5. dist yatay ve dikey farkları toplamaz.
40 < 40 yanlıştır. Kenarı da isabet saymak isteseydik <= yazardık. Hangisini istediğinize siz karar verirsiniz.
mousePressed’in başındaki return’lü if’i silersek?Daire artık çizilmiyor ama hedefX ve hedefY hâlâ duruyor. İsabet testi çalışır; skor 11, 12… olur.
mouseX, mouseY imlecin konumunu verir; her frame güncellenir.mouseIsPressed basılı tutulduğu her frame doğrudur; mousePressed() basma anında bir kez çalışır.text, textSize, textAlign ile ekrana yazı yazılır.dist < yarıçap: nokta dairenin içinde.random(min, max) ile hedef, kenardan bir yarıçap içeride seçilir.return fonksiyondan erken çıkar; oyunBitti bayrağı oyunu durdurur.Sıradaki bölüm
Aynı satırı yüz kez yazmadan yüz şekil çizmek.