Seinään

Home » Blogi » Seinään

Ei ole hauskaa saada sankari, joka osaa kävellä, mutta ei voi iskeä seinään. Saamme sankarimme tuntemaan kiinteän tiiliseinän voiman. Tai mikä tahansa muu laatta, jota emme päätä kävellä:

Ensimmäisessä luvussa asetimme laattojemme omaisuutta “kävelyyn”. Kun nykyisessä sijainnissa olevaa ruutua edustavan objektin käveltävä ominaisuus on asetettu arvoon “false”, sankari ei voi mennä sinne. Mutta sitten taas, jos käveltävä omaisuus on “tosi”, niin sankari voi kävellä siellä (tätä kutsutaan “logiikaksi”, ihmiset oppivat sen koulussa, jotkut jopa yliopistossa, köyhät, köyhät paholaiset).

Jotta tämä taika toimisi, teemme seuraavaa: nuolinäppäimen painamisen jälkeen tarkistamme, onko laatta, jossa char kävelee, kävellä. Jos on, siirrämme sankarin. Jos laatta ei ole käveltävä (kovatiiliseinätyyppi), jätämme huomioimatta painetut nuolinäppäimet.

Tämä on täydellinen törmäys seinään:

Sankari seisoo seinän vieressä ja seuraavassa vaiheessa hän olisi seinän sisällä. Emme voi antaa sen tapahtua, joten emme tee. Ei liikuta, mies! Mutta maailma ei ole täydellinen, entä jos vain osa sankarista törmää:

Tämä edellyttää, että tarkistamme sankarin ja seinän välisen törmäyksen kaikilla neljällä hahmon kulmapisteellä. Jos jokin sankarin kulmista (tässä esimerkissä vasen alakulma) olisi seinän sisällä, pysäytämme sankarin.

Tai jos sankari ei ole vielä seinän vieressä, mutta menisi silti seinän sisään, jos annat hänen astua sinne:

Meidän on asetettava sankari seinälle:

“Voi ei!” saatat itkeä: “Kaikki tämä on mahdotonta tehdä!” Älä huoli, se ei itse asiassa ole kovin vaikeaa.

Anna minulle kulmani

Emme halua osia hahmostamme menevän seinän sisään, joten meidän on tarkistettava sankarin ja kävelemättömän esineen välinen törmäys käyttämällä ei yhtä, vaan neljää pistettä. Käytämme kulmapisteitä ja odotamme, että useimmat sankarit näyttävät suorakulmioilta (he TOIMIVAT!).

Tehdään tätä tarkoitusta varten uusi toiminto nimeltä getMyCorners:

function getMyCorners (x, y, ob) {

ob.alasY = Math.floor((y+ob.height-1)/game.tileH);

ob.upY = Math.floor((y-ob.height)/game.tileH);

ob.leftX = Math.floor((x-ob.width)/game.tileW);

ob.oikeaX = Math.floor((x+ob.width-1)/game.tileW);

//tarkista, ovatko ne seiniä

ob.upleft = peli[“t_”+ob.upY+”_”+ob.leftX].kelpoinen;

ob.downleft = peli[“t_”+ob.downY+”_”+ob.leftX].kelpoinen;

ob.upright = peli[“t_”+ob.upY+”_”+ob.rightX].walkable;

ob.downright = peli[“t_”+ob.downY+”_”+ob.rightX].kelpoinen;

}

Tämä funktio hyväksyy 3 argumenttia: objektin keskipisteen x/y sijainti lavalla (pikselit) ja objektin nimi. Odota, tiedämme jo objektin x/y sijainnin, olemme tallentaneet sen char-objektin sisään, saatat ihmetellä. Se on totta, mutta olemme tallentaneet charin NYKYISEN sijainnin, tässä on kyse paikan char WOULD BE jos se liikkuisi.

Ensin lasketaan ruudut, joissa merkki ulottuu. Sen keskipiste voi olla yhdessä laatassa, mutta sen vasen puoli voi olla toisessa laatassa, sen korkein kohta voi olla kolmannessa laatassa. Lisäämällä muuttuja y sankarin korkeuteen ja jakamalla se laatan korkeudella, saadaan laattojen lukumäärä, jossa objektin alin kohta (alasY) seisoo.

