Kyseessä on siis eräs projektini, mutta yksi pieni ongelma tuli ilmi, ja nyt pohdin, kumpi näistä nyt on syypää? Lopputuloksena pitäisi saada pelaaja ampumaan yhden luodin jokaisella hiiren painalluksella (näin alkuun). Muutenhan olenkin hyvin sillä suunnalla, mutta tuntuu että hiiren painalluksiin ei aina reagoida, eli vaikka painat, mitään ei tapahdu. Ja välillä kun taas painaa, ammutaan normaalisti ja juuri niin kuin haluankin. Näytetäänpäs koodia...
//mouse_c on tietysti SDL_Event while(SDL_PollEvent(&mouse_c)) { switch(mouse_c.type) { case SDL_MOUSEBUTTONDOWN: //tarkistetaan ettei ammuta jo ennestään, ja painetaan vasenta hiiren nappia if(mouse_c.button.button == SDL_BUTTON_LEFT && canshoot == false) { //annetaan tulituskäsky... canshoot = true; } break; } } //käsky käy... if(canshoot == true) { //aloitetaan inventoryn selaaminen for(inventoryitem = inventoryitems.begin(); inventoryitem != inventoryitems.end(); ++inventoryitem) { //etsitään esine joka on varustettu käyttöön if(inventoryitem->equip == true) { //... //tietynlainen ase löytyi, tässä tapauksessa pistooli if(inventoryitem->pre_id == 8) { //selataan toisella selaajalla inventory uudestaan, ja etsitään sopivia panoksia for(inventoryitem_alt = inventoryitems.begin(); inventoryitem_alt != inventoryitems.end(); ++inventoryitem_alt) { //tarkistetaan onko esine ammuksia, ja onko niitä ammuttavaksi, pre_id on numero jolla tunnistetaan mikä ase on kyseessä if(inventoryitem_alt->ammo && inventoryitem_alt->pre_id == 1 && inventoryitem_alt->capacity > 0) { //luodaan luoti bullets.push_back(Bullet((int)x, (int)y, angle)); //vähennetään ammuksien määrää yhdellä inventoryitem_alt->capacity -= 1; //tulituslupa perutaan canshoot = false; break; } } } } } }
Koodiin kommentoitu kaikki tarpeellinen. Tämä sijaitsee pelaajan "input"-metodissa, jossa siis kaikki näppäinkomennot käsitellään, kuten liikkuminen, tässä tapauksessa hyökkääminen/ampuminen.
Kumpi siis tässä on vikana, hiiri, vai selaaminen? Itse epäilisin hiirtä, sillä muutaman kokeilun jälkeen huomasin ettei se ota vastaan painalluksia, vaikka loppua koodia tai mitään estoja ei olisikaan. Jos jotain muita ratkaisumalleja tulee mieleen niin otan mielellään vastaan.
Kyllä tuo hiiren luku on ihan oikein. Ongelmaksi ilmeisesti muodostuu muun ohjelman hitaus.
Kokeileppa siten, että painat hiirtä rauhallisesti, eli pidät hiirtä joka painalluksella pohjassa vaikka puoli sekuntia. Tällöin ohjelman pitäisi reagoida jokaiseen painallukseen.
Ja mahdollisia ajatuksia kuinka nopeuttaa tuota selausta:
a) pidät varustettuna olevat tavarat erillään jolloin ei tarvitse selata koko listaa löytääksesi varustettuina olevat tavarat.
b) sensijaan että selaat kaikki tavarat ammusten varalla pistä aseeseen ammusmäärä(vaikkapa lippaan koko). Jos tuo sitten tyhjenee niin SITTEN selaat inventaarion uusiksi(etsit uutta lipasta esmes). Luulisi vähentävän selausta(tietty jos inventaario on pieni niin sitten ei pitäisi olla merkittävää haittaa).
Ja sivuhuomautuksena kai tuo canShoot menee falseen muutenkin kuin ammuksen tapahtuessa? Nyt esmes tuollaisenaan jos ammuksia puuttuu ei ammu mutta canShoot edelleen on true joten jos saat ammuksia ampuu se "itsestään". Luultavasti olet vain sniputtanu tuon koodin veks mutta kunhan tarkistin.
Tuo selaaminen tuskin on niin hidasta, että aiheuttaa ongelmia. Sen sijaan esimerkiksi piirtopuolella optimointi saattaisi olla tarpeen.
Inventory on aina maksimissaan 10 esineen kokoinen, ja testaillessa se määrä on yleensä 3 (pistooli, ammuksia, muu). Yksi tapa tietysti selaamisen nopeutukseen olisi luoda selaaja, joka jää aina kohtaan jossa on varustettu esine (ja jota ei käytetä siis ollenkaan selaamiseen vaan varustetun esineen osoittamiseen). Tällöinhän se varustettu esine löydettäisiin samantien. Mutta epäilen ettei tälle ole tarvetta...
Mutta ei, hiiri ei reagoinut ollenkaan vaikka painoin hieman pidempää. Ja sitten välillä myös reagoi saman tien.
Piirtopuolen optimointia rupesin juuri värkkäilemään, nimittäin kokemuksesta on todettava että jatkuva pintojen vapauttelu ja latailu syö nopeutta. Niinpä päätin toteuttaa tämän pelaajan kuvan muuttamisen animaationa, mutta tällä hetkellä ongelmana on sitten kuvan kääntäminen (animointi Lazy Foo' Productionsin esimerkin avustuksella), sillä tämä isompi kuva kääntyy, mutten tiedä miten saisin tämän halutun alueen ainoastaan kääntymään.
Debuggauksen perusteet: laita jokaiseen iffiin ja foriin jotain informatiivista tulostusta mukaan:
// Joka kerta kerrotaan aluksi myös aika, niin selviää pelin FPS. std::cout << std::endl; std::cout << SDL_GetTicks() << std::endl; if (canshoot) { std::cout << "canshoot: true" << std::endl; for (...) { std::cout << "item: " << esinetietoja << std::endl; //... } }
On tuotakin yritetty tutkailla, mutta FPS:ää en ole tutkinut. Tässä pätkä tulkittavaksi:
lainaus:
FPS: 9832
FPS: 9841
canshoot: true
item: name - Axe
item: name - Pistol Ammo
item: name - Pistol
FPS: 9856
FPS: 9873
FPS: 9889
Itse en ainakaan näe mitään sen erikoisempaa...
Eräs asia tuli myös kokeiltua. Mitä jos ei tarkistetakaan nyt ihan testausmielessä että onko ammuksia? Eli suoraan pre_id:n tarkistuksen jälkeen lähetetään luoti. Lopputuloksena oli kyllä sama kuin ilman tätä kokeilua, eli ampuminen on satunnaista. Äsken myös kevensin ainakin omasta mielestäni asioiden piirtelyä, mutta vaikutusta ei paljoa näkynyt.
Gaxx kirjoitti:
Kyllä tuo hiiren luku on ihan oikein. Ongelmaksi ilmeisesti muodostuu muun ohjelman hitaus.
Siis että pyöritään event-luupissa niin kauan kuin mitä tahansa eventtejä on saatavilla. Sitten kun mitään tapahtumia ei enää tule, katsotaan, tarttuiko haaviin ampumiskomento. Näinkö on meininki?
Jos nuo ampumavehjelistat ovat tavanomaisia otuksia, niin niiden läpikäyntiin menee aikaa arviolta silmänräpäyksen murto-osa.
Pätkän tulkinta: Ajoista (joiden eteen olet tosin virheellisesti tulostanut "FPS") nähdään, että FPS on sadan paikkeilla, joten ainakaan piirtokoodin hitaus tms. ei tässä ole ongelmana. (Harvoin on muutenkaan, kun kuitenkin tuossa nyt haetaan klikkaus eikä sitä, onko hiiri yhä pohjassa; ampumisen pitäisi tapahtua joka tapauksessa seuraavalla framella. Taisi jäädä Gaxxilta huomaamatta.)
Pätkän tulkinnan puutokset: Et tulostanut tarpeeksi tietoja, joten pätkästä ei selviä, mihin kohti homma katkeaa eli löytyykö ase, löytyvätkö panokset, onko panoksia ja luodaanko Bullet-olio. Eipä kai tullut tarpeeksi suoraan sanottua.
Jos Bullet aina luodaan, kannattaakin ruveta tutkimaan, minne se menee ja mitä sille tapahtuu. Luultavammin virhe on tässä. Voisitkin testimielessä kokeilla, ettet vaivaudu etsimään edes asetta:
if (canshoot) { canshoot = false; std::cout << "Bang! pos: (" << x << ", " << y << "); angle: " << angle << std::endl; bullets.push_back(Bullet((int)x, (int)y, angle)); }
Onko int-muunnokselle muuten jokin järkevä syy? Uskoakseni se ei ole millään tavalla tarpeen.
koo kirjoitti:
Siis että pyöritään event-luupissa niin kauan kuin mitä tahansa eventtejä on saatavilla. Sitten kun mitään tapahtumia ei enää tule, katsotaan, tarttuiko haaviin ampumiskomento. Näinkö on meininki?
Kyllä, näin on meininki. Loogisempaa olisi tietysti sijoittaa tapahtumien käsittely jonnekin aivan muualle kuin pelaajaa kuvaavaan luokkaan — esimerkiksi pelin pääsilmukkaan. Täällä sitten tulkattaisiin jo valmiiksi napinpainallukset toiminnoiksi ja syötettäisiin pelaajille, ja samalla tavalla voitaisiin syöttää myös tekoälyn komennot tekoälypelaajille.
Metabolix kirjoitti:
Onko int-muunnokselle muuten jokin järkevä syy? Uskoakseni se ei ole millään tavalla tarpeen.
No ei oikein kummoista syytä, mutta Bullet-olion x ja y arvot ovat double (vaikkei oikeastaan tarvitsisi olla mutta jostain syystä olen näin tehnyt) ja pelaajan int. Tästä syystä ainakin Dev-C++:lla tuli warning-viesti, jonka halusin pois.
Tässä taas vähän monipuolisempi tuloste:
lainaus:
8271
8286canshoot: true
canshoot: true
canshoot: true
Pistol löytyi
Pistol Ammo löydetty
ammus lähetetty
ammuksia jäljellä: 28
8303
8318
8334
8350
ammus tuhottu
8370
8382
Ensimmäiset canshootit tulevat tietysti toisista esineistä.
Ja tässä Bullet-olion seurantaa:
lainaus:
9668
9686
Bullet - pos: (246,193) angle: 20
9701
Bullet - pos: (359,248) angle: 20
9717
Bullet - pos: (472,304) angle: 20
9733
Bullet - pos: (586,360) angle: 20
9751
ammus tuhottu
9766
9785
Selvästikkään vika ei ole selaamisessa, jo tämä Bullet-olion luominen oli satunnaista.
Metabolix kirjoitti:
(Harvoin on muutenkaan, kun kuitenkin tuossa nyt haetaan klikkaus eikä sitä, onko hiiri yhä pohjassa; ampumisen pitäisi tapahtua joka tapauksessa seuraavalla framella. Taisi jäädä Gaxxilta huomaamatta.)
Ajattelin ongelman olevan siinä, että jos hiiri ehditään painaa alas ja nostaa ylös ennen, kuin viestejä tutkitaan seuraavan kerran, alaspainaminen jää ylösnoston varjoon. Näin se tuntui toimivan minulla, kun lisäsin viivettä looppiin.
koo kirjoitti:
Siis että pyöritään event-luupissa niin kauan kuin mitä tahansa eventtejä on saatavilla. Sitten kun mitään tapahtumia ei enää tule, katsotaan, tarttuiko haaviin ampumiskomento. Näinkö on meininki?
Joo, ei ole kovin fiksu tapa, mutta se tuskin on ongelman ydin.
Ps. Olen usein viritellyt noita SDL:n eventtikäsittelyitä, mutta niissä on aina tullut jotain käsittämättömiä ongelmia, joten olen päätynyt käyttämään omia systeemejä, menestyksekkäästi.
Gaxx kirjoitti:
Ajattelin ongelman olevan siinä, että jos hiiri ehditään painaa alas ja nostaa ylös ennen, kuin viestejä tutkitaan seuraavan kerran, alaspainaminen jää ylösnoston varjoon. Näin se tuntui toimivan minulla, kun lisäsin viivettä looppiin.
Varmuuden vuoksi vielä testasin asian, ja kyllä minulla ainakin jäävät klikkaukset kiltisti odottamaan — jopa useampi kerralla eikä vain viimeinen.
erakko- kirjoitti:
9686
Bullet - pos: (246,193) angle: 20
9701
Bullet - pos: (359,248) angle: 20
9717
Bullet - pos: (472,304) angle: 20
9733
Bullet - pos: (586,360) angle: 20
9751
No eikös tämä jo kerro ongelman ytimen aika hyvin? Panoksesi lentää 47 millisekunnissa eli 0.047 sekunnissa x-suunnassa 340 ja y-suunnassa 167 pikseliä. Ei siis ihme, jos et ehdi sitä kovin hyvin huomata. Jos hidastat sen vauhdin noin kymmenesosaan nykyisestä, saatat päästä paremmin perille sen liikkeistä.
Perustelusi int-muunnokselle meni nyt jossain kohti pieleen, nimittäin väitit juuri, että int-arvo täytyy muuttaa int-tyyppiseksi (kuten se jo ennestään on), jotta kääntäjä ei varoittaisi siirrosta doubleen (joka pystyy hyvin sisältämään minkä tahansa int-arvon).
Metabolix kirjoitti:
Perustelusi int-muunnokselle meni nyt jossain kohti pieleen, nimittäin väitit juuri, että int-arvo täytyy muuttaa int-tyyppiseksi (kuten se jo ennestään on), jotta kääntäjä ei varoittaisi siirrosta doubleen (joka pystyy hyvin sisältämään minkä tahansa int-arvon).
Siis Bullet-oliolla on double-tyyppiset x ja y muuttujat, pelaajalla nämä ovat int. Eihän se nyt olekkaan niin tarpeellinen, mutten välittäisi katsoa warning-viestiä siitä (g++ ei tosin sano mitään...).
Metabolix kirjoitti:
No eikös tämä jo kerro ongelman ytimen aika hyvin? Panoksesi lentää 47 millisekunnissa eli 0.047 sekunnissa x-suunnassa 340 ja y-suunnassa 167 pikseliä. Ei siis ihme, jos et ehdi sitä kovin hyvin huomata.
Mutta silti näen Bullet-olion piirtämän kuvan, ja parit tulosteetkin kertovat etten ole missannut yhtäkään (en usko että ne sitä osaavat ohittaa). Jos yhden luodin näen, miksen näe siis toistakin ja tästä ei jää mitään tulosteita?
Ajattelinpa nyt hieman muokata koodiani suosituksienne mukaan, ja siirsin hiiren painalluksen lukemisen pääsilmukkaan (samaan kuin Esc-napilla sulkeminen jne). Ja kylläpäs se muuttikin tilannetta. Nyt panokset ilmestyvät jokaisella napin painalluksella, mutta viiveellä (selaaminen kuitenkin hidastaa?), ja tällä kertaa ampumista ei siis ole rajoitettu niin että yksi luoti per yksi painallus, vaan nappia pohjassa pitämällä pääsee eroon kaikista ammuksista. Vaikka periaatteessahan tämän pitäisi olla jo estetty juttu.
Metabolix kirjoitti:
Varmuuden vuoksi vielä testasin asian, ja kyllä minulla ainakin jäävät klikkaukset kiltisti odottamaan — jopa useampi kerralla eikä vain viimeinen.
Noin sen luulisi toimivankin, oma testini ei ollut mikään idioottivarma. En jaksa enää testailla, joten luotan tulokseesi :)
Koska en pysty tarkastamaan, niin voiko joku korjata, jos päättelen jotain väärin:
Buttondowneja tulee niin kauan, kun nappi on pohjassa. Kun nappi nousee, tulee yksi buttonup. Alkuperäisessä silmukassa "löydetään" ensimmäinen buttondown. Myöhemmin tulee vielä buttonup, mutta silmukassa pysytään, kunnes ei tule enää mitään, ei downeja, ei uppeja, ei moveja tms. Tähän voi mennä paljonkin aikaa. Lopulta tarkastellaan ampumavehkeitä. Kohtuullisilla tietomäärillä tarkastuksiin ei mene aikaa paljon mitään. Ammusten piirtelyyn aikaa voi kulua (koodi ei näkyvillä), samoin ammukset saattavat mennä ruudulla niinkin vikkelään, ettei niitä kunnolla näe.
Kun event-luuppirakennetta muutettiin (tarkalleen ottaen miten?), tilanne muuttuikin merkittävästi. Nyt kaikki buttondownit ryhtyivät ampumaan, mutta laukauksissa näyttää olevan käsittelyviive.
Onko tuossa alkuperäisessä luupissa tosiaankin oikea meininki? Miksei yhtä hyvin käytetä buttonup-eventtejä ampumiseen?
Eikö niitä ammuksia tosiaan kannattaisi hidastaa edes testiä varten, jotta visuaalinen tulkinta olisi varmasti oikea?
koo: Hiiri ei tuota kuin yhden buttondown-tapahtuman. (Näppäimistö tuottaa useita, mutta tälle onkin selvä peruste. Hiiren kohdalla vastaavassa ei olisi erityisesti järkeä.) Viestisilmukka ei myöskään kestä kauan, koska se ei odota viestejä vaan katsoo, onko niitä tullut. Tämä tarkistus vie sen mainitun "silmänräpäyksen murto-osan", jonka aikana viestejä harvoin ehtii paljon lisää tulla. Jos viestejä tulisi niin tiheästi usean millisekunnin ajan, olisi kone varmasti jo aivan jumissa noihin viesteihin tarvittavista laitteistokeskeytyksistä ja prosessinvaihdoista eikä peli pyörisi, vaikka viestit käsiteltäisiin millä tavalla.
Viestien käsittelyyn ei muutenkaan ole kuin nämä kaksi tapaa: joko viestejä odotetaan (kuten passiivisissa, tapahtumapohjaisissa ohjelmissa) tai ne käsitellään joka ohjelman kierroksella (kuten yleensä ohjelmissa, joissa asioita tapahtuu silloinkin, kun käyttäjä ei tee mitään). WinAPI tarjoaa käytännössäkin funktiot juuri näille tavoille: WaitMessage odotukseen, PeekMessage odottavien tarkistukseen ja hakuun. Tässä käytetty viestienkäsittelytapa on siis aivan oikea: viestit käsitellään, olennaiset tiedot otetaan muistiin (tässä canshoot-muuttuja) ja itse toiminnot suoritetaan myöhemmin.
Se virhe, johon teksteissäsi viittaat, tapahtuisi vain, jos esimerkiksi ampumiskoodi olisi tässä sijoitettu viestienkäsittelysilmukan sisään. Tällöin painalluksia voisi periaatteessa ehtiä jonoon useita. On tälläkin foorumilla nähty surullisia esimerkkejä, joissa viestisilmukkaan on sijoitettu while-silmukka, jossa piirretään panoksen liike ruudun poikki SDL_Delay-funktiolla tauotettuna — ja sitten ihmetellään, miksi peli pysähtyy ampumisen ajaksi. Tämä on toki äärimmäinen esimerkki, mutta tarkoitukseni on sanoa, että tällä kertaa kysyjän viestisilmukka on ainakin tässä nähdyn koodin perusteella aivan mallillaan.
Napin painaminen taas on nostamista loogisempi paikka ampumiselle, koska lähteehän pyssynkin panos yleensä liipasinta painaessa eikä nostaessa.
Alkuperäiselle kysyjälle täytyy vielä ihmetellä, miksi inventorio on pitänyt tehdä, ennen kuin panoksetkaan lentävät oikein. Kannattaa pelinteossakin lähteä liikkeelle perusasioista ja tehdä siis ensin toimiva objektijärjestelmä, siis piirto, liikkuminen ja törmääminen.
Metabolix kirjoitti:
Alkuperäiselle kysyjälle täytyy vielä ihmetellä, miksi inventorio on pitänyt tehdä, ennen kuin panoksetkaan lentävät oikein. Kannattaa pelinteossakin lähteä liikkeelle perusasioista ja tehdä siis ensin toimiva objektijärjestelmä, siis piirto, liikkuminen ja törmääminen.
Tähän voin vedota vain huonolla suunnittelulla, olen kokonaisuutta suunnitellut mutten ole ajatellut missä järjestyksessä tietyt asiat hoidetaan (tietysti jollain tapaa "loogisessa" järjestyksessä). Pelaajan ominaisuuksista kokonaisuus lähti liikkeelle, mutta jatkossa taidan miettiä näitä asioita enemmän.
Ok, olen valaistunut. En ole hirveästi SDL:ään perehtynyt. Päättelyni hiiren buttondowneista ja -upeista on väärä, ja se, että nappia pohjassa pitämällä pääsee eroon kaikista ammuksista, olikin vähän eri juttu. Luupissa pitäisi siis oikeasti tutkia sekä buttondownit että -upit, jotta liipaisu menee oikein.
Wait on toki eri juttu kuin Peek tai Poll. Vaikka viestejä tulisi taukoamatta millisekuntien ajan, ei kone helposti ihan polvilleen mene. Kyllähän esimerkiksi mousemove-eventtejä tulee joskus aika lailla - ainakin WinAPI:ssa - ja ihan käyttistason prosessivaihtojakin ehditään tehdä sekunnissa satoja tai tuhansia. Mutta tuon event-luupin suoritus on niin nopea, että todennäköisesti esimerkiksi peräkkäisten move-eventtien välillä on niin pitkä aika, että nekin välillä "loppuvat".
Vika siis mitä ilmeisimmin ei ole missään tässä nähdyssä koodissa vaan jossain muualla. Todennäköisimmin siinä, että kudit viuhuvat silmää nopeammin.
Noh, tutkitaanpas niitä Bullet-olion ominaisuuksia. Alkuun sanon, että olen tehnyt Bullet-olion, joka kuvaa siis yhtä luotia. Sitten minulla on toinen BulletHandler-olio, joka taas käy läpi koko kokoelman Bullet-olioita läpi, ja tällä tavoin hieman siistiyttää pääsilmukkaa. Laitan nyt tähän niitä kohtia joissa ongelma voi piileä:
//luodin liikkumismetodi void Bullet::Move() { //parempiakin tapoja varmasti on mutta itse tein näin //tämä siis toistetaan 25 kertaa for(int i = 0; i < 25; i++) { //directionin arvo saadaan aina pelaajalta (ks. ekan viestin koodi) x += cos(-DegToRad(direction)); y += sin(-DegToRad(direction)); } //jos luoti ajautuu tietylle alueelle, se tapetaan if(x < 0 || x > 640 || y < 0 || y > 480) { dead = true; } }
//luodin piirtämismetodi void Bullet::Show(SDL_Surface *screen) { //kutsutaan Draw(SDL_Surface *image, SDL_Surface *screen, int x, int y) metodia //ja annetaan sille tarvittavat arvot oikeaan kohtaan piirtämiseen Draw(image, screen, x, y); }
//BulletHandler-olion luotien piirtämismetodi void BulletHandler::ShowBullets(SDL_Surface *screen) { //tarkistetaan, onko kokoelmassa mitään if(bullets.size() > 0) { //aloitetaan silmukka jossa käydään koko kokoelma läpi for(bullet = bullets.begin(); bullet != bullets.end();) { //dead on boolean arvo, jos tosi... if(bullet->dead) { //luodin tiedot vapautetaan... bullet->FreeData(); //...ja se heitetään pois kokoelmasta bullet = bullets.erase(bullet); } else { //...jos epätosi, annetaan sen liikkua... bullet->Move(); //...kutsutaan luodin omaa piirtometodia ja piirretään se bullet->Show(screen); //edetään selaamisessa ++bullet; } } } }
Tässä kaikki mitä tarvitaan Bullet-olioiden toimintaan, eikä omiin silmiini tule muuta vikaa kuin yksi kohta jonka saisi suoritettua ehkä paremmin. Omasta mielestäni Bullet-olioiden toiminta on ollut moitteetonta, joten epäilyni ovat edelleen painamisen käsittelyn kohdalla, mutta jos nyt joku mahdollisesti ratkaiseva vika löytyy niin mielelläni kuulen asiasta.
erakko- kirjoitti:
parempiakin tapoja varmasti on
Joo, oletko kuullut kertolaskusta?
erakko- kirjoitti:
tarkistetaan, onko kokoelmassa mitään
Turhaan tarkistat, koska jos ei ole, v.begin() palauttaa arvon v.end() ja for-silmukka jää joka tapauksessa suorittamatta.
Suosittelen, että opettelet säilyttämään kulmat radiaaneina, koska niillä joudut kuitenkin laskemaan. Kannattaa myös hyväksyä koordinaatiston asento ja tehdä laskut ihan oikeilla kulmilla — siis niin, että cos(-DegToRad(direction))
muuttuu muotoon cos(direction)
.
Vika ei tosiaan vaikuta olevan tuossa. Laita nyt vaikka ukko ampumaan automaattisesti sekunnin välein, niin selviää helposti, onko vika ampumisessa vai panoksissa.
Metabolix kirjoitti:
Laita nyt vaikka ukko ampumaan automaattisesti sekunnin välein, niin selviää helposti, onko vika ampumisessa vai panoksissa.
Panokset ilmestyivät tasaisin väliajoin, joten vika ei ole sitten panoksissa.
Sittenpä ei voi kuin ihmetellä, miten oikein hoidat viestien käsittelyn sillä tavalla, että onnistut hukkaamaan osan klikkauksista. Onhan sinulla varmasti täsmälleen yksi viestisilmukka, jossa käsittelet kaikki viestit ja poimit klikkaukset?
Heh. Nyt se toimii juuri niinkuin pitääkin. Ja selitys: silloin kun tämän ongelman esitin, minulla oli virheellisesti kaksi tapahtumien käsittelijää. Noh, tässä ajan kuluessa se virhe tuli korjattua. Tilanne tämän jälkeen oli se, että ampuminen tapahtui viiveellä ja panoksia sai yhdellä liipaisulla ampua niin paljon kuin vain ammuksia löytyi. Jälkimmäinen juttuha onnistui ihan simppelisti:
case SDL_MOUSEBUTTONDOWN: //tarkistetaan että painetaan vasenta hiiren nappia, ja että pelaajan canshoot-muuttuja on arvolla false if(event.button.button == SDL_BUTTON_LEFT && event.button.state == SDL_PRESSED && player.GetCanShoot() == false) { //annetaan lupa ampua player.SetCanShoot(true); } break; case SDL_MOUSEBUTTONUP: //tarkistetaan että hiiren vasen nappi on vapautettu if(event.button.button == SDL_BUTTON_LEFT && event.button.state == SDL_RELEASED) { //asetetaan canshoot false arvoksi, jolloin ampumista ei enää tehdä, ja liipaisu voidaan suorittaa player.SetCanShoot(false); } break;
Sitten jäi vielä yksi ongelma, missä on viiveen vika? Äskeisessä Metabolixin viestissä sana "viestisilmukka" kolahti, ja älysin mistä oli kyse. Niinpä muutin pääsilmukassa olevaa tapahtumakäsittelijää näin:
while(SDL_PollEvent(&event)) { switch(event.type) { //... } }
... ja presto, problem solved. Kiitos kaikille!
Aihe on jo aika vanha, joten et voi enää vastata siihen.