I wonder if there is some setting och significant difference between iPad and iPhone?
I'm developing a game with Sprite Kit, SKD 8.1 and target iOS 7.1.
The game is using A* pathfinding to move the 2 characters on my map during the testing.
The problem I've encountered is when the characters looking for a path.
On my iPad 4, 16gb, the pathfinding freeze while the characters looking for a path.
On my iPhone 6 and iPhone 4, it works flawlessly.
It works great on the simulator (iPad Retina, iPhone 4 and iPhone 6) and there is no freeze in the game, only on my Ipad 4...
Is there something I've missed? The game is developed to be used both on iPhone and iPad.
Very grateful for any help ..
-(NSArray*)nearbyBlocks:(SKNode*)blocks {
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:4];
NSArray *leftB = [blocks.name componentsSeparatedByString:#"_"];
/* LEFT */
SKNode *b = [background childNodeWithName:[NSString stringWithFormat:#"block_%i_%i", [[leftB objectAtIndex:1] intValue]-1, [[leftB objectAtIndex:2] intValue]]];
if ([blockArrayWalk containsObject:b]) {
[tmp addObject:b];
}
/* RIGHT */
b = [background childNodeWithName:[NSString stringWithFormat:#"block_%i_%i", [[leftB objectAtIndex:1] intValue]+1, [[leftB objectAtIndex:2] intValue]]];
if ([blockArrayWalk containsObject:b]) {
[tmp addObject:b];
}
/* UP */
b = [background childNodeWithName:[NSString stringWithFormat:#"block_%i_%i", [[leftB objectAtIndex:1] intValue], [[leftB objectAtIndex:2] intValue]+1]];
if ([blockArrayWalk containsObject:b]) {
[tmp addObject:b];
}
/* DOWN */
b = [background childNodeWithName:[NSString stringWithFormat:#"block_%i_%i", [[leftB objectAtIndex:1] intValue], [[leftB objectAtIndex:2] intValue]-1]];
if ([blockArrayWalk containsObject:b]) {
[tmp addObject:b];
}
return [NSArray arrayWithArray:tmp];
}
I've run Time Profiler now and it spikes when the character is looking for a path. The search for childNodeWithName is at yellow with 24%... nearbyBlocks is called every time the path has found the next block so its called multiple times depending on the path length.
The problem is that I need to use the SKNodes because the char can fall down if someone is removing a block underneath... Might abandon the game idea soon ;)
Related
I have coded an App that can convert normal Text like : "Hello my Name is XY"
into points and strokes ( ..-. ; --.- ; . ; - ; etc etc)
Now I want to Convert these points and stroke into light flashes with the lenght of 0.3 sec for points an 0.6 seconds for strokes. also there is a pause with the length of a point after each point or stroke, a double pause after each Word, and a tripple pause/break after each sentences.
The breaks are also implied into my code.
The problem is now that the light strokes aren't different enough.
Because the Idea behind it is to convert the Light flashes via an Arduino Duo and a fototransistor back to Text.
Here is the Code Passage for the Light converting Process:
- (IBAction)send:(id)sender{
// Converting Text to morsecode etc
float needTime;
NSString *string = plotter;
for (int d = 0;d < [string length]; d++) {
NSString *punktoderstrich = [string substringWithRange:NSMakeRange(d, 1)];
if ([punktoderstrich isEqualToString:#"."]) {
needTime = needTime + 0.4f;
[self performSelector:#selector(playpunkt) withObject:nil afterDelay:needTime];
}
if ([punktoderstrich isEqualToString:#"-"]) {
needTime = needTime + 1.0f;
[self performSelector:#selector(playstrich) withObject:nil afterDelay:needTime];
}
if ([punktoderstrich isEqualToString:#" "]) {
needTime = needTime + 0.4f;
[self performSelector:#selector(playpause) withObject:nil afterDelay:needTime];
}
if ([punktoderstrich isEqualToString:#"/"]) {
needTime = needTime + 0.3f;
[self performSelector:#selector(playpause) withObject:nil afterDelay:needTime];
}
}
- (void)torchAn {
[captureDevice lockForConfiguration:nil];
[captureDevice setTorchMode:AVCaptureTorchModeOn];
[captureDevice setFlashMode:AVCaptureFlashModeOn];
[captureDevice unlockForConfiguration];
}
- (void)torchAus {
[captureDevice lockForConfiguration:nil];
[captureDevice setTorchMode:AVCaptureTorchModeOff];
[captureDevice setFlashMode:AVCaptureFlashModeOff];
[captureDevice unlockForConfiguration];
}
-(void)playstrich{
// AudioServicesPlaySystemSound (outSystemSoundID2);
[self torchAn];
//[self performSelector:#selector(torchAus) withObject:nil afterDelay:0.8f];
}
-(void)playpunkt{
//AudioServicesPlaySystemSound (outSystemSoundID1);
[self torchAn];
//[self performSelector:#selector(torchAus) withObject:nil afterDelay:0.4f];
}
- (void)playpause{
// AudioServicesPlaySystemSound (outSystemSoundID3);
[self performSelector:#selector(torchAus) /*withObject:nil afterDelay:0.4f*/];
}
Like You see I also imported sound files (short and Long) but the Main target is to give a right light signal out.
My Problems:
Short lights are mostly okay, exept the first when the LED is firstly flashing.
Long light signals aren't really longer. Sometimes I get equal results when I'm recording them.
And after a Long light should light up the following short ones aren't short as normal.. hm..
After I had commented the Part with the sounds out, the whole process became more stable.
I also moved the Part (turning LED OFF) from the sign it self to the breaks.
I hope somebody can give me some tipps or so :)
Greets from Germany!
P.S.: My divice is an iPhone 4s (with torch ^^)
Like Brad said the iPhone flash needs a few ms to turn on. If you still want to use it the only possibility would be (in my eyes) to change your protocol and give the single signals more time.
This slows down your transmission but on the receiver-side you could define some confidence intervals (like plus-minus 2 seconds). Maybe a human beeing would not understand your morse code because it could be too slow (but maybe they will), a machine like the iPhone as a receiver would be perfectly able to understand it.
You have to play around with the time intervals to find the shortest ones that are working.
Greetings from GER.
I have an application in which I have taken imageview as a background and in that imageview I am using 89 images to make an animation.Here's my code to do the animation
-(void)viewWillAppear:(BOOL)animated
{
NSString *cachesDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(#"cachesDirectoryPath: %#", cachesDirectoryPath);
CPIAppDelegate *obj=(CPIAppDelegate *)[[UIApplication sharedApplication]delegate];
arrayOfImages=[[NSMutableArray alloc]init];
viewMenu.hidden = obj.buttonStatus;
for (int i=0; i<IMAGE_ANIMATION_COUNT; i++) {
// [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/streamvideo351_frame%d.jpg",cachesDirectoryPath,i]];
[arrayOfImages addObject:[UIImage imageNamed:[NSString stringWithFormat:#"streamvideo351_frame%d.jpg",i]]];
}
BackGrdImage.animationImages=arrayOfImages;
BackGrdImage.animationDuration =5.0;
BackGrdImage.animationRepeatCount =3;
[BackGrdImage startAnimating];
[arrayOfImages removeAllObjects];
}
and in dealloc method I am using
[imageAnimations release];
[BackGrdImage removeFromSuperview];
[BackGrdImage release];
it works fine on simulator But crashes on Ipad.What actually happens in ipad is sometimes it gets blink and some time time it disappear.So please help me out with this friends.I am also releasing the array on -(void)viewWillDisappear So please friends help me out with it Any help or suggestion will be appreciated.
Your app crashing because BackGrdImage animating only one time after that you releasing the array
[arrayOfImages removeAllObjects];
and
BackGrdImage.animationRepeatCount =3;
due to this your image goes animating second time but BackGrdImage does not get arrayOfImages for animation therefore your app going to crash.
There is one way when your image animation three time means in 1.5 sec then after you have to call one method for releasing your arrayOfImages.
The above process sure will work out.
May be you are getting memory warning. Because I don't think that device will support images array of 89 images/imageviews. Try debuggig your app on device.
i have three simple images each for 2 hens (6 images) which I am trying to animate (a hen walking) using a very good tutorial by Ray Wenderlich:
http://www.raywenderlich.com/1271/how-to-use-animations-and-sprite-sheets-in-cocos2d
The animation works fine when I start the game but after 2-3 mins the Frame Rate begins to drop and slowly it drops to below 10 and the application hangs.. btw I am using iPhone 3G with iOS 4.1 ... can that be the reason for the FPS drop or just the iPhone becomes idle after some time?
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"hen.plist"];
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"hen.png"];
[self addChild:spriteSheet];
// Load up the frames of our animation
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 3; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
self.bear = [CCSprite spriteWithSpriteFrameName:#"1.png"];
_bear.position = ccp(20,400);
self.walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
[_bear runAction:_walkAction];
[spriteSheet addChild:_bear];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"monkey.plist"];
CCSpriteBatchNode *spriteSheetMonkey = [CCSpriteBatchNode batchNodeWithFile:#"monkey.png"];
[self addChild:spriteSheetMonkey];
NSMutableArray *walkAnimFramesMonkey = [NSMutableArray array];
for(int i = 1; i <= 3; ++i) {
[walkAnimFramesMonkey addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"%d.png", i]]];
}
CCAnimation *walkAnimMonkey = [CCAnimation animationWithFrames:walkAnimFramesMonkey delay:0.1f];
self.monkey = [CCSprite spriteWithSpriteFrameName:#"1.png"];
_monkey.position = ccp(40,80);
self.walkMonkey = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnimMonkey restoreOriginalFrame:NO]];
[_monkey runAction:_walkMonkey];
[spriteSheetMonkey addChild:_monkey];
float bearVelocity = 480.0/3.0;
CGPoint moveDifferenceHen = ccpSub(HenLoction, _bear.position);
float distanceToMoveHen = ccpLength(moveDifferenceHen);
float moveDurationHen = distanceToMoveHen / bearVelocity;
self.moveAction = [CCSequence actions:
[CCMoveTo actionWithDuration:moveDurationHen position:HenLoction],
[CCCallFunc actionWithTarget:self selector:#selector(bearMoveEnded)],
nil
];
[_bear runAction:_moveAction];
Sounds like you might have a memory leak. My advice would be to run the Leaks and ObjectAlloc Instruments on the device. Also, you should post the relevant code if you want more detailed assistance.
A memory leak seems most likely.
If that's not it then I'd look at things like data structures you're traversing, any kind of decision-tree-like elements you're building over time, that kind of thing. Anything where there isn't necessarily a memory leak but something might be legitimately getting big or complex, requiring increasing processing time.
If the app has to work through this several-to-many times a second, everything would slow down. It could be the kind of thing where it's getting twice as complicated or large ever few minutes, and the early doublings are still fast and easy to calculate. When it doubles from, say, 256 times as complex as the original to 512 times, the slowdown starts to become apparent.
I'm creating an universal application and my CCMenu appears just fine on both iPhone, iPhone 4 and iPad. However the buttons do nothing when touched on the iPad.
I have no specific iPad code other than modifying the contentScaling property so that the iPad uses the same images as the iPhone 4. This means that the same images work on iPhone 4 but not on the iPad.
I am using cocos2d 0.99.rc0 and the iOS 4.1 SDK. I don't even know where to start troubleshooting this.
The only oddity i noticed recently is that the iPad seems to draw the menu scene once, then quickly redraws it for some reason, moving everything one pixel or something. My menu class is very simple and has no "refreshing" code or anything that is supposed to move. This doesnt happen on either low or high res iPhones.
Here is my code, sloppy but yet very simple.
MainMenu.m:
CCMenuItemImage * playItem = [self makeMenuButtonWithSprite:#"Play.png" withSelector:#selector(play:)];
CCMenuItemImage * resumeItem = [self makeMenuButtonWithSprite:#"Resume.png" withSelector:#selector(resume:)];
CCMenuItemImage * optionsItem = [self makeMenuButtonWithSprite:#"Options.png" withSelector:#selector(options:)];
CCMenuItemImage * helpItem = [self makeMenuButtonWithSprite:#"Help.png" withSelector:#selector(help:)];
CCMenu *myMenu;
// Check if there is a valid savegame by comparing versions.
if ([[uD stringForKey:#"CFBundleVersion"] isEqualToString:[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleVersion"]] ) {
myMenu = [CCMenu menuWithItems:playItem, resumeItem, optionsItem, helpItem, nil];
} else {
myMenu = [CCMenu menuWithItems:playItem, optionsItem, helpItem, nil];
}
// Arrange the menu items vertically
[myMenu alignItemsVerticallyWithPadding:0.0f];
myMenu.position = ccp(dB.wWidth/2,dB.wHeight/2);
// add the menu to your scene
[self addChild:myMenu z:100];
And the CCMenuItemImage factory:
- (CCMenuItemImage *)makeMenuButtonWithSprite:(NSString *)spriteFileName withSelector:(SEL)selector {
CCSprite *spriteForButton = [CCSprite spriteWithFile:spriteFileName];
spriteForButton.anchorPoint = ccp(0.5f,0.5f);
CCMenuItemImage * buttonImage =[CCMenuItemImage itemFromNormalImage:#"button.png"
selectedImage: #"button.png"
target:self
selector:selector];
[buttonImage addChild:spriteForButton z:100];
spriteForButton.position = ccp([buttonImage boundingBox].size.width/2,([buttonImage boundingBox].size.height/2)-5);
return buttonImage;
}
I don't think that any known bug exists for this issue. Not sure how to debug this without seeing any code, but, if it helps, here's some code of mine that successfully adds a menu using cocos2d 0.99.5, on iOS 4.0, 4.1 and 4.2 (no difference when I upgraded):
-(void) initBottomMenu {
CCMenuItem *aboutButton = [self gameButtonWithName:#"about" selector:#selector(onAbout:)];
CCMenuItem *settingsButton = [self gameButtonWithName:#"settings" selector:#selector(onSettings:)];
CCMenuItem *tutButton = [self gameButtonWithName:#"tutorial" selector:#selector(onTutorial:)];
CCMenu *menu = [CCMenu menuWithItems:aboutButton, settingsButton, tutButton, nil];
menu.position = ccp(xPos, yPos);
[menu alignItemsHorizontallyWithPadding:45.0];
[self addChild:menu];
}
The gameButtonWithName:selector: method looks like this:
-(CCMenuItem *) gameButtonWithName:(NSString *)name selector:(SEL)s {
NSString *iPadSuffix = #"IPad";
NSString *normal = [[NSString alloc] initWithFormat:#"%#Btn%#.png", name, iPadSuffix, nil] ;
NSString *selected = [[NSString alloc] initWithFormat:#"%#Btn%#.png", name, iPadSuffix, nil];
CCMenuItem *retButton = [CCMenuItemImage itemFromNormalImage:normal
selectedImage:selected
disabledImage:selected
target:self
selector:s];
[selected release];
[normal release];
return retButton;
}
sort of sloppy, but it works out well for adding a menu to my main scene.
Problem found. This was related to my custom hack to make the iPad load retina graphics. The problem was in my appDelegate where i set the contentScaleFactor which made ccDirector scale and UIScreen scale mismatch.
Problem boiled down to graphics being big but cocos2d thinking that coordinates are low res.
I am looking to persistently display a game score in an iPhone app using cocos2d. Going off the code that cocos2d shows the FPS the app is running at:
-(void) showFPS
{
frames++;
accumDt += dt;
if ( accumDt > 0.1) {
frameRate = frames/accumDt;
frames = 0;
accumDt = 0;
}
NSString *str = [NSString stringWithFormat:#"%.1f",frameRate];
[FPSLabel setString:str];
[FPSLabel draw];
}
I can get the score to display properly, but it flickers, even though the app is running at faster that 60 FPS... Any ideas?
For anyone who might be interested, I ended up using a cocos2d Label as so:
scoreLabel = [Label labelWithString: [NSString stringWithFormat:#"%d", score] dimensions: CGSizeMake(180, 20) alignment: UITextAlignmentRight fontName:#"Arial" fontSize: 20];
[scoreLabel setPosition: cpv(100,100)];
[self add: scoreLabel];
Hopefully this can help someone else.
Try using LabelAtlas instead. It is faster (it consumes much less CPU).
See the AtlasDemo that comes with the cocos2d distribution to see how to use it.