Հիմնական նյութ
Դասընթաց․ (Ծրագրավորում) > Բաժին 4
Դաս 5: Making a memory gameՀիշողության խաղ․ նկարել սալիկացանց
«Հիշողություն» խաղը կսկսենք՝ պատաhական սկզբունքով խառնելով բոլոր սալիկները: Ապա սալիկները կդասավորենք ուղղանկյունաձև վանդակներում՝ դեմքով հակառակ շրջված, որպեսզի չերևա, թե ինչ է պատկերված սալիկի վրա:
Երեսով հակառակ կողմ շրջված սալիկներ
Ծրագրավորումը սկսենք՝ մտածելով, թե ինչպես կարելի է ստեղծել երեսով շրջված սալիկներ, իսկ հետո էլ պարզենք թե ինչպես կարելի աշխատել տարբեր պատկերների հետ:
Սալիկը բավականին կարևոր օբյեկտ է «Հիշողություն» խաղում, որտեղ օգտագործում ենք օբյեկտային կողմնորոշվածություն սկզբունքներ, որպեսզի սահամանենք
Tile
օբյեկտը և հետո էլ ստեղծենք սալիկի բազում օրինակներ: Հետո էլ յուրաքանչյուր Tile
-ով կարող ենք ասոցիացնել և հատկությունները (ինչպես, օրինակ՝ դիրքը և պատկերը ), և գործողություններ (ինչպես, օրինակ՝ պատկերելը):Սահմանենք
Tile
կոնստրուկտոր ֆունկցիան: Դրան կփոխանցենք x
և y
արգումենտներ, քանի որ մենք դեռ չենք աշխատում պատկերների հետ: var Tile = function(x,y) {
this.x = x;
this.y = y;
this.width = 50;
};
Իսկ այժմ, երբ արդեն սահմանել ենք կոնստրուկտորը, դրա միջոցով կարող ենք ստեղծել սալիկներ՝ համապատասխան x և y դիրքերում: Կօգտագործենք երկու
for
ցիկլ: Կիրառելու ենք ներդրված for
ցիկլը, քանի որ այն գաղափարային տեսանկյունից հեշտացնում է վանդակների համար կոորդինատներ գտնելը: Նախ պետք է հայտարարել դատարկ
սալիկների
շարքը, որպեսզի կարողանանք պահեստավորել բոլոր սալիկները.var tiles = [];
Մեր արտաքին ցիկլը կարող է կրկնվել այնքան սյունակների համար, որքան ցանկանանք: Մեր ներքին ցիկլը կրկնվում է յուրաքանչյուր տողի համար, և յուրաքանչյուր նոր
Tile
-ին տրվում է x և y կոորդինատ, որը համապատասխանում է այդ տողին և սյունին:var NUM_COLS = 5;
var NUM_ROWS = 4;
for (var i = 0; i < NUM_COLS; i++) {
for (var j = 0; j < NUM_ROWS; j++) {
var tileX = i * 54 + 5;
var tileY = j * 54 + 40;
tiles.push(new Tile(tileX, tileY));
}
}
Բայց դժվար է իմանալ՝ արդյոք սալիկները լավ տեսք կունենան, քանի որ դեռ չունենք որևէ կոդ՝ դրանք պատկերելու համար: Երևի թե այդ ամենը պետք է նախապես անեինք: Երբեմն ծրագրավորում կատարելիս դժվար է որոշել, թե որ քայլը պետք է անել առաջինը: Այժմ
Tile
օբյեկտին կավելացնենք նոր մեթոդ, որը կանվայի վրա դեմքով հակառակ կողմ շրջված սալիկ է նկարում: Կպատկերենք կլորացված ուղղանկյուն, որը հանձնարարված գագաթի հատվածում կունենա «Քանի» տերև: Tile.prototype.draw = 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);
};
Այնքան մոտ ենք, որ կարող ենք տեսնել, թե ինչպիսի տեսք ունեն սալիկները: Նոր
for
ցիկլ ավելացրու, որը կրկնվում է բոլոր սալիկներում և կանչում է պատկերման մեթոդին:for (var i = 0; i < tiles.length; i++) {
tiles[i].draw();
}
Ահա թե ինչպիսի տեսք ունի մեր ծրագիրը՝ բոլոր կոդերով հանդերձ: Խաղա տարբեր թվերի հետ ներդրված ցիկլում, և տես, թե ինչպես է այն փոխում վանդակները կամ էլ նկարման ձևը (գուցե ուրի՞շ խորհրդանշան):
Երեսով դեպի մեր կողմ շրջված սալիկներ
Իսկ այժմ, երբ արդեն ունենք դեմքով մյուս կողմը շրջված սալիկներ, մի փոքր էլ բարդացնենք խնդիրը՝ յուրաքանչյուր սալիկին պատկեր հանձնելով: Այնպես, որ շարքում յուրաքանչյուր պատկերից լինի երկուական՝ պատահականորեն բաշխված: Տվյալ արդյունքին հասնելու հավական շատ եղանակներ կան, բայց մենք կառաջարկենք հետևյալը.
- Ստեղծում ենք հավանական պատկերների շարք և օգտագործելում ենք
getImage
ֆունկցիան, որպեսզի ընտրենք գրադարանում եղած տարբերակներից: - 20 սալիկների երեսների համար անհրաժեշտ է միայն 10 պատկեր: Հետո էլ կստեղծենք նոր շարք՝ 10 պատահական սկզբունքով ընտրված պատկերների համար այն կունենա 2 կրկնօրինակ առաջին շարքից:
- Կխառնենք ընտրված պատկերների շարքը: Այսպիսով՝ շարքում պատկերների զույգերը այլևս չեն լինի կողք կողքի:
- Սալիկները ստեղծում ենք նեդրված ցիկլում ևամեն սալիկին մի պատկեր տալիս այդ շարքից:
Գուցե այդ քայլերը հասկանալի չլինեն: Արի կատարենք յուրաքանչյուրը և տեսնենք՝ ինչ տեսք ունենք:
Քայլ 1. Ստեղծում ենք հավանական պատկերների շարք՝
getImage
ֆունկցիան, որով էլ ընտրում ենք պատկերներ գրադարանից.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")
];
Ընտրել ենք բազում ավատարներ, բայց կարող ես փոխել այն և ընտրել քո սիրելի պատկերը: Համոզվիր, որ շարքն ունի նվազագույնը 10 պատկեր՝ հակառակ դեպքում Նկարները բավարար չեն լինի 20 սալիկների համար: Չնայած կարելի է ավելացնել ավելի քան 10 պատկեր և արդյունքում մեր խաղը կունենա ավելի լայն տեսականի, նաև հաջորդ քայլում հստակեցնելու ենք ցուցակը:
Քայլ 2: Մեր 20 սալիկների երեսների համար պետք է ընդամենը 10 պատկեր: Հետո էլ կստեղծենք նոր շարք, որը կպարունակի է առաջին շարքից 10 պատահական սկզբունքով ընտրված պատկերի 2 կրկնօրինակ:
Այս ամենը կատարելու համար կստեղծենք for ցիկլը, որը կկրկնվի 10 անգամ: Յուրաքանչյուր կրկնության ժամանակ պատահականորեն կընտրենք մեկ ցուցիչ
դեմքեր
շարքից՝ երկու անգամ տանելով այն դեպի ընտրված
շարք, իսկ հետո օգտագործենք splice մեթոդը և կհեռացնենք այն faces
շարքից: Արդյունքում երկու անգամ չենք ընտրի: Վերջին քայլը շատ կարևոր է: var selected = [];
for (var i = 0; i < 10; i++) {
// Պատահական սկզբունքով շարքից ընտրիր երեսներից մեկը
var randomInd = floor (random(faces.length));
var face = faces[randomInd];
//Քաշելով 2 կրկնօրինակները՝ դիր շարքի մեջ
selected.push(face);
selected.push(face);
// Հեռացրու դեմքերի շարքից, որ նորից չընտրես
faces.splice(randomInd, 1);
}
Քայլ 3: Խառնենք ընտրված պատկերների շարքը, որպեսզի շարքում պատկերների զույգերն այլևս իրար կողքի չլինեն:
Երևի թե խառնած կլինես քարտերի կապոց, իսկ երբևէ խառնե՞լ ես որևէ շարք JavaScript-ում: Խառնելու ամենատարածված մեթոդը ցանկացած ծրագրավորման լեզվով կոչվում է Fisher-Yates Shuffle, և դա այն է, ինչ կօգտագործենք:
Ֆիշր-Յեթս խառնումը սկսվում է՝ ընտրելով կամայական տարր շարքից և փոխելով այն շարքի վերջին էլեմենտով: Հաջորդ քայլում այն ընտրում է կամայական մի տարր շարքի ցանկացած մասից բացի վերջին տարրից և փոխանակում է վերջից երկրորդ տարրի հետ: Շարունակվում է մինչև բոլոր տարրեի փոխանակվելը:
Կարող ես սեղմել տեսողականացման վրա և կտեսնես, թե ինչ նկատի ունեմ:
JavaScript-ում գործածելու համար արի ստեղծենք
shuffleArray
ֆունկցիա, որը մտնում է շարք և խառնում է տարրերը՝ փոխելով նախնական շարքը.var shuffleArray = function(array) {
var counter = array.length;
// Մինչդեռ կան տարրեր շարքում
while (counter > 0) {
//Ընտրիր կամայական ցուցիչ
var ind = Math.floor(Math.random() * counter);
// Հակադիրը նվազեցրու 1-ով
counter--;
// և Փոխանակիր վերջին տարրը դրա հետ
var temp = array[counter];
array[counter] = array[ind];
array[ind] = temp;
}
};
Եթե ալգորիթմը միանգամայն հասկանալի չէ տեսողականացումից և կոդ կարդալուց հետո, ապա կարող ես փորձել իրական քարտերով կամ դիտել Ադամ Քոուրի Youtube-յան տեսանյութը:
Ֆունկցիան սահմանելուց հետո անհրաժեշտ է կանչել՝
shuffleArray(selected);
Իսկ այժմ 10 պատկերից կազմված զույգերի շարք՝ կամայականորեն խառված:
Քայլ 4: Կհանձնարարենք այդ շարքից պատկեր յուրաքանչյուր սալիկին՝ ներդրված ցիկլում, որտեղ էլ ստեղծում ենք սալիկներ:
Մեր
ընտրված
շարքում ունենք 20 պատկեր, և այն կրկնում ենք 20 անգամ, որպեսզի վանդակներում գործարկենք նոր սալիկներ: Յուրաքանչյուր սալիկի համար կամայական պատկեր ընտրելու համար կանչենք փոփ մեթոդը շարքի վրա: Այս մեթոդը հեռացնում է շարքից վերջին տարրը և վերադարձնում է այն: Ամենահեշտ եղանակն է, որով կարող ենք հանձնարարել բոլոր պատկերները, բայց խուսափենք կրկնակի անգամ դրանք հանձնարարելուց: for (var i = 0; i < NUM_COLS; i++) {
for (var j = 0; j < NUM_ROWS; j++) {
var tileX = i * 54 + 5;
var tileY = j * 54 + 40;
var tileFace = selected.pop();
var tile = new Tile(tileX, tileY, tileFace);
tiles.push(tile);
}
}
Նկատո՞ւմ ես, թե ինչպես է կոդը փոխանցում
tileFace
-ը Tile
կոնստրուկտորին՝ որպես երրորդ պարամետր: Մեր կոնստրուկտորը ուներ միայն 2 նախնական պարամետր՝ x
և y
, իսկ հիմա այն կփոխենք, որ կարողնանաք նույնպես հիշել յուրաքանչյուր սալիկի երեսի պատկերը, նաև, որ այդ սալիկը երեսը դեպի մեր կողմն է:var Tile = function(x, y, face) {
this.x = x;
this.y = y;
this.width = 70;
this.face = face;
this.isFaceUp = false;
};
Այժմ տեսականորեն ունենք յուրաքանչյուր սալիկին տրված պատկերներ, սակայն դեռ այն չենք ցուցադրի: Արի փոխենք
Tile.draw
մեթոդը, որ այն կարողանա պատկերել սալիկներ, որոնց երեսը դեպի մեզ է:Tile.prototype.draw = function() {
fill(214, 247, 202);
strokeWeight(2);
rect(this.x, this.y, this.width, this.width, 10);
if (this.isFaceUp) {
image(this.face, this.x, this.y,
this.width, this.width);
} else {
image(getImage("avatars/leaf-green"),
this.x, this.y, this.width, this.width);
}
};
Վերջապես՝ ստուգելու համար, թե ինչպես է այն աշխատում, կարող ենք փոխել մեր
for
ցիկլը, և նախքան պատկերելը տանք յուրաքանչյուր սալիկին երեսը դեպի մեր կողմ շրջած
հատկությունը. ճիշտ է
:for (var i = 0; i < tiles.length; i++) {
tiles[i].isFaceUp = true;
tiles[i].draw();
}
Ահա բոլորը միասին: Փորձիր վերսկսել և կտեսնես, թե ինչպես են սալիկները փոխվում ամեն անգամ:
Ուզո՞ւմ ես միանալ խոսակցությանը։
Առայժմ հրապարակումներ չկան։