Cocos2D isTouchEnabled = NO; scene release and crash - iphone

I'm working on an iPhone game using cocos2d and I'm new to Objective C and Cocos2d so I'm sorry if this is a really beginner question. I've done a lot of searching and I can't seem to find a solution for this problem. I've found that cocos2d will not call the dealloc function, release a scene, or a layer unless I put -(void) onExit{self.isTouchEnabled = NO;} at the end of the .m file. The problem is that in the next scene the game crashes when the screen is touched, even if I put self.isTouchEnabled = YES; in the init method, onEntermethod, or anywhere else within the second scene.
When the game crashes (gbd) points to:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if( dispatchEvents )
[self touches:touches withEvent:event withTouchType:kCCTouchBegan];
}
as the source of the problem stating "EXC_BAD_ACCESS"
Please help!! Thank you!!

I am new to iPhone as well:-) But for my experiences, the reason you get "EXC_BAD_ACCESS" is not because of your code here. it should be "release" problem. i guess you release a released object...
you can try to use Xcode's Zombies instruments to detect where you get this problem. There are heaps of tutorials about Xcode Zombies online, just google it if you want.
good luck:-)

Related

iOS 9, Xcode 7, Multitouch with SpriteKit

Hello I've made an iOS game named 'Racing Horses' and published it to App Store. It was fine with playing on iOS 8.x.x, but after I installed iOS 9 Beta 3, in the same game (same codes), iPhone cannot recognize multiple touches. I have to leave my finger to make the next touch. But it was not like this, I could make a new tap even if I still hold my previous tap. What is the problem, what should I do?
I had the same problem on a game launched this summer.
I had to explicitly enable multiple touch in the SKScene:
-(void)didMoveToView:(SKView *)view {
self.view.multipleTouchEnabled = YES;
}
Here's more detail -
The game uses sub-classes of SKSpriteNode.
They test for number of touches depending on the the sprite.
In the sub-class:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"TapCount = %lu", (unsigned long)touches.count);
if (touches.count == 2) {
// do something
}
}
It looks like as of ios 9 multitouch has to be explicitly enabled. I don't think this used to be the case. I now have this issue on all my spritekit apps. Just adding self.view.multipleTouchEnabled = YES; in viewDidLoad, fixes it for me.
Just a simple mistake, I've enabled multitouch at interface builder, problem solved. But I don't know how it turned off by itself :)

cocos2d: animation stopped. Integrate Cocos2D and UIKit

I already integrate Cocos2D and UIKit.
I have the navigation among the views and the first time that I open the cocos view, it works.
But when I return to my main menu, the log console displays:
cocos2d: animation stopped
After that, if I try to get in to the cocos2D view again, the animation does not start.
What can I do to solve this?
I followed this tutorial but it donĀ“t help
http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit
There have been issues regarding this. There was a similar discussion in another SO Question.
Whenever I want to include UIKit elements, I tend to do it the other way round.
With the CCUIViewWrapper code at: https://github.com/splhack/CCUIViewWrapper
This maybe be different depending on the version of cocos2d you are using, but stopAnimation should be being called on CCDirectorIOS.m:viewDidDisappear and startAnimation should be being called on viewWillAppear. So I would set breakpoints there to make sure it is being called on. And if your -(void) mainLoop:(id)sender is running.
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self startAnimation];
}
-(void) viewDidDisappear:(BOOL)animated
{
[self stopAnimation];
[super viewDidDisappear:animated];
}
If you want to investigate further the mainLoop calls drawScene and if it is not isPaused, then the CCScheduler will update the CCActionManager which runs all of the animations.
Hope this helps.

Cocos2d fails on iPad yet works in simulator

I have a very simple game using Xcode v4.2.1, Cocos2d v5.0.1. I've tried both compilers in Xcode (LLVM GCC 4.2 and Apple LLVM compiler 3.0. Is there a preference??) On the game screen is a UIKit button that presents the user with a Interface Builder (nib) Settings/Options screen to customize the game a bit. This is all based on what I learned in Ray Wenderlich's tutorial (http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit).
After the user makes their changes, they are returned to the game and the changes are in place.
This all works as I want in the simulator, however, when I test the game on an iPad I get the following errors in the debug window:
2012-01-27 18:25:27.305 BonkBonk[1082:707] failed to call context
2012-01-27 18:25:27.310 BonkBonk[1082:707] cocos2d: surface size: 1024x768
2012-01-27 18:25:27.316 BonkBonk[1082:707] Failed to make complete framebuffer object 8cdd
OpenGL error 0x0506 in -[EAGLView swapBuffers]
OpenGL error 0x0506 in -[EAGLView swapBuffers]
OpenGL error 0x0506 in -[EAGLView swapBuffers]
The OpeenGl errors continue on indefinitely.
I use the function viewWillAppear to capture the return from the settings/options screen so that I can pass the new settings to the game layer. If I comment out this code the problem goes away, however, I am not able to get the new user settings to the game layer.
Here is the code:
- (void) viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
//CCScene *scene = [[CCDirector sharedDirector] runningScene];
CCScene *scene = [BonkBonkLayer scene];
id layer = [scene getChildByTag:1];
[layer userSettings];
[super viewWillAppear:animated];
}
The commented out line //CCSene *scene... was another failed attempt at getting the layer object from the scene so that I could call the userSettings method where the game layer then can assimilate it into the game.
OK, so I've found something that alleviates my issue.
If anyone knows anything about this, please let me know. I will continue to use this fix unless I hear a reason from someone more knowledgable than myself (and that's not that difficult).
The solution is found in the comment by "psionic" at the end of the following discussion:
http://www.cocos2d-iphone.org/forum/topic/7068.
Basically, I created a static bool in the EAGLView class (EAGLView.m) that surrounds the call to _resizeFromLayer in the layoutSubViews member function. The call to _resizeFromLayer is only called the first time through, and then never again.
Please read the above discussion and let me know what you like/dislike about this solution, other than the obvious... it's a hack.
A hack,that works. I think.
I had a similar problem. I've integrated cocos2d with UIKit. I added adMob. The problem shows up when user clicks on Ads that presents the google BrowserView. If you dismiss the View using the Done button, the App works fine. However, if user press the Home button when in Browser View, and resume the App, I got the same exception.
OpenGL error 0x0506 in -[EAGLView swapBuffers]
UIKit buttons and the Ads are shown, but it does not render the cocos2d layer.
I got the solution from https://github.com/cocos2d/cocos2d-iphone/pull/198, but I did not change the cocos2d source. Instead, I added a boolean ivar called isAnimating in AppDelegate.m, and expose the property to the Layers.
To solve this, I stop animation on CCDirector before entering google Browser View. and start animation once resume to the App. isAnimating ivar is used to check that start animation is not called twice.
Hope it helps,
I had similar errors in my app when implementing Cocos2D via CCGLView.
The solution that worked for me was to call
[[CCDirector sharedDirector] popScene]
when presenting the Interface Builder Viewcontroller.

Creating a "developer screen" for game development in cocos2d

I'm currently developing a game on iPhone using the Cocos2D API. It's going well. One issue I'm having though is that I have to recompile each time I want to change my variables. This is very tedious, especially now that I am tweaking gameplay.
Is there any implementation for a sort of developer console screen? What I mean is: I want to have a type of game screen that I load, that contains a list of variables that I register to the game screen(with scroller). And I want to be able to modify these variables on the spot.
I remember there being a presentation on a WWDC event in which they showed such a screen on an ipad. The developer would just press a button and the gamescreen would change to a developer console like screen. I know this presentation had nothing to do with Cocos2D, but still, if this already exists in some shape or form, I would love to re-use this code instead of writing it on my own.
Though if I had to write it on my own, I wouldn't really know where to start. So any help there would be appreciated as well.
Thx!
It was (I believe) Graeme Devine at Apple's WWDC last year who had some suggestions on how to implement such a developer console (check the video on iTunes University). An example called Game Console is included with the example code of WWDC 2010 (232 MB). I've also added a link (57 kb) to GameConsole.zip from DropBox, for convenience.
This is a seriously backdated reply but we implemented a developer console for Mega Run to test out various stages and modify player properties at run time. Implementation was to tap in the top left corner of the screen at any point in the game to bring up the console. From there you could modify to your needs. The skeleton of the implementation was to override EAGLView and handle the touchesBegan touch callback yourself. Here is the implementation...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
const CGFloat DEV_DASHBOARD_ENABLE_TOUCH_AREA = 20.0f;
for (UITouch* t in touches)
{
CGPoint pt = [t locationInView:self];
if (pt.x < DEV_DASHBOARD_ENABLE_TOUCH_AREA && pt.y < DEV_DASHBOARD_ENABLE_TOUCH_AREA)
{
ToolSelectorContainer* editorViewController = [[ToolSelectorContainer alloc] initWithNibName:#"ToolSelectorContainer" bundle:nil];
if (editorViewController != nil)
{
CCScene* g = [CCDirector sharedDirector].runningScene;
// Pause the game if we're in it playing
//
if ([g isKindOfClass:[Game class]])
[((Game *)g) menuPause];
[[GSGCocos2d sharedInstance].navigationController pushViewController:editorViewController animated:YES];
[editorViewController release];
break;
}
}
}
#endif
[super touchesBegan:touches withEvent:event];
}
ifdef is used to not compile this code for production builds.

Why do I get this strange Memory Leak when I touch my UIImageView?

It's really strange. I have a blank UIImageView subclass that implements the -touchesEnded:, -touchesMoved, and -touchesBegan: methods. The implementations of these methods are empty. They just do nothing. However, when I run Instruments with "Leaks", and I touch the UIImageView and move my finger outside of that UIImageView while still touching the screen, I get an Memory Leak warning from Instruments.
In my demo app there's no object allocation happening when doing that. The methods are empty. Everything I read in Instruments is related to Foundation and Run Loop stuff. I've checked my class twice and removed any object allocation. It's just an skelleton that only shows an image, but that image is not changed when touching it or moving the finger on the screen. That makes no sense.
Did anyone else encounter problems like this?
UPDATE: I testet a little more around and figured out, that memory leaks happen at any spot on the screen when tapping fast around with 5 fingers. Everything I get from Instruments.app is regarding some run and event loops. It seems like if the device can't handle the touches fast enough and then gets stuck at some point with releasing allocated objects. Please try it out and report here if you can see the same problems.
UPDATE: I've tested now a few Apple example apps as well. When I hack with 3 - 5 fingers around on the screen, like a normal user does (yes, they will do!), then Instrument shows up memory leaks regarding event and run loops. Definitely there's a big in the framework, or in instruments. Tested with iPhone OS 2.2.1.
As reading on an apple forum, it's an unsolved problem in the SDK. It happens when the accelerometer delegate is not nil. Touch event objects are allocated but never freed. The faster the accelerometer delegate is called, the faster those allocation failures happen. Many of the apple sample codes show the same problem. I had the accelerometer turned on.
But I also encountered, that this kind of leaks happen when a touch is tracked from one view onto another. If I keep touching one and the same view and moving my finger on that view without leaving it, I'll not get that problem.
Solutions: Turn accelerometer off (delegate set to nil), reduce the amount of views in your app. I don't know if they fixed that issue in iPhone OS 3.0.
Unfortunately, this will not help:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[UIAccelerometer sharedAccelerometer] setDelegate:nil]; // because of framework bug
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[UIAccelerometer sharedAccelerometer] setDelegate:self]; // because of framework bug
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[[UIAccelerometer sharedAccelerometer] setDelegate:self]; // because of framework bug
}
More info at: http://discussions.apple.com/thread.jspa?messageID=9396584t