how to close layer that showed in other layer in cocos2d-iphone - cocos2d-iphone

I have one layer called alayer, and there is a button called abutton, when click the button, another layer called blayer will show in alayer, not replaceScene, please look at the following code,
alayer.m
-(void)abuttonclicked:(id)sender
{
blayer *blayer = [blayer node];
blayer.position = ccp(1,1);
[self addChild:blayer];
}
blayer.m has a button called bbutton and string value called bstring, I want to click the b button, it will close blayer (remove blayer from alayer), and pass the string value bstring to alayer, please look at following code,
-(void)bbuttonclicked:(id)sender
{
// how can do here to close its self(remove its self from alayer), and pass the bstring to alayer?
}
thanks.
ps. I can use NSUserDefault to pass the string value, but I think it's a bad way to do this, is there another way to pass value?

maybe to pass the string you could declare and implement a property in ALayer.h/.m
#property(nonatomic,copy) NSString *stringFromLayerB;
to remove bLayer when bButtonClicked :
-(void)bbuttonclicked:(id)sender
{
ALayer *lay = (ALayer*) self.parent;
lay.stringFromLayerB = #"Whatever you want to set";
[self removeFromParentAndCleanup:YES];
}
There are other ways to do this. You could implement a callback mechanism , use notifications, some kind of delegate protocol binding BLayer and ALayer. All depends what your real (unsaid) requirements are.

Considering your scenario, I think its better to use NSNotificationCenter.
You can post notification from blayer when the button is tapped and add an observer in alayer to respond exactly how to want.
Add [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedNotification:) name:#"BlayerNotification" object:nil]; in alayer's init and [[NSNotificationCenter defaultCenter] removeObserver:self]; in its dealloc.
Its selector like:
- (void)receivedNotification:(NSNotification *)notification {
NSString *string = (NSString *)notification.object;
NSLog (#"String received %#", string);
}
Now you can post notification from blayer when hte button is clicked:
-(void)bbuttonclicked:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:#"BlayerNotification" object:self];
[self removeFromParentAndCleanup:YES];
}

Related

'NSInvalidArgumentException', reason: '-[MenuScene distance]: when replacing a scene

In my code I have made a GameManager singleton which has a method responsible for changing scenes. The first scene I call is the MenuScene after that I replace it with the GameScene. When I do this the Console output shows:
2013-10-07 19:40:55.895 MyGame[56164:a0b] -[MenuScene distance]: unrecognized selector sent to instance 0xb460690
2013-10-07 19:40:56.011 MyGame[56164:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MenuScene distance]: unrecognized selector sent to instance 0xb460690'
From the log, I don't understand why I get -[MenuScene distance] ... because distance is a property of GameScene not MenuScene.
Below is GameManager method for changing scenes:
-(void)runSceneWithID:(SceneTypes)sceneID {
SceneTypes oldScene = currentScene;
currentScene = sceneID;
//NSString* str;
id sceneToRun = nil;
switch (sceneID)
{
case kBeginScene:
sceneToRun = [BeginScene node];
break;
case kGameScene:
sceneToRun = [GameScene node];
break;
case kMenuScene:
sceneToRun = [MenuScene node];
break;
default:
CCLOG(#"Unknown ID, cannot switch scenes");
return;
break;
}
if (sceneToRun == nil) {
// Revert back, since no new scene was found
currentScene = oldScene;
return;
}
if ([[CCDirector sharedDirector] runningScene] == nil) {
[[CCDirector sharedDirector] runWithScene:sceneToRun];
} else {
[[CCDirector sharedDirector] replaceScene:sceneToRun];
}
}
Also the call to replace scene is in a layer class which is part of the MenuScene. See below:
-(void)startGameScene {
[[GameManager sharedGameManager] runSceneWithID:kGameScene];
}
Please help.
You get this message because the distance message was sent to the MenuScene instance which doesn't have this selector (GameScene does apparently).
So probably somewhere in your scene managing singleton something goes wrong and you still (or already) have a MenuScene instance where you expect to have a GameScene instance.
Add an exception breakpoint in Xcode to see exactly where the message was coming from.
PS: be very careful when managing scenes in a global instance like a singleton. You could easily leak memory if you keep a strong reference to a scene (or any node for that matter) in a global instance/variable. Make sure that every scene has the dealloc method implemented with a log to see that it actually does deallocate.

Cocos2D how to remove/release/clean up CCMenu

How can I add/remove CCMenu when the same button is clicked? I have added some code..
Thanks in advance..
CCMenu *menu;
if (!isMenuVisible) {
CCMenuItemSprite *item = [CCMenuItemSprite itemFromNormalSprite: .......];
menu = [CCMenu menuWithItems:item, nil];
[self addChild:menu];
} else {
// [menu cleanup];/// didn't work
// [menu removeFromParentAndCleanup:YES]; //// didnt work
// [menu removeAllChildrenWithCleanup:YES]; //// didn't work
}
isMenuVisible = !isMenuVisible;
}
you probably want to have the top line in your .h file, making the menu an iVar, to that the reference is kept in between successive executions of this code. Set menu to nil after you remove it.
One way - to create two menus. One for show/hide button, another for all buttons that have to be shown/hidden. It is not good way.
Another way is just to add/remove menuitems to the menu. I mean something like that:
- (void) removeItems
{
for(CCNode* item in _addedItems)
{
[item removeFromParentAndCleanup: YES];
}
[_addedItems removeAllObjects];
}
- (void) addItems
{
// create needed items and add them as children
// to your menu and add them to _addedItems array
// to be able to remove added objects
}
Also before using methods like cleanup, check it's code or at least cocos2d documentation. In your case it was comletely useless.

