1. 程式人生 > >Quick-cocos2d-x如何判斷點選的sprite位置是否透明

Quick-cocos2d-x如何判斷點選的sprite位置是否透明

如果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, 0, 0);
pLayer->m_pSpriteStar->visit();
GLubyte pColor[4];
Director::getInstance()->getRenderer()->render();//3.x中缺了這行就沒效果
glReadPixels(point.x, point.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pColor[0]);
render->end();


if (pColor[3] != 0) {
CCLOG("no");
}
else
{
CCLOG("yes");
}


下面主要說明下quick-cocos2d-x下需要怎麼做。
1.修改\frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto\lua_cocos2dx_auto.cpp檔案,增加一個Director類的render匯出介面
這是因為預設情況下,quick沒有匯出Director類的getRenderer介面,Lua裡面沒法調,所以直接加個render介面,裡面執行cobj->getRenderer()->render();
2.修改\frameworks\cocos2d-x\cocos\scripting\lua-bindings\auto\lua_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, 0, 0)
self.spriteStar:visit()
local sharedDirector = cc.Director:getInstance()
sharedDirector:render()--自己新增的匯出介面
local vt4 = gl.readPixels(event.x, event.y, 1, 1, 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類判斷透明的方法