Author Topic: Functio "loadimage" zum laden einzelner Frames eines Tilesets  (Read 6363 times)

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
Hi ich habe mich mal an einer Function gemacht,
die es erlaubt Frames aus einem Tileset zu laden das nicht nur Horizontal oder Vertical angelegt ist.
Mit hilfe von "STATIC" werden auch keine globalen Variablen benutzt.

Ich hoffe ich habe nicht allzu wirr Programiert ;)

Hier mal die Bilder dazu:
http://www.deuteriumoxid.com/glbasic/tile.bmp
http://www.deuteriumoxid.com/glbasic/tile2.png

Function und Beispiel:
Code: GLBasic [Select]
// --------------------------------- //
// Project: LoadImage2
// Start: Saturday, March 03, 2007
// IDE Version: 4.114




///Beispiel:

// Die Bilder haben je 18 Tiles, einmal 32x32 und 128x128
DIM bild1[18]
DIM bild2[18]
                                // ertes Bild laden
                                // 0 - 17 = 18 Tiles
        FOR i = 0 TO 17
                bild1[i] = loadimage("tile.bmp",32,32,17,0)
        NEXT
                                // zweites Tile laden
        FOR i = 0 TO 17
        bild2[i] = loadimage("tile2.png",128,64,17,0)
        NEXT

// Variablen für das anzeigen, nur Testweise
GLOBAL c = 0
GLOBAL d = 0

//////////////////////////////////////////////////////////////////////////

WHILE TRUE
KeyHitUpdate()

IF KeyHit(57) = 2
                INC c,1
                IF c > 17 THEN c = 0
ENDIF

                        SPRITE bild1[c],0,0
                        SPRITE bild2[c],32,32

                        PRINT bild1[c],0,200
                        PRINT bild2[c],0,220
                        PRINT "Space Taste Drücken",100,100
                SHOWSCREEN

WEND
/////////////////////////////////////////////////////////////////////////

// Ende vom Beispiel


//----Function loadimage ------------------------------------------

// erklärung der Argumente:
// l_path$ übernimmt die Pfad angabe der Datei
// l_tilex und l_tiley sind die Pixelbreite und höhe des einzelnen Tiles
// l_anzahl bekommt den Maximal wert der forschleife, siehe beispiel.
// l_tilenr ist der Index für loadsprite, er kann aber muss nicht unterschiedlich sein



FUNCTION loadimage:l_path$,l_tilex,l_tiley,l_anzahl,l_tilenr
        STATIC s_counter = 1000  //Ab 1000 damit überschneidungen mit loadsprite nicht vorkommen
        STATIC s_controll  //Kontrollschalter damit Loadsprite nur einmal benutzt wird
        STATIC s_temp
        STATIC s_x,s_y  // zum berechnen der Tile anzahl
        STATIC s_xcount,s_ycount // Counter für die Positions verschiebung
                // Variablien für Grundposition auf die sich die Verschiebung berechnet| x = 0 | y = 0
                LOCAL l_posx
                LOCAL l_posy



// maximal 2000 möglich, hier kann/muss man selber etwas verwalten
        IF s_counter > 2000 THEN s_counter = 1000
                        IF s_controll = 0
                                s_temp = s_counter
                                LOADSPRITE l_path$,l_tilenr
                                GETSPRITESIZE l_tilenr,s_x,s_y // Abfrage wie gross das Bild ist
                                                        //Damit nur Ganzzahlen zurückgegeben werden
                                s_x = INTEGER(s_x/l_tilex)
                                s_y = INTEGER(s_y/l_tiley)
                        ENDIF

                 s_controll = 1 // damit loadsprite nich mehrmals ausgeführt wird
               
//------------------------------------------------------
                        IF s_xcount < s_x // X ACHSE
                                        l_posx = (-s_xcount*l_tilex)    // position nach links verschieben
                                        l_posy = (-s_ycount*l_tiley)    //position nach oben verschieben
                                        s_xcount = s_xcount +1                  // für den nächsten durchlauf x achse erhöhen

                                                        // Y ACHSE
                                                IF s_xcount = s_x
                                                s_ycount = s_ycount +1  //y achse nach ober erhöhen
                                                s_xcount = 0                    // x achse wieder auf 0 setzen
                                                                                                        // S_controll wieder auf null zurücksetzen
                                                                                                        // damit man auch das nächste Bild wieder laden kann
                                                                        IF s_counter >= (s_temp+l_anzahl) THEN s_controll = 0

                                                                IF s_controll  = 0
                                                                s_xcount = 0    // X/Y Verschiebung zurücksetzen
                                                                s_ycount = 0
                                                                ENDIF
                        ENDIF
                                // Einzelne Sprites erstellen
                                        SPRITE l_tilenr,l_posx,l_posy
                                        GRABSPRITE s_counter,0,0,l_tilex,l_tiley
                                        SHOWSCREEN // Showscreen kann auskommentiert werden
                                        BLACKSCREEN //Bilschirm Buffer wieder leeren
                                //---------------------------------------------------- 
                                        INC s_counter,1 // Counter um 1 erhöhen
        ENDIF




                        RETURN s_counter -1
