首页 > 编程 > C > 正文

cocos2dx实现橡皮擦效果以及判断是否擦除完毕

2020-01-26 13:36:35
字体:
来源:转载
供稿:网友

本文实例为大家分享了cocos2dx实现橡皮擦效果,以及判断是否擦除完毕,供大家参考,具体内容如下

首先修改HelloWorld.h文件

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h"#include "cocos-ext.h"USING_NS_CC_EXT;USING_NS_CC;class HelloWorld : public cocos2d::Layer{public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene();  // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init();  // a selector callback void menuCloseCallback(cocos2d::Ref* pSender);  // implement the "static create()" method manually CREATE_FUNC(HelloWorld); void myUpdate(float dt);//不断判断是否全部擦除 void onTouchesMoved(const std::vector<Touch*>& touches, Event* event); bool myIsDataClear(RenderTexture *pRenderTexture);//是否完全擦除 bool myIsDataClearInRect(RenderTexture *pRenderTexture,int x,int y,int width ,int height);//某个区域是否完全擦除 Sprite *sprFore; RenderTexture *renderTexture; Vector<Sprite*> _brushs;}; #endif // __HELLOWORLD_SCENE_H__

然后修改HelloWorld.cpp文件

#include "HelloWorldScene.h" USING_NS_CC; Scene* HelloWorld::createScene(){ // 'scene' is an autorelease object auto scene = Scene::create();  // 'layer' is an autorelease object auto layer = HelloWorld::create();  // add layer as a child to scene scene->addChild(layer);  // return the scene return scene;} // on "init" you need to initialize your instancebool HelloWorld::init(){  if ( !Layer::init() ) {  return false; }  Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin();  auto closeItem = MenuItemImage::create(           "CloseNormal.png",           "CloseSelected.png",           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));  closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,        origin.y + closeItem->getContentSize().height/2));  auto menu = Menu::create(closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1);     auto label = Label::createWithTTF("Test Eraser", "fonts/Marker Felt.ttf", 24);   label->setPosition(Vec2(origin.x + visibleSize.width/2,       origin.y + visibleSize.height - label->getContentSize().height));  this->addChild(label, 1);    sprFore = Sprite::create("HelloWorld.png"); sprFore->setPosition(Vec2(visibleSize / 2) + origin); sprFore->retain(); renderTexture = RenderTexture::create(visibleSize.width, visibleSize.height, Texture2D::PixelFormat::RGBA8888); renderTexture->setContentSize(visibleSize); renderTexture->retain(); this->addChild(renderTexture); renderTexture->setPosition(Vec2(visibleSize / 2) + origin);    renderTexture->beginWithClear(0, 0, 0, 0); sprFore->visit(); renderTexture->end();    auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);  //不断判断是否擦除完毕 schedule(schedule_selector(HelloWorld::myUpdate), 0.5f); return true;}  void HelloWorld::menuCloseCallback(Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return;#endif  Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0);#endif} void HelloWorld::myUpdate(float dt){ if (myIsDataClear(renderTexture) == true) {  log("image is clear !"); }  if (myIsDataClearInRect(renderTexture,300,200,50,50) == true) {  log("image in rect is clear !"); }} void HelloWorld::onTouchesMoved(const std::vector<Touch*>& touches, Event* event){ auto touch = touches[0]; auto start = touch->getLocation(); auto end = touch->getPreviousLocation();  // begin drawing to the render texture renderTexture->begin();  // for extra points, we'll draw this smoothly from the last position and vary the sprite's // scale/rotation/offset float distance = start.getDistance(end); if (distance > 1) { int d = (int)distance; _brushs.clear(); for (int i = 0; i < d; ++i) { //橡皮擦 auto sprite = CCSprite::create("red.png");//主要根据图片定义橡皮擦的形状 BlendFunc blendFunc; blendFunc.src = GL_ZERO; blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA; sprite->setBlendFunc(blendFunc); sprite->setScale(1.8f); renderTexture->addChild(sprite); _brushs.pushBack(sprite); } for (int i = 0; i < d; i++) { float difx = end.x - start.x; float dify = end.y - start.y; float delta = (float)i / distance; _brushs.at(i)->setPosition(Vec2(start.x + (difx * delta), start.y + (dify * delta))); _brushs.at(i)->visit(); } }  // finish drawing and return context back to the screen renderTexture->end(); } bool HelloWorld::myIsDataClear(RenderTexture *pRenderTexture){ bool m_bEraserOk = false;  Image* image = new Image(); image = pRenderTexture->newImage(true);  int m = 3; if (image->hasAlpha()) { m = 4; }  unsigned char *data_ = image->getData();  int x = 0, y = 0; /// 这里要提醒一点,即Opengl下,其中心点坐标在左上角 for (x = 0; x < pRenderTexture->getContentSize().width; ++x) { for (y = 0; y < pRenderTexture->getContentSize().height; ++y) { //获取每个点的像素点值 unsigned char *pixel = data_ + (x + y * image->getWidth()) * m;  // You can see/change pixels' RGBA value(0-255) here ! unsigned int r = (unsigned int)*pixel; unsigned int g = (unsigned int)*(pixel + 1); unsigned int b = (unsigned int)*(pixel + 2); unsigned int a = (unsigned int)*(pixel + 3);  if (r != 0 && g != 0 && b != 0 && a != 0) { m_bEraserOk = false; break; } } //如果改列 有一个点的像素点值不为零 跳出 if (pRenderTexture->getContentSize().height != y) { break; } }  //如果所有点的像素点值都为0 则擦除完毕 if (x == pRenderTexture->getContentSize().width && y == pRenderTexture->getContentSize().height) { m_bEraserOk = true; }  delete image;  return m_bEraserOk;} bool HelloWorld::myIsDataClearInRect(RenderTexture *pRenderTexture, int x, int y, int width, int height){    bool m_bEraserOk = false;  Image* image = new Image(); image = pRenderTexture->newImage(true);  int m = 3; if (image->hasAlpha()) { m = 4; }  int i = 0, j = 0; unsigned char* mdata = (unsigned char*)image->getData(); for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) {  unsigned char *pixel = mdata + (i + x + (image->getHeight() - y - (height - j)) * image->getWidth()) * m;  // You can see/change pixels' RGBA value(0-255) here ! unsigned int r = (unsigned int)*pixel; unsigned int g = (unsigned int)*(pixel + 1); unsigned int b = (unsigned int)*(pixel + 2); unsigned int a = (unsigned int)*(pixel + 3);  if (r != 0 && g != 0 && b != 0 && a != 0) { break; }  }  if (height != j) { break; } }  if (i == width && j == height) { m_bEraserOk = true; } return m_bEraserOk;}

看下运行效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选