 |
 |
|
 |
06-26-2009, 01:52 PM
|
#1 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
How to simplify this code block?
I'm looking for a way to simplify some of my code so it doesn't take up 18,000 lines. Basically the code is the same code inside 12 switches.
Code:
Switch (1stage){
case 0:
1.animationimages = empty; // this is an array of image filenames, works fine
break;
case 1:
if (1stuff >= 3){
if (1otherstuff >= 3{
1stage++;
1stuff = 0;
1otherstuff = 0;
1.animationimages = newstageimage; // this is an array of image filenames, works fine
}
}
And so on for 112 stages
What I'm having trouble finding how to do is creating an array of each of the 12 items and a forLoop that makes the changes for each of the items in the array. Thus reducing my 18,000 lines of code to only 1700ish.
Any suggestions?
Last edited by ataranlen; 06-30-2009 at 11:53 AM.
|
|
|
06-26-2009, 03:31 PM
|
#2 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
|
You almost certainly want to use an NSArray or NSMutableArray of items instead of 12 separate variables, and you probably want a custom class too. Your variable names are all too generic to tell what's going on, but you want to write something like this:
Code:
for ( (StageClass )*stage in stageArray){
stage.count++;
stage.stuff=0;
stage.otherStuff=0;
stage.animationImages = newStageImage
}
This is going to require writing your own class call StageClass, and setting up stuff and otherStuff as "properties." It's also possible to do it without your own class, with multiple arrays like stuffArray and otherStuffArray, but it's bad design and it will be difficult to maintain.
Better yet, you may be able to put the operation inside a method in StageClass, and just run that method on every object. This would cause every object in the array to call [self myMethod] .
Code:
[stageArray makeObjectsPerformSelector:@selector(myMethod)];
I know this sounds like a lot to learn, but it will really make this code simple and easier to debug.
__________________
|
|
|
06-26-2009, 03:47 PM
|
#3 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
Code:
switch (plant1stage) {
case 0:
plant1water = 0;
plant1fertilizer = 0;
[plant1 stopAnimating];
plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
plant1.animationImages = empty_plot;
[plant1 startAnimating];
plant1stage = 0;
break;
case 1:
if (plant1fertilizer >= required_fert_tree) {
if (plant1water >= required_water_tree) {
plant1water = 0;
plant1fertilizer = 0;
[plant1 stopAnimating];
plant1.frame = CGRectMake(50, plant1.center.y-160, 320, 350);
plant1.animationImages = apple_stage_1;
[plant1 startAnimating];
plant1stage = 2;
} else {
[plant1 stopAnimating];
plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
plant1.animationImages = empty_plot;
[plant1 startAnimating];
plant1stage = 0;
}
} else {
[plant1 stopAnimating];
plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
plant1.animationImages = empty_plot;
[plant1 startAnimating];
plant1stage = 0;
}
break;
case 2:
Thats the gist of my code, there are a total of 12 plants, each one has its one Water, Fertilizer, stage and image. The switch is designed to be the end of a day cycle that causes the plants to grow. They grow only if they have enough water and fertilizer.
|
|
|
06-26-2009, 04:15 PM
|
#4 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
|
Then you definitely want to create a Plant class, with a dayCycle method. Then when the sun goes down, you can call this code to to update every plant in the array. Search this board for NSMutableArray if you need help creating the array.
Code:
[plantArray makeObjectsPerformSelector:@selector(dayCycle)];
Inside your plant class, you'll have an "init" method that sets up all of the variables, and the "dayCycle" method that updates all of the variables for this *ONE* plant. dayCycle will look something like this:
Code:
-(void) dayCycle{
switch (stage) {
case 0:
water = 0;
fertilizer = 0;
[imageView stopAnimating];
imageView.frame = CGRectMake(50, frame.center.y-25, 50, 50);
imageView.animationImages = empty_plot;
[imageView startAnimating];
stage = 0;
break;
case 1:
//etc...
}
__________________
|
|
|
06-27-2009, 01:23 AM
|
#5 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
Alright, I am having alot of issues with creating my own class called StageClass. Do you know of any tutorial on how to create a custom class? Every google search turns up junk about how the iphone is world class ect. I'll keep looking though.
Edit: So I finally found some tutorials, and here's what I'm up to:
The only problem is, I can't get the image to show up at all.
Code:
//
// StageClass.h
//
#import <Foundation/Foundation.h>
@interface StageClass : NSObject
{
// Initialization of the properties
int plantState;
int water;
int harvest;
int harvestCounter;
int fertilizer;
UIImageView *imageView;
}
@property(assign, readwrite) int plantState;
@property(assign, readwrite) int water;
@property(assign, readwrite) int harvest;
@property(assign, readwrite) int harvestCounter;
@property(assign, readwrite) int fertilizer;
@property(retain, readwrite) UIImageView *imageView;
@end
Code:
// StageClass.m
#import "StageClass.h"
@implementation StageClass
@synthesize plantState = _plantState;
@synthesize water = _water;
@synthesize fertilizer = _fertilizer;
@synthesize harvest = _harvest;
@synthesize harvestCounter = _harvestCounter;
@synthesize imageView = _imageView;
- (void)endDayCycle{
switch (plantState) {
case 0:
water = 0;
fertilizer = 0;
[imageView stopAnimating];
imageView.userInteractionEnabled = YES;
imageView.frame = CGRectMake(50, 430, 320, 350);
imageView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:@"empty_plot_filler.png"],nil] ;
[imageView startAnimating];
plantState = 0;
break;
case 1:
if (fertilizer >= 3) {
if (water >= 3) {
water = 0;
fertilizer = 0;
[imageView stopAnimating];
imageView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:@"001.png"],
[UIImage imageNamed:@"001.png"],nil] ;;
[imageView startAnimating];
plantState = 2;
} else {
[imageView stopAnimating];
imageView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:@"empty_plot_filler.png"],nil] ;;
[imageView startAnimating];
plantState = 0;
}
} else {
[imageView stopAnimating];
imageView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:@"empty_plot_filler.png"],nil] ;;
[imageView startAnimating];
plantState = 0;
}
break;
}
}
-(void) dealloc
{
[imageView release];
[super dealloc];
}
@end
Code:
//exerpt from ViewController.h:
IBOutlet StageClass *plant1;
}
@property(nonatomic,retain) StageClass *plant1;
Code:
//exerpt from -(void)viewdidload from ViewController.m:
plant1.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
plant1.imageView.userInteractionEnabled = YES;
plant1.imageView.frame = CGRectMake(50, 0, 320, 350);
plant1.imageView.animationImages = empty_plot;
plant1.imageView.animationDuration = 0.5;
plant1.imageView.animationRepeatCount = 0;
[plant1.imageView startAnimating];
Last edited by ataranlen; 06-27-2009 at 02:54 AM.
|
|
|
06-27-2009, 11:12 AM
|
#6 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
|
You've done very well! Only a few things I see missing. You don't need plant1 to be an IBOutlet; it's easier to create it in code than in interface builder. To create the plant object, you do this:
Code:
//in (void)viewdidload from ViewController.m:
plant1 = [[StageClass alloc] init];
Also replace your @synthesize lines to just this one:
Code:
@synthesize plantState, water, fertilizer, harvest, harvestCounter, imageView;
You don't need water = _water, becuase you don't have variable named _water. The properties already match the variable names.
__________________
|
|
|
06-27-2009, 11:37 AM
|
#7 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
So when you say I do not need an IBOutlet, I run into problems with that, I use plant1 in more places than just viewdidload. If I only init it in viewdidload, it shows as not found.
Am I supposed to remove it from viewcontroller.h? or just take out the IBOutlet? OR take out the entire IBOutlet line?
Experimentation tells me I just take out the IBOutlet part of the line and it works fine now! Wow, I never thought I would figure out classes!
|
|
|
06-27-2009, 02:57 PM
|
#8 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
|
Quote:
Originally Posted by ataranlen
So when you say I do not need an IBOutlet, I run into problems with that, I use plant1 in more places than just viewdidload. If I only init it in viewdidload, it shows as not found.
Am I supposed to remove it from viewcontroller.h? or just take out the IBOutlet? OR take out the entire IBOutlet line?
Experimentation tells me I just take out the IBOutlet part of the line and it works fine now! Wow, I never thought I would figure out classes!
|
Success! I was afraid that learning to create classes would be intimidating, but it's necessary in the long run. May as well do it now.
__________________
|
|
|
06-27-2009, 03:11 PM
|
#9 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
Alright, So remember How I had those arrays that I would use to set the animationImages?
They are set in the Viewcontroller. How would I go about using them in the Class in the endDayCycle?
|
|
|
06-27-2009, 06:00 PM
|
#10 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
|
Quote:
Originally Posted by ataranlen
Alright, So remember How I had those arrays that I would use to set the animationImages?
They are set in the Viewcontroller. How would I go about using them in the Class in the endDayCycle?
|
Many options; you could make them properties of the viewController, and pass the whole viweController into the endDayCycle method. If you did that, then endDayCycle would look like this:
Code:
-(void) endDayCycle: (ViewController*) controller{
self.imageView.animationImages = controller.newstageimage;
//other stuff I assume
}
Another method would be to put them in the application delegate, which you can get to from anywhere in your program with [[UIApplication sharedApplication] delegate] , or you could put them in a C global variable.
__________________
|
|
|
06-28-2009, 12:28 AM
|
#11 (permalink)
|
|
Registered Member
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
|
So basicly just use them as if the viewController as a class itself and use the objects in it? Sounds like a very simple solution! I'll have to try it out when I go back to work on Monday.
EDIT: When i try and set it up like this:
-(void) endDayCycle: (ProjectViewController*) controller{
It says error: expected ')' before 'ProjectViewController'
Last edited by ataranlen; 06-30-2009 at 11:53 AM.
|
|
|
 |
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
» Advertisements |
» Online Users: 382 |
| 35 members and 347 guests |
| Ajameel, Argus, bebus77, BrianSlick, Cooper_1988, dany88, Dorald, drakan, ethan, flowsky, giampo, hawksz, hrom, iphoneappguy, Jeremy1026, johnlikesit, KarlG, lanej, Marcel, MiniRobinho, mitch, Mr Jack, natekruser, nibby, nitrorazor, opipes, QuantumDoja, rahulskh, Rainer, salvah, shalevo, sketchmd, Tambourin, tyro, _nivek |
| Most users ever online was 779, 05-11-2009 at 09:55 AM. |
» Stats |
Members: 24,291
Threads: 39,080
Posts: 171,361
Top Poster: smasher (2,575)
|
| Welcome to our newest member, tyro |
|