What's the best way of reading a sprite sheet in Java? - java

I'm writing a basic sprite engine for my own amusement and to get better aquainted with Java's 2d API. Currently I am making use of large numbers of separate .png files with transparent backgrounds to represent the various sprites and different frames of animation that I need. Most 'real world' game development projects seem to make use of 'sprite sheets' which contain multiple sprites or frames of animation within a single file. Also, rather than making use of native image transparency support, people often nominate an arbitrary colour that does not appear in the sprite pallette to be the transparent colour. How does one manage a file like this programatically?
how do you know where one sprite
starts and the next begins
how do you deal with transparency
There may be other factors that I've not thought of here, so I may add to the list above as I think of things or as people make suggestions (please do so in the comments).

I currently use XML files generated by a simple sprite editor that store the sprite as a collection of (optionally animated) poses, which are in turn a collection of frames or cells. Frames store per-frame information like the x and y offset of the frame in sheet, cell width and height, and any transformation (resize/rotation/hue/etc.). Poses store individual frames and animation information (speed, for example), and a pose name to easily identify them in the program (hero.pose = sprite.pose["standing_right"]). Sprites serve as a document root to hold several poses, such as a pose for each facing direction.
A less flexible alternative I used earlier was to specify fixed sizes for cells and sheets and calculate frame offsets and sizes based on these values (e.g. width is always 32 pixels, so third sprite is at 32 * 2). Later I started specifying these dimensions in the file name (e.g. sprite_name_32x64.png) for sprites that don't fit the fixed cell dimensions. I like the new approach more, especially with a simplistic editor that fills most values for me and allows me to use sprites as templates for other sprites.
I use the alpha and transparency information stored in PNG images directly so I don't need to worry about storing it elsewhere, although other approaches would be to pick a fixed value per sprite and store somewhere, use the leftmost pixel in the pose if you know it's always empty, use a specific palette entry if you're using those, sprite masks, or what have you.

