CCsprite精灵类

创建方法

1.Sprite* Sprite::createWithTexture(Texture2D *texture)

2.Sprite* Sprite::createWithTexture(Texture2D *texture, const Rect& rect, bool rotated)

3.Sprite* Sprite::create(const std::string& filename)

4.Sprite* Sprite::create(const std::string& filename, const Rect& rect)

5.Sprite* Sprite::createWithSpriteFrame(SpriteFrame *spriteFrame)

6.Sprite* Sprite::createWithSpriteFrameName(const std::string& spriteFrameName)

实例

 1     //load bg.plist
 2     SpriteFrameCache::getInstance() ->addSpriteFramesWithFile("bg/bg.plist");
 3     SpriteFrameCache::getInstance() ->addSpriteFramesWithFile("game/shoot.plist");
 4 
 5     // creat bg
 6     Sprite *bgsprite = Sprite::createWithSpriteFrameName("background.png");
 7     bgsprite->setAnchorPoint(Vec2::ZERO);
 8     this->addChild(bgsprite);
 9 
10     //creat player
11     _playersprite = Sprite::createWithSpriteFrameName("hero1.png");
12     _playersprite->setPosition(Size(visibleSize.width/2,visibleSize.height/2));
13     this->addChild(_playersprite);
View Code

 方法void Sprite::updateTransform(void    CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode");

// recalculate matrix only if it is dirty
    if( isDirty() ) {

        // If it is not visible, or one of its ancestors is not visible, then do nothing:
        if( !_visible || ( _parent && _parent != _batchNode && static_cast<Sprite*>(_parent)->_shouldBeHidden) )
        {
            _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vec3(0,0,0);
            _shouldBeHidden = true;
        }
        else
        {
            _shouldBeHidden = false;

            if( ! _parent || _parent == _batchNode )
            {
                _transformToBatch = getNodeToParentTransform();
            }
            else
            {
                CCASSERT( dynamic_cast<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
                Mat4 nodeToParent = getNodeToParentTransform();
                Mat4 parentTransform = static_cast<Sprite*>(_parent)->_transformToBatch;
                _transformToBatch = parentTransform * nodeToParent;
            }

            //
            // calculate the Quad based on the Affine Matrix
            //

            Size size = _rect.size;

            float x1 = _offsetPosition.x;
            float y1 = _offsetPosition.y;

            float x2 = x1 + size.width;
            float y2 = y1 + size.height;
            float x = _transformToBatch.m[12];
            float y = _transformToBatch.m[13];

            float cr = _transformToBatch.m[0];
            float sr = _transformToBatch.m[1];
            float cr2 = _transformToBatch.m[5];
            float sr2 = -_transformToBatch.m[4];
            float ax = x1 * cr - y1 * sr2 + x;
            float ay = x1 * sr + y1 * cr2 + y;

            float bx = x2 * cr - y1 * sr2 + x;
            float by = x2 * sr + y1 * cr2 + y;

            float cx = x2 * cr - y2 * sr2 + x;
            float cy = x2 * sr + y2 * cr2 + y;

            float dx = x1 * cr - y2 * sr2 + x;
            float dy = x1 * sr + y2 * cr2 + y;

            _quad.bl.vertices = Vec3( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _positionZ );
            _quad.br.vertices = Vec3( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _positionZ );
            _quad.tl.vertices = Vec3( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _positionZ );
            _quad.tr.vertices = Vec3( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _positionZ );
        }

        // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS
        if (_textureAtlas)
        {
            _textureAtlas->updateQuad(&_quad, _atlasIndex);
        }

        _recursiveDirty = false;
        setDirty(false);
    }

    // MARMALADE CHANGED
    // recursively iterate over children
/*    if( _hasChildren )
    {
        // MARMALADE: CHANGED TO USE Node*
        // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform()
        arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*);
    }*/
    Node::updateTransform();
}

// draw

void Sprite::draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated)
{
    // Don't do calculate the culling if the transform was not updated
    _insideBounds = transformUpdated ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;

    if(_insideBounds)
    {
        _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
        renderer->addCommand(&_quadCommand);
#if CC_SPRITE_DEBUG_DRAW
        _customDebugDrawCommand.init(_globalZOrder);
        _customDebugDrawCommand.func = CC_CALLBACK_0(Sprite::drawDebugData, this);
        renderer->addCommand(&_customDebugDrawCommand);
#endif //CC_SPRITE_DEBUG_DRAW
    }
}
#if CC_SPRITE_DEBUG_DRAW
void Sprite::drawDebugData()
{
    Director* director = Director::getInstance();
    CCASSERT(nullptr != director, "Director is null when seting matrix stack");
    Mat4 oldModelView;
    oldModelView = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
    // draw bounding box
    Vec2 vertices[4] = {
        Vec2( _quad.bl.vertices.x, _quad.bl.vertices.y ),
        Vec2( _quad.br.vertices.x, _quad.br.vertices.y ),
        Vec2( _quad.tr.vertices.x, _quad.tr.vertices.y ),
        Vec2( _quad.tl.vertices.x, _quad.tl.vertices.y ),
    };
    DrawPrimitives::drawPoly(vertices, 4, true);
    
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, oldModelView);
}
#endif //CC_SPRITE_DEBUG_DRAW

