【Cocos2d-x】Cocos2d-x 3.0 区域裁切 的具体应用之游戏公告显示

本文介绍了一个使用 Cocos2d-x 开发的游戏示例项目,重点讲解了初始化过程、精灵的添加及位置设置,并演示了如何通过 OpenGL 的 glScissor 函数实现屏幕区域裁剪以达到特定的视觉效果。

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

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    this->addChild(sprite, 0);


    glEnable(GL_SCISSOR_TEST);// 开启显示指定区域
    return true;
}
void HelloWorld::visit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated){
    
    float x = 100;
    float y = 100;
    float n_width = Director::getInstance()->getWinSize().width;
    float n_height = Director::getInstance()->getWinSize().height/2;
    log("x = %f,y = %f,w = %f,h = %f",x,y,n_width,n_height);
    glScissor(x, y, n_width, n_height);     // 只显示当前窗口的区域
    Layer::visit(renderer, parentTransform, parentTransformUpdated);//显示父类的内容
    //glDisable(GL_SCISSOR_TEST);             // 禁用
    
    
    return;
	
}
glScissor 显示当前窗口的区域
利用这个函数可以实现 类似游戏公告的显示
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    this->addChild(sprite, 0);
    sprite->setTag(1000);

    return true;
}

void HelloWorld::visit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated){
    
    this->beforeDraw(renderer, parentTransform, parentTransformUpdated);
    Node::visit(renderer, parentTransform, parentTransformUpdated);//显示父类的内容
    this->afterDraw(renderer, parentTransform, parentTransformUpdated);
    
	
}


void HelloWorld::setNeedClip(bool need){
	mIsNeedClip=need;
}
bool HelloWorld::isNeedClip(){
	return mIsNeedClip;
}
void HelloWorld::beforeDraw(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated)
{
    _beforeDrawCommand.init(_globalZOrder);
    _beforeDrawCommand.func = CC_CALLBACK_0(HelloWorld::onBeforeDraw, this,parentTransform, parentTransformUpdated);
    renderer->addCommand(&_beforeDrawCommand);
}
static Rect mClip;
static int mClipCounter=0;
float math_abs(float v){
	if(v>0){
		return v;
	}
	return 0-v;
}

float math_max(float v1,float v2){
	if(v1>v2){
		return v1;
	}
	return v2;
}


float math_min(float v1,float v2){
	if(v1>v2){
		return v2;
	}
	return v1;
}
void HelloWorld::onBeforeDraw(const kmMat4& parentTransform, bool parentTransformUpdated){
    
    int clipW=1024;
    int clipH=768/4;
    
    bool needClip=clipW>0&&clipH>0;
    
    if(isNeedClip()&&needClip){
        glEnable(GL_SCISSOR_TEST);
        Point selfPos =Point(790,500);//this->getPosition();
        
        float scaleX = 1;
        float scaleY = 1;
        
        Rect viewPortRect =  Director::getInstance()->getOpenGLView()->getViewPortRect();
        float clipX=selfPos.x *scaleX  +  viewPortRect.origin.x;
        float clipY=selfPos.y * scaleY  +  viewPortRect.origin.y;
        clipW*=scaleX;
        clipH*=scaleX;
        if(mClipCounter>0){
            saveOldRect=mClip;
            float right=math_min(clipX+clipW,mClip.origin.x+mClip.size.width);
            float top=math_min(clipY+clipH,mClip.origin.y+mClip.size.height);
            clipX=math_max(clipX,mClip.origin.x);
            clipY=math_max(clipY,mClip.origin.y);
            clipW=right-clipX;
            clipH=top-clipY;
            if(clipW<0){
                clipW=0;
            }
            if(clipH<0){
                clipH=0;
            }
        }
        if(clipW>0&&clipH>0){
            //glScissor(clipX  ,clipY ,clipW, clipH);
            Director::getInstance()->getOpenGLView()->setScissorInPoints(clipX  ,clipY ,clipW, clipH);//设定裁切区域大小
            mClip=Rect(clipX,clipY,clipW,clipH);
        }
        mClipCounter++;
    }
}


void HelloWorld::afterDraw(Renderer *renderer, const kmMat4& parentTransform, bool transformUpdated){
    _afterDrawCommand.init(_globalZOrder);
    _afterDrawCommand.func = CC_CALLBACK_0(HelloWorld::onAfterDraw, this,parentTransform, transformUpdated);
    renderer->addCommand(&_afterDrawCommand);
    
}

void HelloWorld::onAfterDraw(const kmMat4& parentTransform, bool parentTransformUpdated){
    int clipW=1024;
    int clipH=768/4;
    bool needClip=clipW>0&&clipH>0;
    if(isNeedClip()&&needClip){
        mClipCounter--;
        if(mClipCounter<=0){
            glDisable(GL_SCISSOR_TEST);
        }else{
            mClip=saveOldRect;
            //glScissor(mClip.origin.x  ,mClip.origin.y ,mClip.size.width, mClip.size.height);
            Director::getInstance()->getOpenGLView()->setScissorInPoints(mClip.origin.x  ,mClip.origin.y ,mClip.size.width, mClip.size.height);//设定裁剪显示区域
        }
    }
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值