Functio "loadimage" zum laden einzelner Frames eines Tilesets

Previous topic - Next topic

D2O

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

D2O

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

D2O

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

D2O

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

peterpan

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

AndyH

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.

D2O

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

Schranz0r

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 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

AndyH

I'm hoping that command can be added soon :)

Kitty Hello


D2O

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

Schranz0r

I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Quentin

Oh Mann, gibts eigentlich keine Geschwindigkeitsbegrenzungen für Updates? ;)

Kitty Hello


Schranz0r

IF Update < Ein_Tag
    BREAKE
ElSE
    NEXT
ENDIF
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard