如果sprite所使用的图片有透明区域,而我们又希望点击这些透明区域的时候不认为点击了这张图片,那就需要判断所点击的位置在图片上是否透明。 网上所提供的使用glReadPixels的方法基本准确,但是在3.x版本中,visit执行后不会立刻render,所以代码需要增加Director::getInstance()->getRenderer()->render();强制渲染一下才行 例如: CCRenderTexture* render = CCRenderTexture::create(CCDirector::sharedDirector()->getWinSize().width,CCDirector::sharedDirector()->getWinSize().height); render->beginWithClear(0,0); pLayer->m_pSpriteStar->visit(); GLubyte pColor[4]; Director::getInstance()->getRenderer()->render();//3.x中缺了这行就没效果 glReadPixels(point.x,point.y,1,GL_RGBA,GL_UNSIGNED_BYTE,&pColor[0]); render->end(); if (pColor[3] != 0) { CCLOG("no"); } else { CCLOG("yes"); } 下面主要说明下quick-cocos2d-x下需要怎么做。 1.修改frameworkscocos2d-xcocosscriptinglua-bindingsautolua_cocos2dx_auto.cpp文件,增加一个Director类的render导出接口 这是因为默认情况下,quick没有导出Director类的getRenderer接口,Lua里面没法调,所以直接加个render接口,里面执行cobj->getRenderer()->render(); 2.修改frameworkscocos2d-xcocosscriptinglua-bindingsautolua_cocos2dx_auto.cpp文件,把RenderTexture导出接口中的end函数改个名,比如end2之类的 这是因为在quick中,end这个函数好像有其他用,所以用render:end()会直接报错 3.编译c++ 4.Lua部分类似于c++的写法 例如: local render = cc.RenderTexture:new() render:initWithWidthAndHeight(display.width,display.height,cc.TEXTURE2_D_PIXEL_FORMAT_RGB_A8888,0) render:beginWithClear(0,0) self.spriteStar:visit() local sharedDirector = cc.Director:getInstance() sharedDirector:render()--自己新增的导出接口 local vt4 = gl.readPixels(event.x,event.y,gl.RGBA,gl.UNSIGNED_BYTE,4) render:end1()--直接用end会报错 if (vt4[4] > 0) then print("不透明") else print("透明") end 这样就可以了 不过上面这种方法每次都要重绘判断,效率比较低,也可以使用Image类预先把图片加载进来,然后增加个判断某个点是否是透明的方法,内存多耗些,性能会好
后话,上述方法在windows下和mac系统下均正常,但是在ios系统下,执行Director::getInstance()->getRenderer()->render();后,opengl会无限报错,也不清楚是什么原因,所以实际还是采用了Image类判断透明的方法 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|