cocos2dx 3.2 利用clippingNode把图片裁剪成圆形,接口可直接使用

本文深入探讨了ClippingNode类在图像处理中的作用,详细介绍了其使用方法,包括创建、设置裁剪规则及关键参数调整。通过实例展示了如何利用圆形图片作为裁剪模板,并解释了如何通过alpha阈值控制透明区域的显示,同时提供了自定义圆形裁剪节点的代码实现,以期简化美术工作并节省资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ClippingNode简介

先简单了解一下clippingNode类的使用。顾名思义,首先它是一个node,可以做为其他sprite,node的容器,而且是一个可以裁剪的node。如何裁剪,如何定义一套裁剪的规则出来。这里可以使用一张图片,根据图片的分辨率或者有效像素进行裁剪,或者自己画出来一个裁剪区域,根据这个区域进行裁剪。那这个图片或者画出来的区域,就是模板,clippingNode根据模板进行图片的裁剪。

主要方法:

 /** Creates and initializes a clipping node with an other node as its stencil.
     The stencil node will be retained.
     */
    static ClippingNode* create(Node *stencil);
create函数中传入一个模板,可以是一个sprite,也可以是一个drawNode(自定义的图形)。
    /** The alpha threshold.
     The content is drawn only where the stencil have pixel with alpha greater than the alphaThreshold.
     Should be a float between 0 and 1.
     This default to 1 (so alpha test is disabled).
     */
    GLfloat getAlphaThreshold() const;
    void setAlphaThreshold(GLfloat alphaThreshold);
这个方法比较重要。设置alpha的值,跟图片的透明度有关,默认是1,就是图片中所有像素点都显示出来。包括透明区域。一般想不显示透明区域,则设置为0.05。
下面讲的裁剪图片的方法,也可以使用一个圆形的图片,中间镂空。那么就需要设置setAlphaThreshold,如果不设置的话,裁剪出来的图片就是正方形的,是图片的实际大小。
/** Inverted. If this is set to true,
     the stencil is inverted, so the content is drawn where the stencil is NOT drawn.
     This default to false.
     */
    bool isInverted() const;
    void setInverted(bool inverted);
显示裁剪的部分,还是被裁剪的部分。

CirCularNode 圆形图片类

写这个类有两种方法。一种是,让美术给切一个圆形的图片,中间镂空,以这个圆形图片做为clippingNode的模板去裁剪,但必须要设置setAlphaThreshold(0.05)。
另一种方法就是下面代码所示,就不麻烦美术了,能省几KB就省几KB吧。我们自己画个圆形出来。只写了一个接口,需要的可以扩展,依照注释 看一下吧。
头文件:
#ifndef __CirCularNode__
#define __CirCularNode__

#include <stdio.h>
#include "cocos2d.h"
#include "extensions/cocos-ext.h"

class CirCularNode:public cocos2d::ClippingNode
{
public:
    CirCularNode();
    virtual ~CirCularNode();
    /**
     *  创建一个圆形clippingNode
     *
     *  @param radius 创建的圆形半径
     *
     *  @return 返回一个剪切node
     */
    static CirCularNode* create(float radius);
    
    /**
     *  创建一个圆形的clippingNode
     *
     *  @param radius 创建的圆形半径
     *  @param sprite 需要切呈圆形的精灵
     *
     *  @return 返回一个剪切node
     */
    static CirCularNode* create(float radius, cocos2d::Node* pNode);
    
    virtual bool init(float radius);
    
    CC_PROPERTY(cocos2d::Node*, m_clipNode, ClipNode);
};
#endif 
实现:
#include "CirCularNode.h"
USING_NS_CC;

CirCularNode::CirCularNode()
	:m_clipNode(nullptr)
{
    
}

CirCularNode::~CirCularNode()
{
    CC_SAFE_RELEASE_NULL(m_clipNode);
}

CirCularNode* CirCularNode::create(float radius)
{
    auto pClipNode = new CirCularNode();
    if (pClipNode && pClipNode->init(radius))
    {
        pClipNode->autorelease();
    }
    else
    {
        delete pClipNode;
        pClipNode = nullptr;
    }
    return pClipNode;
}

bool CirCularNode::init(float radius)
{
    if (!ClippingNode::init())
    {
        CCLOG("CirCularNode parent init failed!");
        return false;
    }
    
	//使用drawNode画圆形
    auto circleNode = DrawNode::create();

	//顶点坐标个数,在需要画大圆的时候,这个值就要相应变大一点
    const int maxTrangle = 360;

	//顶点数组
    Vec2 circleVec2[maxTrangle];
	//计算圆上面的各个点的坐标
    for (int i = 0; i < maxTrangle; i ++)
    {
        float x = cosf( i * (M_PI/180.f)) * radius;
        float y = sinf( i * (M_PI/180.f)) * radius;
        circleVec2[i] = Vec2(x, y);
    }

	//颜色
    auto circleColor = Color4F(0, 1, 0, 1);
    circleNode->drawPolygon(circleVec2, maxTrangle, circleColor, 1, circleColor);

	//设置clippingNode的模板类
	setStencil(circleNode);
    return true;
}

CirCularNode* CirCularNode::create(float radius, Node* pNode)
{
    auto clipNode = CirCularNode::create(radius);
    if (clipNode)
    {
        clipNode->setClipNode(pNode);
    }

    return clipNode;
}

void CirCularNode::setClipNode(Node* pNode)
{
    CC_SAFE_RELEASE_NULL(m_clipNode);
    m_clipNode = pNode;
    CC_SAFE_RETAIN(m_clipNode);
    
    addChild(pNode);
}

Node* CirCularNode::getClipNode()
{
    return m_clipNode;
}

测试效果:



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值