ASCII - Raytracer

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Vincent

Betreff: ASCII - Raytracer

BeitragSa, Aug 26, 2006 16:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo !

Beim letzten Blitzbasic-Stammtisch in Leipzig, hatten Cornelius und ich nix Besseres zu tun, als eine kleine Raytracer Routine zu schreiben. Bis zu letzt hatten wir gehofft damit einen mini - Contest für ASCII Spiele unter den Anwesenden auszulösen.

Um das Programm auszuführen braucht ihr noch ein "lvl.bmp" mit 100 * 100 Pixeln. Schwarze Flächen sind begehbar .. der Rest kann bunt sein, und wird auch so im Programm angezeigt.

Code: [AUSKLAPPEN]

Graphics 800 , 600 , 16 , 2
SetBuffer BackBuffer()
Dim feld( 100 , 100 , 3 ) ; 0 = kollision , 1-3 = farbwerte der wand
Dim Bildschirm#( 3 , 90 ) ; 0 = entfernung der wand , 1-3 = farbwerte der wand

create_lvl()

Global Spieler1_Speed# = 0.5 , Spieler1_X# = 2 , Spieler1_Y# = 2 , Spieler1_W# = 45


While Not KeyDown( 1 )

   If  KeyDown( 17 ) ; vorwärts
      Spieler1_X = Spieler1_X + Cos( Spieler1_W ) * Spieler1_Speed# 
      Spieler1_Y = Spieler1_Y + Sin( Spieler1_W ) * Spieler1_Speed#
   EndIf
   
   If KeyDown( 31 ) ; rückwärts
      Spieler1_X = Spieler1_X - Cos( Spieler1_W ) * Spieler1_Speed#
      Spieler1_Y = Spieler1_Y - Sin( Spieler1_W ) * Spieler1_Speed#
   EndIf
   
   
   Spieler1_W = ( Spieler1_W + (KeyDown( 32 ) - KeyDown( 30 ))*6 ) Mod 360 ; aktuellen drehwinkel ändern
   
   draw( Spieler1_X , Spieler1_Y , Spieler1_W) ; wir haben das ausgelagert, um mehrspielermodus zu ermöglichen.
   minimap()
   Flip
   Cls
Wend
End

Function minimap() ; die kleine karte .. nicht ASCII .. also nur zum testen
   Color 64,64,64
   Rect 0,0,100,100 ; man köntne das auch schwarz lassen .. sieht man aber doof auf schwarz
   For a = 0 To 100: For b = 0 To 100
      If feld(a, b, 0) = 1 Then WritePixel a, b, $FFFFFF
   Next:Next   
   WritePixel(  Spieler1_X , Spieler1_Y , $FF0000 ) ; spieler punkt ... vollkomen sinnfrei .. da die linien den eh überdecken ^^
   Color 0,0,255
   Line Spieler1_X , Spieler1_Y , Spieler1_X + Cos( Spieler1_W - 45 ) * 20 , Spieler1_Y + Sin( Spieler1_W - 45 ) * 20 ; sichtfeld links
   Line Spieler1_X , Spieler1_Y , Spieler1_X + Cos( Spieler1_W + 45 ) * 20 , Spieler1_Y + Sin( Spieler1_W + 45 ) * 20 ; sichtfeld rechts
End Function

Function create_lvl() ; auslesen des levels aus dem bild
   img = LoadImage( "lvl.bmp" )
   SetBuffer ImageBuffer( img )
   For a = 0 To 100 : For b = 0 To 100
      GetColor a , b
      r=ColorRed()
      g=ColorGreen()
      t=ColorBlue() ; ich hätt gerne blau "b" gegeben ... aber das gabs schon .. daher t ^^
   
      If ( r <> 0  Or g <> 0 Or t <> 0 ) feld( a , b , 0 ) = 1
      
      feld( a , b , 1 ) = r
      feld( a , b , 2 ) = g
      feld( a , b , 3 ) = t
   Next : Next
   SetBuffer BackBuffer()
End Function