// Node overrides
void Sprite::addChild(Node *child, int zOrder, int tag)
{
    CCASSERT(child != nullptr, "Argument must be non-nullptr");

    if (_batchNode)
    {
        Sprite* childSprite = dynamic_cast<Sprite*>(child);
        CCASSERT( childSprite, "CCSprite only supports Sprites as children when using SpriteBatchNode");
        CCASSERT(childSprite->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "");
        //put it in descendants array of batch node
        _batchNode->appendChild(childSprite);

        if (!_reorderChildDirty)
        {
            setReorderChildDirtyRecursively();
        }
    }
    //CCNode already sets isReorderChildDirty_ so this needs to be after batchNode check
    Node::addChild(child, zOrder, tag);
}

void Sprite::reorderChild(Node *child, int zOrder)
{
    CCASSERT(child != nullptr, "child must be non null");
    CCASSERT(_children.contains(child), "child does not belong to this");

    if( _batchNode && ! _reorderChildDirty)
    {
        setReorderChildDirtyRecursively();
        _batchNode->reorderBatch(true);
    }

    Node::reorderChild(child, zOrder);
}

void Sprite::removeChild(Node *child, bool cleanup)
{
    if (_batchNode)
    {
        _batchNode->removeSpriteFromAtlas((Sprite*)(child));
    }

    Node::removeChild(child, cleanup);
}

void Sprite::removeAllChildrenWithCleanup(bool cleanup)
{
    if (_batchNode)
    {
        for(const auto &child : _children) {
            Sprite* sprite = dynamic_cast<Sprite*>(child);
            if (sprite)
            {
                _batchNode->removeSpriteFromAtlas(sprite);
            }
        }
    }

    Node::removeAllChildrenWithCleanup(cleanup);
}

void Sprite::sortAllChildren()
{
    if (_reorderChildDirty)
    {
        std::sort(std::begin(_children), std::end(_children), nodeComparisonLess);

        if ( _batchNode)
        {
            for(const auto &child : _children)
                child->sortAllChildren();
        }

        _reorderChildDirty = false;
    }
}

//
// Node property overloads
// used only when parent is SpriteBatchNode
//

void Sprite::setReorderChildDirtyRecursively(void)
{
    //only set parents flag the first time
    if ( ! _reorderChildDirty )
    {
        _reorderChildDirty = true;
        Node* node = static_cast<Node*>(_parent);
        while (node && node != _batchNode)
        {
            static_cast<Sprite*>(node)->setReorderChildDirtyRecursively();
            node=node->getParent();
        }
    }
}

void Sprite::setDirtyRecursively(bool bValue)
{
    _recursiveDirty = bValue;
    setDirty(bValue);

    for(const auto &child: _children) {
        Sprite* sp = dynamic_cast<Sprite*>(child);
        if (sp)
        {
            sp->setDirtyRecursively(true);
        }
    }
}

// XXX HACK: optimization
#define SET_DIRTY_RECURSIVELY() {                       \
                    if (! _recursiveDirty) {            \
                        _recursiveDirty = true;         \
                        setDirty(true);                 \
                        if (!_children.empty())         \
                            setDirtyRecursively(true);  \
                        }                               \
                    }

void Sprite::setPosition(const Vec2& pos)
{
    Node::setPosition(pos);
    SET_DIRTY_RECURSIVELY();
}

