Why doesn`t Cosos2d ClippingNode work properly? - c++

I try to use ClippingNode for my Cocos2d project, but due to some unknown reason it doesn`t work the proper way neither on Iphone, nor Android. Here is the code being used. The stencil is Label with string "7". Are there any mistakes or is it simply a Cocos2d problem?
auto colors = Sprite::create("colors.png");
colors->setContentSize(Size(nodeSize.width * 1.25, nodeSize.height * 1.25));
colors->setPosition(recordNumLbl->getPosition());
colors->setName("recordNum");
auto cropNode = ClippingNode::create(recordNumLbl);
cropNode->setGlobalZOrder(11);
cropNode->setName("cropNode");
cropNode->addChild(colors);
this->addChild(cropNode);
You can see the result I get on the first image, and what I try to get on the second one. Any help is highly appreciated!
https://i.stack.imgur.com/fZ9LX.png
https://i.stack.imgur.com/xH1hp.png

The global Z value needs to be exactly the same for any children of a clipping node. So, for the example you posted, you would need to set this:
colors->setGlobalZOrder(11);
Also, make sure the stencil you use (recordNumLbl?) is also set to a global Z of 11.

Related

Specifiying twice LWA_COLORKEY in Win32 API

I'm trying to find a way to be able to replace 2 COLORS on a specific Window (which isn't made by me, it's another problem).
LONG ExtendedStyle = GetWindowLong(handle,GWL_EXSTYLE );
SetWindowLong(handle,GWL_EXSTYLE,ExtendedStyle | WS_EX_LAYERED );
::SetLayeredWindowAttributes(handle,RGB(251,254,249),0,LWA_COLORKEY);
This works well, now I'm trying to call twice:
::SetLayeredWindowAttributes(handle,RGB(251,254,249),0,LWA_COLORKEY);
with a different color code
LONG ExtendedStyle = GetWindowLong(handle,GWL_EXSTYLE );
SetWindowLong(handle,GWL_EXSTYLE,ExtendedStyle | WS_EX_LAYERED );
::SetLayeredWindowAttributes(handle,RGB(251,254,249),0,LWA_COLORKEY);
::SetLayeredWindowAttributes(handle,RGB(251,254,220),0,LWA_COLORKEY);
This does NOT work and only the last one is taken into account, I've searched extensively and wish to not go into too advanced solutions as my problem seems simple. Anyone has a clue?
EDIT: I'm sorry I'm very unfamiliar with this API and I have a client that requires me to replace 2 colors (or more) in a window, I'm already losing way too much time on this. Your help is very very welcome. Thank you
According to the document of SetLayeredWindowAttributes function, if you use a parameter LWA_COLORKEY, all areas of the form where the color is crKey will become transparent and the bAlpha parameter is invalid. So only the last function is valid. If you want to make multiple areas transparent, you can set them to the same color in advance.

XLib - Window hints behave differently when I construct XWindowAttributes in the main function?