Not about java but generally you can make your all sprites in the same size. Thus, you will be able to generate your sprites in your game (or app) with a simple for loops.
But for different sized sprites there may be problem for spritesheet size (it can be larger than expected). So you must define an xml or json file for your spritesheet to find your sprite images in your code. You can use sprite sheet editors (there are plenty of them, I'm using Sprite Master) for quick and easy way to generate sprite sheet and coordinate datas.

Make your sprite sheet knowing the size and number of each sequence.
Grab a buffered image of your sheet and use something like this:
currentframe=spritesheet.getSubimage(x, y, w, h);
Your x and y will change based on the frame you are on. Keep the width and height the same to make things easy on yourself.
Forget trying to keep the entire game on one sheet. It's nuts and hard to manage. Use a new png for each animation sequence. If you are anal about saving space only create moving right animations and just flip the buffered image real time to move left.
Java will read png files with the alpha so don't worry about the transparency colour. Draw everything in pngs. Use Photoshop or Gimp.
Search google for java image TYPE_INT_ARGB

Well, since most of them are custom, those details are up to the implementor.
You'd generally have the file start with header information that contains the details of height/width and encoding, transparency, etc.
A lot of the time things are in one file because it is very expensive to open/read multiple files compared to open/read one file. Many game engines use zip or "ziplike" files with 0 compression to treat a single file as a filesystem.

Related

Is there a way to draw Strings in libgdx without BitmapFonts?

I want to draw Strings in my Libgdx game but i cant use BitMap Fonts because the scale of my game is to smal to use them.
It sounds like you mean the scale of your viewport is too small to show fonts correctly. There are two solutions. The first is better for legibility while the second is quick and dirty.
One is to use a second viewport for the UI that has an appropriate scale for text. You would first call gameViewport.apply(), draw the game, and end the batch. Then use uiViewport.apply() and then draw the UI. The downside with this method would be if you want to draw text that aligns with moving objects in the game, you would have to use the two viewports to convert coordinates. Otherwise, this is the ideal method to get a crisp looking UI. Ideally you would use a ScreenViewport and select a font size at runtime based on the screen dimensions, either by shipping your game with multiple versions of the font at different scales, or by using FreeTypeFontGenerator.
The second method is to scale down all your text. First call bitmapFont.setUseIntegerPositions(false) do it won't round off positions to integers. Then call bitmapFont.setScale() with however much you want to shrink it to fit in your game viewport.
There is a gdx-freetype project:
https://www.badlogicgames.com/wordpress/?p=2300
and it uses TrueType fonts as source to generate bitmap font on the fly.
Not sure how stable this is - didn't use it.

Store large bitmap into memory or constantly decode smaller bitmaps

(if you want to skip all this text you can go straight to the "short
question" version at the bottom)
Hello, guys!
I'm a beginner android developer currently creating a 2D RPG game. It basically consists of a map where the player walks (in 8 possible directions - west, north-west, and so forth) and interact with objects, creatures and others. The player's character walking animation consists of 9 sprites per available walking direction, totalizing 72 sprites. I have these sprites both in individual .png files as well as in an organized sprite sheet.
Until some days ago, I've been using the individual sprites in the game. I would load their drawable ID into an int[][] array and then, when each frame was going to be drawn, I would decode (using BitmapFactory.decodeResource() method) the necessary sprite and pass it to my renderer class that would then draw it.
After some thinking, I decided to try and use the sprite sheet instead, since the constant decoding of the sprites images was bothering me. For that, I decode the bitmap containing the sprite sheet with all the needed sprites and store it into a member variable. Depending on the required sprite for the next frame, my program would crop the required sprite out of the sprite sheet (previously saved into memory), resize it according to the player's devices needs and then pass it to my renderer in order to be drawn.
The problem is, I can't tell which method is more efficient! While it's easy to measure how much memory the decoded sprite sheet bitmap occupies (when stored in a member variable) in the player's memory (approximately 4MB), it's hard to know how much memory my program uses for constantly decoding small bitmaps, that corresponds to the individual sprites. Does anyone have any insights on how I could make this comparison? Or perhaps can share a previous experience related to this subject? I have searched for hours and, despite having found much useful information on how to load bitmaps efficiently and suggestions for libraries (like Glide, Fresco, and Picasso), I still couldn't find an answer nor better methods. Thanks in advance!
SHORT QUESTION: Is it better to constantly decode small bitmaps or to just decode a large bitmap once and then crop smaller bitmaps from it as needed?
P.S.: I'm aware that both presented methods for creating the animations in my game are probably inefficient. But, for the sake of my learning (my primary objective for creating this game), I don't want to use game engines, like AndEngine and libgdx. I also started learning OpenGL ES (which I've read provides great tools for loading and displaying bitmaps), but implementing it into my game would require a complete remake, in which I'm not interested right now.

Libgdx - 3 images in a group, best practice - also overdraw

I am trying to write a card game, that will have an image in the middle, a coloured border and potentially a symbol in the top left. I am using libgdx and a stage/scene2d.
The image will change depending on the suit (these are not your normal 52 deck type of cards), the border colour will change to match the suit, though this colour can be pre determined by the user so I can't pre-save coloured images (though I guess I could pre save about 15 diff colours and give the user a choice of 15) and the symbol will only be on some cards and not others.
As you can see from the two images I've added I have two diff images, border colours and symbols.
My question is relating to groups and overdraw.
1) I presume I should set up a group with 3 images in, and I'm hoping having this won't slow my game down as I will have potentially 30 cards on screen at once and 30 groups with up to 3 images in each could be a lot to draw. Is this right and will LibGDX be able to handle it fine?
2) How should I do the coloured border? Should I have the entire card a coloured rectangle and the image drawn on top? Would the draw method be trying to draw the coloured section underneath the image and thus wasting GPU/CPU time? A friend of mine said I could just have a white image, and then set the colour using RGB values in the code? Is this possible? That would mean I could only have a single jpg which would be much better for apk size.
3) Or should I ignore using a jpg image and try and draw the coloured square using ShapeRenderer?
Thanks, I hope these questions aren't too many in one post.
Of course it will not slow you game - 90 (30 groups x 3 textures) sprites on screen are like nothing for (I guess) every framework - so LibGDX will do the thing also.
Although it does matter how these graphics will be stored! Please use one TextureAtlas with all textures instead of many textures in many files - you can prepare the Atlas by using TexturePacker (for a basic usage like this free version will be ok).
The reason of this is that if you are using many single Textures LibGDX needs to switch graphic in GPU bufor (maybe it is not perfect term) before rendering each of them - if you have one big texture (including others) it does not need to switch anything because nothing changes in the buffor.
To get more information about using TextureAtlas take a look at the manual
Yes you can "color" the Actor (like Image) by using for example
actor.addAction(Actions.color(new Color(1f,1f,1f, 0.2f), 2f));
another approach is to have 1px x 1px texture of every color (packed in your Texture Atlas) and just to change it's size. There no reason to keep full size singe-colour textures since it is great vaste of space and memory.
It is generally not good idea to use ShapeRenderer - of course it is helpful sometimes but drawing sprites has a greater performance.
You are generally a little bit too scared about performance but if you want to save your CPU avoiding ShapeRenderer seems to be good idea.

