Labyrint I

Jaa meneillään olevat projektisi tai valmiit pelit muun yhteisön kanssa täällä.
User avatar
CCE
Artist
Artist
Posts: 650
Joined: Mon Aug 27, 2007 9:53 pm

Re: Labyrint I

Post by CCE »

Hohoo kelpo raycasteri, fps mateli 15 hujakoilla mutta komean näköinen oli! Kuvien tarkkuus kyllä loppui liian pian kesken, voisit vielä vähän isompia tekstuureja laskea.
User avatar
MetalRain
Active Member
Posts: 188
Joined: Sun Mar 21, 2010 11:17 am
Location: Espoo

Re: Labyrint I

Post by MetalRain »

FPS poukkoilee 2-60 välillä, liikkuessa ehkä keskimäärin 13. Taustakuva ei näkynyt ollenkaan. Miten piirrät seinät? Mitä piirtokomentoja käytät?

Onkohan kellään muulla semmoista ongelmaa ettei CB:n kuvat piirry jos ne ovat ikkunan kokoisia ja piirretään 0,0 koordinaatteihin? Käyttöjärjestelmäni on Windows 7 64-bit.
Wingman
Devoted Member
Posts: 594
Joined: Tue Sep 30, 2008 4:30 pm
Location: Ruudun toisella puolella

Re: Labyrint I

Post by Wingman »

MetalRain wrote:FPS poukkoilee 2-60 välillä, liikkuessa ehkä keskimäärin 13. Taustakuva ei näkynyt ollenkaan. Miten piirrät seinät? Mitä piirtokomentoja käytät?

Onkohan kellään muulla semmoista ongelmaa ettei CB:n kuvat piirry jos ne ovat ikkunan kokoisia ja piirretään 0,0 koordinaatteihin? Käyttöjärjestelmäni on Windows 7 64-bit.
kaikilla vissiin on se ongelma, kuvat eivät piirry ruudun ulkopuolisiin koordinaatteihin... (0,0 on siten ulkopuolella)

itse en voi labyrinttiä kokeilla, kännykällä tässä selailen ;)
- - - -
Jonhu
Active Member
Posts: 186
Joined: Mon Aug 04, 2008 5:45 pm

Re: Labyrint I

Post by Jonhu »

MetalRain wrote:FPS poukkoilee 2-60 välillä, liikkuessa ehkä keskimäärin 13. Taustakuva ei näkynyt ollenkaan. Miten piirrät seinät? Mitä piirtokomentoja käytät?

Onkohan kellään muulla semmoista ongelmaa ettei CB:n kuvat piirry jos ne ovat ikkunan kokoisia ja piirretään 0,0 koordinaatteihin? Käyttöjärjestelmäni on Windows 7 64-bit.
Seinien piirto tapahtuu ihan drawimage - komennoilla.. Taustan piirrän viivoilla vaakatasossa, muita piirtokomentoja en tuossa käytä :? Seinien piirto perustuu ensin perus raycastingiin.. Teksturet ladataan raitoina muistiin ja tallennetaan jokaiseen kokoon valmiiksi alussa, jolloin itse ajossa tarvitsee vain hakea muistista oikea image ja piirtää se oikeaan kohtaan. Teksturet tallennan tyyppiin, joka sisältää muistipalan, johon tallennan generoitujen kuvien osoitteet ja haen niitä piirrettäessä..

Tuli tehty tuo aijempi läpinäkyvyys CB:n ikkunaan, mutta se ei toiminut ihan haluamallani tavalla :S CB:n ruutu päivittyy takaisin mustaksi, kun päivittää ruudun.. Kai tästä jollekkin on kuitenkin hyötyä, funktion voisi lisätä CBfuniin.

EDIT: siis piirrän taustan kuvaan,mutta taustakuvan piirrän viivoilla :D
EDIT2: Kokeiltu on vähän kaikkea tuon läpinäkyvyyden kanssa, mutta vaikuttaa siltä, että drawscreen-komento mustaa aina näytön.. Jos joku keksii, miten tuota läpinäkyvyyttä saisi käytettyä kätevästi, niin voisi käyttää cbSDL:n ja cbOpenGL:n komentoja yhtäaikaa cb:n komentojen kanssa.

EDIT3:
DLL Source... Editoitu hieman cbFunin SetWindowAlpha funktiota..

Code: Select all

