Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Game Development

Reply
 
LinkBack Thread Tools Display Modes
Old 08-13-2011, 06:48 AM   #1 (permalink)
Registered Member
 
Join Date: Aug 2011
Posts: 3
sadia is on a distinguished road
Default Help needed to squeeze more performance in iPad app

Hi - I really really need any help you can throw my way.



Essentially this game will allow two characters to fight each other.



The problem is that the actual game on the device is considerably slower. Well that is to be expected but we are talking very slow here. I am developing this as a universal app however below is the info for the iPad version.



On the XIB there are two UIImageViews (one for hero and one for villain). The user can press buttons or pan the screen to invoke an action. The function below will take whatever the current move is along with its current position within that move and replace the current image in the UIImageView with the next one.



Some of the things I have done to help performance (i.e. in calling the function pasted below) are:



1) Place some of the images in an NSMutableArray so that they would load quicker. However I cannot do that for all moves (ideal when I did) as I swiftly get a memory issue



2) Stopped using ImagedNamed



3) I did try NSTimer - ran into problems as the function below got fired erratically and at times very slowly



4) I tried CADisplayLink - despite everyone on the internet stating its the best thing ever, it reduced the performance considerably.



5) Just for laughs I did the following and left it there:
[self.view setNeedsDisplay];
and
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:0]; [[UIAccelerometer sharedAccelerometer] setDelegate:self];



6) I do have a 1024x748 background image which scrolled - i disabled this and noticed a big difference.



7) The actual images are PNGs which I have reduced in file size ranging from 12KB to 40KB. I would say the average is 18KB. The canvas size is 308x296 for the images.

Code:
  //This is the function which keeps getting called - it gets the hero & villains next image/move set and also cheks for collision
-(void) skynet_main {
    
    //1) TIMER
    if(canItimer==0){
        secx++;
        if(secx==20){
            secx=0;
            timercount--;
            timerx.text = [NSString stringWithFormat:@"%i",timercount];  
            if(timercount==0){ 
                [self GameOver];
            }
        }
        
    } 
    //Hero - change his image
    jcount++;
    if(jcount==(no_moves_char[char_chosen-1][currentmove1-1])){ // is he at the end (move) of his current form 
        //is it forward or backward?
        if(currentmove1==9      || currentmove1==10){
            jcount=0;
        } else {
            //
            //reached the end of the current seq then time to get a new currentmove
            [self whatsnextmove:1];
        }
    }  else { // else he still has some moves left in his current form
        
        if(currentmove1>2 && currentmove1<5 && jcount<(no_moves_char[char_chosen-1][currentmove1-1])){ 
            
            //For certain moves we have put the images in an array so that they load faster. We cannot fo this for all moves as we run into memory issues.
            
            [fish1 setImage:[dict_cachemoves1 objectForKey:[NSString stringWithFormat:@"%d%@%d",currentmove1, @"_",jcount]]]; 
            
        } else {
            
            //We set the image from file for the rest of the moves
            
            NSString *imageName, *xx2;
            if(jcount<10){
                xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",char_chosen,@"_", currentmove1, @"_000", jcount];  
            } else if(jcount<100) {
                xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",char_chosen,@"_", currentmove1, @"_00", jcount];   
            }  else {
                xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",char_chosen,@"_", currentmove1, @"_0", jcount];  
            }   
            imageName = [[NSBundle mainBundle]  pathForResource:xx2 ofType:@"png"];
            UIImage *image = [[UIImage imageWithContentsOfFile:imageName] retain];
            if(image){
                [fish1 setImage:image];
            }
            [image release]; image=nil;
        }
        
        //was it a special move? - then move forward and then back
        if(currentmove1==5){
            if(jcount<(no_moves_char[char_chosen-1][currentmove1-1]/2)){
                //move forward
                if(jcount==1){
                    float difference = fish2.center.x - fish1.center.x;
                    if(difference<100){
                        fish1.center = CGPointMake(fish2.center.x-100, fish1.center.y);
                    }
                }
                fish1.center = CGPointMake(fish1.center.x+specialmoveNO, fish1.center.y);
            }else {
                //move back
                fish1.center = CGPointMake(fish1.center.x-specialmoveNO, fish1.center.y);
            }
        } 
        //END SPECIAL MOVE
        
        //were you inhured? if so then move back
        if(currentmove1>6 && currentmove1<9 && fish1.center.x >-10){
            fish1.center = CGPointMake(fish1.center.x-2, fish1.center.y);
        }
    }
    
    
    // Should we move the background and/or hero?
    if(bg_pressed==-1){ // LEFT PRESSED
        if(bg_counter>1){
            bg_counter--;
            //[self chgbg]; <- I disabled this as when I did it greatly improved the performance.
        }
        //move hero?
        //  float difference = fish2.bounds.origin.x - fish1.bounds.origin.x;
        if(fish1.center.x>-40){
            
            fish1.center = CGPointMake(fish1.center.x-40, fish1.center.y);
        }  
    } else if(bg_pressed==1){ // RIGHT PRESSED
        if(bg_counter<50){
            bg_counter++;
            [self chgbg];
        }  
        //move hero?
        float difference = fish2.center.x - fish1.center.x;
        if(difference>190){
            
            fish1.center = CGPointMake(fish1.center.x+40, fish1.center.y);
        }  else {
            fish1.center = CGPointMake(fish2.center.x-190, fish1.center.y);
        }
    }
    
    
    //LETS DO THE SAME FOR Villain 
    jcount2++;
    if(jcount2==(no_moves_char[fish2_char_selected-1][currentmove2-1]/1)){
        //is it forward or backward?
        if(currentmove2==9      || currentmove2==10){
            jcount2=0;
        } else {
            //
            //reached the end of the current sew=q
            [self whatsnextmove:2];
        }
    }  else {
        NSString *imageName;
        if(jcount2<10){ 
            NSString *xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",fish2_char_selected,@"_", currentmove2, @"_000", jcount2];  
            imageName = [[NSBundle mainBundle]  pathForResource:xx2 ofType:@"png"];
        } else if(jcount2<100) {  
            NSString *xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",fish2_char_selected,@"_", currentmove2, @"_00", jcount2];  
            
            imageName = [[NSBundle mainBundle]  pathForResource:xx2 ofType:@"png"];
        }  else {  
            NSString *xx2 = [NSString stringWithFormat:@"%@%d%@%d%@%d",@"fish_",fish2_char_selected,@"_", currentmove2, @"_0", jcount2]; 
            
            imageName = [[NSBundle mainBundle]  pathForResource:xx2 ofType:@"png"];
        }   
        UIImage *image = [[UIImage imageWithContentsOfFile:imageName] retain];
        if(image){
            [fish2 setImage:image];
        }
        [image release]; image=nil;
        
        //was it a special move?
        if(currentmove2==5){
            if(jcount2<(no_moves_char[fish2_char_selected-1][currentmove2-1]/2)){
                //move forward
                if(jcount2==1){
                    float difference = fish2.center.x - fish1.center.x;
                    if(difference<100){
                        fish2.center = CGPointMake(fish2.center.x+100, fish2.center.y);
                    }
                }
                fish2.center = CGPointMake(fish2.center.x-specialmoveNO, fish2.center.y);
            }else {
                //move back
                fish2.center = CGPointMake(fish2.center.x+specialmoveNO, fish2.center.y);
            }
        } 
        //END SPECIAL MOVE
        
        //was it a hit 1 or 2 if so then move back
        if(currentmove2>6 && currentmove2<9 && fish2.center.x < self.view.bounds.size.width-50){
            
            fish2.center = CGPointMake(fish2.center.x+2, fish2.center.y);
        }
        // }
        
        
    }
    
    //Lets wrap this up:
    
    //1)  //HIT COLLISION!! - send to collision detection
    
    [self collision_check:1];
    
    //2) Check the health bars
    
    [self setbars];
    
    
    
    //3) Call this function again
    if(canIcontinue==0){ 
        switch(currentmove1){
            case 1:
            {
                [self performSelector:@selector(skynet_main) withObject:nil afterDelay:0.001];    
                break;
            }
            case 11:
            {
                [self performSelector:@selector(skynet_main) withObject:nil afterDelay:0.003];    
                break;
            }
            case 12:
            {
                [self performSelector:@selector(skynet_main) withObject:nil afterDelay:0.001];    
                break;
            }
            default:
                
            {
                [self performSelector:@selector(skynet_main) withObject:nil afterDelay:0.005];   
                break;
            }
        }
        
    } //*/
    
    
    
}

I would appreciate any help you can throw my way.
sadia is offline   Reply With Quote
Old 08-13-2011, 10:35 AM   #2 (permalink)
Registered Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 3,858
smasher will become famous soon enough
Default

How often did you set your NSTimer to run? You'll probably only get 10-15 FPS from UIImages / UIKit once you starts drawing more than a few images. It's just not built for fast swapping of images.

I'd try turning your timer down to 10 times a second or skipping frames in your displayLink to get 10FPS. You'll probably get a more *even* framerate that way, even if it's slower.

If that doesn't work then you've hit the limit of UIKit. You could try CALayer, which is supposed to me more lightweight, but it's probably a dead-end. You need OpenGL or Cocos2D (my favorite) for speedy drawing.
__________________

Free Games!
smasher is offline   Reply With Quote
Reply

Bookmarks

Tags
iphone ipad game

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 413
11 members and 402 guests
AppleDev, chemistry, Emy, Gi-lo, ipodphone, mistergreen2011, pipposanta, Retouchable, skrew88, SLIC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,679
Threads: 94,128
Posts: 402,923
Top Poster: BrianSlick (7,990)
Welcome to our newest member, xzoonxoom
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:20 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0