How to turn off keyboard sounds in Cocoa application?

I have a problem with my OpenGL Cocoa application - every time a keyUp / KeyDown event is fired, a system sound is being played... How can I disable this logic for my application?
I have a bad feeling that for some strange reason my application may treat a key press as an error and play system alert sound... Please help!
add to your NSView/NSWindow subclass
- (void)keyDown:(NSEvent *)theEvent {
and make exception on up and down keys, but for other [super keyDown:theEvent];
i think it's may sense
For me, the following has turned out to be the optimal solution:
override func awakeFromNib() {
// Do your setup here.
NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
if keyDownPressed(with: $0) {
return nil
}
return $0
}
}
func keyDownPressed(with event: NSEvent) -> Bool {
print("caught a key down: \(event.keyCode)")
if event.keyCode == 125 {
//your code for arrow down here
return true
}
if event.keyCode == 126 {
//your code for arrow up here
return true
}
return false
}
Create a Cocoa Class, subclassing it from NSView
Set it as the class for your View instead of standard greyed-out NSView in storyboard
Add the following to your subclass implementation:
#implementation YourCustomNSView
- (BOOL)acceptsFirstResponder {
return YES;
}
- (void)keyDown:(NSEvent *)theEvent {
NSLog (#"keypress %#", theEvent);
// [super keyDown:theEvent]; // this line triggers system beep error, there's no beep without it
}
#end
Swift 5.6 solution
It's caused because of unhandled keydown events in your responder chain.
Make sure some NSView subclass in your responder chain overrides this and returns true.
override performKeyEquivalent(with event: NSEvent) -> Bool {}

how to implement Action in sectionIndexTitlesForTableView Delegate method.?

Hi friends i want know sectionIndexTitlesForTableView Action is works
i have the following code... but i want to call the web services with A/B/C/D.... Z as parameter.. So i need to know how it is?
My actual need is the products list in with starting letter As A in default , when click on B then i want to show the Product list with Starting letter as B. And also i want A.to..Z in the Right side for table view for select the letter... so i tried this but i dont know how to give the Action so please help me..
selectArray = [[NSMutableArray alloc] initWithObjects:#"A",#"B",#"C",#"D",#"E",nil];
Method is:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return selectedArray;
}
I solved my Question as shown below
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
if (title) {
[self webCall:title];
[tableData setArray:nil];
[table reloadData];
}
return 1;
}

CCLabelAtlas setString doesn't update label

I have a CCLabelAtlas that I have on a layer to display the current score within my game...the problem that I am having with it is that it does not update when I use [scoreLabel setString:]. Here's how I have it laid out:
In the header:
#interface GameScene : CCLayer {
...
CCLabelAtlas* scoreLabel;
}
And in the init:
scoreLabel = [[CCLabelAtlas alloc] initWithString:#"0" charMapFile:#"scoreCharMap.png" itemWidth:6 itemHeight:8 startCharMap:'.'];
[scoreLabel setPosition:ccp(105, 414)];
[self addChild:scoreLabel z: 6];
scoreCharMap.png is a custom map that includes ./0123456789 of my desired font. When the score is changed, I attempt to do this to get the label to update with the current score:
NSString* str = [[NSString alloc] initWithFormat:#"%d", [[GameRunner sharedInstance] currentScore]];
[scoreLabel setString: str];
[str release];
[scoreLabel draw];
Problem is that it doesn't ever update - it just sits there and displays 0. I know for a fact due to breakpoints and debugging that setString is being called, and that the string that it should be displaying is correct - but it just doesn't update. Hard-coding the value and saying [scoreLabel setString:#"1234"] does nothing, either. What am I doing wrong here? I am using Cocos2d 0.99 - thanks in advance!
Maybe this is something wrong with the font you are using? Try using one of the font maps that came with Cocos2D and see if it works for you.
The method -[CCLabelAtlas setString:] does a few things.
Can you verify that following goes right: (place a breakpoint and step through the function)
resizeCapacity doesn't fail to resize
updateAtlasvalues retreives a UTF8 character array pointer. Inspect that to see if that's the correct string, and while you're there, inspect n in the same method, which should be your string length
See code for setString below:
- (void) setString:(NSString*) newString {
if( newString.length > textureAtlas_.totalQuads )
[textureAtlas_ resizeCapacity: newString.length];
[string_ release];
string_ = [newString retain];
[self updateAtlasValues];
CGSize s;
s.width = [string_ length] * itemWidth;
s.height = itemHeight;
[self setContentSize:s];
}
Let me know what the results are, if you still need any help.