How to use sprite sheets?
#1
Question 
First off, greetings! Nice to see some familiar names on here after the whole QB64 nuking fiasco.

Still working on my game (Scrapship) and just recently started learning about sprite sheets.

I have a program that can create sprite sheets (Texturepacker), but now that I have a sprite sheet, I'm not sure how I would implement it in QB64/PE.
Below is little pic of the sprite sheet I currently have.


[Image: SSpic.jpg]

Has anyone done any work with sprite sheets in QB64 before or am I walking into uncharted territory?

Side note: I am not using any libraries or game engines, strictly QB64 code.

exclude duplicates
Reply
#2
as a genral outline:

load the sprites into an image with LOADIMAGE
create variables to hold the sprites.
use GET and  PUT  or _PUTIMAGE to put them where you want them.
There are more picky details but that's how you do it. There's code examples in the wiki that will help you out.
Reply
#3
(09-09-2022, 12:39 AM)40wattstudio Wrote: I have a program that can create sprite sheets (Texturepacker), but now that I have a sprite sheet, I'm not sure how I would implement it in QB64/PE.
You could use a program like Windows Paint (Windows) or GIMP (Linux) that shows you the current position of the mouse cursor in pixels. Then make rectangular selections around the picture elements to get the top and left coordinates, and the width and height of each sprite. This promises a long time of hard work, and experimentation and it's not for the lazy. The considerate people creating the sprite sheets create sprites that require the same width and height which would make programming easier, but the sprites have to be gathered correctly. You have to watch out because some larger screen elements (like a boss in an arcade game) could occupy two or more squares of an "unit" in the sprite sheet.
Reply
#4
Code: (Select All)
Screen _NewImage(800, 600, 32)

Dim Shared CardDeck As Long
CardDeck = _LoadImage("PlayingCards.png")
If CardDeck = -1 Then Print "PlayingCards.png failed to load, bye.": End
_Source CardDeck
_ClearColor Point(0, 0), CardDeck 'set background to transparent
_Source 0

ShowCard 0, 0, 0, 0 'ace of hearts is first top left corner of image
' king of spades below
ShowCard 0, 101, 12, 3
' 9 of diamonds under
ShowCard 0, 202, 8, 2

Sub ShowCard (x, y, h, v) 'screen x, y  h= horizontal  , v =vertical  image h, v
    ' 4 (0 to 3) rows across for Ace to King  0 to 12 cards
    ' hearts 1st row then clubs, diamonds then spades with 2 jokers in row 5
    ' image size of card is 38 x 51
    ch = 38 * h + 1: cv = 51 * v + 1
    'step doubles size of cards from image
    _PutImage (x, y)-Step(76, 102), CardDeck, 0, (ch, cv)-(ch + 37, cv + 50)
End Sub

   


Attached Files Image(s)
   
