CCSprite gives the unpredictable result? - cocos2d-android

I am using the Cocos2d-android library
Qus :
Image what I call from CCSprite.sprite("Star.png") , Sometime Appear correctly or Sometime randomly pick an Image from asset foler ?
Basically I am follow the Sample example which is in the library of cocos2d-android.
Now, I have created a GameScene, In which 3 MenuItem like as sample example (Next, restart, previous)
I have created different classes and extends the GameScene, when One class done their functionality after 5 sec I call the next class and previous disappear and new class appear on the same CClayer.
from class A to class B it'll take 5 sec and in this time intervel I call a CCSprite for completing its class A. This Image (CCSPrite ) create problem otherwise all images working fine.
What happen I don't know. Even I cleaup() CCSprite before going into the class B.
If someone face this problem than help me
All Suggestions are welcome.

There might be two resources of the same name STAR.png. Check all the drawable folders. Like there are 5 folders in res folder of the project like Drawable HDPI, drawable IDPI and so on. check all the folders for duplicate images.

if you want to move from one scene to another scene use this line.This will automatically remove your all children.
CCDirector.sharedDirector().replaceScene(gamePlayScene);
if you want to move from one layer to another with in the scene then remove that layer by using
this.removeSelf();
parentlayer.addChild(nextLayer);

Related

SpriteKit not playing audio file?

I have made a custom class, SoundNode, to handle the playing of audio files. For now, it only plays the default "A2.mp3"
class SoundNode : SKSpriteNode{
func playSound(){
run(SKAction.playSoundFileNamed("A2", waitForCompletion: false))
}
}
I then call the playSound method in my SKScene like so:
SoundNode().playSound()
But, the sound never plays?? I have made sure the file exists within my project and have also double checked the file name to make sure it is correct. What is the problem here?
SoundNode is a kind of node. Every node only works when it is in a scene. Just creating a SoundNode and calling playSound does not do anything because the node has not been added to the scene!
To make this work, just add it to the scene:
let node = SoundNode()
self.addChild(node)
node.playSound()
Also, I suggest that SoundNode should not inherit SKSpriteNode because it is obviously not a sprite i.e. something that can be seen on screen. Just make it inherit SKNode.

Touch Event on Sprite with Cocos2d-x 3.x?

In my scene I have a vector with multiple custom sprites. When I tap on one of them, I want an action to be fired on another element on the scene, can be another sprite in the vector, or another node. I have been researching the best way to do this, but I'm not quite sure how to implement it. The options are:
Add a touch listener to the scene, and verify if it was tapped inside the bounds of the sprite with rect. containsPoint(point). And after that, I have to get the sprite that was tapped to do the action I want. For me, it doesn't seems very clean to do it this way. And if two sprites are overlaped, I have to verify if the sprite is behind or in the front in order to retrieve the desired sprite. I followed this example: Touch Event example
Add a touch listener in the subclass of the sprite (my custom sprite). And add onTouchBegan and onTouchEnded inside it. But this way, I don't know how to modify an attribute of another sprite, or another element in the scene (Is it possible to use Delegates like Objective-C does?). I followed this example: Subclass Sprite Example
My main problem is that I don't understand very well how to make a node interact with another node in the scene. I have seen a lot of tutorials, but in all of them, when you interact with a node, it only changes its attributes, not other nodes' attributes.
Thanks in advance.
I shall propose "EventCustom" way :)
You can add in your touchBegan / touchEnded methods (wherever you put them... you got the point...) additional code for passing an EventCusto to the _eventDispatcher and get it announced to the world ;)
EventCustom *e = new EventCustom("MyAwesomeEvent");
e->setUserData(ptrMyFantasticData); //This function takes a void pointer. cheers :)
_eventDispatcher->dispatchEvent(e);
You may subclass the EventCustom class but that is hardly necessary. You can always hang an object to it with setUserData().
Now the objects which need to react to the event can listen to it by
_myCustomListener = EventListenerCustom::create(
"MyAwesomeEvent",
CC_CALLBACK_1(
ListeningClass::onMyAwesomeEvent,
this
)
);
_eventDispatcher->addEventListenerWithXXXXXPriority(_myCustomListener, XXX);
//ScreenGraphPriority / FixedPriority depends on situation. Either should work.
It's always a good practice to remove your listeners when you go off, so somewhere, perhaps in onExit(), where you removed touch listeners remove this listener too, as
_eventDispatcher->removeEventListener(_myCustomListener);
Going a bit off the track, a clarification:
CC_CALLBACK_X are a bit tricky names. The X indicates the no. of args the target function will get. Here, event dispatcher will pass 1 arg i.e. ptr to object of EventCustom you handed it, so we use CC_CALLBACK_1. The next arg - here "this" - is the object on which the method will be invoked.
In short, we may say that this callback is going to result into a function call this->onMyAwesomeEvent(e);
For CC_CALLBACK_2 onwards, we can specify additional args, 3rd arg onwards.
Coming back to the issue at hand, ListeningClass::onMyAwesomeEvent will look something like
void ListeningClass::onMyAwesomeEvent(EventCustom *e)
{
MyFantasticData *d = (MyFantasticData *) e->getUserData();
CCLOG("[ListeningClass::onMyAwesomeEvent] %d", d->getMyPreciousInt());
}
Hope it helps :)
Set your elements tags or names with setTag and setName. Then if element x is touched, get them with getChildByTag or getChildByName and do what you need to do.
With the second option you list above.
To make a node interact with another node in the scene you can add touch callback function to your custom sprite object like that:
https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase
and in main scene you can define function to handle this callback. So you can do every thing to unit in you scene

