Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Grafik und Fonts

RayCaster (Untexturiert)

Lizenz:Erster Autor:Letzte Bearbeitung:
k. A.MitgliedPMedia 19.06.2007

Screenshot der Umsetzung des RayCasters von C nach FB

''Copyright (c) 2004-2007, Lode Vandevenne (converted from C to FreeBasic by PMedia in 2007)
''All rights reserved.
''
''This software is provided 'as-is', without any express or implied
''warranty. In no event will the authors be held liable for any damages
''arising from the use of this software.
''
''Permission is granted to anyone to use this software for any purpose,
''including commercial applications, and to alter it and redistribute it
''freely, subject to the following restrictions:
''
''    1. The origin of this software must not be misrepresented; you must not
''    claim that you wrote the original software. If you use this software
''    in a product, an acknowledgment in the product documentation would be
''    appreciated but is not required.
''
''    2. Altered source versions must be plainly marked as such, and must not be
''    misrepresented as being the original software.
''
''    3. This notice may not be removed or altered from any source
''    distribution.

'' sure, the original had some includes more, but FB doesn't need them ^^
#include "fbgfx.bi"

'' fbc raycaster_flat.bas

#define mapWidth 24
#define mapHeight 24

dim shared as integer worldmap(mapWidth, mapHeight) =         _
  {                                                    _
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1}, _
    {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1}, _
    {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, _
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}  _
  }

Sub Main(argc As UInteger = 0, argv As String = "")

    ''x and y start position
    Dim As Double posX = 22
    Dim As Double posY = 12

    '' initial direction vector
    Dim As Double dirX = -1
    Dim As Double dirY = -1

    '' the 2d raycaster version of camera plane
    Dim As Double planeX = 0
    Dim As Double planeY = 0.66

    '' time of current frame
    Dim As Double curtime = 0

    ''time of previous frame
    Dim As Double oldTime = 0

    '' (PMedia)
    '' code-cleaned here:
    Dim As Integer X
    Dim As Double  cameraX
    Dim As Double  rayPosX
    Dim As Double  rayPosY
    Dim As Double  rayDirX
    Dim As Double  rayDirY
    Dim As Integer mapX
    Dim As Integer mapY
    Dim As Double  sideDistX
    Dim As Double  sideDistY
    Dim As Double  deltaDistX
    Dim As Double  deltaDistY
    Dim As Double  perpWallDist
    Dim As Integer stepX
    Dim As Integer stepY
    Dim As Integer hit
    Dim As Integer side
    Dim As Integer lineHeight
    Dim As Integer drawStart
    Dim As Integer drawEnd
    Dim As UInteger ColorRGB
    Dim As Double  frameTime
    Dim As Double  moveSpeed
    Dim As Double  rotSpeed
    Dim As Double  oldDirX
    Dim As Double  oldDirY
    Dim As Double  oldPlaneX
    Dim As Double  oldPlaneY

    ScreenRes 512, 384, 32
    WindowTitle "RayCaster"
    Do Until (multikey(fb.sc_escape))

        '' sacrifice 5 milliseconds per frame to free some CPU time
        Sleep 5
        screenlock
        cls

        for x = 0 to 512 step 1

            '' calculate ray position and direction
            cameraX = 2 * x / 512 - 1 '' x-coordinate in camera space

            rayPosX = posX
            rayPosY = posY
            rayDirX = dirX + planeX * cameraX
            rayDirY = dirY + planeY * cameraX

            mapX = rayPosX
            mapY = rayPosY

            '' length of ray from current position to next x or y-side
            ' --

            '' length of ray from one x or y-side to next x or y-side
            deltaDistX = sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
            deltaDistY = sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))

            '' what direction to step in x or y-direction (either +1 or -1)

            '' was there a wall hit?
            hit = 0

            '' was a NS or a EW wall hit?

            '' calculate step and initial sideDist
            if (rayDirX < 0) then
                stepX = -1
                sideDistX = (rayPosX - mapX) * deltaDistX
            else
                stepX = 1
                sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX
            end if

            if (rayDirY < 0) then
                stepY = -1
                sideDistY = (rayPosY - mapY) * deltaDistY
            else
                stepY = 1
                sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY
            end if

            '' Perform DDA
            do while (hit = 0)
                '' jump to next map square, OR in x-direction OR in y-direction
                if (sideDistX < sideDistY) then
                    sideDistX += deltaDistX
                    mapX += stepX
                    side = 0
                else
                    sideDistY += deltaDistY
                    mapY += stepY
                    side = 1
                end if

                '' Check if ray has hit a wall
                if (worldMap(mapX, mapY) > 0) then hit = 1

            loop

            '' Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
            if (side = 0) then
                perpWallDist = abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
            else
                perpWallDist = abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
            end if



            '' calculate height of line to draw on screen
            lineHeight = abs(int(384/perpWallDist))

            '' Calculate lowest and highest Pixel to fill in current stripe
            drawstart = -lineHeight / 2 + 384 / 2
            if (drawstart < 0) then drawStart = 0
            drawEnd   = lineHeight / 2 + 384 / 2
            if (drawEnd   < 0) then drawEnd   = 0

            select case worldmap(mapX, mapY)
            case 1
                colorRGB = rgb(255, 0, 0) '' red
            case 2
                colorRGB = rgb(0, 255, 0) '' green
            case 3
                colorRGB = rgb(0, 0, 255) '' blue
            case 4
                colorRGB = rgb(255,255,255) '' white
            case else
                colorRGB = rgb(255, 255, 0) '' yellow
            end select

            '' Give x and y sides different brightness
            if (side = 1) then colorRGB = colorRGB / 2

            '' draw the pixels of the stripe as a vertical line
            line (x, drawStart) - (x, drawEnd), colorRGB

        next

        print (1.0 / frameTime)

        screenunlock

        '' timing for input and FPS counter
        oldtime = curtime
        curtime = timer * 1000
        frametime = (curtime - oldTime) / 1000.0 ''frameTime is the time this frame has taken, in seconds
        '' frametime = 1 / 60

        '' speed modifiers
        movespeed = frameTime * 5.0 '' the constant value is in squares/second
        rotspeed  = frameTime * 3.0 '' the constant value is in radians/second

        '' move forward if no wall in front of you
        if multikey(fb.sc_up) then
            if worldMap(int(posX + dirX * moveSpeed),int(posy)) = 0 then posX += dirX * moveSpeed
            if worldMap(int(posX),int(posY + dirY * moveSpeed)) = 0 then posY += dirY * moveSpeed
        end if


        '' move backwards if no wall behind you
        if multikey(fb.sc_down) then
            if(worldMap(int(posX - dirX * moveSpeed),int(posY)) = 0) then posX -= dirX * moveSpeed
            if(worldMap(int(posX),int(posY - dirY * moveSpeed)) = 0) then posY -= dirY * moveSpeed
        end if

        '' rotate to the right
        if multikey(fb.sc_right) then
            ''both camera direction and camera plane must be rotated
            oldDirX = dirX
            dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed)
            dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed)
            oldPlaneX = planeX
            planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed)
            planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed)
        end if


        '' rotate to the left
        if multikey(fb.sc_left) then
            ''both camera direction and camera plane must be rotated
            oldDirX = dirX
            dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed)
            dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed)
            oldPlaneX = planeX
            planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed)
            planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed)
        endif


    Loop

End Sub


Main()

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 19.06.2007 von MitgliedPMedia angelegt.
  • Die aktuellste Version wurde am 19.06.2007 von MitgliedPMedia gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen