Skip to content

Latest commit

 

History

History
263 lines (205 loc) · 8.86 KB

3.md

File metadata and controls

263 lines (205 loc) · 8.86 KB

Chapter 3: Sprites

What are Sprites

A Sprite is a 2D image that can be animated or transformed by changing its properties, including rotation, position, scale, color, etc.

Creating Sprites

There are different ways to create Sprites depending upon what you need to accomplish. You can create a Sprite from an image with various graphic formats including: PNG, JPEG, TIFF, and others. Let's go through some create methods and talk about each one.

Creating a Sprite

A Sprite can be created by specifying an image file to use.

auto mySprite = Sprite::create("mysprite.png");

The statement above creates a Sprite using the 'mysprite.png' image. The result is that the created Sprite uses the whole image. Sprite has the same dimensions of mysprite.png. If the image file is 200 x 200 the resulting Sprite is 200 x 200.

Creating a Sprite with a Rect

In the previous example, the created Sprite has the same size as the original image file. If you want to create a Sprite with only a certain portion of the image file, you can do it by specifying a Rect.

Rect has 4 values: origin x, origin y, width and height.

auto mySprite = Sprite::create("mysprite.png", Rect(0,0,40,40));

Rect starts at the top left corner. This is the opposite of what you might be used to when laying out screen position as it starts from the lower left corner. Thus the resulting Sprite is only a portion of the image file. In this case the Spritedimension is 40 x 40 starting at the top left corner.

If you don't specify a Rect, cocos2d-x will automatically using the full width and height of the image file you specify. Take a look at example below, if we use an image with dimension 200 x 200 the following 2 statements would have the same result.

auto mySprite = Sprite::create("mysprite.png");

auto mySprite = Sprite::create("mysprite.png", Rect(0,0,200,200));

Creating a Sprite from a Sprite Sheet

A sprite sheet is a way to combine sprites into a single file. This reduces the overall file size compared to having individual files for each Sprite. This means you will significantly reduce memory usage, file size and loading time.

Also, using sprite sheets is a needed condition in order to achieve better performance by batching the draw calls. More on this in the Advanced Chapter.

When using a sprite sheet, it is first loaded, in its entirety, into the SpriteFrameCache. SpriteFrameCache is a caching class that retains SpriteFrame for future quicker access.

And a SpriteFrame is a object that contains the image file name and a Rect that specifies the size of the sprite.

The SpriteFrameCache prevents needing to load a SpriteFrame multiple times, over and over. The SpriteFrame is loaded once and retained in the SpriteFrameCache

Here is an example sprite sheet:

It doesn't look like much but let's take a closer look at what is happening:

As you can see the sprite sheet, at a minimum reduces unneeded space, consolidates all sprites into a single file.

Let's tie this all together!

Loading a Sprite Sheet

Load your sprite sheet into the SpriteFrameCache, probably in AppDelegate:

// load the Sprite Sheet
auto spritecache = SpriteFrameCache::getInstance();

// the .plist file can be generated with any of the tools mentioned below
spritecache->addSpriteFramesWithFile("sprites.plist");

Now that we have a sprite sheet loaded into SpriteFrameCache we can create Sprite objects by utilizing it.

Creating a Sprite from SpriteFrameCache

This creates a Sprite by pulling it from the SpriteFrameCache.

auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");

Creating a Sprite from a SpriteFrame

Another way to create the same Sprite is by fetching the SpriteFrame from the SpriteFrameCache, and then creating the Sprite with the SpriteFrame. Example:

// this is equivalent to the previous example,
// but it is created by retrieving the spriteframe from the cache.
auto newspriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite.png");
auto newSprite = Sprite::createWithSpriteFrame(newspriteFrame);

Tools for creating Sprite Sheets

Creating sprite sheet manually is a tedious process. Fortunately there are tools that can generate them automatically. These tools also can provide many more adjustments you can make to optimize your sprite sheet even further. Here are a few tools:

Sprite Manipulation

After creating a Sprite, there are a variety of properties it has that can be manipulated.

Given:

auto mySprite = Sprite::create("mysprite.png");

Anchor Point and Position

Anchor Point is a point that you set as a way to specifying what part of the Sprite will be used when setting the position of it. Anchor Point affects only properties that can be transformed. This includes scale, rotation, skew. This excludes color and opacity. Anchor Point uses a bottom left coordinate system. This means that when specifying X and Y coordinate values you need to make sure to start at the bottom left hand corner to do your calculations. By default the anchor point of all Node objects is (0.5, 0.5).

Setting anchor point is easy:

// DEFAULT anchor point for all Sprites
mySprite->setAnchorPoint(0.5, 0.5);

// bottom left
mySprite->setAnchorPoint(0, 0);

// top left
mySprite->setAnchorPoint(0, 1);

// bottom right
mySprite->setAnchorPoint(1, 0);

// top right
mySprite->setAnchorPoint(1, 1);

To represent this visually:

Sprite properties effected by anchor point

Anchor Point effects only properties that can be transformed. This includes scale, rotation, skew.

Position

A sprites position is affected by anchor point as it is this point that is used as a starting point for positioning. Let's visually look at how this happens. Notice the colored line and where the sprites position is in relation to it. Notice as we change the anchor point values, the sprites position changes. It is important to note that all it took was changing the anchor point value. We did not use a setPosition() statement to achieve this:

There are more ways to set position than just anchor point. Sprite objects can also be set using specific setPosition() statement.

// position a sprite to a specific position of x = 100, y = 200.
mySprite->setPosition(Vec2(100, 200);

Rotation

Changes the sprites rotation, by positive or negative degrees. A positive value rotates the sprite clockwise while a negative value rotates the sprite counter clockwise. The default value is 0.

// rotates sprite by +20
mySprite->setRotation(20.0f);

// rotates sprite by -20
mySprite->setRotation(-20.0f);

// rotates sprite by +60
mySprite->setRotation(60.0f);

// rotates sprite by -60
mySprite->setRotation(-60.0f);

Scale

Changes the sprites scale, either by x, y or uniformly for both x and y. The default value is 1.0 for both x and y.

// increases X and Y size by 2.0 uniformly
mySprite->setScale(2.0);

// increases just X scale by 2.0
mySprite->setScaleX(2.0);

// increases just Y scale by 2.0
mySprite->setScaleY(2.0);

Skew

Changes the sprites skew, either by x, y or uniformly for both x and y. The default value is 0,0 for both x and y.

// adjusts the X skew by 20.0
mySprite->setSkewX(20.0f);

// adjusts the Y skew by 20.0
mySprite->setSkewY(20.0f);

Sprite properties not affected by anchor point

There are a few properties of Sprite objects that are not affected by anchor point. Why? Because they only change superficial qualities like color and opacity.

Color

Changes the sprites color. This is done by passing in a Color3B object. Color3B objects are RGB values. We haven't encountered Color3B yet but it is simply an object that defines an RGB color. An RGB color is a 3 byte value from 0 - 255. Cocos2d-s also provides pre-defined colors that you can pick from. Using these will be a bit faster since they are pre-defined. A few examples: Color3B::White and Color3B::Red.

// set the color by passing in a Color3B object.
mySprite->setColor(Color3B(255, 255, 255));

// set the color by passing in a pre-defined Color3B object.
mySprite->setColor(Color3B::White);

Opacity

Changes the sprites opacity by the specified value. It expects a value from (2-255). The default value is 255 (non-opague).

// set the opacity by passing in a value
mySprite->serOpacity(30);