TrueType Font rendering in Java?

I have made a GUI that has multiple components with it and now I need to populate those components with text.
My specifications:
Preferably uses LWJGL (OpenGL)
Isn't exceptionally complicated
Doesn't use any other external libraries (bar the LWJGL library)
Has to be fairly optimised, it will be used a lot on a very fps intensive GUI
Has the possibility of being anti-aliased?
Possibly have the ability to run on most major Operating Systems
How could I do this in java?
I would consider using SVG, and particularly Batik for managing the fonts. I am doing quite a lot with this myself and it's somewhat of a learning curve. I would be prepared to start simply and find out what particular features you need before worrying about performance. But until you give clearer ideas I'm not sure we can help much more
You have three options: Bitmap fonts, texture fonts and vector fonts.
Bitmap fonts are only useful if all you want to do is render text for a 2D GUI. However, you can't do antialiasing if you use Bitmap fonts. On the other hand, they're pretty easy to use and they're quick to render.
Texture fonts allow for antialiasing, but again they're best for 2D GUIs. If you want to render text in world space, you'll get lots of artifacts because of the texture scaling that's taking place. To use texture fonts, you have to create a texture atlas that contains an image for each character of a particular font that you want to use (usually you'll want to restrict the character set to ASCII, otherwise your texture will be too large). You can use AWT to create a rectangular image that contains all the characters you need. Then you can render a character by rendering a quad with the appropriate texture coordinates for that character. It is advisable to use a luminance alpha texture so that you can blend it with the color you want the text to be in. You can optimize this by using display lists for each character and possible for each string, but you'll run into problems with kerning etc.
Vector fonts give you the best results if you want to render your text in world space. They will give you perfect font rendering incl. kerning, but they're more expensive to render. My usual approach is to create a path (using AWT) for each string that I want to render, flatten that path and then trace it using the GLU tesselator. This will give you a bunch of triangles, triangle strips and triangle fans which you can put into a VBO for optimal performance. Then you can render that string by issuing the appropriate rendering commands for the VBO. You can optimize this further by using a display list for each string. That way, you will only have to send one command per string, but of course this will still be more expensive than the other methods.

JOGL: How can I draw many strings quickly

I'm using JOGL (OpenGL for Java) for my application and I need to draw tons of strings on screen at once and my current solution is far too slow. Right now I'm drawing the strings using TextRenderer using the draw3D method and for even a moderate number of strings (around 300-500), it just kills the FPS. I started messing with drawing text onto the object textures, which is much faster, but there are a few problems with it. The first is that allocating all those textures requires a lot of memory. The second is that I need to find a way to size the texture so its only as big as the string and then map it to the object without stretching. The problem there is that all these thousands of boxes are using a single model being rendered with a call list. I'm not sure its possible to change the texture mapping for each object in that situation.
I don't mind if the text appears flat or 3D, it just has to be positioned in 3D space. I would prefer to render the text in the highest quality possible without sacrificing too much speed, since readability of the text is the most important part of the application. Also, nearly all of the strings are different, there aren't many duplicates.
So, my question: Am I going down the right path with drawing the strings on the textures, and if so, how can I overcome those 2 problems? Or is there another method that would suit my needs?
Depending on exactly how TextRenderer works - you might be able to use display lists to batch up your text drawing commands.
If TextRenderer works by having a texture of individual character glyphs and piecing together a string a glyph at a time: it'll be fine. just bookend your text drawing code with glNewList and glEndList. Once a list is defined, just use glCallList to use it.
If however, TextRenderer works by drawing complete strings into a texture and using one quad per string - display lists may not work. If the strings in one batch do not all fit within TextRenderer's cache, it will delete the least-recently used one to reclaim some space. Display lists will only recreate the OpenGL calls made, and so the work done by TextRenderer to update the string cache texture will be lost and you'll get incorrect output. From a quick scan of the source, I suspect that TextRenderer works in this manner.
To summarise: Display lists will greatly speed up your rendering, but will only if you don't overflow TextRenderer's string cache texture and don't use the TextRenderer after the display list has been defined.
If you can't meet these constraints you're going to have to go a bit hardcore and write your own text renderer that renders glyph-by-glyph - it'll then be trivial to cache the output geometry and extremely quick to re-render. There's an example of such a system here, with the tool to create a font here. It uses LWJGL rather than JOGL, but the translation between the two will be the least of your worries if you want to integrate it - it's meshed with the texture management etc.

Categories