Image and Animation - Rombusevil/flixel-gdx GitHub Wiki
Flixel allows you display objects on the stage or within display groups. These include images, text, animated sprites and more. In this guide you’ll learn how to display graphics and how to create animations.
Display images and shapes are done via FlxSprite
. This class is a graphical representation of a game object. The script is fairly simple and short.
Load a simple none animated image via constructor. The last argument is the path to the image.
FlxSprite sprite = new FlxSprite(0, 0, "player.png");
Create a rectangle shape, red rectangle 100 by 100 pixels.
sprite.makeGraphic(100, 100, 0xFFFF0000);
An animation contains individual sprites, also known as sprite sheet. The sprites are placed one after the other. An animation can be achieved by playing each frame by an interval. The following image shows chick Nutmeg. As you can see, Nutmeg can stand, run, jump and hurt. You may want to keep your sprites facing to right, because that’s the default in flixel. Flixel also support multi-row sprite sheet rows. Keep in mind that the first frame is at the top-left.
FlxSprite sprite = new FlxSprite();
// Path of the image, animated, reverse support, width and height of the frame.
sprite.loadGraphic("path/image.png", true, true, 16, 16);
// animation name, frames, frame rate, looped.
sprite.addAnimation("stand", new int[]{0},0, false);
sprite.addAnimation("walk", new int[]{0,1}, 5, true);
sprite.addAnimation("jump", new int[]{2}, 1, true);
sprite.play("walk");
Examples:
FlxText
supports bitmap font and True Type Font via Freetype font generator. It can tint, rotate and scale just like a sprite.
The constructor, which displays Hello World.
FlxText text = new FlxText(0, 0, 100, "Hello World");
Using the Freetype font generator it will generate bitmap fonts on runtime. Simply passing the path to the .ttf will generate a bitmap font.
text.setFormat("path/font.ttf");
Note: It is not recommended to use freetype in production because the generator affects the load time. Use distance field font if you are planning to use multiple fonts with different sizes.
_Note 2: The Freetype font generator doesn’t work for HTML5, you need to create a Bitmapfont. See the limitations.
There are many tools that generates bitmap fonts. The format must be Angel Code font format (.fnt
). When you save a bitmap font, add the size behind e.g. "font16.fnt", "font32.fnt". You can then load the font like this:
// The path to the font without the number behind!
String font = "path/font.ttf";
text.setFormat(font, 16);
text.setFormat(font, 32);
The traditional bitmapfont looks fine when they are 1:1 on screen, but they look bad when they are scaled or rotated. The distance field solves this problem. With this you can render crisp text even if it is scale very large, rotated or other transforms. See the difference below:
Source: https://github.com/libgdx/libgdx/wiki/Distance-field-fonts
Read this article before getting started: https://github.com/libgdx/libgdx/wiki/Distance-field-fonts
Using distance field in FlxText
is simple. The only thing you need to do, is calling setDistanceField()
before setting the format.
private String font = "path/font.fnt"; // font size is 32
FlxText text = new FlxText(0, 0, FlxG.width, "flixel-gdx");
// Enable, padding, smoothness, shader name (optional)
// The padding that is set to generate the bitmap font.
text.setDistanceField(true, 4, 0.3f, "fontShader");
// Don't forget to set the correct font size.
text.setFormat(font, 32);
// Now you can scale to anything.
text.scale.x = text.scale.y = 3f;
Formatting, changing font, size, alignment and drop shadow can be done in one line.
text.setFormat("path/font.ttf", 16, 0xFFFFFF, "center", 2, 2);
Examples:
Texture atlas is a large image which contains many smaller sub-images. Below you see an example of texture atlas from the game Mode.
There are two main reasons to use a texture atlas. First, it can increase rendering speed by allowing you to batch more objects into a single draw call. For example, if all the plants in the game use just one texture atlas, then you can draw them all at the same time. Otherwise you would have to draw one group of plants, switch texture state, draw another group of plants, and so on.
Second, it allows you to use unusually-shaped textures. Most graphics cards are designed to use textures that are square and have dimensions that are powers of two, such as 256x256, 512x512, and so on. But what if you have a graphic that is 550x130? You would have to put it in the middle of a 1024x1024 texture, and waste all the extra space. Alternately, you could pack a lot of unusually-shaped textures into one square texture atlas, and hardly waste any space at all!
Source: http://blog.wolfire.com/2010/03/Using-texture-atlases by David Rosen
For the mobile platform you are limited to the size of the texture atlas. The common texture size is 1024 x 1024 px. Some high-end devices can handle 2048 x 2048 pixels. It’s going to take pretty much of the memory. It’s better to use the common size if you want your game to run on almost all devices. Checkout out http://www.glbenchmark.com for OpenGL environment and performance details for mobile devices.
Manually setting every sprite on a texture atlas takes a long time. Fortunately there are many tools that packs sprites into texture atlas(es). An open source program TexturePacker-Gui is especially developed for libgdx and is used in this article. When a texture atlas is generated you’ll also get a text file with the extension named “pack” (or what you’ve named it). In the pack file the region of packed images described and provides information about the original image before it was packed.
Loading an image from a texture atlas is bit different than loading a single image. You need to give then name of the pack file followed by a semicolon and the name of the image without the extension.
String ImgPlayer = "folder/pack:player";
FlxSprite player = new FlxSprite().loadGraphic(ImgPlayer);
Flixel uses the Universal Tween Engine by Aurelien Ribon. It’s very powerful and easy in use. It doesn’t interfere with any framework (hence the name Universal). It only needs accessor to get tweening done.
The accessor lets you interpolate any attribute from any object. Just implement it as you want register it to the engine.
The TweenPlugin
for flixel got two tween accessor of FlxSprite
and FlxPoint
. The possible tweens are position, scale, angle, color and alpha. That’s because FlxSprite
got these variables.
// Hook the TweenPlugin to the plugin system.
FlxG.addPlugin(new TweenPlugin());
// A simple sprite.
FlxSprite sprite = new FlxSprite(0, 0);
sprite.makeGraphic(50, 50, 0xFFFF00FF);
add(sprite);
// The magical part to tween the sprite.
Tween.to(sprite, TweenSprite.XY, .75f)
.target(100, 200)
.repeat(2, 1f)
.setCallback(callback) // TweenCallback
.setCallbackTriggers(TweenCallback.BEGIN | TweenCallback.COMPLETE)
.start(TweenPlugin.manager);
The class you want to tween, the accessor
Tween.registerAccessor(FlxSprite.class, new TweenSprite());
Examples:
With blend modes you can achieve creative visual effects within your game and that in one line of code. You’re probably familiar with blend modes if you used Photoshop or other design tools.
Flixel utilizes layers to arrange visual objects in an ordered z-index from back to front. Blend modes change the way that an image within a layer reacts to the images in the layers below it. Take a look at the image in NORMAL
and ADD
blend mode.
If you want more information what blend mode is, you can visit this page: http://en.wikipedia.org/wiki/Blend_modes
Available Blend Modes for OpenGL ES 1.0
ADD | MULTIPLY |
ALPHA | NORMAL |
ERASE | SCREEN |
FlxSprite sprite = new FlxSprite(0, 0, Img);
sprite.blend = BlendMode.NORMAL;
Creating custom blend mode can be done with the same class. You need to give a unique name and the GL10 arguments. If you want to experiment different blends you can visit Anders Riggelsen online Blending tool.
BlendMode.addBlendMode("ALPHA", GL10.GL_SRC_ALPHA, GL10_GL_ONE);
sprite.blend = BlendMode.getOpenGLBlendMode("ALPHA");
A lot of blend modes can’t be done with OpenGL ES 1.0. Fortunately OpenGL ES 2.0 will cover the rest. However it requires code that is written with OpenGL Shader Language. Fortunately, flixel ships with a lot of premade blend modes. Applying blend mode is very simple. You need a base image (background) and a blend image (layer).
You can find the available blend modes at BlendModeGL20
.
Apply Blend Mode
FlxSprite base;
add(base = new FlxSprite(0, 0, ImgBaseImage));
FlxSprite blend = new FlxSprite(0, 0, ImgBlendImage);
BlendModeGL20.blend(BlendModeGL20.COLOR_DODGE, base, blend);
Add custom Blend Mode
BlendModeGL20.addBlendMode("BlendName", vertex, fragment);
BlendModeGL20.blend(“BlendName”, base, blend);
Alternative way
FlxShaderProgram shader = BlendModeGL20.addBlendMode("BlendName", vertex, fragment);
base.blendGL20 = shader;
base.blendTexture = blend.getTexture();
Do not to add the blend sprite to the state. If you want more control over the texture and shader bindings, you can override FlxSprite.renderBlend()
.
That's pretty it. You don’t have to write a single Shader Language code.
Note 1: When you add your own blend mode, be sure the following uniforms are written correctly in the fragment shader:
u_texture
u_texture1
Note 2: You need to turn on OpenGL ES 2.0 support or you’ll get error. Click here for how to.
Note 3: Android minimal requirement is 2.2
Examples:
Resources