使用cocos2dx 实现一个画板,控制颜色,画笔大小。橡皮擦大小。还有回滚操作。
两个文件DrawView.h
#ifndef __DRAW_VIEW_H_
#define __DRAW_VIEW_H_
#include "cocos2d.h"
#include "PageBase.h"
class DrawView :public CCLayer
{
public:
DrawView();
~DrawView();
std::vector<cocos2d::CCPoint*> points;
std::vector<cocos2d::CCPoint*> lines;
static cocos2d::CCScene *scene();
virtual bool init();
void setlinecolor(cocos2d::ccColor3B cc3);
void setsize(int size);
void setDrawingMode(bool isDrawing);
void RollBack();
void ClearAllDraw();
void playeraser(float dt);
virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
virtual void ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
virtual void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
virtual void registerWithTouchDispatcher(void);
CREATE_FUNC(DrawView);
//parm
int linesize;
cocos2d::ccColor3B m_cc3;
bool isDraw;
std::vector<cocos2d::CCNode*> m_pBrushvec;
std::vector<int> m_pBrushLengthvec;
std::vector<bool> m_pBrushTypevec;
cocos2d::CCRenderTexture *m_pTarget ;
bool couldDraw;
int m_length;
};
#endif
DrawView.cpp
#include "DrawView.h"
using namespace cocos2d;
DrawView::DrawView()
{
m_cc3= ccc3(255,255,255);
linesize = 0;
isDraw = true;
couldDraw = false;
m_length = 0;
}
DrawView::~DrawView()
{
}
cocos2d::CCScene *DrawView::scene()
{
CCScene *scene = CCScene::create();
DrawView *layer = DrawView::create();
scene->addChild(layer);
return scene;
}
bool DrawView::init()
{
CCLayer::init();
bool bRet = false;
do
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
m_pTarget = CCRenderTexture::create(winSize.width, winSize.height,kCCTexture2DPixelFormat_RGBA8888);
m_pTarget->retain();
m_pTarget->setPosition(ccp(winSize.width * 0.5, winSize.height * 0.5));
this->addChild(m_pTarget);
bRet = true;
} while (0);
return bRet;
}
void DrawView::registerWithTouchDispatcher()
{
// 注册层响应屏幕触摸事件
CCDirector *director = CCDirector::sharedDirector();
director->getTouchDispatcher()->addTargetedDelegate(this, 9, false);
}
bool DrawView::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){
CCPoint touchPoint = pTouch->getLocation();
m_length = 0;
if (!couldDraw)
{
return false;
}
if (isDraw)
{
m_pTarget->begin();
CCSprite*m_pBrush = CCSprite::create("bishua.png");
m_pBrush->retain();
m_pBrush->setColor(m_cc3);
m_pBrush->setScale((float)linesize/m_pBrush->getContentSize().height);
m_pBrush->setRotation(rand() % 360);
m_pBrush->setPosition(touchPoint);
m_pBrush->visit();
m_pTarget->end();
m_pBrushvec.push_back(m_pBrush);
m_length++;
}
else
{
schedule(schedule_selector(DrawView::playeraser),0.6,kCCRepeatForever,0.1);
m_pTarget->begin();
CCDrawNode *m_pEraser = CCDrawNode::create();
float fRadius = linesize;
const int nCount = 100;
const float coef = 2.0f * (float)M_PI/nCount;
static CCPoint circle[nCount];
for(unsigned int i = 0;i <nCount; i++) {
float rads = i*coef;
circle[i].x = fRadius * cosf(rads);
circle[i].y = fRadius * sinf(rads);
}
m_pEraser->drawPolygon(circle, nCount, ccc4f(0, 0, 0, 0), 0, ccc4f(0, 0, 0, 0));
m_pEraser->retain();
ccBlendFunc blendFunc = { GL_ONE, GL_ZERO };
m_pEraser->setBlendFunc(blendFunc);
m_pEraser->visit();
m_pTarget->end();
m_pBrushvec.push_back(m_pEraser);
m_length++;
}
return true;
}
void DrawView::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){
CCPoint start = ccp(pTouch->getLocation().x, pTouch->getLocation().y );
CCPoint end = ccp(pTouch->getPreviousLocation().x, pTouch->getPreviousLocation().y);
if (!couldDraw)
{
return;
}
m_pTarget->begin();
if (isDraw)
{
float distance = ccpDistance(start, end);
if (distance > 1)
{
int d = (int)distance;
for (int i = 0; i<d; i++){
if(i%(linesize/2) == 0){
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float)i / distance;
CCSprite*m_pBrush = CCSprite::create("bishua.png");
m_pBrush->retain();
m_pBrush->setColor(m_cc3);
m_pBrush->setScale((float)linesize/m_pBrush->getContentSize().height);
m_pBrush->setRotation(rand() % 360);
m_pBrush->setPosition(ccp(start.x + (difx * delta), start.y + (dify * delta)));
m_pBrush->visit();
m_length ++;
m_pBrushvec.push_back(m_pBrush);
}
}
}
}
else
{
float distance = ccpDistance(start, end);
if (distance > 1)
{
int d = (int)distance;
for (int i = 0; i<d; i++){
if(i%(linesize/2) == 0){
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float)i / distance;
CCDrawNode *m_pEraser = CCDrawNode::create();
float fRadius = linesize;
const int nCount = 100;
const float coef = 2.0f * (float)M_PI/nCount;
static CCPoint circle[nCount];
for(unsigned int i = 0;i <nCount; i++) {
float rads = i*coef;
circle[i].x = fRadius * cosf(rads);
circle[i].y = fRadius * sinf(rads);
}
m_pEraser->drawPolygon(circle, nCount, ccc4f(0, 0, 0, 0), 0, ccc4f(0, 0, 0, 0));
m_pEraser->retain();
ccBlendFunc blendFunc = { GL_ONE, GL_ZERO };
m_pEraser->setBlendFunc(blendFunc);
m_pEraser->setPosition(ccp(start.x + (difx * delta), start.y + (dify * delta)));
m_pEraser->visit();
m_length ++;
m_pBrushvec.push_back(m_pEraser);
}
}
}
}
m_pTarget->end();
m_pBrushTypevec.push_back(isDraw);
}
void DrawView::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){
if (!couldDraw)
{
return;
}
if (m_length!=0)
{
m_pBrushLengthvec.push_back(m_length);
}
m_length = 0;
if (isDraw == false)
{
unschedule(schedule_selector(DrawView::playeraser));
}
}
void DrawView::setlinecolor(ccColor3B cc3)
{
m_cc3 = cc3;
}
void DrawView::setsize(int size)
{
linesize = size;
}
void DrawView::RollBack()
{
if(m_pBrushLengthvec.size() == 0){
return;
}else if (m_pBrushLengthvec.size() == 1){
m_pBrushLengthvec.pop_back();
m_pBrushLengthvec.clear();
m_pTarget->clear(0, 0, 0, 0);
return;
}
for(int i=0; i<m_pBrushLengthvec[m_pBrushLengthvec.size()-1]; i++){
m_pBrushvec.pop_back();
}
m_pBrushLengthvec.pop_back();
m_pTarget->clear(0, 0, 0, 0);
m_pTarget->begin();
for(int i=0; i<m_pBrushvec.size(); i++){
m_pBrushvec[i]->visit();
}
m_pTarget->end();
}
void DrawView::setDrawingMode(bool isDrawing)
{
isDraw = isDrawing;
}
void DrawView::playeraser(float dt)
{
//playEffect("eraser_02.mp3");
}
void DrawView::ClearAllDraw()
{
}