ENDFUNCTION







// Gernots spitzen Function für ein KeyHit()



FUNCTION KeyHitUpdate:
GLOBAL gKeyDown[], gKeyState[]
LOCAL  k
LOCAL i
    // First Time call/ zum ersten Mal hier
    IF BOUNDS(gKeyDown[],0)=0
        DIM gKeyDown[256]
        DIM gKeyState[256]
    ENDIF

    // For each key / für jede Taste
    FOR i=0 TO 255
        k = KEY(i)
        // Key is pressed / Taste ist gedrückt
        IF k
            IF gKeyDown[i]
                gKeyState[i]=1
            ELSE
                gKeyDown[i]=1
                gKeyState[i]=2
            ENDIF
        ELSE
            // Key is not pressed / Taste nicht gedrückt

            // Has key been pressed before?
            // War die Taste gedrückt?
            IF gKeyDown[i]
                gKeyDown[i] = 0
                gKeyState[i] = -1
            ELSE
                gKeyState[i]=0
            ENDIF
        ENDIF
    NEXT
ENDFUNCTION





//  0 = not pressed / nicht gedrückt
//  2 = just pressed / gerade runtergedrückt
//  1 = pressed / gedrückt (gehalten)
// -1 = release event / wieder losgelassen
FUNCTION KeyHit: nkey
    RETURN gKeyState[nkey]
ENDFUNCTION
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
Edit:
Oops, hier hatte sich ein schreibfehler eingeschlichen,
Code: GLBasic [Select]
player1= loadimage("tile.bmp",32,32,18)
Wurde  ausgebessert, Danke BumbleBee.



HI,
hier gibts ne neue version.
Diesmal wird ein Type benutzt, das hat den vorteil das ich die forschleife für das laden in der Function nutzen kann.
Aufgerufen wird jetzt so:

Code: GLBasic [Select]
Global player as Tloader
player = loadimage("Datei", grösse X, grösse Y, Anzahl der Frames)
Code und Beispiel:

// --------------------------------- //
// Project: imageloaderv4
// Start: Wednesday, March 07, 2007
// IDE Version: 4.114

Code: GLBasic [Select]
// Beispiel:

GLOBAL player1 AS Tloader
GLOBAL player2 AS Tloader


player1= loadimage("tile.bmp",32,32,18)
player2 = loadimage("tile2.png",128,64,18)

GLOBAL a
WHILE TRUE
INC a,1
IF a > 17 THEN a = 0

SPRITE player1.pic[a],0,0
SPRITE player2.pic[a],100,100

SHOWSCREEN

MOUSEWAIT
WEND
/////////// Beispiel Ende


//--------------------------------loadimage---------------------------