QT add widgets to UI anywhere

The application that I'm building is supposed to create, destroy, and manipluate widgets that I've created
The problem is I'm not making a simple program with nice buttons where everything is symmetrical and needs to be evenly spaced and handled via a layout that will automatically move everything around and space it.
And yet, the only way I know of is to manually instance a layout and add the widgets to it, but then I can't set the coordinates of them
How can I simply instance my widget, and add it to the project generated frame?
This is how I'm instantiating my class, in which case I then set my own parameters:
Tile *tile = new Tile;
tile->setImg("://Images/placeholderTile.png");
tile->setCol(true);
tile->setGeometry(retX(line),retY(line),50,50);
To reiterate, I want to add my own widgets to a frame outside of the editor (only by code), and be able to manually move them around the frame by code.
I don't see an ".addWidget() as a method accessible from the QFrame, and yet they can be children within the designer, why can't I do this by code? Whenever I try to do it manually and add them to any layout, any attempt I make to manually set the widgets location doesn't do anything. I haven't overridden the setGeometry
I fixed my problem
After 2 hours of continual searching I finally came across my answer
I never thought that you could set the parent of a widget by code, as I thought you strictly had to add it in as a child of something else, not the reverse and declare that it should have a parent
So, by simply adding the line:
tile->setParent(ui->frame);
completely fixed my problem.
I will change this post back and submit the answer tomorrow when I'm allowed to by this site.
Thank you to those who actually came though. I'm just glad I managed to fix it before that.
All you need is to pass the parent to the widget's constructor:
Tile *tile = new Tile(ui->frame); // <-- here
tile->setImg("://Images/placeholderTile.png");
tile->setCol(true);
tile->setGeometry(retX(line),retY(line),50,50);
Since Tile is your own class, you should definitely have a Qt-style, parent-taking explicit constructor for it:
class Tile : public QWidget {
...
public:
explicit Tile(QWidget * parent = 0) : QWidget(parent) { ... }
};
Another approach is to write your own layout that would know about the relationships that are to be held between your objects. After you do it once, writing custom layouts isn't that hard.

C++ cocos2d-x pointer

I've just used cocos2d-x for creating some games. When I read the HelloWorld.cpp, I saw this line
Scene* HelloWorld::createScene()
That's strange for me. How does it work? A method named creatScene that takes no parameters and returns a pointer to a Scene ?
In different libraries, there are different methods to initialize library or some part of that. So, in this case, it maybe create a new context inside library and return it without any argument. It maybe needs no arguments (use defaults) it this step of get them from somewhere else like configuration file. And note that this is convenient to use this type of initializing. Like this:
rc = redis.Redis() #uses default values for server address
It is really an easy question even it cannot be called as question when you check the source code.
In cocos2d-x, CCScene always create this way.
1. create a Layer, which coded by yourself with a lot of other widgets.
2. create a Scene
3. add the layer to the scene
4. return the scene you create.

Cocos2d HOWTO access CCNode using getChildByTag from another class

Could someone help me, I am trying to access a CCLabelTTF that resides in a CCLayer subclass(GameLayer), but I want to access it from another Player class(also a CCLayer). I thought
[self getChildByTag: DEBUG_LABEL];
searches the scene and finds the object that matches it and returns a pointer to it, since all objects are stored in a tree data structure.
I was able to access the label through trial and error using the follwing code but would appreciate if someone could advise if I am not understanding the getChildByTag method or if there is a way of searching the scene for an object without using the code below.
CCLabelTTF *lbl = (CCLabelTTF *)[[[[CCDirector sharedDirector] runningScene] getChildByTag: GAME_LAYER_TAG] getChildByTag: DEBUG_LABEL_TAG];
Please advise.
getChildByTag only checks direct children of the parent CCNode calling it. It will not check children's children (grandchildren, if you will).
For example, if your node hierarchy looks like this:
MyCCLayer1->MyCCLayer2->MyCCSprite->MyCCLabel
Calling MyCCLayer1 only has direct access to MyCCLayer2 via the getChildByTag call. In turn, MyCCLayer2 could call getChildByTag to get MyCCSprite, and then MyCCSprite could call getChildByTag to get MyCCLabel.