I am experimenting with some fundamental Xlib stuff. I am creating a basic window and creating an OpenGL context for it.
I am trying to prevent the user from being able to resize or manually full screen the window. I added the code:
XSizeHints hints;
hints.min_width = hints.max_width = setup.w;
hints.min_height = hints.max_height = setup.h;
XSetWMNormalHints(dpy, win, &hints);
This worked at first. However after experimenting with it I have found that it mysteriously stops working sometimes. It is not a matter of unusual window managers or anything like that, I am using the default windows manager installed with Ubuntu. What causes it to change, strangly enough, is whether or not I include this line in main:
XWindowAttributes atts;
It does not matter where I put it. At the beginning, or inside a loop, or even after the return. As long as I put that somewhere in main the hints prevent resizing (just to be clear, any name for the variable works). It does not matter if I use it at all or not, it was initially there for a call to XGetWindowAttributes. I discovered the problem when I tried moving that into a separate function call. If I take it out, the window will have a full screen button and I will be able to shrink it. I have experimented with declaring the variable other places, such as in the struct where I contain the Window and GLXContext.
What is going on here? The way I see it I either have a very subtle and unusual bug coming from my virtual machine or something weird like that, or I have missed some obvious piece of information. Can anyone shed some light on this?
Well, I have no explanation for why declaring a XWindowAttributes instance in main was making it work, but I did figure out what was wrong with my code and I was able to make it behave as expected when I made the following changes:
Do not create XSizeHints directly as shown above. Create it as follows:
XSizeHints *hints = XAllocSizeHints();
Set flags in the object specifying which variables are used:
hints->flags = PMinSize|PMaxSize;
Use XSetWMNormalHints and XSetWMSizeHints:
XSetWMNormalHints(dpy, win, hints);
XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
I also put a pointer to the hints in my struct containing data about the window. All together the code above became:
XSizeHints *hints = wind->hints = XAllocSizeHints();
hints->flags = PMinSize|PMaxSize;
hints->min_width = hints->max_width = setup.w;
hints->min_height = hints->max_height = setup.h;
XSetWMNormalHints(dpy, win, hints);
XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
For those that came here:
1. Communicating with the Windows Manager
It's all about convention like said at 12.3 in the "Xlib Programming Manual VOL1". Some WM will completely ignore hints like max & min size, because eg they manage Windows as Tiled Windows. So, how YOUR Window Manager will get your choices is an issue.
2. Make things in the right order.
This will perhaps answer your question : "What is going on here?"
Most difficulties with X comes from the order you make things. I encountered the same trouble as yours, and solve it because I saw I didn't follow the right process.
Chapter 12.3.1 from the "Xlib Prog Manual" says:
'Once the client has created the windows, BUT BEFORE IT MAPS THEM, it must place properties to help WM manage them effectively'
In your case, it means you cannot use XSetWM* functions AFTER your window is mapped. Some properties will have an effect, some others not, and sometimes some will be overridden with bad values.
3. The right order. (AFAIK)
a. Set an Error Handler
b. Get a Display
c. Init your Context (here GLX) & get a Visual from it.
d. set Window Attributes (events mask, ...)
e. Create your Window
e. Set WM Properties (eg your sizehints, min/max size, class, title, ...)
e.1 always init pointers you need with XAlloc* when possible
e.2 use X11r4 XSetWMProperties that will put them all at once, avoid use of deprecated functions.
e.3 XFree your 'pointers'
f. Set the Wm Protocols you are interested in (WM_DELETE_WINDOW, ...)
g. set some others properties according to your needs (eg _NET_WM_PID, ...)
h. Finally, Map your Window
4. See what happens : use xprop
xprop will report how your window is known by your Windows Manager.
If your size hints were properly set, you will see some lines like:
WM_NORMAL_HINTS(WM_SIZE_HINTS):
user specified location: 550, 200
user specified size: 500 by 500
program specified minimum size: 500 by 500
program specified maximum size: 65535 by 65535
Hope it helps future users,
(PS: the previous answer TS#Oct 27 '14 at 15:26 has an error: XSetWMSizeHints expect an Atom as 3rd arg.).

cocos2d -CCLabelTTF is not printing more then once

i am losing my mind !!
i have done this so many times and now its just not working !
in my init method i have this label :
teamLabel = [CCLabelTTF labelWithString:#"WAITING..." fontName:#"Marker Felt" fontSize:32];
teamLabel.position = ccp( 150,100);
teamLabel.color = ccc3(150, 50, 80);
[self addChild:teamLabel];
[teamLabel setVisible:YES];
then i call a function which i know it has been called(NSLOG) and there i am trying to print something in all kind of ways:
[teamLabel setString:#"ran"];
[teamLabel setString:[NSString stringWithFormat:#"%ig", (int) (ran)]]; //ran int==5;
the function is fired, but i can still see the first string from the init in my label without a change..
EDIT ::
it now prints a red big square which is in the size of my word. if the word is small i get small red square etc...
whats that ?!?
thanks .
I once came upon similar behavior, and it ended being due to lack of memory to allocate the TTF texture.
Perhaps you have been growing your game/app resource utilization and you are now seeing the same behavior.
Try disabling a number of these other resources, or create the TTF labels only. You can also try moving the creation of these TTFs out of the init method, to check whether there might be a load order/priority problem.
Cheers,

C++: Cannot instantiate a pointer directly

This is an SDL problem, however I have the strong feeling that the problem I came across is not related to SDL, but more to C++ / pointers in general.
To make a long story short, this code doesn't work (edited to show what I really did):
player->picture = IMG_Load("player");
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I see nothing on the screen. However, when I do it like this, it works:
SDL_Surface* picture = IMG_Load("player.png");
player->picture = picture;
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I can see the little guy just fine.
The real problem is that I cannot instantiate Player::picture directly. Even when I try
picture = IMG_Load("player.png")
in player.cpp, I end up with a nullpointer.
I am so stupid. Turns out like I forgot the file extension ".png" every time I tried to store the surface in Player::picture, and conveniently remembered to add it every time I stired it in an SDL_Surface declared in main.cpp.
I had the feeling I was overlooking something really simple here, but this is just embarassing. What's a fitting punishment for this?
What data type is player->picture? What type does IMG_Load return? It's really hard to come up with a scenario where saving an expression in a temporary variable changes the result, unless a type conversion is involved.
And I wouldn't call this pointer instantiation. You're instantiating an instance of some picture type and storing a pointer to it.
This is why you should always check to see what IMG_Load() returns...
SDL_Surface* picture = IMG_Load("player.png");
if (picture == NULL) {
// there was obviously some sort of error.
// what does SDL_GetError() say?
}
Some SDL functions return -1 if there is an error. Just check the documentation and make sure you're checking your function returns. These steps make debugging a lot easier.

Cocos2d-x: How to replace sprite dynamically?

I am struggling to replace the sprite I selected to another sprite.
Here is what I've got so far:
void Object::replaceSprite(const string & resourceName)
{
cocos2d::SpriteFrameCache * spriteFrameCache = cocos2d::SpriteFrameCache::getInstance();
cocos2d::SpriteFrame * spriteFrame = spriteFrameCache->getSpriteFrameByName(resourceName);
//mSprite->setTexture(spriteFrame->getTexture());
//mSprite->setDisplayFrame(spriteFrame);
mSprite->setSpriteFrame(resourceName);
}
As you can see, I tried different approach but none of them worked.
Also, I would like to ask if I do have to add the sprite again once I replace the frame onto the scene? What I am thinking right now is to create a new sprite every time I asked to replace it with a new one. But I do not know if there is more elegant and efficient way to do this.
Thank you!
setSpriteFrame accept a string or SpriteFrame* as argument
in your code
mSprite->setSpriteFrame(resourceName);
the argument is a string, you have no need to get frame from frameCache, but you must make sure that the frame exists in frameCache.
you can make breakpoint in the function, and check if spriteFrame is nullptr after
cocos2d::SpriteFrame * spriteFrame = spriteFrameCache->getSpriteFrameByName(resourceName);