views:

42

answers:

2

Dear all,

Hi, I am a newbie of xcode and objective-c and I have a few questions regarding to the code sample of a game attached below. It is written in objective C, Xcode for iphone4 simulator. It is part of the code of 'ball bounce against brick" game. Instead of creating the image by IB, the code supposes to create (programmatically) 5 X 4 bricks using 4 different kinds of bricks pictures (bricktype1.png...). I have the bricks defined in .h file properly and method written in .m.

My questions are for the following code:

- (void)initializeBricks
{
    brickTypes[0] = @"bricktype1.png";
    brickTypes[1] = @"bricktype2.png";
    brickTypes[2] = @"bricktype3.png";
    brickTypes[3] = @"bricktype4.png";

    int count = 0;
    for (int y = 0; y < BRICKS_HEIGHT; y++)
    {
        for (int x = 0; x < BRICKS_WIDTH; x++)
        {
             UIImage *image = [ImageCache loadImage:brickTypes[count++ % 4]]; - Line1
             bricks[x][y] = [[[UIImageView alloc] initWithImage:image] autorelease];
             CGRect newFrame = bricks[x][y].frame;
             newFrame.origin = CGPointMake(x * 64, (y * 40) + 50);
             bricks[x][y].frame = newFrame;
             [self.view addSubview:bricks[x][y]];
        }  
    }  
} 

1) When it is compiled, error "ImageCache undeclared" in Line 1. But I have already added the png to the project. What is the problem and how to fix it? (If possible, please suggest code and explain what it does and where to put it.)

2) How does the following in Line 1 work? Does it assign the element (name of .png) of brickType to image?

brickTypes[count ++ % 4]

For instance, returns one of the file name bricktype1.png to the image object? If true, what is the max value of "count", ends at 5? (as X increments 5 times for each Y). But then "count" will exceed the max 'index value' of brickTypes which is 3!

3) In Line2, does the image object which is being allocated has a name and linked with the .png already at this line before it is assigned to brick[x][y]?

4) What do Line3 and Line5 do? Why newFrame on left in line3 but appears on right in Line5?

5) What does Line 4 do?

A: 

When it is compiled, error "ImageCache undeclared" in Line 1. But I have already added the png to the project. What is the problem and how to fix it?

ImageCache is the name of an object you're supposed to create. Since you haven't created one, it's undefined.

How does the following in Line 1 work? Does it assign the element (name of .png) of brickType to image?

It uses the count modulo 4 (% is the modulus operator) as the index to the array and then increments count. It will not exceed the array size - that's what the modulus operation is preventing. Suggest you study: Modulo Operation

In Line2, does the image object which is being allocated has a name and linked with the .png already at this line before it is assigned to brick[x][y]?

Not sure I understand the question, but yes, the image has been loaded.

What do Line3 and Line5 do? Why newFrame on left in line3 but appears on right in Line5?

They set newFrame to the same frame as an existing image and then create a CGPoint with which they set a new origin for newFrame. Lines 3, 4, and 5 get the frame of an image, set it's origin to a new value, and then replace the image with the newFrame.

Wade Williams
`bricks[x][y] = [[[UIImageView alloc] initWithImage:image] autorelease];` Sorry, please bear with me, confused by what returns. Need to know what are being returned at each part and its name in the code above.Like: UIImageView alloc returns a class object? Then it calls a class method initWithImage? Passing a parameter named 'image' which is an pointer created in line 1? And 'image' points to an 'ImageCache' object ? And ImageCache contains bricktype1.png? Last, bricks[0][0] = *image? Left is an array pointer? Right is an object UIImageView which holds a pointer named "image"?
NorthKyut
A: 

1) ImageCache is not a standard class, so the class must be defined somewhere in the game's project. You are missing an import "ImageCache.h" (or whichever header file ImageCache is defined in).

