Eli teen alien phobia tyylistä peliä ja nyt törmäystarkistus kusee, olen miettinyt monta tuntia ongelmaa ja etsinyt putkan haulla ym.. mutta ei apua.
Eli aluksi kun tein, tyyppi menetti jatkuvasti energiaa, nyt se taas ei menetä enään yhtään, tarkotus on, että kun vihollinen osuu pelaajaan pelaaja menettää energiaa.
tässä se funktio
int px1,px2,py1,py2; int v1x1,v1x2,v1y1,v1y2; int v2x1,v2x2,v2y1,v2y2; void CheckCollinsion() { px1=ukko.GetX(); px2=px1+IMAGE_SIZE; py1=ukko.GetY(); py2=py1+IMAGE_SIZE; for(int i=0;1<ENEMIES;i++) { v1x1=viholliset[i].GetX(); v1y1=viholliset[i].GetY(); v1x2=v1x1+IMAGE_SIZE; v1y2=v1y1+IMAGE_SIZE; v2x1=vihulaiset[i].GetX(); v2y1=vihulaiset[i].GetY(); v2x2=v2x1+IMAGE_SIZE; v2y2=v2y1+IMAGE_SIZE; } if ((px1 < v1x1) && (px1 > v1x2) || (px2 < v1x1) && (px2 > v1x2) || (px1 > v1x1) && (px2 < v1x2) && (py1 < v1y1) && (py1 > v1y2) || (py2 < v1y1) && (py2 > v1y2) || (py1 > v1y1) && (py2 < v1y2)) { ukko.DecreaseEnergy(10); } if ((px1 < v2x1) && (px1 > v2x2) || (px2 < v2x1) && (px2 > v2x2) || (px1 > v2x1) && (px2 < v2x2) && (py1 < v2y1) && (py1 > v2y2) || (py2 < v2y1) && (py2 > v2y2) || (py1 > v2y1) && (py2 < v2y2)) { ukko.DecreaseEnergy(10); } }
for(int i=0;1<ENEMIES;i++)
Tuon ykkösen pitäisi varmaankin olla i
?
Koodi tarkistaa pelkästään, onko ukko viimeisen vihollisen/vihulaisen päällä, koska ylikirjoitat noiden vnxn
-muuttujien arvot joka kierroksella käyttämättä niitä mihinkään siinä välissä. Siirrä ehtolausekkeet for
-silmukan sisälle, jos haluat, että kaikkiin vihuihin törmäämisestä menettää energiaa.
Lisäys:
Myös nuo itse tarkistukset vaikuttavat todella epämääräisiltä. Eihän esim. (px1 < v2x1) && (px1 > v2x2)
voi koskaan olla tosi, vai onko IMAGE_SIZE
negatiivinen? Muista myös, että &&
tulee laskujärjestyksessä ennen kuin ||
.
Ei muuttunut mitenkään tuon toimivuus, eli ei vieläkään vie energiaa... Miten saisin silleen että ainakun vihollinen hipaisisia/osuisi kunnolla menettää energiaa? :O
Koska tarkistus ei ole silmukan sisällä, tarkistat törmäyksen vain sen vihollisen kanssa, jonka tiedot muuttujissa on silmukan päätyttyä. Lisäksi sijoitat muuttujiin v1* ja v2* samat arvot ja siis teet saman tarkistuksen kaksi kertaa. Ehtosikin on pielessä. Jos et muuten saa sitä kohdalleen, kannattaa ehkä valita käänteinen lähestymistapa eli miettiä, milloin ei törmää. Oikea ehtolause kahden palikan törmäyksestä sisältää nimittäin vain neljä vertailua.
Korjaa ensin kaikki mainitut asiat ja tule vasta sitten kyselemään lisää.
En sijoita toinen on vihulainen ja toinen vihollinen... ja mää kutsun tota funktioo pääloopista, sekä siirsin ton ehdon tonne forin sisään, mutta kokeilen vielä säätää.. :D
EDIT: IMAGE_SIZE = 32; eli on positiivinen.
vehkis91 kirjoitti:
En sijoita toinen on vihulainen ja toinen vihollinen...
Niinpä näköjään onkin. Mitä eroa näillä kahdella on, ja onko niitä varmasti yhtä monta? Jos niillä ei ole mitään tekemistä keskenään, olisi minusta semanttisesti oikein käsitellä ne silmukoissa. Jos niitä voi olla eri määrä, ohjelma voi tuollaisessa muodossa kaatua.
Koodin selkeyden vuoksi suosittelen tällaista lähestymistapaa:
void tarkista_kaikki() { for (int i = 0; i < MAARA; ++i) { tarkista_yksi(&otukset[i]); } // Ja kaikki muutkin tarkistettavat asiat omissa silmukoissaan } void tarkista_yksi(otusluokka *otus) { if (laatikot_osuvat(otus->laatikko, ukko.laatikko)) { // Seuraukset tänne (ukko.meneta_energiaa(otus->vaarallisuus)) } } bool laatikot_osuvat(laatikkoluokka const& a, laatikkoluokka const& b) { // Törmäystarkistus tänne, palautetaan tarkistuksen tulos. if (a.alareuna > b.ylareuna) return false; // a on ylempänä if (a.ylareuna < b.alareuna) return false; // a on alempana // ... return true; }
Aluksi voi tuntua, että tällaisesta funktiomäärästä syntyy hirvittävästi turhaa koodia, loppujen lopuksi koodista tulee äärimmäisen paljon selkeämpää, jolloin myös virheitä tulee vähemmän. Lisäksi tällä tavalla syntyy paljon monikäyttöisempää koodia: seuraavassa törmäyksiä käsittelevässä kohdassa ei tarvitsekaan miettiä ja kirjoittaa ehtoja uudestaan, vaan voi käyttää valmista funktiota "laatikot_osuvat". Myös kommenttirivejä säästyy, kun koodissa lukee suoraan selkeästi "if (laatikot_osuvat(...))
" eikä "if (ax < bx || ax2 > bx2 || ... && ... ...)
". Voit itse miettiä, tuntuuko selkeämmältä sijoittaa funktioita noin irralleen vai luokkien sisään; esimerkissä voisi hyvin lukea myös "if (ukko.laatikko.osuu(otus->laatikko))
".
Kiitos, muutan systeemin tämän mukaiseksi, niin on paljon helpompi lisätä uusia juttuja, ja koodia on paljon selkeämpää.. :D
Tuo systeemi on ihan kätevä vihollisia käsiteltäessä, mutta vihollisten ja pelaajan törmäyksiä ei voi testata noin, koska viholisilla on oma luokkansa ja pelaajalla omansa, näin ollen en voi tunkea niitä samaan taulukkoon. Muuten oisinkin tehnyt saman tyylisen systeemin, kuin sinun koodivinkissäsi on.
[offtopic]
onko
otus->laatikko
sama asia kuin
otus.laatikko
?
[/offtopic]
Edit: Tai sitten en vain ymmärtänyt tuota oikein. :(
Edit2: Muutin kuitenkin silleen, että kaikki viholliset ovat samassa taulukossa, koska silloin niitä on helpompi hallita. :D
otus->laatikko ja otus.laatikko ovat sikäli samat, mutta "nuolioperaattori" on lyhennemerkintä merkinnälle (*otus).laatikko, eli sillä siis söhitään pointterin osoittamaa oliota.
vehkis91 kirjoitti:
Tuo systeemi on ihan kätevä vihollisia käsiteltäessä, mutta vihollisten ja pelaajan törmäyksiä ei voi testata noin, koska viholisilla on oma luokkansa ja pelaajalla omansa, näin ollen en voi tunkea niitä samaan taulukkoon. Muuten oisinkin tehnyt saman tyylisen systeemin, kuin sinun koodivinkissäsi on.
Miksi niitä ei voi ulkopuolisella funktiolla tarkastaa törmäystä? Annat parametrinä kummankin (pelaaja & vihu) viitteet tarkastusfunktiolle
tarkastaKaikki(&pelaaja, &vihu);
Juu, niinpäs näkyykin. :D En vaan tarvi noita viittauksia, koska viholliset ja kaikki muutkin oliot on luotu funktioiden ulkopuolella. :D
Nyt sain ton törmäystarkistuksen pelaan kiitos vinkeistä. :D:D:D
Aihe on jo aika vanha, joten et voi enää vastata siihen.