cocos2dx实现自定义图形橡皮擦功能 不是利用ClippingNode

前端之家收集整理的这篇文章主要介绍了cocos2dx实现自定义图形橡皮擦功能 不是利用ClippingNode前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

好了这里我先上代码

首先定义这个函数

  1. void HelloWorld::changeDatas(Image *image,Image * image1,Point point)
  2. {
  3. auto data = image->getData();//橡皮擦数据头指针
  4. auto data1 = image1->getData();//被擦除数据头指针
  5. auto size = Director::getInstance()->getVisibleSize();
  6. int pha = 3;
  7. if (image->hasAlpha())//判断是否有Alpha通道
  8. {
  9. pha = 4;
  10. }
  11.  
  12. for (int x = 0; x < image->getWidth(); ++x)
  13. {
  14. for (int y = 0; y < image->getHeight(); ++y)
  15. {
  16. /*下面是获取rgb颜色值 这里说明一下
  17. data是指向数据的头指;指针指向数据的排列方式是 data 0~3 rgba data 4~7 rgba
  18. 所以没有Alpha通道 的排列方式是 data 0~2 rgb data 3~5 rgb
  19. */
  20. unsigned char *pixel = data + (x + y * image->getWidth()) * pha;//遍历每个像素点的rgb
  21. unsigned int r = (unsigned int)*pixel;
  22. unsigned int g = (unsigned int)*(pixel + 1);
  23. unsigned int b = (unsigned int)*(pixel + 2);
  24. unsigned int a = (unsigned int)*(pixel + 3);
  25.  
  26. if (r != 0 || g != 0 || b != 0 || a != 0)//如果该点有颜色就将被剪裁区域的颜色替换成无色
  27. {
  28. Point changep = Point(size.width/2,size.height-size.height/2);//因为Opengl的坐标在左上角所以做坐标转换;这里应该把被剪裁区域的图坐标转换成OPENGL
  29. Point changep1 = Point(changep.x - image1->getWidth() / 2,changep.y - image1->getHeight() / 2);
  30.  
  31. int c = x + point.x - changep1.x - image->getWidth() / 2;
  32. int d = y + point.y - changep1.y - image->getHeight() / 2;
  33.  
  34. if (c>0&&d>0&&c < image1->getWidth() && d <image1->getHeight())
  35. {
  36. int pha1 = 3;
  37. if (image1->hasAlpha())
  38. {
  39. pha1 = 4;
  40. }
  41. unsigned char *pixel1 = data1 + (c + d * image1->getWidth()) * pha1;
  42. *pixel1 = 0;//数据修改
  43. *(pixel1 + 1) = 0;
  44. *(pixel1 + 2) = 0;
  45. }
  46. }
  47.  
  48. }
  49. }
  50.  
  51.  
  52. }

然后在初始化方法
  1. auto CliperImage = new Image();//创建一个需要剪裁的Image
  2.  
  3. CliperImage->initWithImageFile("HelloWorld.png");
  4. auto image = new Image();//创建一个橡皮擦Image
  5.  
  6. image->initWithImageFile("123.png");
  7. auto text = new Texture2D();
  8. text->initWithImage(CliperImage);
  9. auto sp = Sprite::createWithTexture(text);
  10. sp->setPosition(visibleSize.width/2,visibleSize.height/2);
  11. this->addChild(sp,33);//通过不停的更新这个SP来实现涂擦效果 也可以认为更新了CliperImage的DATA来实现
  12.  
  13. /*创建监听事件*/
  14. auto linstener = EventListenerTouchOneByOne::create();
  15.  
  16. linstener->onTouchBegan = [this](Touch *touch,Event *event)
  17. {
  18. return true;
  19. };
  20. linstener->onTouchMoved = [this,CliperImage,image](Touch *touch,Event *event)
  21. {
  22. auto size = Director::getInstance()->getVisibleSize();
  23. this->removeChildByTag(33);
  24. changeDatas(image,Point(touch->getLocation().x,size.height - touch->getLocation().y));
  25. auto text1 = new Texture2D();
  26. text1->initWithImage(CliperImage);
  27. auto sp = Sprite::createWithTexture(text1);
  28. sp->setPosition(size.width / 2,size.height / 2);
  29. addChild(sp,33);
  30. };
  31.  
  32. linstener->onTouchEnded = [this,Event *event)
  33. {
  34. auto size = Director::getInstance()->getVisibleSize();
  35. this->removeChildByTag(33);
  36. changeDatas(image,size.height - touch->getLocation().y));
  37. auto text1 = new Texture2D();
  38. text1->initWithImage(CliperImage);
  39. auto sp = Sprite::createWithTexture(text1);
  40. sp->setPosition(size.width/2,size.height/2);
  41. addChild(sp,33);
  42. };
  43.  
  44. _eventDispatcher->addEventListenerWithSceneGraPHPriority(linstener,this);

好了我们来看下效果同样的123.png是这个

效果


其实原理就是通过修改这张图的二进制文件数据来实现擦涂效果

不像我上一篇介绍的ClippingNode一样可以添加很多精灵进行裁剪;

猜你在找的Cocos2d-x相关文章