2) First, the count modulo 4 is taken. That is: divide count by 4 and take the rest. That rest is used as an index to brickTypes. So you will always get a value between 0 and 3 (including). Then, count is increased by 1 (the postfix ++ operator first returns the variable value and afterwards increases the variable by one). Since brickType seems to of type NSString *brickType[4] (you haven't showed us the declaration) this code will always return a string @"bricktype1.png" ... @"bricktype4.png".

3) I don't understand that question, sorry. Please try to explain.

4) First, the position and size of the brick are queried (line 3). Then, the position is changed, while leaving the size unmodified (line 4). Lastly, the changed position and size are assigned to the brick. In effect, this just moves the brick to a new position. It must be done this way because frame is property of type CGRect (that is: it's a method called setFrame:(CGRect)rect but the compiler provides a more convenient way to access it) which is a struct containing other structs, so one can't just do brick[x][y].frame.origin.x = x * 64.

5) It assigns a new position to the brick (or rather, to the struct queried from the brick). The CGPointMake(x,y) method returns a struct of type CGPoint. The result is assigned to the frame's member origin. One could also write:

newFrame.origin.x = x * 64;
newFrame.origin.y = (y * 40) + 50;

(here you can directly do the assigns because newFrame is a struct on your stack, not a method like brick[x][y].frame)

DarkDust
Thanks for your clear explanations. I understood the purpose in line 3-5 now. But in 4, `newFrame.origin` has given new co-ordinate to the `CGPointMake(x * 64, (y * 40) + 50);` why still need line 5? code. Also, in your explaination starting "It must be..." I am really confused, especially `which is a struct containing other structs` and I am totally lost in your reply 5). Could you make a graphically explanation or some code example?
NorthKyut
`frame` returns a CGRect. That's defined as: struct CGRect { CGPoint origin; CGSize size; }; typedef struct CGRect CGRect;CGPoint and CGSize are again structs. So a CGRect is a struct, and it contains two other structs, origin and size. Now, `[foo frame]` and `[foo setFrame:bar]` only know about CGRect, but not CGRect's origin and size. This means that you first need to copy the CGRect (line 3). You can then modify that copy (line 4). But `newFrame` doesn't know about the change yet, so you need to pass the modified copy back to `newFrame` which is done in line 5.
DarkDust
See CGRect definition: http://iphonedevelopertips.com/c/cgrect-cgsize-and-cgpoint.htmlIt contains a CGPoint and CGSize which are again structs. But the "package" (CGRect with origin + size) is just ONE memory area, and only this can be copied or modifed. Now, `[foo frame]` and `[foo setFrame:bar]` can copy CGRects, but not parts of it (CGRect's origin and size). This means that you first need to copy the CGRect (line 3). You can then modify that copy (line 4). But `newFrame` doesn't know about the change yet, so you need to pass the modified copy back to `newFrame` which is done in line 5.
DarkDust
Thanks for your clear explanations. So Newframe is an object and works like variable this case? First, bracks[x][y].frame's info is copied to Newframe and after Newframe's origin information is updated, all info is copied back to bracks[x][y].frame. If that is true, why can't just directly update bracks[x][y] location? And in your explanation, I am lost starting from "It must be done..." especially "struct containing other structs" Could you give me simpler code example to explain it? Also, no need to add some kind of (dot)property to newFrame before assigning it to bricks[x][y].frame?
NorthKyut
`newframe` is a struct, an ordered area of memory but you can think of it as an object without methods. But you seem to have a problem grasping that a CGRect is undivisable :-) It'a atomic. You either get/set all or nothing. Including its members origin and size. And it's important to understand that `newFrame = brick[x][y].frame` is a different way of writing of something like: `UIImage *tmp = brick[x][y]; newFrame = [tmp frame];`. `frame` is a method. And line 5 is a different way of writing `[tmp setFrame:newframe]`. Please read up on properties in Objective-C :-) Hard to explain here.
DarkDust