Viimeiset 4 riviä käyttävät pisteitä, jotka olemme laskeneet saadaksemme kulmissa kuljetettavan kiinteistön arvon. Esimerkiksi ylempi kulma käyttää upY- ja leftX-muuttujia. Kuten näette, kaikki pisteet tallentuvat myös ob-objektiin ja pääsemme niihin käsiksi myöhemmin, kun siirretään merkkiä. Haluaisin jälleen huomauttaa, kuinka getMyCorners-toiminto toimii minkä tahansa liikkuvan kohteen, ei vain sankarin, kanssa.

Liiku

Kun tiedämme, minkä tyyppisiä laattoja kukin hahmon kulma on päällä, voimme helposti kirjoittaa liikkeen merkille: jos kaikki kulmat ovat käveleviä, siirrä, muuten älä liiku. Lisää työtä tarvitaan sankarin sijoittamiseksi seinän viereen, jos törmäys tapahtuisi. Modifioitu MoveChar-toimintomme käsittelemään kaikkia 4 mahdollista suuntaa saattaa näyttää hieman hämmentävältä, mutta suurin osa siitä on kirjoitettu 4 kertaa jokaiselle suunnalle. Katsotaanpa toimintoa:

function moveChar(ob, dirx, diry) {

getMyCorners (ob.x, ob.y+ob.speed*diry, ob);

if (diry == -1) {

if (ob.upleft ja ob.upright) {

ob.y += ob.speed*diry;

} muu {

ob.y = ob.ytile*game.tileH+ob.height;

}

}

if (diry == 1) {

if (ob.downleft ja ob.downright) {

ob.y += ob.speed*diry;

} muu {

ob.y = (ob.ytile+1)*game.tileH-ob.height;

}

}

getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);

if (dirx == -1) {

if (ob.downleft ja ob.upleft) {

ob.x += ob.speed*dirx;

} muu {

ob.x = ob.xtile*game.tileW+ob.width;

}

}

if (dirx == 1) {

if (ob.upright ja ob.downright) {

ob.x += ob.speed*dirx;

} muu {

ob.x = (ob.xtile+1)*game.tileW-ob.width;

}

}

ob.clip._x = ob.x;

ob.clip._y = ob.y;

ob.clip.gotoAndStop(dirx+diry*2+3);

ob.xtile = Math.floor(ob.clip._x/game.tileW);

ob.ytile = Math.floor(ob.clip._y/peli.tileH);

palauttaa (tosi);

}

Kuten ennenkin, moveChar-toiminto saa kohteen ja ohjeet havaituilta näppäimiltä. Rivi:

getMyCorners (ob.x, ob.y+ob.speed*diry, ob);

laskee pystysuuntaisen liikkeen kulmapisteet (kun diry ei ole yhtä suuri kuin 0). Kun olemme laskeneet kulmat, voimme käyttää kunkin laatan kävelykelpoisen ominaisuuden arvoja tarkistaaksemme, voiko sankari astua sinne:

if (diry == -1) {

if (ob.upleft ja ob.upright) {

ob.y += ob.speed*diry;

} muu {

ob.y = ob.ytile*game.tileH+ob.height;

}

}

Tämä koodilohko toimii ylöspäin liikkeessä. Kun ylänuolinäppäintä painettiin, diryn arvo = -1. Käytämme arvoja ob.upleft ja ob.upright, jotka on laskettu getMyCorners-funktiossa. Jos ne ovat molemmat “tosia” eli molemmat laatat ovat walkabale, annamme charin liikkua kuten teimme ennen kuin lisäämme speed*diryn charin y-ominaisuuteen.

Mutta jos yksi kulmista sattuu olemaan seinän sisällä ja niin ob.upleft tai ob.upright arvo on “false”, asetamme esineen lähelle seinää. Jotta char olisi seinän vieressä sen yläpuolella, sen keskipisteen tulee olla nykyisten laattojen yläreunan alapuolella char.height-arvon verran.

ob.ytile*game.tileH sijoittaisi hahmon keskipisteen kahden ruudun väliselle viivalle, lisäämme objektin korkeusominaisuuden siirtääksesi sitä alemmas. Samalla tavalla moveChar-toiminto käy läpi liikkeet alas (diry == 1), vasemmalle (dirx == -1) ja oikealle (dirx == 1).

Viimeiset rivit asettavat todellisen hahmoleikkeen laskettuun paikkaan, saavat hahmon näyttämään oikean kehyksen animaatiolla ja laskevat uudet arvot merkkien keskipisteelle (xtile, ytile). Aivan kuten ennenkin, funktio palauttaa “true”.

Voit ladata lähdekoodin ja kaikki koodit ja elokuvat täältä.