FUNCTION loadimage AS Tloader:l_path$,l_tilex,l_tiley,l_anzahl//,l_index
        STATIC s_counter = 1000  //Ab 1000 damit überschneidungen mit loadsprite nicht vorkommen

                //-------------
        LOCAL l_x,l_y  // zum berechnen der Tile anzahl aus der Image grösse
        LOCAL  l_xcount,l_ycount // Counter für die Positions verschiebung
        LOCAL imagetemp // für die aufnahme des Tilsets
        LOCAL image AS Tloader //für die aufnahme der Tiles


        LOCAL l_posx,l_posy     // Variablien für Grundposition auf die sich die Verschiebung berechnet| x = 0 | y = 0
        LOCAL l_i                                // für die for schleife
        LOCAL countertemp


                REDIM image.pic[l_anzahl]

                        countertemp = s_counter //Index Temporär speichen um später den Speicher wieder freizu geben
                        LOADSPRITE l_path$,countertemp //image laden
                        GETSPRITESIZE countertemp,l_x,l_y       //Image grösse ermitteln

                                l_x = INTEGER(l_x/l_tilex)
                                l_y = INTEGER(l_y/l_tiley)



                                         LOADSPRITE l_path$,countertemp
                                                INC s_counter,1  //index um 1 erhöhen


                        FOR l_i = 0 TO l_anzahl-1

                                        IF l_xcount < l_x
                                                        l_posx = (-l_tilex*l_xcount)
                                                        ELSE
                                                                l_xcount = 0
                                                                l_posx = (-l_tilex*l_xcount)
                                                                INC l_ycount,1
                                        ENDIF

                                        IF l_ycount < l_y
                                                        l_posy = (-l_tiley*l_ycount)
                                                        ELSE
                                                                INC l_ycount,1
                                                                l_posy = (-l_tiley*l_ycount)
                                        ENDIF

                                        SPRITE countertemp,l_posx,l_posy
                                        GRABSPRITE s_counter,0,0,l_tilex,l_tiley
                                        SHOWSCREEN //__________________________________________
                                        BLACKSCREEN

                                                image.pic[l_i] = s_counter
                                        INC l_xcount,1
                                        INC s_counter,1
                        NEXT

                                LOADSPRITE "NULL",countertemp  //Speichfreigenen

                                RETURN image

ENDFUNCTION




// Dieser Type wir gebraucht um aus der function loadimage ein array als rückgabe wert zu nutzen
// er könnte auch für die bild positionen usw. erweitert werden
TYPE Tloader
pic[]
ENDTYPE
Noch ne Frage :)
Ist das so richtig um einen Speicher wieder Frei zugeben wenn nichts geladen wird?
Code: GLBasic [Select]
LOADSPRITE "NULL",countertemp  //Speichfreigenen
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
Habe hier eine kleine erweiterung eingbaut, einen Ladebalken mit Prozent anzeige.
Bei grösseren Tilestes kann das Laden/Graben ein paar sekunden dauern, und es ist ja nicht schlecht wenn man den fortschritt sieht.
Den Type Tloader ist in Tsprite umgetauft worden, finde das das besser passt.

Edit: Hab vergessen die Transparentfarbe mit einzubauen.
Code gefixt.

Code: GLBasic [Select]
// --------------------------------- //
// --------------------------------- //
// Project: loadimagev6
// Start: Saturday, March 10, 2007
// IDE Version: 4.114

// Code example :

GLOBAL player1 AS Tsprite
GLOBAL player2 AS Tsprite


player1= loadimage("tile.bmp",32,32,18)
player2 = loadimage("tile2.png",128,64,18)
//
GLOBAL a
WHILE TRUE

IF a > 17 THEN a = 0
SPRITE player1.pic[a],0,0
SPRITE player2.pic[a],100,100

SHOWSCREEN

MOUSEWAIT
INC a,1
WEND
/////////// Code example End


//--------------------------------loadimage---------------------------
// file Path, tile wight, tile high, tile pay down

FUNCTION loadimage AS Tsprite:l_path$,l_tilex,l_tiley,l_anzahl
    STATIC s_counter = 1000  //Ab 1000 damit überschneidungen mit loadsprite nicht vorkommen

        //-------------
    LOCAL l_x,l_y  // zum berechnen der Tile anzahl aus der Image grösse
    LOCAL  l_xcount,l_ycount // Counter für die Positions verschiebung
    LOCAL imagetemp // für die aufnahme des Tilsets
    LOCAL image AS Tsprite //für die aufnahme der Tiles
    LOCAL l_showload // Variablen für Ladebalken
    LOCAL l_prozent
    l_showload = 100/l_anzahl

    image.tilex = l_tilex
    image.tiley = l_tiley
    image.frame = l_anzahl -1


    LOCAL l_posx,l_posy     // Variablien für Grundposition auf die sich die Verschiebung berechnet| x = 0 | y = 0
    LOCAL l_i                 // für die for schleife
    LOCAL countertemp


        REDIM image.pic[l_anzahl]

            countertemp = s_counter    //Index Temporär speichen um später den Speicher wieder freizu geben
            LOADSPRITE l_path$,countertemp //image laden
            GETSPRITESIZE countertemp,l_x,l_y    //Image grösse ermitteln

                l_x = INTEGER(l_x/l_tilex)
                l_y = INTEGER(l_y/l_tiley)



                     LOADSPRITE l_path$,countertemp
                         INC s_counter,1  //index um 1 erhöhen


            FOR l_i = 0 TO l_anzahl-1

                    IF l_xcount < l_x
                            l_posx = (-l_tilex*l_xcount)
                            ELSE
                                l_xcount = 0
                                l_posx = (-l_tilex*l_xcount)
                                INC l_ycount,1
                    ENDIF

                    IF l_ycount < l_y
                            l_posy = (-l_tiley*l_ycount)
                            ELSE
                                INC l_ycount,1
                                l_posy = (-l_tiley*l_ycount)
                    ENDIF
                    FILLRECT 0,0,l_tilex,l_tiley,RGB(255,0,128) ///<<<<<<<< FIX :)
                    SPRITE countertemp,l_posx,l_posy
                    GRABSPRITE s_counter,0,0,l_tilex,l_tiley
                    BLACKSCREEN
                   
                    ///Ladebalken---------------
                    INC l_prozent,l_showload
                        PRINT INTEGER(l_prozent)+"% geladen",100+l_prozent,480
                        FILLRECT 100,500,100+l_prozent,500+10,RGB(20,200,20)
                    ///-----------------------------
                    SHOWSCREEN //__________________________________________
                   

                        image.pic[l_i] = s_counter
                    INC l_xcount,1
                    INC s_counter,1
            NEXT

                LOADSPRITE "",countertemp  //Speichfreigenen

                RETURN image

