Ana içerik
Konu: Bilgisayar Programlama > Ünite 4
Ders 5: Bir Hafıza Oyunu YapmaFayans ağı
"Bellek" oyununu oynamanın ilk adımı, kartları rastgele karıştırmak ve kartları kapalı olarak, dikdörtgen oluşturacak şekilde dizmektir; böylece kartların arkasında hangi resimlerin olduğunu göremeyiz.
Kapalı kartlar
Oyunu programlamaya başlarken sadece kapalı kartları nasıl oluşturacağımıza odaklanalım ve farklı resimleri nasıl yapacağımızı daha sonra görelim.
"Bellek" oyununda "kart" yeterince önemli bir nesnedir ve
kart
nesnesini tanımlamak ve daha sonra birden çok örneğini oluşturmak için nesne tabanlı ilkeleri kullanacağız. O zaman, Karo
ların her biriyle iki özelliği (konum ve görüntü gibi) ve davranışı (aşağı veya yukarı çevirmek gibi) ilişkilendirebileceğiz.Başlamak için,
Kart
oluşturucu işlevini tanımlayacağız. Daha görüntülerle ilgilenmediğimiz için, sadece x
ve y
girdileri geçireceğiz. Karo eninin (bir sabit) nesne üzerinde bir özellik olduğunu da hatırlayacağız.var Tile = function(x, y) {
this.x = x;
this.y = y;
this.width = 70;
};
Artık oluşturucuyu tanımladığımıza göre, bunu döngüde kullanarak, uygun x ve y konumlarında karolar yaratabiliriz. Aslında, iki for döngüsü kullanacağız - iç içe bir for döngüsü - çünkü bu, bir ağ için koordinatlar oluşturmayı kavramsal olarak kolaylaştırır.
Boş bir
tiles
dizisini sıfırlayarak başlarız:var tiles = [];
Dıştakş döngümüz istediğimiz kadar sütunda yineleme yapar, içteki döngümüz her sütunda yineleme yapar, ve her yeni
Fayans
a bu satır ve sütuna denk gelen başlangıç için bir x ve y değeri verilir.var NUM_COLS = 5;
var NUM_ROWS = 4;
for (var i = 0; i < NUM_COLS; i++) {
for (var j = 0; j < NUM_ROWS; j++) {
tiles.push(new Tile(i * 78 + 10, j * 78 + 40));
}
}
Ancak, fayansların iyi görünüp görünmeyeceğini bilmemiz zordur, çünkü bunları çizmek için henüz bir kodumuz yoktur! Aslında, belki de önce bunu yapmalıydık. Bazen, programlama yaparken, önce neyi yapacağını bilmeniz zordur, öyle değil mi? Şimdi
Fayans
nesnesine tuval üzerine kapalı bir fayans çizen bir yöntem ekleyelim. Atanan konumda, üzerinde sevimli bir Khan yaprağı olan köşeleri yuvarlanmış bir dikdörtgen çizeceğiz.Tile.prototype.drawFaceDown = function() {
fill(214, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
image(getImage("avatars/leaf-green"), this.x, this.y, this.width, this.width);
};
Ve şimdi fayanslarımızın nasıl göründüğünü kontrol edebiliriz. Tüm fayanslardan yinelenen ve çizim yöntemini çağıran yeni bir for döngüsü ekleyelim:
for (var i = 0; i < tiles.length; i++) {
tiles[i].drawFaceDown();
}
Bütün bu kodla, programımız şuna benzer. İç içe for döngüsünde sayıları değiştirerek bunun ağı veya bunların çizimini nasıl değiştirdiğine bakın (belki de farklı bir logo?)
Yukarı bakan fayanslar
Artık elimizde aşağı bakan bir fayans gridi olduğuna göre, daha zor bir soruya bakalım: dizide her görüntüden rastgele dağıtılmış 2 adet olmak üzere, bunların her birine bir görüntü dağıtalım. Büyük olasılıkla, bunu yapmak için birçok yolumuz vardır, ama size şunu tavsiye edebilirim:
getImage
fonksiyonunu kullanarak kütüphanemizden seçerek, bir dizi olası görüntü seçeriz.- 20 fayansın yüzü için sadece 10 görüntüye ihtiyacımız olacak, böylece, bu ilk diziden rastgele seçilmiş 10 görüntüden 2 kopya olan yeni bir dizi oluştururuz.
- Seçilen görüntü dizisini rastgeleleştiririz, böylece görüntü çiftleri artık dizide yan yana olmaz.
- Fayansları oluşturduğumuz for döngüsünde, bu diziden her fayansa bir görüntü atayacağız.
Bu adımlar henüz anlamlı gelmeyebilir - bunların her birini yapalım ve neye benzediğini görelim.
1. Adım:
getImage
fonksiyonunu kullanıp kütüphanemizden seçerek, bir dizi olası görüntü oluştururuz.var faces = [
getImage("avatars/leafers-seed"),
getImage("avatars/leafers-seedling"),
getImage("avatars/leafers-sapling"),
getImage("avatars/leafers-tree"),
getImage("avatars/leafers-ultimate"),
getImage("avatars/marcimus"),
getImage("avatars/mr-pants"),
getImage("avatars/mr-pink"),
getImage("avatars/old-spice-man"),
getImage("avatars/robot_female_1"),
getImage("avatars/piceratops-tree"),
getImage("avatars/orange-juice-squid")
];
Ben birkaç avatar seçtim, ama siz en sevdiğiniz görüntülerle değiştirebilirsiniz. Buradaki önemli hususi bu dizide en az 10 görüntü olduğundan emin olmaktır, ki 20 fayansımız için görüntümüz bitmesin. Her oynandığında çeşitlilik katmak için, 10 görüntüden çok daha fazlasını da ekleyebiliriz, çünkü bir sonraki adımda listeyi kısıtlayacağız.
2. Adım 20 fayansın yüzü için sadece 10 görüntüye ihtiyacımız olacak, böylece, bu ilk diziden rastgele seçilmiş 10 görüntüden 2 kopya olan yeni bir dizi oluştururuz.
Bunu yapmak için, 10 kere uygulanan bir for döngüsü oluştururuz. Her yinelemede,
faces
dizisinden rastgele bir indeks seçeriz, bunu selected
dizisine iki kere iteriz ve sonra da, iki kere seçmemek için splice yöntemini kullanarak faces
dizisinden çıkarırız. Bu son adım çok önemlidir!var selected = [];
for (var i = 0; i < 10; i++) {
// Yüzler dizisinden rastgele şekilde bir tanesini seçin
var randomInd = floor(random(faces.length));
var face = faces[randomInd];
// Diziye 2 kopya itin
selected.push(face);
selected.push(face);
// Tekrar seçmememiz için, yüzleri diziden çıkarın
faces.splice(randomInd, 1);
}
3. Adım: Seçilen görüntü dizisini rastgeleleştiririz, böylece görüntü çiftleri artık dizide yan yana olmaz.
JavaScript'de bir dizinin nasıl rastgele sıralandığını merak ediyor olabilirsiniz. Birkaç teknik mevcuttur, ama ben size en çok beğendiğimi göstereceğim.
JavaScript'de her dizi nesnesinin diziyi "sözlüğe göre" sıralayacak bir
sort
yöntemi vardır. Bu, her öğeyi bir dizeye dönüştüreceği ve bunları bir sözlükteki sözcükler gibi sıralayacağı anlamına gelir. Örneğin, bir dizi sayı ve harfi nasıl sıralayacağına bakalım:var items = ["A", 1, "C", "H", 10, "D", 2];
items.sort();
1,10,2,A,C,D,H
Bu sıralama bazen faydalı olabilir, ama çoğunlukla dizimizi başka bir şekilde sıralamak isteriz. Örneğin, bir sayı dizimiz olsaydı, bunu sayısal olarak sıralamak isteyebilirdik. Bu nedenle,
sort
yöntemi isteğe bağlı bir girdi, dizideki her öğe çifti için çağrılan ve bir öğeyi diğerinden yukarı mı sıralayacağını belirten bir değer veren bir geri çağırma fonksiyonu, alabilir. Negatif bir sayı, birinci öğenin birinci, pozitif sayı ikinci öğenin birinci olması gerektiğini belirtir, ve sıfır sırayı değiştirmez.Bir diziyi sayısal olarak küçükten büyüğe sıralamak istersek,
a-b
'yi veren bir fonksiyon geçirebiliriz.var nums = [1, 5, 10, 2, 4];
nums.sort(function(a, b) {
return a-b;
});
// 1,2,4,5,10
Tamam, şimdi bunu rastgele bir şekilde diziyi sıralamak için nasıl kullanabiliriz? Yani, bu fonksiyondan sadece rastgele bir sayı elde etmeliyiz, pozitif veya negatif olan bir sayı. Yukarıdaki
selected
dizimize bunu şu şekilde uygulayabiliriz:selected.sort(function() {
return 0{,}5 - random();
});
Ve artık elimizde, rastgele sıralanmış 10 çift görüntü var!
4. Adım: Fayansları oluşturduğumuz iç içe for döngüsünde, her fayansa bu diziden bir görüntü atayacağız.
selected
dizimizde 20 görüntümüz var, ve ağdaki konumlarda yeni fayanslar oluşturmak için 20 kere yineliyoruz. Her görüntüyü bir fayansa atamak için, dizide pop
yöntemini kullanabiliriz. Bı yöntem dizideki son öğeyi çıkarır ve verir, ve tüm görüntüleri atamanın ve iki kere atamamanın en iyi yoludur.for (var i = 0; i < NUM_COLS; i++) {
for (var j = 0; j < NUM_ROWS; j++) {
tiles.push(new Tile(i * 78 + 10, j * 78 + 40, selected.pop()));
}
}
Yani artık her fayansa teorik olarak görüntüler atadık, ama henüz bunları göstermiyoruz!
Fayans
nesnesine, onları yukarı bakacak şekilde çizmekten sorumlu bir yöntem ekleyelim. Aşağı bakacak şekilde çizmeye benzer olacak, yalnızca bu this.face
özelliği image
fonksiyonuna geçirilir.Tile.prototype.drawFaceUp = function() {
fill(214, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
image(this.face, this.x, this.y, this.width, this.width);
};
Tekrarlanan kodu azaltmak için, sadece anahatlarını çizmekten sorumlu ek bir yöntem ekleyebilir, ve çizim yöntemlerinin her birinden bu yöntemi çağırabilirdik. Ancak şimdilik bunu böyle bırakacağız.
Son olarak, bunun işe yaradığını test etmek için, for döngümüzü
drawFaceDown
yerine drawFaceUp
çağıracak şekilde değiştirebiliriz:for (var i = 0; i < tiles.length; i++) {
tiles[i].drawFaceUp();
}
Şimdi, hepsi birlikte. Fayansların her seferinde nasıl değiştiğini görmek için tekrardan başlatmayı deneyin.
Tartışmaya katılmak ister misiniz?
Henüz gönderi yok.