void SetTransparency(HWND hwnd, UINT nAlpha) // http://www.codeproject.com/KB/system/vistra.aspx
{
      HMODULE hUser32 = GetModuleHandle(("USER32.DLL"));
      typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr,BYTE bAlpha, DWORD dwFlags);
      lpfn pSetLayeredWindowAttributes;
      pSetLayeredWindowAttributes =
        (lpfn)GetProcAddress(hUser32,"SetLayeredWindowAttributes");
      if(!pSetLayeredWindowAttributes) return;
      LONG nStyle=GetWindowLong(hwnd, GWL_EXSTYLE);
      if(( nStyle | 0x00080000)!=nStyle)
            ::SetWindowLong(hwnd, GWL_EXSTYLE, nStyle ^ 0x00080000);
      pSetLayeredWindowAttributes(hwnd, 0,(BYTE) nAlpha, 0x00000002);
      ::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}

DLLEXPORT void SetWindowAlpha2(LPBYTE pData)
{
	CParamBuffer a; a.InitBuffer(pData);

	char pVariableName[512];
	int x;

	a.GetString(pVariableName);
	x = a.GetInt();

    HWND hwnd = FindWindow(NULL, pVariableName);
    SetWindowLong (hwnd, (-20), WS_EX_LAYERED);
  //  SetLayeredWindowAttributes (hwnd, 0, x, LWA_ALPHA);
//    pSetLayeredWindowAttributes (hwnd, 0, x, LWA_ALPHA);    /* <--- ei toiminut suoraan jostain syystä    */
    SetTransparency(hwnd, x);

	a.Clear();
}
EDIT4: Latausaikaan vaikuttaa myös aika paljon ajaako ohjelman puretusta vai purkamattomasta tiedostosta.
Attachments
Transparency.rar
Läpinäkyvä cb:n ruutu
(757.37 KiB) Downloaded 279 times
Last edited by Jonhu on Tue May 18, 2010 6:53 pm, edited 5 times in total.
Tekeillä pikkupelejä ja ohjelmia :)
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Labyrint I

Post by koodaaja »

Kannattaa ehdottomasti piirtää tausta kuvaan ja piirrellä siitä, nopeus kasvaa tuhansia.
Wingman
Devoted Member
Posts: 594
Joined: Tue Sep 30, 2008 4:30 pm
Location: Ruudun toisella puolella

Re: Labyrint I

Post by Wingman »

Jonhu wrote:...Tuli tehty tuo aijempi läpinäkyvyys CB:n ikkunaan, mutta se ei toiminut ihan haluamallani tavalla :S CB:n ruutu päivittyy takaisin mustaksi, kun päivittää ruudun.. Kai tästä jollekkin on kuitenkin hyötyä, funktion voisi lisätä CBfuniin.
koitappas komentaa DrawScreen OFF; jättää näin sitten edelliset piirtokerrat näytölle

E: anteeksi offtopic
- - - -
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Labyrint I

Post by esa94 »

Jonhu wrote:

Code: Select all

//    pSetLayeredWindowAttributes (hwnd, 0, x, LWA_ALPHA);    /* <--- ei toiminut suoraan jostain syystä    */
Ehkä koska alussa on tuo p?

Offia:
Itsehän olen harras Systems Hungarianin, eli siis tämän yleisesti käytetyn unkarilaisen notaation vastustaja. Siinä ei ole mitään järkeä. Alun perinkin sen käyttö johtuu siitä, että Microsoftilla järjestelmäpuolen koodaajat eivät ymmärtäneet, mitä sen keksinyt koodaaja tarkoitti muuttujan 'tyypillä'. Mieshän ajatteli käyttötarkoitusta, järjestelmäihmiset datatyyppiä. Ja siksi joudun nyt kärsimään tällaisen koodin katselusta. :P
Jonhu
Active Member
Posts: 186
Joined: Mon Aug 04, 2008 5:45 pm

Re: Labyrint I

Post by Jonhu »

esa94 wrote:
Jonhu wrote:

Code: Select all

//    pSetLayeredWindowAttributes (hwnd, 0, x, LWA_ALPHA);    /* <--- ei toiminut suoraan jostain syystä    */
Ehkä koska alussa on tuo p?
Nuo ovat kaksi eri komentoa ;)
http://www.dreamincode.net/code/snippet1338.htm

SetLayeredWindowAttributes muuttaa vain ikkunan laitojen läpinäkyvyyttä ja pSetLayeredWindowAttributes muuttaa koko ikkunan läpinäkyvyyttä. Itsekkään en pidä erityisemmin WinApista, mutta ei tässä oikein toista keinoa löytynyt läpinäkyvyyteen ja tästäkään ei ihan minun tarkoitukseeni soveltuvaa :S
Tekeillä pikkupelejä ja ohjelmia :)
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Labyrint I

