Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C# vihollisen spawnaaminen (pseudokoodikin auttaisi)

Sivun loppuun

feltsu [04.10.2013 01:46:11]

#

Moros!

Oliskohan kellään antaa vihjettä, että miten saan tarkistettua onko kyseinen spawnpoint jo käytössä (eli siihen on jo luotu vihollinen) :)

Tilanne siis se että mulla on kaks arrayta, josta toisessa on viholliset mitä voi spawnata ja toisessa koordinaatit mihin voi spawnata, eli näin (Unityssa siis):

// array joka sisältää pelissä olevat vihollisen spawnaus areat
GameObject[] enemySpawns = GameObject.FindGameObjectsWithTag("EnemySpawnArea");

// array joka sisältää kaikki vihollisobjektit
GameObject[] EnemyPrefab = GameObject.FindGameObjectsWithTag("Enemy");

// luo random määrä vihollisia (min 1 ja max spawnpointtien määrä (10))
int numberOfEnemies = Random.Range(1, enemySpawns.Length);

// laskuri millä pidetään vaan kirjaa kuinka monta vihollista luotu
int enemyCounter = 0;

    // käy kaikki luodut viholliset läpi
	for (int i = 0; i < numberOfEnemies; i++)
	{
        // lisää laskuriin yksi, jotta pysytään mukana luotujen vihollisten määrässä
		enemyCounter++;

        // luo random objekti (vihollinen) vihollisarraysta, sijoita luotu vihollinen random spawnareaan spawnarea arraysta sijaintiin Vector3(x, y, z), pyöritä vihollinen katsomaan pelaajaa
		GameObject enemy = Instantiate(EnemyPrefab[Random.Range(0, EnemyPrefab.Length)], enemySpawns[Random.Range(0, enemySpawns.Length)].transform.position, enemySpawns[i].transform.rotation) as GameObject;

        // nimeä juuri luotu vihollinen
		enemy.name = "Enemy" + enemyCounter;
	}

Toivottavasti tosta saa jotain selvää, ei kauneinta mut aina ei voi voittaa :)

Mut tosiaan miten tohon sais lisättyä tarkastuksen joka pitää kirjaa semmosista spawnareoista joissa on jo vihollinen? Ja samalla pysyttyä mukana siinä missä spawnareassa ja vihollisessa ollaan menossa ettei skipata kummankaan yli?

Kiitoksia kun jaksoit lukea ja vaikket ois jaksanukkaan niin silti.

Ideoita odotellassa :)

-EDIT- Niin ja siis vielä voin sen verran selventää että kyseisellä loopilla ei ainakaan tähän mennessä oo tullu samaan spawnareaan kahta SAMAA vihollista mutta eri vihollisia saattaa tunkea samalle spawnarealla, jos yhtään selventää ongelmaa.

-EDIT2- Aiheeseen lisätty tieto pseudokoodin auttamisesta :)

lapm [04.10.2013 09:36:13]

#

Jos tarkoitus on tietää onko spawn käytössä niin joudut sitten pitämään listaa asiasta. Eli Spawnpoint - Vihollinen ja päivität tuota aina kun luot vihollisen tai se kuolee.

feltsu [04.10.2013 09:41:34]

#

No luonnollisesti on pidettävä kirjaa, muttaku miten :) Mihin kohtaan laitan minkätyylisen tarkistuksen onko spawn vapaana vai ei :)

Lisäys: Vai toimisko siinä joku tyyliin if-blokki missä tarkistetaan isOccupied -> true -> continue else -> spawnmonster? ja sit monsterspawni omaan for-looppiin ton alkper spawnloopin sisään? tms

Lisäys: vai toimiiko toi continue nyt niin että se sit skippaa yhen loopin?

The Alchemist [04.10.2013 09:55:38]

#

Kyllähän sä nyt sen verran ymmärrät algoritmeista, että jotenkin sun pitää ne spawnpointit iteroida läpi, koska sinun täytyy testata jokainen yksitellen? Sehän on sitten sinun omasta koodistasi kiinni, onko siellä joku isOccupied()-funktio vai miten sp:n varaustilanne pitää selvittää.

P.S. Tuosta koodista saisi paljon luettavamman jättämällä redundantit kommentit pois. Muuttujien merkityksen voi joskus kommentoida, jos niiden merkitys on epäselvä, mutta yleensä sekin on ihan turhaa. Tuossa koodisnippetissä kaikki kommentit ovat ilmeisen turhia.

