What's the best way to achieve a popup in Cocos2D? - cocos2d-iphone

I am developing an iOS game using Cocos2D. I would like to show a popup, something like UIAlertView, but completely custom. What is the best way to achieve this?
Thanks a lot!
Benza

I would suggest to use a layer for this and to pause the scene. Here are a couple forum posts from the Cocos2d site that go over this a bit:
http://www.cocos2d-iphone.org/forum/topic/6511
http://www.cocos2d-iphone.org/forum/topic/1954

Unfortunately pausing the scene means you will also pause whatever you have in your popup.
Maybe it's not your case, but I quite often have scrolling lists in my popups. If I pause the scene it will not work.
I've added a method to CCNode which goes through all children and stops their activity rather than pausing the scene.
If you open the popup as a child of your scene then first you deactivate all children of the scene and then open the popup. This means that you can still do whatever you want in your popup and everything else is paused or does not respond to touch [like menus].

Related

Scrolling region in cocos2d version 2

I am trying to implement a help screen in my cocos2d game, using cocos2d version 2.0. My screen will have a title bar ("Help") at the top and then the rest of the screen below that is where I want to put a scrolling help section. Ideally I would be able to put both text and images into this help window.
The problem is that cocos2d does not have any functionality like UIScrollView, and from what I have seen doing Google searches, every custom solution I have found seems to have problems with various bugs popping up on various devices.
I have tried these solutions thus far:
CCScrollLayer: http://www.cocos2d-iphone.org/forum/topic/17118/page/3
Scrolling CCNode: http://tonyngo.net/2011/11/scrolling-ccnode-in-cocos2d/
CCScrollView: http://bitbattalion.com/2011/09/uikit-uiscrollview-and-cocos2d/
The closest thing I got to work was embedding a UITextView but that seemed to randomly crash after a few scrolls so it seems unreliable to me.
Does anyone know of a good simple robust solution to this problem? It seems like it should be straightforward but it isn't.
I recommend that you make new class say:(HelpViewClass) and implement it with an UIScrollView and add whatever you want to add on UIScrollView and then you can use this as a child to your layer.
Steps
Make a class - inherited with UIView
Add UIScrollView to the View.
Add Your components to it.
Add this UIView to the HelpLayer.
You can add any UIKit component to the cocos2d Layer by using this
[[[CCDirector sharedDirector] view] addSubView:scrollView];
Note : Remove all UI component when you go back from this HelpLayer.
I think this may help you !

Overdrawing on the toolbar? Alternative idea?

Main aim is wanting to draw Tab's within the draw area of the Toolbar of the Applicaiton for a NoteBook or Tab's to use the above space instead of being bellow the toolbar.
The frame work we're using is WxWidgets, C++/C. I have looked around but have not been able to find a solution or if anyone has done a similar approach with drawing tab's actually inside the toolbar itself.
I read some Microsoft MSDN articles and they recommend against controls drawing over controls.
I did some test's today, and think I've come up with a solution. My solution is to draw the window like normal, but have the NoteBook on the right in a child window that is dynamically resized and repositioned so that it's tab's are overlay on-top of the toolbar to make the most effective use of the area. I would have to deal with on focus and lose focus window messages, but this is the most elegant way I can think about achieving the task.
Any Idea's you can recommend or problem's I may face with following this approach.
I would be concerned about using overlapping widgets like this. Although it may not look quite the same visually I would suggest looking at wxToolBook which puts tabs in a toolbar and would solve your problem, you could use the GetToolBar method to insert your own toolbar items.
If that wasn't close enough visually to what you are looking to achieve I would suggest deriving a new control from wxBookCtrlBase and then creating a tab control with custom drawn tabs which you could add to the toolbar using wxToolBar::AddControl.

What is the best way to set up menus with cocos2d?

I'm new to development and I have played around with a few tutorials. I wonder what the best way to set up a menu for a game with cocos2d?
I want a MainMenu with a Startbutton, SettingsButton, HighScoresButton and a little info/creditsButton in the corner.
How should I set this up?
Should I have the MainMenu as a Scene and the others as layers or just make all of them as separate Scenes?
The buttons that I add, should they be a plain button and then I add the textLabel on top or should I make them complete with textLabel?
I would like the buttons to "wiggle" like it is made of jello when i tap them, how do I do that?
As I said, I am new to this but I wanna learn as much as I can before school starts. I'm currently taking a summer class in iphone development so I get a head start for the next semester. I would like to see experienced game developers to help me out with this since i want to work with that when I get older, if they could also show me how to structure a game and the design.
Thank you so much.
David H
You've got several questions buried in there, so I'll address them in order...
First, to save on memory, you should break sections of your game, including menus, into separate scenes and switch between them using:
[[CCDirector sharedDirector] replaceScene: yourScene];
Alternatively you can use pushScene: and popScene, but these hold pushed scenes in memory and can be very costly depending on what you've got in the scene.
As for how to design your buttons, that's completely up to you and what fits best with the game. Some games look fine with text buttons. Others need a more stylized button that is best created with images. Remember, a CCMenuItem (button) is just a CCNode, so you can layer images and text in almost any way you wish.
Animating buttons is going to be a manual thing. I suggest subclassing the CCMenuItem, or CCMenuItemImage and overriding the selected and unselected methods to animate the underlying images.
We used cocos2d for our game The Selfish Birdbreeder. You can find the game and source here and dig around. I'm pretty certain we have a main menu.
http://pyweek.org/e/BirdBreeder/