Post by esa94 »

Jonhu wrote:
esa94 wrote:
Jonhu wrote:

Code: Select all

//    pSetLayeredWindowAttributes (hwnd, 0, x, LWA_ALPHA);    /* <--- ei toiminut suoraan jostain syystä    */
Ehkä koska alussa on tuo p?
Nuo ovat kaksi eri komentoa ;)
http://www.dreamincode.net/code/snippet1338.htm

SetLayeredWindowAttributes muuttaa vain ikkunan laitojen läpinäkyvyyttä ja pSetLayeredWindowAttributes muuttaa koko ikkunan läpinäkyvyyttä. Itsekkään en pidä erityisemmin WinApista, mutta ei tässä oikein toista keinoa löytynyt läpinäkyvyyteen ja tästäkään ei ihan minun tarkoitukseeni soveltuvaa :S
Ach, no olet kai säätänyt _WIN32_WINNT:n Windows XP:lle?
Jonhu
Active Member
Posts: 186
Joined: Mon Aug 04, 2008 5:45 pm

Re: Labyrint I

Post by Jonhu »

Esa: En nyt lähtenyt tarkemmin tuota tutkimaan, mutta sama lopputulos tuosta olisi kuitenkin tullut, että CB:n ikkuna on läpinäkyvä vain raahattaessa ja silloin, kun sitä ei päivitetä cb:n piirtokomennoilla.. Tuo läpinkyvyys mahdollistaa cb:n syötteiden käyttämistä cbSDL:n ja cbOpenGLn kanssa, mutta tuosta tuskin on suurtakaan hyötyä..

Sourcet jakoon (hieman muunneltu versio).. Projektia tuskin vien enään eteenpäin, koska tulin siihen lopputulokseen, että nykyisellä CB:llä ilman suurta DLL-säätöä (eli kaikki piirto/syötteet DLL:ien kautta..) ei saa aikaiseksi tarpeaksi nopeaa latausta, jos haluaa ladata useampia tekstuureja kerralla.. Minulta saa toki kysyä apua aiheesta, jos joku lähtee tätä viemään eteenpäin..

Code: Select all


SCREEN 400, 300

Const Map_Width  = 20
Const Map_Height = 20

Const TEXTURE_max_height = 300
Const TEXTURE_min_height = 20

Type TEXTURE
    Field twidth 
    Field theight 
    Field mem          
    Field id
EndType

Dim Map( Map_Width, Map_Height ) 

loading_time1 = Timer()
LoadMap1("2d_map.txt")
LoadTextures("Wall1.jpg", 64, 64, 1 )
background = MakeBackGroundImg() 
loading_time = Timer() - loading_time1

// alkuasetukset..
posX# = 12.5 : dirX# = -1.0 : planeX# = 0.00 : MoveSpeed# = 0.1
posY# = 12.5 : dirY# =  0.0 : planeY# = 0.66 : RotSpeed#  = 4.0

