try to play around with cocos2dx with cpp:
Here is the Header file:
#ifndef FirstScene_h
#define FirstScene_h
#include "cocos2d.h"
class FirstScene: public cocos2d::Scene
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
void menuCloseCallback(cocos2d::Ref* pSender);
CREATE_FUNC(FirstScene);
bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event);
bool onTouchMoved(cocos2d::Touch *touch, cocos2d::Event * event);
bool onTouchEnd(cocos2d::Touch *touch, cocos2d::Event *event);
private:
cocos2d::Label *logLabel;
};
#endif /* FirstScene_h */
And here is the cpp file:
#include "FirstScene.h"
#include "SimpleAudioEngine.h"
USING_NS_CC;
Scene* FirstScene::createScene(){
return FirstScene::create();
}
bool FirstScene::init(){
if(!Scene::init()){
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto label = Label::createWithTTF("this is the first scene", "fonts/Marker Felt.ttf", 24);
label->setPosition(visibleSize.width/2,visibleSize.height/2);
this->addChild(label,1);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(visibleSize.width/3,visibleSize.height/3);
logLabel = Label::createWithTTF("Log holder", "fonts/Marker Felt.ttf", 24);
logLabel->setPosition(visibleSize.width/2 + 10.0f, visibleSize.height/2 + 10.0f);
this->addChild(logLabel,3);
this->addChild(sprite,0);
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(FirstScene::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(FirstScene::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(FirstScene::onTouchEnd, this);
return true;
}
bool FirstScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event) {
CCLOG("touch at x=%f, y=%f", touch->getLocation().x, touch->getLocation().y);
std::string s = "";
s += "touch at x=";
s += touch->getLocation().x;
s += "y=";
s += touch->getLocation().y;
logLabel->setString(s);
return true;
}
bool FirstScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event) {
std::string s = "";
s += "touch moved at x=";
s += touch->getDelta().x;
s += " y=";
s += touch->getDelta().y;
CCLOG("touch moved at x=%f, y=%f", touch->getDelta().x, touch->getDelta().y);
logLabel->setString(s);
return true;
}
bool FirstScene::onTouchEnd(cocos2d::Touch *touch, cocos2d::Event *event) {
std::string s="";
s += "touch ended at x=";
s += touch->getLocation().x;
s += " y=";
s += touch->getLocation().y;
CCLOG("touch ended at x=%f, y=%f", touch->getLocation().x, touch->getLocation().y);
logLabel->setString(s);
return true;
}
The things I want is when I touch and move on the screen, the log will be showed and the logLabel will show the message, but it seems there is no message saw either in the log window nor the logLabel changed.
What did I missing?
Note
I load this scene by one previous scene by following code if it matters:
void HelloWorld::menuCloseCallback(Ref* pSender)
{
auto firstScene = FirstScene::createScene();
Director::getInstance()->replaceScene(firstScene);
}
Really a newbie for cocos2dx and cpp, thanks in advance.
You need to add/register you event listener to event dispatcher :
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
If you want to add an event listener for a specified event with the priority of scene graph :
addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
else want add an event listener for a specified event with the fixed priority.
addEventListenerWithFixedPriority(EventListener* listener, Node* node)
Related
I am trying something that would seem quite easy, but am struggling a bit with it. I want to be able to draw rectangles in a GUI. What I am doing now is:
I create a GUI with Qt Designer, in which I include a QGraphicsView.
In my main window I create a myGraphicsScene (class derived from QGraphicsScene, but with mouse press, move and release events overridden) and I set the scene to the QGraphicsView created in the UI.
The problem is that I am not able to properly control the refresh and update of the view when I change the scene.
Here is the relevant part of the code:
MainGUIWindow constructor and initialization:
MainGUIWindow::MainGUIWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainGUIWindow)
{
ui->setupUi(this);
_init();
}
void MainGUIWindow::_init()
{
scene = new myGraphicsScene(ui->frame_drawing);
scene->setSceneRect(QRectF(QPointF(-100, 100), QSizeF(200, 200)));
ui->graphicsView->setScene(scene);
QRect rect(10, 20, 80, 60);
scene->addText("Hello world!");
scene->addRect(rect, QPen(Qt::black), QBrush(Qt::blue));
}
I can perfectly see the HelloWorld text and this rectangle. However when I start with clicking events, I don't properly get updates anymore.
myGraphicsScene class header:
#ifndef MYGRAPHICSSCENE_H
#define MYGRAPHICSSCENE_H
#include <QGraphicsScene>
class QGraphicsSceneMouseEvent;
class QPointF;
class QColor;
class myGraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit myGraphicsScene(QObject *parent = 0);
public slots:
signals:
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
private:
QPen* pen;
QBrush* brush;
QRect* rect;
QPoint* p1;
QPoint* p2;
bool firstClick;
// bool startedRect;
};
#endif
myGraphicsScene class implementation:
#include "myGraphicsScene.h"
#include <QGraphicsSceneMouseEvent>
#include <QRect>
myGraphicsScene::myGraphicsScene(QObject *parent)
: QGraphicsScene(parent)
{
pen = new QPen(Qt::black);
brush = new QBrush(Qt::blue);
rect = 0;
// startedRect = false;
firstClick = true;
}
void myGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
// rect = new QRect((mouseEvent->scenePos()).toPoint(), (mouseEvent->scenePos()).toPoint());
// addRect(*rect, *pen, *brush);
// startedRect = true;
if(firstClick)
{
p1 = new QPoint((mouseEvent->scenePos()).toPoint());
QRect tmp_rect(*p1, *p1);
addRect(tmp_rect, *pen, *brush);
}
else
{
p2 = new QPoint((mouseEvent->scenePos()).toPoint());
QRect tmp_rect(*p2, *p2);
addRect(tmp_rect, *pen, *brush);
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
void myGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// if(startedRect)
// {
// rect->moveBottomRight((mouseEvent->scenePos()).toPoint());
// qDebug("Mouse Position: %d, %d", (mouseEvent->scenePos()).toPoint().x(), (mouseEvent->scenePos()).toPoint().y());
// qDebug("Rectangle BottomRight Position: %d, %d", rect->bottomRight().x(), rect->bottomRight().y());
// }
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void myGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
// rect = 0;
// startedRect = false;
if(firstClick)
{
firstClick = false;
}
else
{
rect = new QRect(*p1, *p2);
addRect(*rect, *pen, *brush);
p1 = 0;
p2 = 0;
rect = 0;
firstClick = true;
}
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
My original idea was to draw the rectangles in a drag and drop fashion, but in the end ended up trying the two-clicks approach, which worked a bit better but still doesn't completely update the view when it should.
I am new to Qt, so I am not very familiar with how it should be done. Any help would be appreciated, since I have been a bit stuck here for some time now.
Thanks!
In each of your mouse*Event() overloads, call QGraphicsScene::update() method. It will schedule redraw on the view.
http://doc.qt.io/qt-5/qgraphicsscene.html#update
I just found the solution: I had to actually change the item added to the scene, and not the rectangle. So, now, my code looks like:
#include "myGraphicsScene.h"
#include <QGraphicsSceneMouseEvent>
#include <QRect>
#include <QGraphicsRectItem>
myGraphicsScene::myGraphicsScene(QObject *parent)
: QGraphicsScene(parent)
{
pen = new QPen(Qt::black);
brush = new QBrush(Qt::blue);
tmp_rect = 0;
startedRect = false;
// firstClick = true;
}
void myGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
// Drag and drop approach
startedRect = true;
p1 = new QPointF(mouseEvent->scenePos());
tmp_rect = new QRectF(*p1, *p1);
// addRect(*tmp_rect, *pen, *brush);
tmp_rect_item = new QGraphicsRectItem(*tmp_rect);
rectangles.push_back(tmp_rect_item);
addItem(rectangles.back());
// Two-clicks approach
// if(firstClick)
// {
// p1 = new QPointF(mouseEvent->scenePos());
// tmp_rect_item = addRect(QRect(p1->toPoint(), p1->toPoint()), *pen, *brush); //save it to remove it after
// }
// else
// {
// p2 = new QPointF(mouseEvent->scenePos());
// // QRect tmp_rect(*p2, *p2);
// // addRect(tmp_rect, *pen, *brush);
// }
update();
QGraphicsScene::mousePressEvent(mouseEvent);
}
void myGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if(startedRect)
{
tmp_rect_item->setRect(QRectF(*p1, mouseEvent->scenePos()));
qDebug("Mouse Position: %d, %d", (mouseEvent->scenePos()).toPoint().x(), (mouseEvent->scenePos()).toPoint().y());
qDebug("Rectangle BottomRight Position: %d, %d", tmp_rect->bottomRight().x(), tmp_rect->bottomRight().y());
update();
}
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void myGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
// Drag and drop approach:
tmp_rect = 0;
startedRect = false;
// Two-clicks approach
// if(firstClick)
// {
// firstClick = false;
// }
// else
// {
// removeItem(tmp_rect_item);
// tmp_rect_item = new QGraphicsRectItem(QRectF(*p1, *p2));
// // *tmp_rect, *pen, *brush);
// rectangles.push_back(tmp_rect_item);
// addItem(rectangles.back());
// p1 = 0;
// p2 = 0;
// tmp_rect = 0;
// firstClick = true;
// }
update();
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
one other helpful hint I found was that when I extended my view, I had put the mouse event handler under "public" instead of "protected". I made the change the calls were made consistently.
I've got an application which handles zooming in/out using the mouse wheel with this event in Qt Creator.
cpp
void QNodeView::wheelEvent(QWheelEvent* event) {
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
// Scale the view / do the zoom
double scaleFactor = 1.15;
if(event->delta() > 0) {
// Zoom in
scale(scaleFactor, scaleFactor);
} else {
// Zooming out
scale(1.0 / scaleFactor, 1.0 / scaleFactor);
}
}
This is in the header file
h
protected:
//Take over the interaction
virtual void wheelEvent(QWheelEvent* event);
How can I add the ability to pan with the middle mouse button being pressed the user dragging the cursor?
I can post the project code if necessary just ask.
Thanks
Project files link (Qt Creator project)
https://www.dropbox.com/s/gbt4qqtdedltxek/QNodesEditor-master_01.zip?dl=0
At first, introduce some new member variables into your viewer class:
class QNodeView : public QGraphicsView
{
// ...
private:
int m_originalX = 0;
int m_originalY = 0;
bool m_moving = false;
};
Then reimplement mousePressEvent(), mouseMoveEvent(), and mouseReleaseEvent().
void QNodeView::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton)
{
// store original position
m_originalX = event->x();
m_originalY = event->y();
// set the "moving" state
m_moving = true;
}
}
void QNodeView::mouseMoveEvent(QMouseEvent* event)
{
if (m_moving)
{
// panning operates in the scene coordinates using x,y
QPointF oldp = mapToScene(m_originalX, m_originalY);
QPointF newp = mapToScene(event->pos());
QPointF translation = newp - oldp;
translate(translation.x(), translation.y());
m_originalX = event->x();
m_originalY = event->y();
}
}
void QNodeView::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton)
{
m_moving = false;
}
}
Briefly, I have two sprites, one of which is a child of another.
With each sprite related the event listener, as described there.
If both sprites are child nodes of the layer, then everything works great.
Now I need to second sprite is a child node of the first sprite.
But in this case, the second sprite does not respond to events in general.
I'm in a panic and have no idea what's wrong and how to fix it. Please help.
Here's a simplified example:
.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
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);
};
class PlaySprite : public cocos2d::Sprite
{
public:
virtual bool init();
CREATE_FUNC(PlaySprite);
void addEvent();
bool touchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
};
class InPlaySprite : public cocos2d::Sprite
{
public:
virtual bool init();
CREATE_FUNC(InPlaySprite);
void addEvent();
bool touchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
};
#endif // __HELLOWORLD_SCENE_H__
.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 instance
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// add a "close" icon to exit the progress. it's an autorelease object
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);
/////////////////////////////
// 3. add your codes below...
auto sprite1 = PlaySprite::create();
this->addChild(sprite1);
auto sprite2 = InPlaySprite::create();
// !!!
sprite1->addChild(sprite2);
return true;
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
}
bool PlaySprite::init()
{
if(!Sprite::init())
return false;
// to do
Size visibleSize = Director::getInstance()->getVisibleSize();
this->setTexture("1.png");
this->setPosition(visibleSize.width / 2, visibleSize.height / 2);
this->addEvent();
return true;
}
void PlaySprite::addEvent()
{
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = [=](Touch* touch, Event* event)
{
return this->touchBegan(touch, event);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
bool PlaySprite::touchBegan(Touch* touch, Event* event)
{
auto target = (Sprite* ) event->getCurrentTarget();
auto rect = this->getBoundingBox();
if(rect.containsPoint(touch->getLocation()))
{
this->setTexture("1d.png");
return true;
}
return false;
}
bool InPlaySprite::init()
{
if(!Sprite::init())
return false;
// to do
Size visibleSize = Director::getInstance()->getVisibleSize();
this->setTexture("2.png");
this->setPosition(150.0f, 150.0f);
this->addEvent();
return true;
}
void InPlaySprite::addEvent()
{
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = [=](Touch* touch, Event* event)
{
return this->touchBegan(touch, event);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
bool InPlaySprite::touchBegan(Touch* touch, Event* event)
{
// auto target = (Sprite* ) event->getCurrentTarget();
auto rect = this->getBoundingBox();
if(rect.containsPoint(touch->getLocation()))
{
this->setTexture("2d.png");
return true;
}
return false;
}
Classes PlaySprite and InPlaySprite are are very similar because this is a very simplified example.
I think your problem is that you are swallowing touch events in the parent sprite when you call
listener->setSwallowTouches(true);
If you make that call inside of PlaySprite::addEvent() with false instead, I suspect things will work out for you.
can't change the color of a background i have this simple class :
here is the c++ file :
#include "HelloWorldScene.h"
USING_NS_CC;
HelloWorld::HelloWorld()
{
;
}
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 instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !LayerColor::initWithColor(Color4B(20,0,0,255)) )
{
return false;
}
winSize = Director::getInstance()->getWinSize();
visibleSize = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
schedule( schedule_selector(HelloWorld::tick) );
return true;
}
void HelloWorld::onExit()
{
LayerColor::onExit();
}
void HelloWorld::onEnter()
{
LayerColor::onEnter();
auto cache = SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("interface/sprites.plist", "interface/sprites.png");
SpriteBatchNode* batch = SpriteBatchNode::create("interface/sprites.png");
this->addChild(batch,BATCH_Z);
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
void HelloWorld::onTouchesBegan(const std::vector<Touch*>& touches, Event *event)
{
for( auto& touch : touches)
{
}
}
void HelloWorld::onTouchesMoved(const std::vector<Touch*>& touches, Event *event)
{
for( auto& touch : touches)
{
}
}
void HelloWorld::onTouchesEnded(const std::vector<Touch*>& touches, Event *event)
{
for( auto& touch : touches)
{
startAnim = true;
};
}
void HelloWorld::tick(float dt)
{
if(startAnim)
{
}
}
void HelloWorld::draw()
{
LayerColor::draw();
}
HelloWorld::~HelloWorld()
{
// Removes Touch Event Listener
_eventDispatcher->removeEventListener(_touchListener);
}
void HelloWorld::menuCloseCallback(Object* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
and the h file :
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class GameObj;
class ReelGameObj;
class HelloWorld : public cocos2d::LayerColor
{
public:
HelloWorld();
~HelloWorld();
// 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(Object* pSender);
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
void tick(float dt);
virtual void draw();
virtual void onEnter();
virtual void onExit();
void onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event);
void onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event);
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event);
protected:
cocos2d::CustomCommand _customCommand;
void onDraw();
private:
cocos2d::EventListenerTouchOneByOne* _touchListener;
cocos2d::Size winSize;
cocos2d::Size visibleSize;
cocos2d::Point origin;
GameObj* pMainWindowObjCenter;
ReelGameObj* pReelGameObj;
bool startAnim;
};
#endif // __HELLOWORLD_SCENE_H__
and nothing no color in the background , why ?
im working on windows with VC 2012
I think your color is too dark. Try changing the values to (255,25,255,255) and check the result.
I created a sample project (in Beta 2), and only changed these lines:
.h:
class HelloWorld : public cocos2d::LayerColor
.cpp:
if( !LayerColor::initWithColor(Color4B(255,255,255,255)) )
The result is a white background.
I cleaned up and updated your code (I use cocos2dx 2.2.1) and I could change the layer's color to red.
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::CCLayerColor
{
public:
HelloWorld();
~HelloWorld();
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::CCScene* 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(CCObject* pSender);
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
virtual void onEnter();
void draw();
private:
cocos2d::CCSize winSize;
cocos2d::CCSize visibleSize;
cocos2d::CCPoint origin;
bool startAnim;
};
#endif // __HELLOWORLD_SCENE_H__
The cpp file
#include "HelloWorldScene.h"
USING_NS_CC;
HelloWorld::HelloWorld()
{}
HelloWorld::~HelloWorld()
{}
CCScene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = CCScene::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 instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
ccColor4B c = ccc4(255,0,0,255);
if ( !CCLayerColor::initWithColor(c) )
{
return false;
}
return true;
}
void HelloWorld::onEnter()
{
CCLayerColor::onEnter();
}
void HelloWorld::draw()
{
CCLayerColor::draw();
}
i try to follow the cocose2d-x 2.2 Test file :
cocos2d-x-2.2\samples\Cpp\TestCpp\Classes\SchedulerTest\SchedulerTest.h
i implemented the slider control and i see it and the :
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
function are triggerd just right when i try to slide
but its not sliding at all this is what i have :
the default close menu is working find :
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
bSliderCtlTouched = false;
this->setTouchEnabled(true);
this->schedule(schedule_selector(HelloWorld::tick));
return true;
}
void HelloWorld::tick(float dt)
{
;
}
void HelloWorld::onEnter()
{
CCLayer::onEnter();
CCSize s = CCDirector::sharedDirector()->getWinSize();
m_pSliderCtl = sliderCtl();
m_pSliderCtl->retain();
m_pSliderCtl->setPosition(ccp(s.width / 2.0f, s.height - (m_pSliderCtl->getContentSize().height*2)));
this->addChild(m_pSliderCtl,1);
}
CCControlSlider* HelloWorld::sliderCtl()
{
CCControlSlider * slider = CCControlSlider::create("extensions/sliderTrack2.png","extensions/sliderProgress2.png" ,"extensions/sliderThumb.png");
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::sliderAction), CCControlEventValueChanged);
slider->setMinimumValue(-3.0f);
slider->setMaximumValue(3.0f);
slider->setValue(1.0f);
return slider;
}
void HelloWorld::sliderAction(CCObject* pSender, CCControlEvent controlEvent)
{
bSliderCtlTouched =true;
CCControlSlider* pSliderCtl = (CCControlSlider*)pSender;
float scale;
scale = pSliderCtl->getValue();
}
void HelloWorld::registerWithTouchDispatcher()
{
// higher priority than dragging
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this,0, true);
}
bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
CCLOGWARN("bSliderCtlTouched is true");
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float screenSizeW = screenSize.width;
//CCLOGWARN("pos: %f,%f -> %f,%f", touchLocation.x, touchLocation.y, location .x, location .y);
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
float halfScreen = screenSize.width/2;
if(location.x <= halfScreen)
{
left = true;
right = false;
}
else
{
left = false;
right = true;
}
#ifdef MOUSEJOINT
return isNodeTouched(locationWorld);
#else
return true;
#endif
}
void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
if (!bSliderCtlTouched)
{
return;
}
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
}
void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
{
bSliderCtlTouched = false;
}
CCPoint touchLocation = touch->getLocation();
CCPoint nodePosition = convertToNodeSpace( touchLocation );
}
As far as your question was unanswered about 7 months, I will answer your question for the new version of cocos2d-x. This code works for cocos2d-x 3.0:
cocos2d::extension::ControlSlider* slider = cocos2d::extension::ControlSlider::create(
"images/buttons/container.png", "images/buttons/progress.png", "images/buttons/knob.png");
slider->setPosition(200, 200);
slider->setMinimumValue(0);
slider->setMaximumValue(10);
slider->setValue(3);
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(IntroView::valueChangedCallback), cocos2d::extension::Control::EventType::VALUE_CHANGED);
addChild(slider);
void IntroView::valueChangedCallback(Ref* sender, cocos2d::extension::Control::EventType evnt)
{
float value = static_cast<cocos2d::extension::ControlSlider*>(sender)->getValue();
CCLOG(std::to_string(value).c_str());
}
Don't forget to #include "GUI/CCControlExtension/CCControlExtensions.h" and use libExtensions in your project.