b = b + ...
Reply
#5
Between the two of you I think I have a general idea of what I need to do. I'll give it a go in the morning and see what happens. I've never tried referencing a segment of a png file, it's always been an all or nothing sorta thing. But if it works it'll be pretty cool because, loaded as individual images, the file size is 2.5MB (which isn't too bad, really), but the sprite sheet condenses it down to about 1.5MB.
Thanks for your help, I'll let you know how it turns out!
Reply
#6
Ahhh, that looks like what I'm looking for! I'll give that a try!
Thanks bplus!
Reply
#7
Tada! Got it to work (in a standalone environment). The tricky part will be implementing it into the game.

Here's the code I used. It differs from what bplus had in that instead of trying to show specific images, I am simply cycling through a sequence of frames to show an animation.
It was a bit less painful than I thought it would be, although it certainly helps when all your images are the same width and height.
Some spritesheets optimize space by trimming them even further, which makes a mess of your width/height dimensions. To take it a step further, some spritesheets even simplify your sprites to polygons. Thankfully I don't need that degree of optimization, sounds like diminishing returns and a mathematical headache.
Code: (Select All)
CLS
SCREEN _NEWIMAGE(1000, 1000, 32)

DIM SHARED deathss AS LONG
DIM SHARED r AS INTEGER
DIM SHARED c AS INTEGER
deathss = _LOADIMAGE("SCRAPSHIP\x\gfx\death\deathSS.png")
_SOURCE deathss
_SOURCE 0
r = 0  'row
c = 0 ' column

DO WHILE c < 8
    DO WHILE r < 8
        DeathAnimation 0, 0, r, c
        r = r + 1
    LOOP
    IF r >= 8 THEN r = 0
    c = c + 1
LOOP

SUB DeathAnimation (x, y, r, c)
    _LIMIT 20
    rh = 200 * r + 1
    ch = 200 * c + 1
    CLS
    _PUTIMAGE (x, y), deathss, 0, (rh, ch)-(rh + 200, ch + 200)
END SUB
Reply
#8
(09-09-2022, 01:23 PM)40wattstudio Wrote: Tada! Got it to work (in a standalone environment). The tricky part will be implementing it into the game.

Here's the code I used. It differs from what bplus had in that instead of trying to show specific images, I am simply cycling through a sequence of frames to show an animation.
It was a bit less painful than I thought it would be, although it certainly helps when all your images are the same width and height.
Some spritesheets optimize space by trimming them even further, which makes a mess of your width/height dimensions. To take it a step further, some spritesheets even simplify your sprites to polygons. Thankfully I don't need that degree of optimization, sounds like diminishing returns and a mathematical headache.
Code: (Select All)
CLS
SCREEN _NEWIMAGE(1000, 1000, 32)

DIM SHARED deathss AS LONG
DIM SHARED r AS INTEGER
DIM SHARED c AS INTEGER
deathss = _LOADIMAGE("SCRAPSHIP\x\gfx\death\deathSS.png")
_SOURCE deathss
_SOURCE 0
r = 0  'row
c = 0 ' column

DO WHILE c < 8
    DO WHILE r < 8
        DeathAnimation 0, 0, r, c
        r = r + 1
    LOOP
    IF r >= 8 THEN r = 0
    c = c + 1
LOOP

SUB DeathAnimation (x, y, r, c)
    _LIMIT 20
    rh = 200 * r + 1
    ch = 200 * c + 1
    CLS
    _PUTIMAGE (x, y), deathss, 0, (rh, ch)-(rh + 200, ch + 200)
END SUB

Sorry I'm late to the discussion but did you check out the tutorial that shows how to use sprite sheets in a few different ways? Here is a link:

https://qb64sourcecode.com/task18.html

My preferred method is to load the sprite images into an array.

Terry
Reply
#9
(09-09-2022, 02:34 PM)TerryRitchie Wrote: Sorry I'm late to the discussion but did you check out the tutorial that shows how to use sprite sheets in a few different ways? Here is a link:

https://qb64sourcecode.com/task18.html

*Facepalm* I have your site bookmarked from a while back but didn't think to see if you mentioned spritesheets there. Good to see that there are alternative ways to accomplish the same thing. Thanks for the link!
Reply
#10
(09-09-2022, 12:57 AM)mnrvovrfc Wrote: You could use a program like Windows Paint (Windows) or GIMP (Linux) that shows you the current position of the mouse cursor in pixels. Then make rectangular selections around the picture elements to get the top and left coordinates, and the width and height of each sprite. This promises a long time of hard work, and experimentation and it's not for the lazy. The considerate people creating the sprite sheets create sprites that require the same width and height which would make programming easier, but the sprites have to be gathered correctly. You have to watch out because some larger screen elements (like a boss in an arcade game) could occupy two or more squares of an "unit" in the sprite sheet.

The cool thing about Texturepacker (besides the fact that it offers a free version to try) is that you can export a JSON (or other format) file that will tell you all those coordinates for you. Because I was thinking the exact same thing as you: If I have to manually go into Paint and get the coordinates of 100+ sprites . . . oh my . . . that is going to be a long day and lots of coffee!

Here's an example of sprite coordinates in JSON format (I'm sure it could be adjusted to use in QB64PE quite easily):

Code: (Select All)
"filename": "4.png",
    "frame": {"x":400,"y":0,"w":200,"h":200},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":200,"h":200},
    "sourceSize": {"w":200,"h":200}
Reply




Users browsing this thread: 8 Guest(s)