Code: Select all
Const ScreenW = 800
Const ScreenH = 600
SCREEN ScreenW, ScreenH
Terrain = CreateTerrain(ScreenW, ScreenH)
Repeat
Color 255, 255, 255
If GetKey() Then DeleteImage Terrain : Terrain = CreateTerrain(ScreenW, ScreenH)
DrawImage Terrain, 0, 0
DrawScreen
Forever
//Luo realistista 2D -maastoa. Palauttaa kuvan. Parametrit:
//Width ja Height kertovat luotavan kuvan koon.
//Smoothness on maaston pehmeys, ]0, 1].
//MaxH kertoo, kuinka kaukana maa saa olla kuvan reunasta.
Function CreateTerrain(Width, Height, Smoothness# = 0.99, MaxH = 100)
GenMem = MakeMEMBlock(Width * 4) //Luodaan muistipala johon tallennetaan maaston korkeudet peräkkäisinä kokonaislukuina.
MaxH = Height / 2 - MaxH //Lasketaan max. Y:n vaihteluväli [-MaxH, MaxH].
MaxV# = (MaxH / Smoothness) - MaxH //Kun tiedetään max. vaihteluväli sekä pehmennyskerroin, lasketaan nopeuden max. vaihteluväli [-MaxV, MaxV].
VelY# = Rnd(-MaxV, MaxV) //Arvotaan lähtönopeus,
YDisp# = Rand(-MaxH / 2, MaxH / 2) //sekä todennäköinen lähtökorkeus (normaalijakauman mukaisesti huippujen puolivälistä).
For i = 1 To 200 //Lasketaan maastoa jo ennen kuvaa, jotta saataisiin mahdollisimman realistinen alku maastolle.
VelY = Max(-MaxV, Min(MaxV, VelY + Rnd(-.1, .1)))
YDisp = (YDisp + VelY - Average) * Smoothness + Average
AvgSum = AvgSum + YDisp
Count = Count + 1
Next i
For x = 1 To Width
VelY = Max(-MaxV, Min(MaxV, VelY + Rnd(-.1, .1))) //Muutetaan korkeuden muutosnopeutta satunnaisella kiihtyvyydellä.
YDisp = (YDisp + VelY - Average) * Smoothness + Average //Nostetaan/lasketaan maastoa ja pakotetaan se pysymään rajoissa pehmeästi.
PokeInt GenMem, (x - 1)*4, YDisp //Tallennetaan korkeus.
AvgSum = AvgSum + YDisp //Lasketaan korkeuden keskiarvo,
Count = Count + 1 //jonka avulla estetään tasaista
Average = Max(-MaxH, Min(MaxH, Float(AvgSum) / Count)) //maastoa.
Next x
GenImg = MakeImage(Width, Height) //Luodaan kuva
DrawToImage GenImg //Nyt maalataan :)
For x = 1 To Width //Haetaan korkeudet muistipalasta ja piirretään viiva kerrallaan.
Line x, Height, x, Height / 2 + PeekInt(GenMem, (x - 1)*4) - Average
Next x
Text 1, 1, Average
DrawToScreen
DeleteMEMBlock GenMem
Return GenImg
EndFunction
EDIT:
Päätin sittenkin laittaa ne sinit sinne takaisin
Maasto ei ehkä ole yhtä realistista, mutta tykkipeliin kuuluvat montut ovat paikallaan
Code: Select all
Const ScreenW = 800
Const ScreenH = 600
SCREEN ScreenW, ScreenH
Const SineCount = 5
Dim Sine_Amp(SineCount), Sine_Disp(SineCount), Sine_Speed#(SineCount)
Terrain = CreateTerrain(ScreenW, ScreenH)
Repeat
Color 255, 255, 255
If GetKey() Then DeleteImage Terrain : Terrain = CreateTerrain(ScreenW, ScreenH)
DrawImage Terrain, 0, 0
DrawScreen
Forever
//Luo kumpuilevan realistista 2D -maastoa. Palauttaa kuvan. Parametrit:
//Width ja Height kertovat luotavan kuvan koon.
//Smoothness on maaston pehmeys, ]0, 1].
//MaxH kertoo, kuinka kaukana maa saa olla kuvan reunasta.
//MaxSine määrää siniaaltojen maksimiosuuden maastosta - siniaaltojen maksimisumma.
Function CreateTerrain(Width, Height, Smoothness# = 0.98, MaxH = 70, MaxSine = 100)
GenImg = MakeImage(Width, Height) //Luodaan kuva
MaxH = Height / 2 - (MaxH + MaxSine)//Lasketaan max. Y:n vaihteluväli [-MaxH, MaxH] ottaen myös huomioon siniaallot.
MaxV# = (MaxH / Smoothness) - MaxH //Kun tiedetään max. vaihteluväli sekä pehmennyskerroin, lasketaan nopeuden max. vaihteluväli [-MaxV, MaxV].
If MaxSine Then
For i = 0 To SineCount
Sine_Amp(i) = Rand(MaxSine / 2)
MaxSine = MaxSine - Sine_Amp(i)
Sine_Disp(i) = Rand(360)
Sine_Speed(i) = Rnd(.1, 1)
Next i
End If
VelY# = Rnd(-MaxV, MaxV) //Arvotaan lähtönopeus,
YDisp# = Rand(-MaxH / 2, MaxH / 2) //sekä todennäköinen lähtökorkeus (normaalijakauman mukaisesti huippujen puolivälistä).
For i = 1 To 300 //Lasketaan maastoa jo ennen kuvaa, jotta saataisiin mahdollisimman realistinen alku maastolle.
VelY = Max(-MaxV, Min(MaxV, VelY + Rnd(-.1, .1)))
YDisp = (YDisp + VelY) * Smoothness
Next i
DrawToImage GenImg //Nyt maalataan :)
For x = 1 To Width
VelY = Max(-MaxV, Min(MaxV, VelY + Rnd(-.1, .1))) //Muutetaan korkeuden muutosnopeutta satunnaisella kiihtyvyydellä.
YDisp = (YDisp + VelY) * Smoothness //Nostetaan/lasketaan maastoa ja pakotetaan se pysymään rajoissa pehmeästi.
y# = Height / 2 + YDisp
For i = 0 To SineCount
y = y + Sin(x * Sine_Speed(i) + Sine_Disp(i)) * Sine_Amp(i)
Next i
Line x, Height, x, y //Piirretään viiva tämänhetkisestä korkeudesta maahan.
Next x
DrawToScreen
Return GenImg
EndFunction