ENDFUNCTION




// Dieser Type wir gebraucht um aus der function loadimage ein array als rückgabe wert zu nutzen
// er könnte auch für die bild positionen usw. erweitert werden
TYPE Tsprite
pic[]
x //positionen
y
tilex // Tilegrösse
tiley
frame //anzahl der frames
ENDTYPE
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
Neuer Alternativer Code für Tileset Grafiken.
Angepasst an GLB > v5.
Bilder dazu kann man im ersten posting downloaden.

Code: GLBasic [Select]
// --------------------------------- //
// Project: Loadanim_v7
// Start: Monday, January 28, 2008
// IDE Version: 5.150


// --------------------------------- //
// --------------------------------- //
// Project: loadimagev6
// Start: Saturday, March 10, 2007
// IDE Version: 4.114

// Code example :

GLOBAL player1 AS Tsprite
GLOBAL player2 AS Tsprite


player1= loadimage("tile.bmp",32,32,18)
player2 = loadimage("tile2.png",128,64,18)
//
GLOBAL a
WHILE TRUE

IF a > 17 THEN a = 0
DRAWSPRITE player1.pic[a],0,0
DRAWSPRITE player2.pic[a],100,100

SHOWSCREEN

MOUSEWAIT
INC a,1
WEND
/////////// Code example End


//--------------------------------loadimage---------------------------
//  file Path, tile wight, tile high, tile pay down

FUNCTION loadimage AS Tsprite:l_path$,l_tilex,l_tiley,l_anzahl
    STATIC s_counter  
        STATIC s_ctrl
                                IF s_ctrl = 0
                                        s_counter = 1000 //Ab 1000 damit überschneidungen mit loadsprite nicht vorkommen
                                        s_ctrl = 1
                                ENDIF
        //-------------
    LOCAL l_x,l_y  // zum berechnen der Tile anzahl aus der Image grösse
    LOCAL  l_xcount,l_ycount // Counter für die Positions verschiebung
    LOCAL imagetemp // für die aufnahme des Tilsets
    LOCAL image AS Tsprite //für die aufnahme der Tiles
    LOCAL l_showload // Variablen für Ladebalken
    LOCAL l_prozent
    l_showload = 100/l_anzahl

    image.tilex = l_tilex
    image.tiley = l_tiley
    image.frame = l_anzahl -1


    LOCAL l_posx,l_posy     // Variablien für Grundposition auf die sich die Verschiebung berechnet| x = 0 | y = 0
    LOCAL l_i                 // für die for schleife
    LOCAL countertemp


        REDIM image.pic[l_anzahl]

            countertemp = s_counter    //Index Temporär speichen um später den Speicher wieder freizu geben
            LOADSPRITE l_path$,countertemp //image laden
            GETSPRITESIZE countertemp,l_x,l_y    //Image grösse ermitteln

                l_x = INTEGER(l_x/l_tilex)
                l_y = INTEGER(l_y/l_tiley)



                     LOADSPRITE l_path$,countertemp
                         INC s_counter,1  //index um 1 erhöhen


            FOR l_i = 0 TO l_anzahl-1

                    IF l_xcount < l_x
                            l_posx = (-l_tilex*l_xcount)
                            ELSE
                                l_xcount = 0
                                l_posx = (-l_tilex*l_xcount)
                                INC l_ycount,1
                    ENDIF

                    IF l_ycount < l_y
                            l_posy = (-l_tiley*l_ycount)
                            ELSE
                                INC l_ycount,1
                                l_posy = (-l_tiley*l_ycount)
                    ENDIF
                    DRAWRECT 0,0,l_tilex,l_tiley,RGB(255,0,128) ///<<<<<<<< FIX :)
                    DRAWSPRITE countertemp,l_posx,l_posy
                    GRABSPRITE s_counter,0,0,l_tilex,l_tiley
                    BLACKSCREEN
                   
                    ///Ladebalken---------------
                    INC l_prozent,l_showload
                       PRINT INTEGER(l_prozent)+"% geladen",1+l_prozent,80
                          DRAWRECT 0, 100, 1*l_prozent, 20, RGB(0, 255, 255) //Türkis

                    ///-----------------------------
                   
                   
                    SHOWSCREEN //__________________________________________
                   
                                       
                        image.pic[l_i] = s_counter
                    INC l_xcount,1
                    INC s_counter,1
            NEXT

                LOADSPRITE "",countertemp  //Speichfreigenen
                               
                RETURN image

