Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: QB: Näköesteet (Qb)

Sivun loppuun

Grey [09.11.2004 08:18:48]

#

Moni on kysynyt täällä kuinka saada hahmo pysähtymään esteeseen. Noh, minä en nyt kysy siitä, vaan paljon vaikeammasta asiasta, eli miten luoda este jonka taakse ei näe vanhempien Ultimoiden tyyliin? Taulukko jossa nuo esteet ovat, näyttää tältä:

10010
10001
10X01
01000
10100

Taulukko on oikeasti tosin 11x11 kokoinen, mutta näin pienempänä se on selvempi. Ykköset tarkoittavat estettä, nollat kohtaa minkä läpi voi liikkua ja X on pelaaja. Nyt pitäisi keksiä tapa, jolla voidaan laskea esteet ja se miten ne peittävät näkökenttää. Itse olen jo yrittänyt ja todennut etteivät omat taitoni riitä keksimään kaavaa, joka toimisi ja olisi vielä ei-purkkamainen :-/

-Grey-

Heikki [09.11.2004 09:49:51]

#

Haulla löytyi tälläinen keskustelu:
https://www.ohjelmointiputka.net/keskustelu/6174-raytracing-los-c-cpp

Grey [10.11.2004 00:44:37]

#

Heikki kirjoitti:

Haulla löytyi tälläinen keskustelu:
https://www.ohjelmointiputka.net/keskustelu/6174-raytracing-los-c-cpp

Valitan, ei ollut apua, vaikka tutkin tuota koko päivän. Seuraava!

-Grey-

renni [10.11.2004 04:16:20]

#

Hommahan on ihan kiinni siitä miten aiot toteuttaa pelisi "kartan". Vaihtoehtoja on miljuuna.

Grey [10.11.2004 06:20:34]

#

renni kirjoitti:

Hommahan on ihan kiinni siitä miten aiot toteuttaa pelisi "kartan". Vaihtoehtoja on miljuuna.

Kartta ja kaikki muu on olemassa, paitsi se algometri jolla voi tarkistaa onko jossain este. Jos nyt haluat välttämättä lisäselvitystä, voin selostaa kartan toiminnan. Koodia kun en luonnollisesti voi antaa. Sen vertaa iso ja vaatii tiedostoja toimiakseen, joiden koko menee jo satoihin kiloihin.

Kun on ensin tutkittu tilet kartasta ja laitettu niiden ID taulukkoon joka on kooltaan tilejen määrä näytöllä, eli 11x11. Itse taulukko ei sisällä tietoa millainen tile on kyseessä, vaan se katsotaan listasta jossa on tiedot tilejen ominaisuuksista. Eli näin:

PRINT TILE(SCR(X, Y)).walltype

Piirto hoituu sitten piirtämällä taulukon tilet näytölle. Nyt tosin ennen piirtoa pitäisi käsitellä taulukkoa niin että esteeksi määritellyn tilen takana olevat ID:t nollataan. Asia jota olen koettanut tämän koko unettoman yöni tutkia ja todeta ettei mikään kokeilemani tapa ole toiminut tarpeeksi hyvin :-P

-Grey-

sqwiik [10.11.2004 13:15:27]

#

Jos kelpaa Erkki-tyyliin neliskanttinen ja nopea näköalgoritmi (nopea koska ei sis. trigonometriaa), niin tässä olisi muinaisessa Erkki QB:ssa ollut näkökenttäalgoritmi. Tunnelitkin näkyvät oikein, sillä viiva ei ole suora (ja aiheuttaa näkökentäm laajenemisen sen mukaan miten lähellä ollaan esim. ovea, tyyliin adom). X,Y on ukkelin näkijän sijanti ja r näkymän kantama.

Merkitsin koodiin paikan, jossa sinun on tutkittava sitä nähdäänkö ko. tilen läpi.

Muista muuttaa Max.X ja Max.Y vastaamaan alueen rajoja.
Koodi olettaa taulukon alkavan 1:stä.

Jos koodista on apua, kiitoksia.

EDIT - toimiakseen koodi tarvitsee myös näkyvyystaulukon, tässä se on Nakyvyys. Alustettu muodossa
DIM Nakyvyys(1 TO Max.X, 1 TO Max.Y) AS STRING * 1
Piirrettäessä sitten taulukkoa katsot näkyykö ko. kohta ("N", jos näkyy). Muista nollata taulukko ennen kuin kutsut aliohjelmaa.

SUB see.area (x AS INTEGER, y AS INTEGER, r AS INTEGER)
  kehapisteet% = r * 8
DIM x1 AS INTEGER, y1 AS INTEGER, kp(1 TO kehapisteet%, 2) AS INTEGER
  'lasketaan kehäpisteiden koordinaatit
  'ylä & alaosa
  w% = 1'mikä piste meneillään
  FOR x1 = (x - r) TO (x + r)
    kp(w%, 1) = x1
    kp(w%, 2) = y - r
    IF kp(w%, 1) < 1 THEN kp(w%, 1) = 1
    IF kp(w%, 2) < 1 THEN kp(w%, 2) = 1
    IF kp(w%, 1) > max.x THEN kp(w%, 1) = max.x
    IF kp(w%, 2) > max.y THEN kp(w%, 2) = max.y
    kp(w% + (r * 4), 1) = x1  'alaosa
    kp(w% + (r * 4), 2) = y + r
    IF kp(w% + (r * 4), 1) < 1 THEN kp(w% + (r * 4), 1) = 1
    IF kp(w% + (r * 4), 2) < 1 THEN kp(w% + (r * 4), 2) = 1
    IF kp(w% + (r * 4), 1) > max.x THEN kp(w% + (r * 4), 1) = max.x
    IF kp(w% + (r * 4), 2) > max.y THEN kp(w% + (r * 4), 2) = max.y
    w% = w% + 1
  NEXT x1
  'vasen & oikea
  FOR y1 = (y - r + 1) TO (y + r - 1)
    kp(w%, 1) = x - r
    kp(w%, 2) = y1
    IF kp(w%, 1) < 1 THEN kp(w%, 1) = 1
    IF kp(w%, 2) < 1 THEN kp(w%, 2) = 1
    IF kp(w%, 1) > max.x THEN kp(w%, 1) = max.x
    IF kp(w%, 2) > max.y THEN kp(w%, 2) = max.y
    kp(w% + (r * 4), 1) = x + r'alaosa
    kp(w% + (r * 4), 2) = y1
    IF kp(w% + (r * 4), 1) < 1 THEN kp(w% + (r * 4), 1) = 1
    IF kp(w% + (r * 4), 2) < 1 THEN kp(w% + (r * 4), 2) = 1
    IF kp(w% + (r * 4), 1) > max.x THEN kp(w% + (r * 4), 1) = max.x
    IF kp(w% + (r * 4), 2) > max.y THEN kp(w% + (r * 4), 2) = max.y
    w% = w% + 1
  NEXT y1
w% = 0: q% = 0 'w:saadaanko mennä suoraan q:kumpaan ensin (-1=x,0=y)
  FOR a% = 1 TO kehapisteet%
    x1 = x: y1 = y: w% = 0
    q% = ABS(x1 - kp(a%, 1)) > ABS(y1 - kp(a%, 2))
    DO
      IF ABS(x1 - kp(a%, 1)) = ABS(y1 - kp(a%, 2)) THEN w% = (1 = 1)
      ' Muutetaan kartanpalanen näkyväksi ellei jo ole
      IF Nakyvyys(x1, y1) <> "N" THEN
        Nakyvyys(x1, y1) = "N"
      END IF

      ' Tähän kohtaan määrittely siitä jos on este!
      ' IF TILE(SCR(X, Y)).walltype = este THEN EXIT DO
      ' Tähän kohtaan määrittely siitä jos on este!

      IF (x1 = kp(a%, 1) AND y1 = kp(a%, 2)) THEN EXIT DO
      IF NOT w% THEN
        IF q% THEN
          IF x1 < kp(a%, 1) THEN
            x1 = x1 + 1
          ELSEIF x1 > kp(a%, 1) THEN
            x1 = x1 - 1
          END IF
        ELSE
          IF y1 < kp(a%, 2) THEN
            y1 = y1 + 1
          ELSEIF y1 > kp(a%, 2) THEN
            y1 = y1 - 1
          END IF
        END IF
      ELSE 'mennään suoraan
          IF x1 < kp(a%, 1) THEN
            x1 = x1 + 1
          ELSEIF x1 > kp(a%, 1) THEN
            x1 = x1 - 1
          END IF
          IF y1 < kp(a%, 2) THEN
            y1 = y1 + 1
          ELSEIF y1 > kp(a%, 2) THEN
            y1 = y1 - 1
          END IF
      END IF
    LOOP
  NEXT a%
END SUB

hunajavohveli [10.11.2004 15:26:00]

#

Tuohan on usein aika pulmallista siksi, että näkökenttä on toisaalta tarpeeksi suuri, ettei sitä viitsi toteuttaa vain kasalla IF-lausekkeita, mutta taas toisaalta niin pieni, ettei siihen viitsisi ruveta trigonometriaa sotkemaan. Tuon tapaisessa algoritmissa on sitten taas se, että siitä tulee neliskanttinen. Voisihan tuossa kyllä etäisyyden laskemisella tarkistaa, pitääkö joku kohta näyttää vai ei, jolloin näkökentästä saisi pyöreän, tosin se voisi alkaa mennä yhtä hitaaksi kuin trigonometria.

sqwiik [10.11.2004 15:46:10]

#

Neliskanttisuuden aiheuttaa vain se, että se on kaikkein nopein muoto jossa jokaisella reunapisteellä on naapuri ylä/alapuolella. Olen yrittänyt keksiä tapaa saada nopeasti vastaavanlainen ympyrä, mutta tähän asti ei oikein ole onnistunut.

Grey [11.11.2004 05:40:32]

#

Koko päivän yrittäneenä sanon yksinkertaisesti että ei pelittänyt :-P Yritin kyllä kaikkea, mutta aina tuli ongelmia. Toisaalta, mielessäni on kyllä ratkaisu ongelmaani, mutta en saa niitä ajatuksia nyt kunnolla kasaan. Liiaksi epäonnistumia, jotka ovat vaikuttaneet psyykkeeseen hieman negatiivisesti.

Kuitenkin, ideani, josta voinee kyllä olla apua niille jotka keksivät miten sen voisi toteuttaa, on simppeli. Eli ammutaan ikään kuin säde, joka laajenee sivuilla aina yhden pisteen vertaa (siis kaksi pistettä), eli näin:

     *
    ***
   *****
  *******
 *********

Yksinäinen piste alkaa tilen vertaa pelaajahahmon alapuolelta (tai yläpuolelta tai sivuilta). Kun säteen piste osuu esteeseen säde muuttuu niin että esteen takana olevat asiat piirretään mustina (tässä tapauksessa taulukon solu asetetaan nollaksi). Jos esteessä oli reikä, niin säde jatkaa kulkuaan sen läpi yhä edelleen laajeten.

Tosin tämä tekniikka jättää säteiden, joita on neljä, välit tyhjiksi, mutta siihen seikkaan ratkaisuna on neljä ylimääräistä sädettä, jotka etenevät keskeltä kulmia kohden, ilman laajenemista.

Tämä vain yksi ratkaisu, jota en tosin voine nyt pitkään aikaan toteuttaa, ennenkuin psyyke ja mieliala ovat taas korkealla. Uskon kuitenkin että ainakin muutamalle täällä on apua moisesta tavasta, jos saavat moisen koodattua. Ainakin Sqwiikille, joka on sopivaa algometriä myöskin etsinyt ja joka yritti auttaa minua äsken, tuloksetta :-/

-Grey-


Sivun alkuun

Vastaus

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

Tietoa sivustosta