Joo eli olen tehnyt tässä omaap eliä ja tein sille täysin oman kartta formaatin. Eli siis mappi formaatti käyttää tilesettejä. Nytten olen tekemässä tormaystunnistus pintaa. Eli jos palikan tyyppi on 2 nii sitten siihen törmätään. Noh olen saanut tehtyä jonkinlaisen törmäyksen tunnistuksen, mutta aina on bugi ilmentynyt. Joskus tormäyksen tunnistus pettää ja joskus se taas tulee esille kun sitä ei tarvita. Eli siis tarkoitus olisi, saada 32x32 palikalle täydellinen törmäyksen tunnistus. Eli jos pelaaja osuu niin se ei mene läpi vaan törmää. Itse sain tehtyä tämän jotenkin, mutta tosiaanki välillä ukkon vauhti oli niin suuri, ettei ukko keretty pysäyttää ja se liukui kappaleen sisälle. Miten tämä tulisi toteuttää niin, että pelaaja ei joutuisi kappaleen sisälle?
Eikös tuo nyt ole aika simppeliä. Tarkistetaan ennen ukon siirtämistä että onko ukkopalikan minkään kulman uusi siirron jälkeinen sijainti seinäpalikan sisällä ja jos menee niin siiretään ukko vain sen verran ettei se mene seinänä sisään.
Minulla on vähän saman tyylinen projekti menossa.
joo, itsekkin luuni että tuo on todella simppeli, mutta kun tuossa pitää ottaa niin paljon asioita huomioon , vetovoima jne jne. Eli ei mee tolla pelkästään.. Toki se toimi, mutta bugeja ilmeni.
Edit1: Tai oikeestaan tein niin, että jos painetaan esim vasemmalle, jos ukko törmää seinään, niin sitten liikuta = false ja ukkoa ei sitten liikuteta. ja tänä bugasi minulla, koska vauhti kertaantuu aina sitä lujemmaksi mitä korkeemmalta ukkoa putoaa, koska vetovoima kerrotaan sen painolla. Esim jos ukko on ilmassa olevan palikan päällä ja hyppää siitä maahan, nii sitten vauhti on niin luja, että se kerkee liikkua palikan seinän yli. Sitten pitää muistaa myös, että vetovoima vaikuttaa koko ajan
Sittenhän pitää vain tuo osuman tarkastinen tehdä aina 32 pikselin välein.
Elikkäs. Jos liikuttava määrä on enemmän kuin 32, tarkastetaan että voiko ukko liikkua 32 pikseliä. Jos voi liikkua, niin liikutaan ja taas tarkastetaan kunnes on liikutte halutta määrä. Jos ei voi liikkua koko 32 pikseliä liikutaan vain sen verran kuin voi ja jäädään siihe.
hmm, tuota meinasitko, että laitan for silmukaan 32 eli jos for(i = 0; i < 32; i++) ja mitä sitten?
Edit itse olen tehnyt tähän mennessä sen x y sijaineilla. Eli jos esim pelaaja.x+leveys > box.x sitten esim törmätään.
Höpö höpö Nail Eye!
Screenillä se ukko ei siirry yhtään mihinkään positioon, jos sitä ei siirretä eli piirretä...
// määrittele esim. public int max = 500 - ukko.width; //... int vastukset = (tuulet + sun_muut_kertoimet); if((kuljettu + (32 - vastukset)) < max) for (i=0; i < (32 - vastukset); i++){ ukko.x += i; } else for(i=0; i < (max -(kuljettu - vastukset)); i++){ ukko.x += i; } kuljettu += i; //...
ööh, eli tuossahan ukko pystyy vain liikkumaan hetken eteenpäin, kunnes törmää seinään, mutta jos eessä onkin palikka ja sen yli hypätään tai ollaan ylempänä, sitten kuljettu muuttuja voi olla suurempi kuin tuo max.
Edit1: Olet oikeassa että pelaajan sijaintia ei muuteta, mutta mapin sijaintia kylläkin. Eli kun liikutetaan kaikki palikoita, näin ollen palikoitten sijainti muuttuu. Eli minulla on taulukko mikä sisältää jokaisen kartassa olevan kuution x ja y:N eli eikös kannattaisi mieluummin käyttää hyväksi x ja y koordinaatteja?
Heippa taas Nail Eye!
Ehdottomasti myös z-koordinaatti käyttöön...
Hmm, Z? mitä teen z Koordinaatilla 2D grafiikassa? Mut taisin keksiä yhden tavan kokeilen sitä jos ei toimi, nii kysyn taas apua.. :D
Ensin vaikkapa lasketaan nopeuden perusteella, paljonko pitäisi liikkua, sitten liikutaan tähän malliin:
while (koko_liikuttava_matka > 0) { // Jos pitäisi liikkua yli ruudun verran, liikutaan vain yksi ruutu, muuten sen oikean verran. Voi toki pienentää vaikka pienimmän mahdollisen objektin kokoiseksi (tai yhtä alle). if (koko_liikuttava_matka > 32) { kerralla_liikuttava_matka = 32; } else { kerralla_liikuttava_matka = koko_liikuttava_matka; } // Vähennetään jäljellä olevasta matkasta tämä nyt liikuttava koko_liikuttava_matka -= kerralla_liikuttava_matka; // Ja sitten voit ihan normaalisti tarkistaa törmäyksen (liikutaan siis kerralla_liikuttava_matka), siis aivan kuten ennenkin. }
Joo, eli tässä on kuva mapista johon pitäisi saada törmäuyksen tunnistus.
Joo, eli tee niin, kuin neuvottiin.
Tota sovelsin näin, en tie onko oikein :P.
if(nappi[SDLK_RIGHT]){ t_map[id].tormaa = t_map[id].x - (pelaaja.x + abkuva->w + 32); while(t_map[id].tormaa > 0){ if(t_map[id].tormaa > 32){ kerralla_l_m = 32; }else{ t_map[id].tormaa = kerralla_l_m; } t_map[id].tormaa -= kerralla_l_m; if(pelaaja.x < t_map[id].x){ if(pelaaja.x+abkuva->w >= t_map[id].x){ }else{ //Liikuta oikealle liikuta_pe(false); } } } }
Katsopa uudestaan, missä kohti oli se kokonaismäärä ja missä se kerralla liikuttava. Koodissasi on äärimmäisen epälooginen nimeäminen muuttujilla (mikä ihmeen "törmää", liikemäärähän se on), mutta kaiketi siis toisella rivillä pitäisi olla se uusi muuttuja kokonaisliikkeelle, ja tuo joku.tormaa olisi se kerralla liikuttava.
Meinaatko, että pelaaja liikuu joka napin painauksen jälkeen 32px?
Ei, kun pelaaja liikkuu joka napin painalluksen jälkeen niin paljon kuin sen kuuluukin liikkua, mutta tämä liikkuminen tehdään vain 32px:n pätkissä.
joo tuota tietoa hain. No entäpä tuo, kun while (koko_liikuttava_matka > 0) { jos ukkoa ei liikutetakkaan 32 pixeliä, vaan ukko päättääki puolessa välissää vaihtaa suuntaa, niin sitten ohjelmahan jää ikuiseen loopiin? Koska koko_liikuttava_matka ei koskaan saavuta 0.
Silloin sinne täytyy laittaa jotain joka pistää sen nollaksi. Tai sitten kiellät ukkoa vaihtamasta suuntaa.
Tuo sinun systeemisi on hieman oudon näköinen. Mistä tuo liikuta_pe() saa edes tietää että kuinka paljon liikutetaan? Onko kerralla_l_m globaali ?
Tuota nytten koodi on tämän näköinen
int koko_liikuttava_matka; int kerralla_liikuttava_matka; koko_liikuttava_matka = t_map[id].x - (pelaaja.x + abkuva->w); if(nappi[SDLK_RIGHT]){ while (koko_liikuttava_matka > 0) { if (koko_liikuttava_matka > 32) { kerralla_liikuttava_matka = 32; } else { kerralla_liikuttava_matka = koko_liikuttava_matka; } koko_liikuttava_matka -= kerralla_liikuttava_matka; liikuta_pe(false,koko_liikuttava_matka); } }
mutta tuossahan on ainakin yksi risti riita, meinaan kun kuutio taulukkoa käydään läpi, niin jos vaikka 230 poksi "sanoo", että koko_liikuttava_matka on 0, niin sittenhän seuraava eli 231 "sanoo", että koko_liikuttava_mata == 32 ja pelaaajaa voidaan taas liikuttaa, ja sittenhän se menee tuon 230 laation läpi?
Miksi siinä edes käydään koko kenttä läpi?
Ootapa hetki niin viimeisteleen vielä koodiani jonka pitäisi edes näyttää sellaiselta että se tarkistelee törmäyksiä.
Edit:
Tuolta pitäisi näyttää törmäyksiä tarkistava koodi:
Tuossa on varmaa jonkin verran virheitä kun en voi testata.
int koko_liike_x, koko_liike_y, liike; if(nappi[SDLK_LEFT]) koko_liike_x=-1*ukon_kävely_nopeus; else if(nappi[SDLK_LEFT]) koko_liike_x=ukon_kävely_nopeus; //TÄSTÄ PUUTTUU TIPPUMISEN ALKUUN LÄHTÖ JA VAUHDIN KASVU! //korkeus suuntainen tarkistus while(koko_liike_y != 0) { if(koko_liike_y > 32 )// ylös liike_x=32; else if(koko_liike_y < -32) // alas liike_y=-32; else liike=koko_liike_y; koko_liike_y-=liike; if(pelaaja.y+liike+32 > t_map[ruutu_joka_on_ukon_alla].y)//ukko menee ainakin osiittain alla oleviin ruutuihin if(/*ruutu jonka alueella on ukon vasen alakulma (pelaaja.x,pelaaja.y+liike+32)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea alakulma(pelaaja.x+32,pelaaja.y+liika+32)*/ == /*seinä*/) { liike=t_map[ruutu_joka_on_ukon_alla].y-pelaaja.y+32; koko_liike_y=0; } else ifpelaaja.y+liike < t_map[ruutu_joka_on_ukon_yllä].y+32)//ukko menee ainakin osiittain yllä oleviin ruutuihin if(/*ruutu jonka alueella on ukon vasen yläkulma (pelaaja.x,pelaaja.y+liike)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea yläkulma(pelaaja.x+32,pelaaja.y+liike)*/ == /*seinä*/) { liike=pelaaja.y-t_map[ruutu_joka_on_ukon_yllä].y+32; koko_liike_y=0; } //liikuta pelaaja y akselilla liike muuttujan verran } //sivuttais suuntainen tarkistus while(koko_liike_x != 0) { int liike; if(koko_liike_x > 32 )//oikeaan liike=32; else if(koko_liike_x < -32) // vasempaan liike=-32; else liike=koko_liike_x; koko_liike_x-=liike; if(pelaaja.x+liike < t_map[ruutu_joka_on_ukon_vasemmalla].x+32)//ukko menee ainakin osiittain vasemmalla oleviin ruutuihin if(/*ruutu jonka alueella on ukon vasen yläkulma (pelaaja.x+liike,pelaaja.y)*/ == /*seinä*/ || /*ruutu jonka alueella on vasen alakulma(pelaaja.x+liike,pelaaja.y+32)*/ == /*seinä*/) { liike=pelaaja.x-t_map[ruutu_joka_on_ukon_vasemmalla].x+32; koko_liike_x=0; } else if(pelaaja.x+liike+32 > t_map[ruutu_joka_on_ukon_oikealla].x)//ukko menee ainakin osiittain oikealla oleviin ruutuihin if(/*ruutu jonka alueella on ukon oikea yläkulma (pelaaja.x+liike+32,pelaaja.y)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea alakulma(pelaaja.x+liike+32,pelaaja.y+32)*/ == /*seinä*/) { liike=t_map[ruutu_joka_on_ukon_oikealla].x-pelaaja.x+32; koko_liike_x=0; } //liikuta pelaaja x akselilla liike muuttujan verran }
Heippa taas!
Minusta tässäkin kannattaisi nyt ruveta soveltaamaan sen QBASIC (DOS 5.0) mukana tulevan apinajutun oppeja ballistisista kuvioista, jos on kerran tarve alkaa hyppimään esteiden yli ja vielä vastatuuleen...
Vastatuuleen? Ei pelissä ole vasta tuulta. :D Vain painovoima!
Missä esim, tuo liike_x määritellään?
Tai saadaanko ruutu_joka_on_ukon_alla
t_map[ruutu_joka_on_ukon_alla].y
selvitettyä niin, että esim.
if(pelaaja.y+korkeus > t_map[i].y && pelaaja.x < t_map[i].x+32 && pelaaja.x+leveys > t_map[i].x)
Itse löysin tälläseen törmäyksen tunnistus funktion googelin avulla.
//Itse funktio int SDL_CollideBoundingBox(SDL_Surface *sa , int ax , int ay , SDL_Surface *sb , int bx , int by) { if(bx + sb->w < ax) return 0; //just checking if their if(bx > ax + sa->w) return 0; //bounding boxes even touch if(by + sb->h < ay) return 0; if(by > ay + sa->h) return 0; return 1; //bounding boxes intersect } if(SDL_CollideBoundingBox(abkuva,pelaaja.x,pelaaja.y , tset,t_map[id].x,t_map[id].y)){ kimpoaa = true; vauhti = 0; }
Tämä toimii nytten niin kuin pitää...
Aihe on jo aika vanha, joten et voi enää vastata siihen.