Custom draw button using uxtheme.dll

I have implemented my custom button inheriting from CButton and drawing it by using uxtheme.dll (DrawThemeBackground with BP_PUSHBUTTON).
Everything works fine but I have two statuses (Normal and Pressed) which Hot status is the same. It means when the user places the cursor over the button it is drawn alike regardless the button status (Pressed or not).
This is a bit confusing to the user and I would like to change the way the button is drawn in Pressed & Hot status. Does anybody know a way?
I have also thought about custumizing the whole drawing but the buttons use gradients, borders, shadows, etc. So it is not easy to achive the same look&feel drawing everything by myself. Is there a way to find the source code of the dll or know how to do it?
Thanks in advance.
Javier
Note: I think I could be able to achive what I want to do by using CMFCButton and overriding the OnDraw method. Let the control draw the button on OnDrawBorder and then drawing the inside button myself. But I need to know how the control draws the inside button when pressed. It is a gradient and I can't guess how it's done. Does anybody have a clue?
In answer to your second question, if you derive from CMFCButton instead of CButton you can override OnDraw() or OnDrawText() instead of the usual DrawItem(). That way the default button background will be drawn, and then your drawing code is executed.
The only way I know of to really tackle this is to use 'custom draw', rather than 'owner draw'. Custom draw came in with Windows 2000, but is only used by button controls with comctrl32 6.0 (so Windows XP onwards), isn't very clearly documented, and isn't something MFC goes out of its way to support.
Anyway, the good thing about custom draw is that it lets you hook in at various points in the drawing process, unlike owner draw, which makes you deal with the whole thing. Have a look in MSDN at the NM_CUSTOMDRAW notification message.
For the other part of your problem, detecting the 'hot' state, the easiest way to do this is to use WM_MOUSEMOVE messages and the TrackMouseEvent() function to track whether the mouse is over your button.
Unfortunately this is a bit of a vague answer: the amount of code you need to demonstrate a button that uses custom draw is a bit too much to type into these answer boxes! I do have a project that demonstrates such techniques, using a custom draw button (falling back to owner draw on older Windows versions) that adds a little arrow to the button. You can have a look at the source code by getting
Windows_UI_source.zip
Open it and have a look at the "DropArrowButton" class. The important bit is the OnCustomDraw() handler and its helper function DrawControl(): these get called at the various button drawing phases, and use UxTheme to draw the control appropriately.
I finally figured out how to achive what I want to do. It's pretty easy indeed.
I use two calls to DrawThemeBackground. The first one with PBS_PRESSED and the second one with state PBS_HOT. Then I make a ExcludeClipRect to avoid from drawing over the center of the button.
Something like this:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
Of course this is not the whole code but I think is enough to make my point.
Thanks.

How to fix an MFC Painting Glitch?

I'm trying to implement some drag and drop functionality for a material system being developed at my work. Part of this system includes a 'Material Library' which acts as a repository, divided into groups, of saved materials on the user's hard drive.
As part of some UI polish, I was hoping to implement a 'highlight' type feature. When dragging and dropping, windows that you can legally drop a material onto will very subtly change color to improve feedback to the user that this is a valid action.
I am changing the bar with 'Basic Materials' (Just a CWnd with a CStatic) from having a medium gray background when unhighlighed to a blue background when hovered over. It all works well, the OnDragEnter and OnDragExit messages seem robust and set a flag indicating the highlight status. Then in OnCtrlColor I do this:
if (!m_bHighlighted) {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kBackgroundColour);
}
else {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kHighlightedBackgroundColour);
}
However, as you can see in the screenshot, the painting 'glitches' below the dragged object, leaving the original gray in place. It looks really ugly and basically spoils the whole effect.
Is there any way I can get around this?
Remote debugging is a godsend for debugging visual issues. It's a pain to set up, but having a VM ready for remote debugging will pay off for sure.
What I like to do is set a ton of breakpoints in my paint handling, as well as in the framework paint code itself. This allows you to effectively "freeze frame" the painting without borking it up by flipping into devenv. This way you can get the true picture of who's painting in what order, and where you've got the chance to break in a fill that rect the way you need to.
It almost looks like the CStatic doesn't know that it needs to repaint itself, so the background color of the draggable object is left behind. Maybe try to invalidate the CStatic, and see if that helps at all?
Thanks for the answers guys, ajryan, you seem to always come up with help for my questions so extra thanks.
Thankfully this time the answer was fairly straightforward....
ImageList_DragShowNolock(FALSE);
m_pDragDropTargetWnd->SendMessage(WM_USER_DRAG_DROP_OBJECT_DRAG_ENTER, (WPARAM)pDragDropObject, (LPARAM)(&dragDropPoint));
ImageList_DragShowNolock(TRUE);
This turns off the drawing of the dragged image, then sends a message to the window being entered to repaint in a highlighted state, then finally redraws the drag image over the top. Seems to have done the trick.