Metabolix [04.10.2013 12:06:05]

#

Jos jokaista pistettä on tarkoitus käyttää vain kerran, yksinkertainen ratkaisu on poistaa piste listalta käytön jälkeen. Joka tapauksessa olisi selvintä ensin tehdä arvonnat omilla riveillään ja sitten vastatuo luonti.

tyyppi = tyypit.satunnainen();
paikka = paikat.satunnainen();
paikat.poista(paikka);
viholliset.lisaa(luo(tyyppi, paikka));

feltsu [04.10.2013 13:32:56]

#

The Alchemist kirjoitti:

P.S. Tuosta koodista saisi paljon luettavamman jättämällä redundantit kommentit pois. Muuttujien merkityksen voi joskus kommentoida, jos niiden merkitys on epäselvä, mutta yleensä sekin on ihan turhaa. Tuossa koodisnippetissä kaikki kommentit ovat ilmeisen turhia.

Itseasiassa mulla ei oo mitään kommentteja tällä hetkellä tossa koodipätkässä, lisäsin ne vaan tänne putkaan, ettei jää kenelläkkään epäselväks mitä mikäkin rivi tekee, mutta turhaa tosiaan tais olla, ei täällä oo idiootteja :P

Metabolix kirjoitti:

Jos jokaista pistettä on tarkoitus käyttää vain kerran, yksinkertainen ratkaisu on poistaa piste listalta käytön jälkeen. Joka tapauksessa olisi selvintä ensin tehdä arvonnat omilla riveillään ja sitten vastatuo luonti.

tyyppi = tyypit.satunnainen();
paikka = paikat.satunnainen();
paikat.poista(paikka);
viholliset.lisaa(luo(tyyppi, paikka));

Joo tolleinhan se voisi onnistuakin, katotaas jos saisin implementoitua jotenkin :D

Kiitoksia.

feltsu [05.10.2013 17:02:58]

#

Metabolix kirjoitti:

tyyppi = tyypit.satunnainen();
paikka = paikat.satunnainen();
paikat.poista(paikka);
viholliset.lisaa(luo(tyyppi, paikka));

No tutkiskelin tätä mahdollisuutta ja näyttäis vähän siltä ettei onnistu ainakaan mitenkään kovin helposti poistamaan tietueita arraysta. Eli pitäis mennä semmosella systeemillä joka flaggaa kaikki arvotut spawnPointit !isOccupied ja sit luo vihollisen vaan semmoseen pointtiin missä isOccupied on false. Kysymys nyt kuuluukin että millanen looppi-rakenne tohon pitää kyhätä että toimis?

Metabolix [05.10.2013 18:27:37]

#

feltsu kirjoitti:

No tutkiskelin tätä mahdollisuutta ja näyttäis vähän siltä ettei onnistu ainakaan mitenkään kovin helposti poistamaan tietueita arraysta.

Poistaminen on kyllä hyvinkin helppoa, mutta jos se nyt vaikealta tuntuu, älä turhaan käytä tavallista taulukkoa vaan esimerkiksi luokkaa System.Collections.ArrayList, tai mitä nyt C# sisältääkään.

Jos välttämättä haluat tehdä tuollaisen silmukkaviritelmän, voit tehdä sen näin:

do {
	x = satunnainen();
} while (x.kaytetty);

Vielä yksi mahdollinen ratkaisu on vain sekoittaa taulukko etukäteen ja ottaa sieltä arvoja järjestyksessä.

Flai [05.10.2013 18:34:29]

#

ArrayListin sijaan kannattaa kuitenkin käyttää List<T>:tä (ArrayList tyypitön). Jos oikein haluaa optimoida, niin voi myös vaikka tehdä niin, että sekoittaa tuon arrayn jollain algoritmillä ja sitten valitsee aina ensimmäisestä viimeiseen sen seuraavan "random" alueen ilman että poistaa mitään. Tai käyttää jotain HashSettiä, missä poistaminen on O(1).

EDIT: Ai Metabolix sanoikin tuosta sekoittamisesta, en huomannutkaan :)

feltsu [06.10.2013 14:17:02]

#

Jee, kiitoksia, onnistu helposti tuolla että randomizee eka paikat ja sit vaan spawnaa järjestyksessä! Eipä ite tullu ajateltua, että noin vois tehdä :D


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta