Page 1 of 1
Line of Sight
Posted: Tue Jun 02, 2009 3:13 pm
by Koodiapina
Mietinpä tuossa, että mitenköhän saisi tehtyä hyvin toimivan Line of Sightin Roguelike-peliä varten. Algorithmin pitäisi yksinkertaisesti siis etsiä kaikki kohdat, joihin pelihahmo kykenee näkemään ja sitten merkata ne nähdyiksi. Homma vaikutti aluksi simppeliltä, mutta tekemäni viritelmä jätti joitain ruutuja havaitsematta.
Tässä omani, jotta kukaan ei postaisi samaa systeemiä.
Code: Select all
for (float i=0; i<360; i++)
{
for (float a=0; a<12; a++)
{
// Location-olio kertoo pelaajan koordinaatit.
int x = Location.x + Cos (i) *a;
int y = Location.y + Sin (i) *a;
Map.Sqr[x][y].Seen = 1;
if (Map.HasCollision (x, y))
break;
}
}
Nyt pyytäisinkin jotakuta tekemään kunnolla toimivan LOSsin. Kielellä ei ole väliä, koska pääasia on, että saan perusajatuksen selville :-)
Re: Line of Sight
Posted: Tue Jun 02, 2009 3:37 pm
by JATothrim
wikipeadia on ystäväsi:
click! Tuon algotrimin "viivalla" kun skannaat karttaasi, niin ei pitäisi olla ongelmia. Et tarvitse ollenkaan trigonometrisiä fuktioita, sillä tuo algotrimi toimii pelkästään kokonaisluvuilla. En jaksa vääntää esimerkkiä, kun artikkelin 2. lähde kertoo kaiken.
Re: Line of Sight
Posted: Tue Jun 02, 2009 3:42 pm
by Koodiapina
Sillähän se onnistui. Kiitos paljon :-)
Re: Line of Sight
Posted: Tue Jun 02, 2009 6:53 pm
by otto90x
Teinpäs tuosta wikipedian mukaisen käännöksen CB:lle. Funktio MemBresenham laskee kahden pisteen välisten ruutujen koordinaatit järjestyksessä ja palauttaa ne muistipalassa, jonka ensimmäinen kokonaisluku on ruutujen määrä. Kun tarkistaa onko näissä ruuduissa seinää, saa helposti jätettyä piirtämättä seinän taakse jäävät ruudut.
Esimerkissä välilyönti piirtää viivan kahden ruudun välille ja matkalle osuvat ruudut värjäytyvät vihreän sävyihin.
Code: Select all
SCREEN 800,600
Const resolution = 40
Const size = 12
Repeat
Color cbwhite
For x=0 To resolution-1
For y=0 To resolution-1
Box x*size+10,y*size+10,size,size,0
Next y
Next x
If mem Then
määrä = PeekInt(mem,0)
o=0
For i=4 To MEMBlockSize(mem)-1 Step 8
o+1
xx=PeekInt(mem,i)
yy=PeekInt(mem,i+4)
väri# = 255-(Float(o)/float(määrä))*255.0
Color 0,väri,0
Box xx*size+10,yy*size+10,size,size,1
Next i
Color cbred
Line lx*size+10+size/2,ly*size+10+size/2,lxx*size+10+size/2,lyy*size+10+size/2
EndIf
If KeyDown(cbkeyspace) Then
If mem Then DeleteMEMBlock mem : mem=0
lx=Rand(resolution-1)
ly=Rand(resolution-1)
lxx=Rand(resolution-1)
lyy=Rand(resolution-1)
mem = MemBresenham(lx,ly,lxx,lyy)
ClearKeys
EndIf
DrawScreen
Forever
Function MemBresenham(x,y,xx,yy)
mem=MakeMEMBlock(4)
PokeInt mem,0,0
lw=Abs(xx-x)
lh=Abs(y-yy)
w=Max(lh,lw)
h=Min(lh,lw)
If lw>lh Then
If x<xx Then
s0=x
t0=y
s1=xx
t1=yy
Else
s0=xx
t0=yy
s1=x
t1=y
EndIf
Else
If y<yy Then
s0=y
t0=x
s1=yy
t1=xx
Else
s0=yy
t0=xx
s1=y
t1=x
EndIf
EndIf
If t0<t1 Then
tstep=1
Else
tstep=-1
EndIf
virhe = w/2
t = t0
For s=s0 To s1
oldsize = MEMBlockSize(mem)
ResizeMEMBlock mem,oldsize+8
PokeInt mem,0,PeekInt(mem,0)+1
If lw>lh Then
PokeInt mem,oldsize,s
PokeInt mem,oldsize+4,t
Else
PokeInt mem,oldsize,t
PokeInt mem,oldsize+4,s
EndIf
virhe = virhe + h
If virhe >= w Then
t = t + tstep
virhe = virhe - w
EndIf
Next s
Return mem
End Function
EDIT: Taas hidastelin
Re: Line of Sight
Posted: Sun Aug 16, 2009 8:40 pm
by JATothrim
*BUMP* anteeksi nostosta, mutta ongelma painaa päälle. Ajattelin toteuttaa pikselin tarkan raycasterin otto90x koodin pohjalle. Funktiossa on kuitenkin yksi vika: 45-255 asteen kulmassa viiva tehdään "väärään suuntaan", mikä tekee funktion kelvottomaksi, koska pikselit pitäisi tarkistaa aina aloituspisteestä -> loppupisteeseen.
koetin fiksata funktiota moneen kertaan, mutta en saanut sitä toimimaan kuten haluaisin. koetin jopa toista algotrimiä, mutta se rasteroi viivan hieman eri tavalla. (huonommin) apuja?
Re: Line of Sight
Posted: Thu Aug 20, 2009 9:44 am
by fella5s
Helpottaisi muuten hieman jos näkisi sen muutetun koodin.
Re: Line of Sight
Posted: Thu Aug 20, 2009 10:25 am
by JATothrim
En nähnyt tarvetta antaa koodia, koska jo otto90x alkuperäisessä versiossa on kyseinen ongelma. Oma viritelmäni on "väärin" toimiessaan tuottanut täysin samanlaisen tuloksen tai käyttökelvottoman (mm. viiva kohdistuu aivan väärin). Käyttökelvottomia koeversioita en ole edes tallentanut. Tarkoituksenani oli siis muokata otto90x koodia niin, että pikselit piirretään/iteroidaan aina "from(x, y) -> to(xx, yy)" vektorin suunnassa. Nykyinen versio kääntää järjestyksen väärinpäin 45-225 kulmissa.