Function draw( Xpos# , Ypos# , Spieler_Winkel# )
   For a = - 45 To 45 ; das das gerade 90 ergibt macht zwar wenig aufwand, ist aber nicht nötig ...
               ; kann ne beliebige zahl sein .. abh. von der spaltenanzahl auf dem screen      
      X# = Xpos : Y# = Ypos
      Bildschirm( 0 , 45 + a ) =  -1 ; wenn keine wand gefunden wurde ... is am ende immernoch -1
      Repeat
         X = X + Cos( Spieler_Winkel + a ) * 0.2
         Y = Y + Sin( Spieler_Winkel + a ) * 0.2
         If feld(  Int( X ) , Int( Y ) , 0 ) = 1
            Bildschirm( 0 , 45 + a ) =  Sqr( (Xpos - X )*(Xpos - X ) + (Ypos - Y )*(Ypos - Y )) ; entfernung der wand zum spieler
            Bildschirm( 1 , 45 + a ) = feld(  Int( X ) , Int( Y ) , 1 ) ; Rot
            Bildschirm( 2 , 45 + a ) = feld(  Int( X ) , Int( Y ) , 2 ) ; gruen
            Bildschirm( 3 , 45 + a ) = feld(  Int( X ) , Int( Y ) , 3 ) ; blau
            Exit ; schleife beenden ... wand gefunden
         EndIf
      Until( X > 100 Or X < 0 Or Y > 100 Or Y < 0 ) ; ausserhalb des spielfeldes ? --> keine wand !
   Next
   
   For a = 0 To 90
      If Bildschirm( 0 , a ) >= 0 ; -1 wär keine wand .. sonst schon
         e = 300.0 / Bildschirm( 0 , a ) ; maximale höhe der wand -> bildschirmhöhe / 2
         For b = 0 To e Step 8 ; step 8, da ein ASCII zeichen bei uns 8 pixel höhe bekommt
         
            c# =  5.0 / (Bildschirm( 0 , a ) ) ; verdunklungsfaktor für hohe entfernung
            
            If c > 1 c = 1 ; sonst wirds komisch, und in sehr großer entfernung wieder heller
         
            Color Bildschirm( 1 , a ) * c , Bildschirm( 2 , a ) * c, Bildschirm( 3 , a ) * c
                  
            char$ = "O" ; standart wand
            If b > e - 9 Then char$ = "-" ; ist das die oberkante der wand ?
            If a > 0 And a < 90 ; an den rändern kein spezialzeugs .. sonst kann es zu fehlern kommen.
               If Bildschirm( 0 , a ) + 4 < Bildschirm( 0 , a + 1 ) Or Bildschirm( 0 , a ) + 4 < Bildschirm( 0 , a - 1 ) Then
                  If char$ = "-" Then char$ = "+" Else char$ = "|" ; wenn die entferung zweier wände sich zu sehr unterscheiden --> kante malen
               End If
            EndIf
            Text a * ( 800 / 90 ) , 300 + b , char$
            Text a * ( 800 / 90 ) , 300 - b , char$
         Next
      EndIf      
   Next
End Function
Gott ist nicht mit uns ... weil er mit Idioten keine Gnade kennt !

StepTiger

BeitragSa, Aug 26, 2006 16:16
Antworten mit Zitat
Benutzer-Profile anzeigen
hab ne Zeit gebraucht, bis ich begriffen hatte, was das überhaupt ist ^^

ist abgesehen davon, dass man durch die wände langsam durchlaufen kann, ganz nett Smile
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer:
AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t
Gewinner: BP Code Compo #2
Π=3.141592653589793238...<--- und das aus dem kopf Laughing
Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser.

maximilian

BeitragSa, Aug 26, 2006 16:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist das nicht ein >RayCASTER<? Raytracer wär geiler. Smile
Variety is the spice of life. One day ignore people, next day annoy them.
 

lettorTrepuS

BeitragSa, Aug 26, 2006 17:34
Antworten mit Zitat
Benutzer-Profile anzeigen
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group