Skip to content

Image and Animation

WingEraser edited this page Mar 15, 2014 · 9 revisions

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.

##Images and shapes 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);

##Animation 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.

Nutmeg
Source: http://www.photonstorm.com/flash-game-dev-tips/flash-game-dev-tip-12-building-a-retro-platform-game-in-flixel-part-1

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:

##Fonts 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");

###True Type Font (.ttf) 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.

###Traditional Bitmap Font 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);

###Distance Field Font 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: distance-field-font
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);

Tools:
Hiero
BMFont

Examples:

##Texture atlas Texture atlas is a large image which contains many smaller sub-images. Below you see an example of texture atlas from the game Mode. Texture Atlas

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.

###Create texture atlas 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.

TexturePacker-Gui

###Use texture atlas in your project 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);

##Transitions / Tweens 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);

###Register accessor The class you want to tween, the accessor

Tween.registerAccessor(FlxSprite.class, new TweenSprite());

Examples:

##Blend Mode 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.

Layers

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.

Blend

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

###Apply Blend Mode

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");

##Blend Mode for OpenGL ES 2.0 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.

###Applying Blend Mode 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