M9 | L6 – Happy beaver II

Astăzi vom afla despre:

  • Crearea caracterului

Aplicațiile pe care le vom folosi sunt:

Khan Academy

PROIECTE:

Happy Beaver

Exemplu: https://www.khanacademy.org/computer-programming/happy-beaver-02/5679074325250048

Habitatul

Acest joc este un „scroll-side” 2D clasic: asta înseamnă că îl privim lateral, iar personajul se mișcă doar înainte sau înapoi prin el. Totuși, vrem personajul nostru în centrul ecranului, așa că, de fapt, simulăm mișcarea aparentă a personajului mutând fundalul pe lângă personaj. Este un truc, dar funcționează!

Pentru a începe, să desenăm doar părțile care nu vor arăta mișcare, cerul albastru și pământul maro:

draw = function() {

    background(227, 254, 255);

    fill(130, 79, 43);

    rect(0, height*0.90, width, height*0.10);

    // …

}

Acum, pentru a crea aspectul de derulare laterală, să adăugăm iarbă, folosind imaginea de iarbă din biblioteca de imagini. O modalitate prin care am putea crea acest mediu în mișcare ar fi să ne prefacem că pânza noastră are o lățime de 3000 de pixeli, și atât de mare este nivelul nostru și să desenăm cât mai multe blocuri de iarbă pentru a se potrivi acelor 3000 de pixeli, mutându-le de fiecare dată. Cu toate acestea, acest lucru nu este foarte eficient și, în programarea jocurilor, avem tendința să ne preocupăm mult de eficiență. În schimb, vom „țiglă” și „șerpi” imaginile cu iarbă. Vom trage cât de mulți avem nevoie pentru a trece peste ecranul de 400 de pixeli, iar atunci când unul cade de pe partea stângă a ecranului din dreapta, îl vom lipi imediat înapoi pe partea dreaptă a ecranului și vom continua făcând asta pentru totdeauna.

Pentru a face acest lucru, vom începe prin inițializarea unui set de poziții inițiale pentru blocurile de iarbă:

var grassXs = [];

for (var i = 0; i < 25; i++) {

    grassXs.push(i*20);

}

Apoi, în interiorul buclei noastre de desen, vom desena fiecare dintre ele:

for (var i = 0; i < grassXs.length; i++) {

   image(getImage(„cute/GrassBlock”), grassXs[i], height*0.85, 20, 20);

}

Arată bine pentru o scenă statică, dar avem nevoie de asta pentru a ne mișca! Deci, putem scădea câte unul din fiecare poziție de iarbă de fiecare dată, deplasându-le spre stânga cu 1 pixel.

for (var i = 0; i < grassXs.length; i++) {

   image(getImage(„cute/GrassBlock”), grassXs[i], height*0.85, 20, 20);

    grassXs[i] -= 1;

}

Acum iarba se va mișca, dar în cele din urmă va dispărea, pe măsură ce valorile x devin din ce în ce mai negative. Amintiți-vă, vrem să „șarpăm” plăcile – vrem să le înfășurăm în partea dreaptă a pânzei odată ce acestea se lasă de pe partea stângă. Pentru a face acest lucru, vom verifica dacă suntem suficient de în afara ecranului (amintiți-vă că imaginile noastre sunt desenate din colțul din stânga sus) și vom seta valoarea x la lățimea pânzei, dacă da:

for (var i = 0; i < grassXs.length; i++) {

   image(getImage(„cute/GrassBlock”), grassXs[i], height*0.85, 20, 20);

    grassXs[i] -= 1;

    if (grassXs[i] <= -20) {

        grassXs[i] = width;

    }

}

Punând totul împreună, acum avem un castor care pare că se mișcă în timp ce țopăie:

var Beaver = function(x, y) {

    this.x = x;

    this.y = y;

    this.img = getImage(„creatures/Hopper-Happy”);

    this.sticks = 0;

};

Beaver.prototype.draw = function() {

    this.y = constrain(this.y, 0, height-50);

    image(this.img, this.x, this.y, 40, 40);

};

Beaver.prototype.hop = function() {

    this.img = getImage(„creatures/Hopper-Jumping”);

    this.y -= 5;

};

Beaver.prototype.fall = function() {

    this.img = getImage(„creatures/Hopper-Happy”);

    this.y += 5;

};

var beaver = new Beaver(10, 300);

var sceneX = 0;

// moving

// snake like fashion, wrap around

var grassXs = [];

for (var i = 0; i < 25; i++) {

    grassXs.push(i*20);

}

draw = function() {

    // static

    background(227, 254, 255);

    fill(130, 79, 43);

    rect(0, height*0.90, width, height*0.10);

    // draw the blocks

    for (var i = 0; i < grassXs.length; i++) {

        image(getImage(„cute/GrassBlock”), grassXs[i], height*0.85, 20, 20);

        // subtract one, so that they appear to move to left (hopper appears to move to right)

        grassXs[i] -= 1;

        // Now move the blocks over once they wrap around

        if (grassXs[i] <= -20) {

            grassXs[i] = width;

        }

    }

    if (keyIsPressed && key.code === 32) {

        beaver.hop();

    } else {

        beaver.fall();

    }

    beaver.draw();

};

Bine, avem un castor care trece printr-un mediu cu derulare laterală. Dar castorul nu are ce face acolo! Trebuie să adăugăm bastoane pentru ca castorul să urce și să se adune.

Să ne gândim puțin la stick-urile noastre, deoarece trebuie să decidem cum să le programăm:

  • Fiecare stick are o poziție x și y. Probabil că vrem pozițiile x distribuite cu o anumită cantitate (posibil constantă sau aleatorie într-un interval) și vrem pozițiile y randomizate într-un interval, astfel încât utilizatorul să controleze hopul și căderea castorului.
  • Bastoanele ar trebui să aibă aceeași mișcare aparentă ca iarba, dar nu ar trebui să șerpuiască în jur. Odată ce un stick este în afara ecranului, acesta a dispărut pentru totdeauna.
  • Ar trebui să existe o anumită cantitate stabilită de bastoane pe nivel – la un moment dat, ar trebui să nu mai existe bastoane.

Există multe modalități prin care ne-am putea programa bastoanele, dar acestea par suficient de complexe, așa că să le modelăm cu un obiect, așa cum ne-am modelat caracterul de castor:

var Stick = function(x, y) {

    this.x = x;

    this.y = y;

};

Stick.prototype.draw = function() {

    fill(89, 71, 0);

    rect(this.x, this.y, 5, 40);

};

Apoi, înainte ca jocul nostru să înceapă să ruleze – ca și după ce ne-am inițializat castorul – să creăm o matrice de 40 de bastoane, cu offset constant și y aleatoriu:

var sticks = [];

for (var i = 0; i < 40; i++) { 

    sticks.push(new Stick(i * 40 + 300, random(20, 260)));

}

Acum putem desena bețele – similar cu modul în care am desenat iarba, chiar și fără înfășurare:

for (var i = 0; i < sticks.length; i++) {

    sticks[i].draw();

    sticks[i].x -= 1;

}

Iată-l, cu bețele trase cu codul respective:

https://www.khanacademy.org/computer-programming/happy-beaver-02/5679074325250048