Simple SpriteSheet Editor step by step in QB64pe - TempodiBasic - 06-04-2023
Hi
this is a first version of a SpriteSheet editor: a program that loads a SpriteSheet and let you modify it painting with simple tools or/and lets to select an area as a single sprite into the sheet. After selected the sprites, you can save their cohordinates into a DATA file to use into your code with the original SpriteSheet and you can see the selected sprite shown on the screen.
It is a project step by step:
this first step brings a program with a main window that will be adapted to the spritesheet loaded and on this the user can define the 2 points to select an area of the picture to do a single sprite. You can accept/store or cancel each point selected before, after stored point 1 and 2 you get the sprite that is highlighted by a red square.
You can stop the selecting function pressing spacebar into the main loop or mousebutton2 while you are selecting the point 2.
the selected sprites will be displayed at the end of the procedure of selection.
This program uses a second area /canvas to give output to the user as messages or warnings or instructions.
I have posted some screenshots.
It is really incomplete but it can grow up if I use Option _explicit avoiding to waste so much time with bugs going out from my typo errors!
Code: (Select All) Option _Explicit
Rem SPRITE SHEET EDITOR
Rem this software has the purpouse to load an image of a sprite sheet
Rem and in SELECT MODE it allows to the user to select an area,
Rem or in EDIT MODE to paint changing the images into the sprite sheet
_Title "SpriteSheet Editor"
Const W = 1200, H = 800
'global varables
Dim Shared Main&, Sprite&, NameFile$, SSheet&, HelpS&
ReDim Sprites&(1 To 1)
Dim Shared As Integer Xm(1 To 2), Ym(1 To 2), SprC(1 To 4, 1 To 100)
' main variables
Dim Mg As Integer, a As Integer, Mb1 As Integer, Mb2 As Integer, kb As Integer, spr As Integer
Main& = _NewImage(W, H, 32)
HelpS& = _NewImage(W, H / 4, 32)
Screen Main&
_PrintString ((W / 2) - (10 * 8), H / 2), "SPRITES SHEET EDITOR" ' the title is 20 characters
_Delay 3
_SetAlpha 125, HelpS& ' area of output is half transparent
LoadI
Mg = 13: a = 0 'Mg pixel between 2 lines of the reticulus, a is a counter
While kb <> 32 ' while user does not press spacebar, he can define area on the screen delimiting sprites to capture into single area/canvas
Helping " Press spacebar to end", 1
If MouseData(Mb1, Mb2) = -1 Then 'it evaluates mouseinput
If Mb1 Then 'did mouse button 1 trigger?
' it starts the procedure for storing X an Y of points 1 (topleft) and 2 (bottomright)
If StoreMouseData(1) = -1 Then ' it stores mouse data for topleft point of sprite
While 1
Helping " Press spacebar to end", 1
Helping Str$(_MouseX) + Str$(_MouseY) + Space$(8), 0
'_Dest HelpS&: Locate 4, 26: Print kb; Space$(10);
'Locate 5, 1: Print _MouseX, _MouseY; Space$(8);: _Dest 0
'_PutImage (0, 2 * (_Height(0))), HelpS&,
If MouseData(Mb1, Mb2) = -1 Then ' it evaluates mouse input
Helping " Press spacebar to end", 1
Helping Str$(_MouseX) + Str$(_MouseY) + Space$(8), 0
' it adjourns the keyboard and mouse information
'_Dest HelpS&: Locate 4, 26: Print kb; Space$(10);
'Locate 5, 1: Print _MouseX, _MouseY; Space$(8);: _Dest 0
'_PutImage (0, 2 * (_Height(0))), HelpS&,
If Mb1 Then 'did mousebutton 1 trigger?
If StoreMouseData(2) = -1 Then ' yes, it stores mouse data bottomright
' after confirming the two points of the sprite it memorizes their cohordinates into SprC array
spr = spr + 1 ' sprite counter
SprC(1, spr) = Xm(1): Xm(1) = 0 'X1
SprC(2, spr) = Ym(1): Ym(1) = 0 'Y1
SprC(3, spr) = Xm(2): Xm(2) = 0 'X2
SprC(4, spr) = Ym(2): Ym(2) = 0 'Y2
Line (SprC(1, spr), SprC(2, spr))-(SprC(3, spr), SprC(4, spr)), _RGB32(233, 0, 6), B
Helping Str$(spr) + "/" + Str$(SprC(1, spr)) + "+" + Str$(SprC(2, spr)) + "--" + Str$(SprC(3, spr)) + "+" + Str$(SprC(4, spr)), 0
_Delay 1
Exit While ' after storing point 2 of sprite it returns to external loop
Else
Helping "To exit press mouse button 2", 0
_Delay 2
End If
End If
If Mb2 = -1 Then Exit While
End If
Wend
End If
' if no data stored for point 1 topleft it runs again the loop
End If
End If
kb = _KeyHit
' escaping way
If kb = 13 Then Grid
Helping Str$(kb), 0
Helping Str$(_MouseX) + Str$(_MouseY), 0
While _MouseInput: Wend ' it voids the mouse buffer
_Limit 10
Wend
Screen Main&
Helping "Save data of sprites into a DATA code file (Y/N)?", 1
kb = 0
While kb = 0
kb = _KeyHit
If kb = 89 Or kb = 121 Then SaveDATAtoFile: Exit While 'Y or y
If kb = 78 Or kb = 110 Then Exit While ' N or n
kb = 0
Wend
' getting single sprites with newimage
ReDim Sprites&(1 To spr), x As Integer, y As Integer
For a = 1 To spr
Sprites&(a) = _NewImage(Abs(SprC(1, a) - SprC(3, a)), Abs(SprC(2, a) - SprC(4, a)), 32)
_PutImage , Sprite&, Sprites&(a), (SprC(1, a), SprC(2, a))-(SprC(3, a), SprC(4, a)) 'it copies area of spritesheet to single area/canvas
x = x + _Width(Sprites&(a)) ' it adjourns the cohordinates X for showing sprites in sequence
y = _Height(Sprites&(a))
_PutImage (x, y), Sprites&(a), 0 ' showing sprites from 1 to top
Next a
End
Sub SaveDATAtoFile
Rem Saveto DATA file
Rem save to file in DATA format the array SprC
Dim n As Integer
Open "Datafile.txt" For Output As #1
Helping "Saving data...", 0
Print #1, "Data";
For n = 1 To 100 Step 1
If SprC(1, n) = 0 Then _Continue ' if it finds a wrong value it exits from FOR loop
If (n Mod 9) = 0 Then Print #1,: Print #1, "Data"; Else If n > 1 Then Print #1, ",";
Print #1, SprC(1, n), ",", SprC(2, n), ",", SprC(3, n), ",", SprC(4, n);
Next
Close #1
Helping "Saved data!", 1
End Sub
Function MouseData (Mb1 As Integer, Mb2 As Integer)
MouseData = 0
While _MouseInput: Wend ' it waits that mouse input ends
Mb1 = _MouseButton(1)
Mb2 = _MouseButton(2)
If Mb1 <> 0 Or Mb2 <> 0 Then MouseData = -1 ' if no mousebutton then function returns failure
End Function
Function StoreMouseData (Index As Integer)
Dim kb As Integer, OldC As Long
StoreMouseData = 0
If _MouseX > 0 Then Xm(Index) = _MouseX Else Xm(Index) = 1 ' it corrects wrong 0 values
If _MouseY > 0 Then Ym(Index) = _MouseY Else Ym(Index) = 1
If Xm(Index) > 0 And Ym(Index) > 0 Then
' both cohordinates are good?
Helping "Storing point " + Str$(Index) + Str$(Xm(Index)) + "-" + Str$(Ym(Index)) + " Cancel/Store?", 0
OldC = Point(Xm(Index), Ym(Index))
PSet (Xm(Index), Ym(Index)), _RGB32(211, 255, 6)
While 1 'kb <> 83 Or kb <> 115
' here the loop to take cancel/store data
kb = _KeyHit
If kb = 67 Or kb = 99 Then
PSet (Xm(Index), Ym(Index)), OldC
Exit Function ' if key is c or C then exit function returning the failure
End If
If kb = 83 Or kb = 115 Then Exit While
Wend
Helping "Stored", 0
_Delay 1
StoreMouseData = -1
Else
Exit Function
End If
End Function
Sub Grid
Shared Mg As Integer, a As Integer
For a = 1 To W Step Mg
Line (a, 1)-(a, W), Mg
Next
For a = 1 To H Step Mg
Line (1, a)-(H, a), Mg
Next
End Sub
Sub LoadI
NameFile$ = ".\defendersprites.jpg" '<----- coming soon Open option to type name of file and better an Opendialog box
If _FileExists(NameFile$) Then
Helping "File founded", 1
Sprite& = _LoadImage(NameFile$)
Else
Helping "Error: image not loaded", 1
Sprite& = -1000 ' sprite& brings the failure flag
_Delay 2
Exit Sub
End If
_Delay 1
SSheet& = _NewImage(_Width(Sprite&), _Height(Sprite&), 32)
Screen SSheet&
_PutImage , Sprite&, 0
End Sub
Sub PaletteS
Dim n As Integer
For n = 1 To 256
'pset (n,1),n
Line (n, 1)-(n, 256), n, BF
Next n
Sleep 2
End Sub
Sub Helping (Msg As String, M As Integer)
_Dest HelpS&
If M = 1 Then Cls
Print Msg
_Dest 0
_PutImage (0, 2 * (_Height(0) / 3)), HelpS&,
End Sub
Welcome feedbacks and propositive criticisms.
I'm thinking to add a third way to select the area with a dragging of mouse like in the graphic editor in which you draw a square/rectangle.
Moreover I need an OpenDialog box to choose the file of the Spritesheet to modify. I think that the created/selected sprites must be managed like in a list box with a single/multiple selection for doing specific actions (Save, Cancel, Edit...).
I have never used a SpriteSheet Editor but I'm doing it from zero with poor plan... this will cause so much modifications! Sob. Better measures twice and cut ones.
this is the spritesheet that I have used as file, but use whatever do you want
RE: Simple SpriteSheet Editor step by step in QB64pe - bplus - 06-04-2023
Nice idea, I remember at the other forum Johnno starting an editor but that was only for single images.
RE: Simple SpriteSheet Editor step by step in QB64pe - TempodiBasic - 06-04-2023
@Bplus
Thanks, I hope to bring to a first finished program this idea!
RE: Simple SpriteSheet Editor step by step in QB64pe - grymmjack - 06-05-2023
This is a great idea!
Like a slicer/atlas maker?
RE: Simple SpriteSheet Editor step by step in QB64pe - TempodiBasic - 06-07-2023
Yes slicer/atlas spritesheet.
the 2 points that led me to take this decision are that I have had difficult to manage SpriteSheet with different sprites' dimensions.
You need map the spritesheet by a grid, but sometimes larger sprites are not a multiple of smaller sprite and so this way fails.
So it is very difficult loading properly the larger sprites without mapping each single sprite.
The other point is that you can choose and save as single image file only the sprites that you need, or the data of their dimensions so you can load directly them without loading all the sprites that are on the spritesheet.
Surely if you use a standar spritesheet in which alla the sprites have standard dimensions (all the same dimension for example 32x32, or multiple dimensions of the smaller sprite for example 32x32 , 64x32, 64x64, 128x32,32x128 etc..) you can avoid using this tool if you work better with math calculations.
RE: Simple SpriteSheet Editor step by step in QB64pe - mnrvovrfc - 06-07-2023
Cool! Now I just discovered an excuse a reason to use Terry Ritchie's sprite header-file--libraries!
https://staging.qb64phoenix.com/showthread.php?tid=81
|