Repeat
    
    // taustalle liikkumaton kuva, joka tuo vähän tunnelmaa :D
    DrawImage background,0,0
    
    // piirretään kenttä
    DrawRays( posX#, posY#, dirX#, dirY#, planeX#, planeY# )
    
    // Liikkuminen eteen ja taakse
    kerroin = KeyDown(cbkeyW) - KeyDown(cbkeyS) + KeyDown(cbkeyLShift)
    If kerroin <> 0 Then
    
        // tutkitaan uudet sijainnit x- ja y-suunnassa
        collision_map1 = Map( RoundDown(posX + dirX * moveSpeed*kerroin), RoundDown(posY) ) 
        collision_map2 = Map( RoundDown(posX), RoundDown(posY + dirY * moveSpeed*kerroin) )
        
        // jos kartalla uusi sijainti ei ole seinän päällä sallitaan siirto
        If collision_map1 + collision_map2 = 0 Then 
            posX# = posX# + dirX * moveSpeed * kerroin
            posY# = posY# + dirY * moveSpeed * kerroin
        EndIf
    EndIf
    
    // kääntyminen oikealle ja vasemmalle
    kerroin = KeyDown(cbkeyA) - KeyDown(cbkeyD) 
    If kerroin <> 0 Then 
    
        // vanhat arvot talteen laskuja varten
        oldDirX# = dirX
        oldPlaneX# = planeX
        
        // lasketaan uudet suuntavektorit
        dirX# = dirX * Cos(rotSpeed*kerroin) - dirY * Sin(rotSpeed*kerroin)
        dirY# = oldDirX * Sin(rotSpeed*kerroin) + dirY * Cos(rotSpeed*kerroin)
        
        // lasketaan uusi taso
        planeX# = planeX * Cos(rotSpeed*kerroin) - planeY * Sin(rotSpeed*kerroin)
        planeY# = oldPlaneX * Sin(rotSpeed*kerroin) + planeY * Cos(rotSpeed*kerroin)
    EndIf
    
    Color cbwhite
    Text 10,10,"FPS: "+FPS() + "  loading time: "+loading_time/1000.0+" s"
   // Text 10,30,posx+" : "+ posy
    
   DrawScreen
Forever

DeleteImage background
ClearImages()
End

Function LoadTextures( file$, width, height, ammount=1 )

    img_start = LoadImage(file$)
    //img_clone = CloneImage( img_start )
    different_sizes = Abs(TEXTURE_max_height-TEXTURE_min_height)+1
    
    Color cbwhite
    Locate ScreenWidth()/2  - 40, ScreenHeight()/2 - 20
    AddText "Loading..."
    
    // latauspalkki
    lbox_sw = ScreenWidth()/2
    lbox_sx = ScreenWidth()/2  - lbox_sw/2
    lbox_sy = ScreenHeight()/2 + 20
    lbox_sh = 10
    
    
    For a=0 To ammount-1
        aa.TEXTURE = New( TEXTURE )
        aa\twidth  = width
        aa\theight = height
        aa\id = a
        aa\mem = MakeMEMBlock( different_sizes*width*4 ) // 200*64*4 
        
          
        For d=TEXTURE_min_height To TEXTURE_max_height
          
            img_clone = MakeImage(width,height)
            CopyBox width*a,0,width,height,   0,0, Image(img_start), Image(img_clone)

            ResizeImage img_clone, width, d
          //  img_clone = ScaleImage( img_start, img_start, width, height )

            For x=0 To width-1
                img2 = MakeImage(1,d)
                CopyBox x, 0, 1, d, 0,0, Image(img_clone), Image(img2)
              //  DrawImage img2, x+100,10
                PokeInt aa\mem,  ((d-TEXTURE_min_height)*width + x)*4, img2
             
            Next x

            DeleteImage img_clone
            
            If (d Mod 5) = 0 Then
                lbox_len = Float(Float( d - TEXTURE_min_height ) / TEXTURE_max_height) * lbox_sw
                Color cbred   : Box lbox_sx, lbox_sy, lbox_len, lbox_sh, 1
                Color cbwhite : Box lbox_sx, lbox_sy, lbox_sw, lbox_sh, 0
                DrawScreen OFF
            EndIf
  
        Next d

        DrawScreen
    Next a
    
    DeleteImage img_start
    Color cbwhite
    ClearText
EndFunction


Function DrawRays( posX#, posY#, dirX#, dirY#, planeX#, planeY# )

    // määritetään raycasting alueen koko
    ProjectionPlane_w = ScreenWidth()
    ProjectionPlane_h = ScreenHeight()

    ff.TEXTURE = First(texture)
    For x=0 To ProjectionPlane_w - 1
        
        Camera_X# = 2.0 * Float(x) / Float(ProjectionPlane_w) - 1.0 
        
        rayPosX# = posX : rayDirX# = dirX + planeX * Camera_X : mapx = RoundDown( rayPosX )
        rayPosY# = posY : rayDirY# = dirY + planeY * Camera_X : mapy = RoundDown( rayPosY )

        deltaDistX# = Sqrt(1.0 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
        deltaDistY# = Sqrt(1.0 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
        
        If rayDirX < 0 Then stepX# = -1.0 Else stepX# = 1.0
        If rayDirY < 0 Then stepY# = -1.0 Else stepY# = 1.0    
        sideDistX# = ( ( mapX - rayPosX# ) * stepX + Min( 1.0, Max(stepx,0) ) ) * deltaDistX#
        sideDistY# = ( ( mapY - rayPosY# ) * stepY + Min( 1.0, Max(stepy,0) ) ) * deltaDistY#
      
        // siirrytään seuraavaan tileen, kunnes törmätään seinään --> etsitään törmäys kohta
        While Map( mapX, mapY ) = 0 
            If sideDistX# < sideDistY# Then
                sideDistX + deltaDistX
                mapX + stepX
                side% = 0
            Else
                sideDistY + deltaDistY
                mapY + stepY
                side% = 1
            EndIf
        Wend  // kun ollaan törmätty seinään, niin side-muuttuja kertoo tapahtuiko törmäys x- vai y-suunnassa. ( side 0 = vaaka, side 1 = pysty)

        // kohtisuoran rayn etäisyys
        If side = 0  Then 
            perpWallDist# = (Float(mapX) - rayPosX# + (1.0 - Float(stepX)) * 0.5) / rayDirX#
        Else           
            perpWallDist# = (Float(mapY) - rayPosY# + (1.0 - Float(stepY)) * 0.5) / rayDirY#
        EndIf
        
        //skaalaus ruutuun..
        LineHeight =  RoundDown(  Float(ProjectionPlane_h) / Abs(perpWallDist#) )
       
        //viivan lähtökohta y-suunnassa
        drawStartY%   = ProjectionPlane_h * 0.5 - lineHeight * 0.5 

        //teksturet..
        If side Then wallX# = rayPosX# + perpWallDist# * rayDirX# Else wallX# = rayPosY# + perpWallDist# * rayDirY#
        wallX# = wallX# - RoundDown(wallX)
        
        texNum = Map( mapX, mapY ) - 1 
        If old_num <> texNum Then // todennäköisesti ei ole muuttunut..
            old_num = 0
            // valitaan oikea teksture
            For aa.TEXTURE = Each TEXTURE 
                If aa\id = texNum Then // aa\id lähtee 0:sta
                    ff = aa
                    Exit
                EndIf
                old_num + 1
            Next aa
        EndIf
        
        //x-koordinaatti teksturessa
        texX% = RoundDown(wallX * Float(ff\twidth))
        If Lineheight > ProjectionPlane_h Then texX = texX - 1

        // Piirto...
        // Box x, Max( drawstartY,0) , 1, Max( Min( lineHeight, TEXTURE_max_height ), 0)
        DrawStripe( x,Max( drawstartY,0), ff\mem, Max(Min(texX,ff\twidth-1),0), ff\twidth,  Max( Min( lineHeight, TEXTURE_max_height ), TEXTURE_min_height) )

    Next x

EndFunction

Function DrawStripe( x1,y1, mem, kohtax, width, height )
        DrawImage PeekInt(mem, ( (height-TEXTURE_min_height)*width+kohtax )*4) ,x1, y1
EndFunction

Function ClearImages()
    For aa.texture = Each texture
        For d=TEXTURE_min_height To TEXTURE_max_height
            For x=0 To TEXTURE_max_height-TEXTURE_min_height
                img = PeekInt(mem, ( (d-TEXTURE_min_height)*aa\twidth+x )*4)
                DeleteImage img
            Next x
        Next d
    Next aa
EndFunction

Function LoadMap1(txt$)
    r=OpenToRead(txt$)
    While Not EOF(r)
        rivi$ = Trim( ReadLine(r) )
        If Len(rivi$)>3 Then
            If rivi$ = Upper("!End") Then
                Exit
            Else
                sanoja = CountWords(rivi$, " ")
                For x=0 To sanoja-1
                    map(x,y1) = Int( GetWord( rivi$, x+1," ") )
                Next x
                y1 + 1
            EndIf
        EndIf
    Wend
    CloseFile r
EndFunction

// tekee taustan piirtämällä erivärisiä viivoja vaakatasoon taustaksi
Function MakeBackGroundImg()
    img = MakeImage( ScreenWidth(),ScreenHeight()) 
    DrawToImage img
    
        For y=0 To ImageHeight(img)/2
            Color 20,20,205-y/2
            Line 0,y,ImageWidth(img),y
        Next y
        
        For y=ImageHeight(img) To ImageHeight(img)/2 Step -1
            l = (y-ImageHeight(img)/2.0)
            Color 20,20+l/2,10
            Line 0,y,ImageWidth(img),y
        Next y
        
    DrawToScreen
    Return img
EndFunction
EDIT:

Aiheesta muualla:
http://www.academictutorials.com/graphi ... ing-ii.asp
http://www.permadi.com/tutorial/raycast/index.html

Osa kaavoista tuli melko suoraan kopioitua, kun ei itse jaksanut alkaa laskea :roll: Kiitokset kaavan keksijälle, mutta samaa kaavaa kyllä käytetään useissa eri esimerkeissä, tiedä sitten mikä niistä on alkuperäinen... Seinäbugin tehokas ratkaisu jäi mysteeriksi, mutta hitaan ratkaisun saisi kai vain muuttamalla kuvan kokoa ruudunkokoa suuremmaksi, mutta tällä hetkellä tuo on rajoitettu ruudun korkeuteen..
Tekeillä pikkupelejä ja ohjelmia :)
Post Reply