Cocos2d-x 3.0rc not detecting touches - cocos2d-x

In the new cocos2d-x 3.0rc I wanted to detect touch in a Layer. I have over ridden functions in my class as mentioned below.
virtual bool onTouchBegan(CCTouch* touch, CCEvent* event);
virtual void onTouchMoved(CCTouch* touch, CCEvent* event);
virtual void onTouchEnded(CCTouch* touch, CCEvent* event);
but touches are not getting detected. Any idea y is this happening?

To enable touches I used the below code. works perfectly in cocos2d-x 3.0 RC1
void class_name::onEnter()
{
Layer::onEnter();
// Register Touch Event
auto dispatcher = Director::getInstance()->getEventDispatcher();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(class_name::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(class_name::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(class_name::onTouchEnded, this);
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

Detect Touch in Cocos2d-x 3.0
write code in (HelloWorld.h)
{
cocos2d::EventListenerTouchAllAtOnce *Listner;
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);
}
write code in init Method(HelloWorld.cpp)
{
Listner = EventListenerTouchAllAtOnce::create();
Listner->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);
Listner->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this);
Listner->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(Listner, this);
}

enable touch on init() Or onEnter()
this->setTouchEnabled(true);
CCDirector::sharedDirector() -> getTouchDispatcher() -> addTargetedDelegate( this, 0, true );

Related

LibGDX crashes when creating a button

I'm new to LibGdx. I have been programming java for a year, but today I got an error with a Button in LibGdx.
What's causing it, and how can I fix it?
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
background.draw(batch);
batch.end();
}
#Override
public void show() {
batch = new SpriteBatch();
// THE ERROR IS HERE|
// V
// BUTTON
Skin skinLibgdx = new Skin();
TextureAtlas ta = new TextureAtlas(Gdx.files.internal("Button.pack"));
skinLibgdx.addRegions(ta);
Button button = new Button(skinLibgdx);
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
// TODO Auto-generated method stub
System.out.println("ABC");
}
});
}
...
}
error:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: No com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle registered with name: default
at com.badlogic.gdx.scenes.scene2d.ui.Skin.get(Skin.java:145)
at com.badlogic.gdx.scenes.scene2d.ui.Skin.get(Skin.java:132)
at com.badlogic.gdx.scenes.scene2d.ui.Button.<init>(Button.java:50)
at com.me.game.screen.MainMenu.show(MainMenu.java:53)
at com.badlogic.gdx.Game.setScreen(Game.java:61)
at com.me.game.screen.Splash$1.onEvent(Splash.java:64)
at aurelienribon.tweenengine.BaseTween.callCallback(BaseTween.java:380)
at aurelienribon.tweenengine.BaseTween.updateStep(BaseTween.java:521)
at aurelienribon.tweenengine.BaseTween.update(BaseTween.java:424)
at aurelienribon.tweenengine.TweenManager.update(TweenManager.java:166)
at com.me.game.screen.Splash.render(Splash.java:35)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.me.game.MainGame.render(MainGame.java:16)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:207)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
The atlas alone is not enough for the button. You would have to provide a default style for the button. This either can be done directly on the skin or by a JSON file you can load. Check https://github.com/libgdx/libgdx/wiki/Skin for the details.
Check the tests of libgdx, that contain a rather complete example (https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests-android/assets/data/uiskin.json).
e.g.
...
com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: {
default: { down: default-round-down, up: default-round },
toggle: { down: default-round-down, checked: default-round-down, up: default-round }
},
...
And then load it e.g.
Skin skinLibgdx = new Skin(Gdx.files.internal("data/uiskin.json"))
See a whole example: https://github.com/libgdx/libgdx/blob/396126f3af63eb9d0d263afc59653e00e8083778/tests/gdx-tests/src/com/badlogic/gdx/tests/UITest.java

How to disable multitouch in Android in cocos2d-x 3.2

I am setting handlers for single touch in this way
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(true);
touchListener->onTouchBegan = CC_CALLBACK_2(MyClass::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(MyClass::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(MyClass::onTouchEnded, this);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
For iOS it works properly, but for Android if I touch the screen with two fingers in the same time it will call onTouchBegan twice.
How can I disable multitouch from cocos2d-x (3.2) code for Android?
I found a workaround, since cocos2d-x doesn't have an official solution for this. (using Cocos2d-x 3.2)
Since each touch has it's own ID, we just need to filter first touch ID from others.
I have achieved this in the following way:
Created layer's instance variable:
int _currentTouchID;
Initialised it with -1 in layer's init() method:
_currentTouchID = -1;
In the beginign of all touch handlers I did next:
bool MyClass::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event)
{
if (_currentTouchID < 0) {
_currentTouchID = touch->getID();
}
else {
return false;
}
//Your code here
return true;
}
void MyClass::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event)
{
if (_currentTouchID != touch->getID()) {
return;
}
//Your code here
}
void MyClass::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event)
{
if (_currentTouchID == touch->getID()) {
_currentTouchID = -1;
}
else {
return;
}
//Your code here
}
That's it. Please provide your solution if you have found a better one.
BTW: Commenting the switch case MotionEvent.ACTION_POINTER_DOWN: in Cocos2dxGLSurfaceView.java file,
as it was offered on cocos2d-x forum, didn't work for me.

Using ccTouchBegan and ccTouchesEnded at the same time in Cocos2dx

Can I use ccTouchBegan and ccTouchesEnded at the same time?
When I'm trying to add actions in ccTouchBegan, I recognize that ccTouchesEnded isn't called. Can anyone explain for me how to use touch events?
Some of my code
bool GameplayScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){
CCActionInterval* actionBy = CCRotateBy::create(1, 180);
weapon->runAction(CCSequence::create(actionBy, NULL, NULL));
location = pTouch->getLocation();
shootBullet();
this->schedule(schedule_selector(GameplayScene::shootBullet), 1.0);
return true;
}
void GameplayScene::ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event){
this->unschedule(schedule_selector(GameplayScene::shootBullet));
}
void GameplayScene::registerWithTouchDispatcher(void) {
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, INT_MIN + 1, true);
}
First you are using ccTouchBegan and ccTouchesEnded, you could use ccTouchesBegan.
To use ccTouchesBegan and ccTouchesEnded, you need to set:
layer->setTouchEnabled(true);
where layer is the main layer of your Gameplay scene.

How to perform drag and drop operation on sprite fetched from array and present on screen ?

I want to perform drag and drop operation on these image.
How can i make it possible with the following code.
void storeLocation::changescene()
{
this->removeAllChildren();
//CCDirector::sharedDirector()->replaceScene(storeLocation::scene());
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
//CCScene* scene=CCScene::create();
storeLocation *layer = storeLocation::create();
CCSprite *k=CCSprite::create("background.png");
this->addChild(k,0);
k->setPosition(ccp(visibleSize.width/2+ origin.x, visibleSize.height/2 + origin.y));
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(storeLocation::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width ,
origin.y + pCloseItem->getContentSize().height/2));
pCloseItem->setScale(1.5);
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
this->addChild(pMenu, 1);
this->setTouchEnabled(true);
int l=5;
int posx=0,posy=0;
int count=0,r,j=-1,i=0,flag=0;
int x=20;
int b[30],a[30];
while(count<=5)
{
srand(time(0));
r=rand()%x+1;
flag=checktag(b,r,j);
if(flag==1)
{
b[i]=r;
i++;
count++;
j++;
}
}
int t;
CCObject* jt=NULL;
CCARRAY_FOREACH(images, jt)
{
// CCSize winSize = CCDirector::sharedDirector()->getWinSize();
//float i=winSize.width;
CCSprite *image = dynamic_cast<CCSprite*>(jt);
t=image->getTag();
for(i=0;i<l;i++)
{
if(t==b[i])
{
this->addChild(image);
image->setPosition(ccp(100+posx,100));
posx=posx+120;
}}}
To drag and drop images from one point to another on screen you have to use touch delegate methods
bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
void ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
Detect image on user touch in ccTouchBegan method, for this you can store all image objects in a array and check if touch is in rect of any image by using for loop.
To move the image with user touch change position of touched image(save touched image object in a global object) in ccTouchMoved.
And in ccTouchEnded method do whatever you want to do on droping image.
the easiest way to catch drag and drop events is by implementing the onTouchBegan and onTouchMoved and onTouchEnded methods like this:
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite);
bool HelloWorld::onTouchBegan(Touch* touch, cocos2d::Event* event){
// this method is not needed but in order to implement the onTouchMoved you have to first implement onTouchBegan then the onTouchMoved
return true;
}
void HelloWorld::onTouchMoved(Touch* touch, cocos2d::Event* event){
if (sprite->getBoundingBox().containsPoint(touch->getLocation()))
{
sprite->setPosition(sprite->getPosition() + touch->getDelta());
}
}
void HelloWorld::onTouchEnded(Touch* touch, cocos2d::Event* event){
if (sprite->getBoundingBox().containsPoint(touch->getLocation()))
{
log("Sprite Drop Event");
}
}

My Libgdx game slow when integrated Admob

I am a new game developing with libgdx. I have a problem with Admob ads. When I call "adView.loadAd(adRequest);" my game is slowl, when I start game, FPS ~ 60 , when I call adView.loadAd(adRequest) my game is slowly FPS ~ 30.
Here is my
public class MainActivity extends AndroidApplication implements IActivityRequestHandler {
protected AdView adView;
AdRequest adRequest;
private final int SHOW_ADS = 1;
private final int HIDE_ADS = 0;
protected Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_ADS: {
System.out.println("SHOW ADVIEW");
adView.setVisibility(View.VISIBLE);
break;
}
case HIDE_ADS: {
adView.setVisibility(View.GONE);
break;
}
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the layout
RelativeLayout layout = new RelativeLayout(this);
// Do the stuff that initialize() would do for you
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
// Create the libgdx View
View gameView = initializeForView(new MyGdxGame(this), false);
// Create and setup the AdMob view`enter code here`
adView = new AdView(this, AdSize.BANNER, "XXXXXX"); // Put in your
// secret key
// here
adRequest = new AdRequest();
adView.loadAd(adRequest);
// adView.loadAd(new AdRequest());
// Add the libgdx view
layout.addView(gameView);
// Add the AdMob view
RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
adParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layout.addView(adView, adParams);
// Hook it all up
setContentView(layout);
}
// This is the callback that posts a message for the handler
#Override
public void showAds(boolean show) {
handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS);
}
}
I read topic Using interstitials from Admob in a Libgdx game for Android, it's slow when dismissing it
but not solution
Please help me if you have a solution.
This is a known issue and at the moment you cant change it.
Post at the libgdx Forum
It has nothing todo with your code. I think