void Sprite::setPosition(float x, floatvoid Sprite::setRotation(float rotation)
void Sprite::setRotationSkewX(float fRotationX) 
void Sprite::setRotationSkewY(float fRotationY)
//倾斜
void Sprite::setSkewX(float sx) void Sprite::setSkewY(floatvoid Sprite::setScaleX(float scaleX) void Sprite::setScaleY(float scaleY) void Sprite::setScale(float fScale) void Sprite::setScale(float scaleX, float scaleY) void Sprite::setPositionZ(float fVertexZ) { Node::setPositionZ(fVertexZ); SET_DIRTY_RECURSIVELY(); } void Sprite::setAnchorPoint(const Vec2& anchor) { Node::setAnchorPoint(anchor); SET_DIRTY_RECURSIVELY(); } void Sprite::ignoreAnchorPointForPosition(bool value) { CCASSERT(! _batchNode, "ignoreAnchorPointForPosition is invalid in Sprite"); Node::ignoreAnchorPointForPosition(value); } void Sprite::setVisible(bool bVisible) { Node::setVisible(bVisible); SET_DIRTY_RECURSIVELY(); } void Sprite::setFlippedX(bool flippedX) { if (_flippedX != flippedX) { _flippedX = flippedX; setTextureRect(_rect, _rectRotated, _contentSize); } } bool Sprite::isFlippedX(void) const { return _flippedX; } void Sprite::setFlippedY(bool flippedY) { if (_flippedY != flippedY) { _flippedY = flippedY; setTextureRect(_rect, _rectRotated, _contentSize); } } bool Sprite::isFlippedY(void) const { return _flippedY; } // // RGBA protocol //  void Sprite::updateColor(void) { Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity ); // special opacity for premultiplied textures if (_opacityModifyRGB) { color4.r *= _displayedOpacity/255.0f; color4.g *= _displayedOpacity/255.0f; color4.b *= _displayedOpacity/255.0f; } _quad.bl.colors = color4; _quad.br.colors = color4; _quad.tl.colors = color4; _quad.tr.colors = color4; // renders using batch node if (_batchNode) { if (_atlasIndex != INDEX_NOT_INITIALIZED) { _textureAtlas->updateQuad(&_quad, _atlasIndex); } else { // no need to set it recursively // update dirty_, don't update recursiveDirty_ setDirty(true); } } // self render // do nothing } void Sprite::setOpacityModifyRGB(bool modify) { if (_opacityModifyRGB != modify) { _opacityModifyRGB = modify; updateColor(); } } bool Sprite::isOpacityModifyRGB(void) const { return _opacityModifyRGB; } // Frames void Sprite::setSpriteFrame(const std::string &spriteFrameName) { SpriteFrameCache *cache = SpriteFrameCache::getInstance(); SpriteFrame *spriteFrame = cache->getSpriteFrameByName(spriteFrameName); CCASSERT(spriteFrame, "Invalid spriteFrameName"); setSpriteFrame(spriteFrame); } void Sprite::setSpriteFrame(SpriteFrame *spriteFrame) { _unflippedOffsetPositionFromCenter = spriteFrame->getOffset(); Texture2D *texture = spriteFrame->getTexture(); // update texture before updating texture rect if (texture != _texture) { setTexture(texture); } // update rect _rectRotated = spriteFrame->isRotated(); setTextureRect(spriteFrame->getRect(), _rectRotated, spriteFrame->getOriginalSize()); } void Sprite::setDisplayFrameWithAnimationName(const std::string& animationName, ssize_t frameIndex) { CCASSERT(animationName.size()>0, "CCSprite#setDisplayFrameWithAnimationName. animationName must not be nullptr"); Animation *a = AnimationCache::getInstance()->getAnimation(animationName); CCASSERT(a, "CCSprite#setDisplayFrameWithAnimationName: Frame not found"); AnimationFrame* frame = a->getFrames().at(frameIndex); CCASSERT(frame, "CCSprite#setDisplayFrame. Invalid frame"); setSpriteFrame(frame->getSpriteFrame()); } bool Sprite::isFrameDisplayed(SpriteFrame *frame) const { Rect r = frame->getRect(); return (r.equals(_rect) && frame->getTexture()->getName() == _texture->getName() && frame->getOffset().equals(_unflippedOffsetPositionFromCenter)); } SpriteFrame* Sprite::getSpriteFrame() const { return SpriteFrame::createWithTexture(_texture, CC_RECT_POINTS_TO_PIXELS(_rect), _rectRotated, CC_POINT_POINTS_TO_PIXELS(_unflippedOffsetPositionFromCenter), CC_SIZE_POINTS_TO_PIXELS(_contentSize)); } SpriteBatchNode* Sprite::getBatchNode() { return _batchNode; } void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode) { _batchNode = spriteBatchNode; // weak reference // self render if( ! _batchNode ) { _atlasIndex = INDEX_NOT_INITIALIZED; setTextureAtlas(nullptr); _recursiveDirty = false; setDirty(false); float x1 = _offsetPosition.x; float y1 = _offsetPosition.y; float x2 = x1 + _rect.size.width; float y2 = y1 + _rect.size.height; _quad.bl.vertices = Vec3( x1, y1, 0 ); _quad.br.vertices = Vec3( x2, y1, 0 ); _quad.tl.vertices = Vec3( x1, y2, 0 ); _quad.tr.vertices = Vec3( x2, y2, 0 ); } else { // using batch _transformToBatch = Mat4::IDENTITY; setTextureAtlas(_batchNode->getTextureAtlas()); // weak ref  } } // Texture protocol void Sprite::updateBlendFunc(void) { CCASSERT(! _batchNode, "CCSprite: updateBlendFunc doesn't work when the sprite is rendered using a SpriteBatchNode"); // it is possible to have an untextured sprite if (! _texture || ! _texture->hasPremultipliedAlpha()) { _blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED; setOpacityModifyRGB(false); } else { _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; setOpacityModifyRGB(true); } } std::string Sprite::getDescription() const { int texture_id = -1; if( _batchNode ) texture_id = _batchNode->getTextureAtlas()->getTexture()->getName(); else texture_id = _texture->getName(); return StringUtils::format("<Sprite | Tag = %d, TextureID = %d>", _tag, texture_id ); }

 

posted @ 2014-07-14 18:27  hcs2024  阅读(823)  评论(0编辑  收藏  举报