ENDFUNCTION




// Dieser Type wir gebraucht um aus der function loadimage ein array als rückgabe wert zu nutzen
// er könnte auch für die bild positionen usw. erweitert werden
TYPE Tsprite
pic[]
x //positionen
y
tilex // Tilegrösse
tiley
frame //anzahl der frames
ENDTYPE
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline peterpan

  • Mr. Polyvector
  • ***
  • Posts: 117
    • View Profile
Hallo D²O,

gute Sache !!

Ich hab sowas ähnliches für mich entwickelt.
Funktioniert alles ganz Prima hier.

LoadAnim und DrawAnim sind aber ganz feine Befehle, die man wirklich
braucht, sollten unbedingt korrigiert werden.

Peter

Offline AndyH

  • Dr. Type
  • ****
  • Posts: 383
    • View Profile
    • http://www.ovine.net/
The LoadAnim and DrawAnim can not currently be used with SPRCOLL command.  We need an ANIMCOLL type of command before DRAWANIM can be used successfully.

Die LoadAnim und DrawAnim kann derzeit nicht verwendet werden, mit SPRCOLL Befehl. Wir brauchen eine Art von Befehl ANIMCOLL vor DRAWANIM erfolgreich genutzt werden können.

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
Hi Andy,
right, I read  in the English forum.

@peterpan,
Du hast recht, das sind zwei super befehle und man muss sich nicht so den kopf machen wegen den Sprite ID, braucht nicht ne extra Type Variable...
usw.
Zudem schauts es einfach besser aus, alles aus einem Guss und nicht dazu gefrimmelt ;)
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5014
  • O Rly?
    • View Profile
AndyH youre right, we need a SPRANIMCOLL!

like this:
(2 Animations)

Code: GLBasic [Select]
SPRANIMCOLL(X1,Y1,Frame1,X2,Y2,Frame2)
(1 Animation and 1 normal Sprite)

Code: GLBasic [Select]
SPRANIMCOLL(X1,Y1,Frame1,X2,Y2,0)
I <3 DGArray's :D

PC:
AMD RYzen 7 1700 @3.9Ghz, 16GB HyperX Fury 2666Mhz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline AndyH

  • Dr. Type
  • ****
  • Posts: 383
    • View Profile
    • http://www.ovine.net/
I'm hoping that command can be added soon :)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
ANIMCOLL. See update.

Offline D2O

  • Prof. Inline
  • *****
  • Posts: 1062
    • View Profile
    • http://www.deuteriumoxid.com
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5014
  • O Rly?
    • View Profile
I <3 DGArray's :D

PC:
AMD RYzen 7 1700 @3.9Ghz, 16GB HyperX Fury 2666Mhz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline Quentin

  • Prof. Inline
  • *****
  • Posts: 915
    • View Profile
Oh Mann, gibts eigentlich keine Geschwindigkeitsbegrenzungen für Updates? ;)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Doch. Max 1 pro Tag ;)

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5014
  • O Rly?
    • View Profile
IF Update < Ein_Tag
    BREAKE
ElSE
    NEXT
ENDIF
I <3 DGArray's :D

PC:
AMD RYzen 7 1700 @3.9Ghz, 16GB HyperX Fury 2666Mhz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard