A Sprite is a 2D image that can be animated or transformed by changing its
properties, including rotation
, position
, scale
, color
, etc.
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.
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.
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
Sprite
dimension 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));
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!
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.
This creates a Sprite
by pulling it from the SpriteFrameCache
.
auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");
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);
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:
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 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:
Anchor Point effects only properties that can be transformed. This includes scale, rotation, skew.
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);
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);
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);
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);
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.
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);
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);