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?
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.
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)
Related
I'm confused about the coordinate.column and coordinate.row used in the code swift plyground provided below. How was column and row accssed when I didn't instantiate the instance coordinate? If the for loop insatntiate coordinate, how was it instantiated when allcoordinates or world.allPossibleCoordinates are not a type? (There are no parathenthesis around world.allPossibleCoordinates...)
let allCoordinates = world.allPossibleCoordinates
var blockSet: [Coordinate] = []
//#-editable-code Tap to enter code
for coordinate in allCoordinates {
// Check for coordinates with a column > 5 OR a row < 4.
if coordinate.column > 2 && coordinate.row < 5 {
// Append coordinate to blockSet.
}
}
In Swift, the for in loop works a bit differently than a for loop in other languages. A for in loop strides over a range (I'm assuming allCoordinates is strideable). In the provided example, if the variable allCoordinates is a strideable range, the loop will go through every single item in that range assigning each value to coordinate per iteration. For more information, have a look at Apple's Documentation
I would like to be able to initialise a big table in matlab easily.
Say I have the bounds x, y, z = 5, 4, 3. I want to be able to make a 5x4x3 table where each element is a struct that stores count and sum. Count and sum in this struct should be 0 when initialised.
I thought it would be enough to do this:
table = []
table(5,4,3) = struct('sum', 0, 'count', 0)
And this would work for a double but not with a structure evidently.
Any ideas?
EDIT:
As another question, (bonus if you will) is there a way to force matlab to store the struct, but when you access the element (i.e., table(1, 2, 3)) get it to return the average (i.e., table(1,2,3).sum/table(1,2,3).count).
Its not vital to the question but it would certainly be cool.
You'll need just to replace the line table = [] to avoid the error, that is
clear table;
table(5,4,3) = struct('sum', 0, 'count', 0)
works fine. Note, however, that this command only initializes one field of your array, i.e., the memory allocation is incomplete. To initialize all fields of your array, you can use
table2(1:5,1:4,1:3) = struct('sum', 0, 'count', 0)
to visualize the difference, use whos, which returns
>> whos
Name Size Bytes Class Attributes
table 5x4x3 736 struct
table2 5x4x3 8288 struct
Your second question can be solved, for instance, by using anonymous functions
myMean = #(a) a.sum./a.count; %define the function
myMean(table2(2,2,2)) % access the mean in the field (2,2,2)
My question is a little tricky, and I'm not exactly experienced (I might get some terms wrong), so here goes.
I'm declaring an instance of an object called "Singer". The instance is called "singer1". "singer1" produces an audio signal. Now, the following is the code where the specifics of the audio signal are determined:
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
//Singer *me = (Singer *)inRefCon;
static int phase = 0;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples = ioData->mBuffers[i].mDataByteSize / sizeof(SInt16);
SInt16 values[samples];
float waves;
float volume=.5;
for(int j = 0; j < samples; j++) {
waves = 0;
waves += sin(kWaveform * 600 * phase)*volume;
waves += sin(kWaveform * 400 * phase)*volume;
waves += sin(kWaveform * 200 * phase)*volume;
waves += sin(kWaveform * 100 * phase)*volume;
waves *= 32500 / 4; // <--------- make sure to divide by how many waves you're stacking
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;
}
99% of this is borrowed code, so I only have a basic understanding of how it works (I don't know about the OSStatus class or method or whatever this is. However, you see those 4 lines with 600, 400, 200 and 100 in them? Those determine the frequency. Now, what I want to do (for now) is insert my own variable in there in place of a constant, which I can change on a whim. This variable is called "fr1". "fr1" is declared in the header file, but if I try to compile I get an error about "fr1" being undeclared. Currently, my technique to fix this is the following: right beneath where I #import stuff, I add the line
fr1=0.0;//any number will work properly
This sort of works, as the code will compile and singer1.fr1 will actually change values if I tell it to. The problems are now this:A)even though this compiles and the tone specified will play (0.0 is no tone), I get the warnings "Data definition has no type or storage class" and "Type defaults to 'int' in declaration of 'fr1'". I bet this is because for some reason it's not seeing my previous declaration in the header file (as a float). However, again, if I leave this line out the code won't compile because "fr1 is undeclared". B)Just because I change the value of fr1 doesn't mean that singer1 will update the value stored inside the "playbackcallback" variable or whatever is in charge of updating the output buffers. Perhaps this can be fixed by coding differently? C)even if this did work, there is still a noticeable "gap" when pausing/playing the audio, which I need to eliminate. This might mean a complete overhaul of the code so that I can "dynamically" insert new values without disrupting anything. However, the reason I'm going through all this effort to post is because this method does exactly what I want (I can compute a value mathematically and it goes straight to the DAC, which means I can use it in the future to make triangle, square, etc waves easily). I have uploaded Singer.h and .m to pastebin for your veiwing pleasure, perhaps they will help. Sorry, I can't post 2 HTML tags so here are the full links.
(http://pastebin.com/ewhKW2Tk)
(http://pastebin.com/CNAT4gFv)
So, TL;DR, all I really want to do is be able to define the current equation/value of the 4 waves and re-define them very often without a gap in the sound.
Thanks. (And sorry if the post was confusing or got off track, which I'm pretty sure it did.)
My understanding is that your callback function is called every time the buffer needs to be re-filled. So changing fr1..fr4 will alter the waveform, but only when the buffer updates. You shouldn't need to stop and re-start the sound to get a change, but you will notice an abrupt shift in the timbre if you change your fr values. In order to get a smooth transition in timbre, you'd have to implement something that smoothly changes the fr values over time. Tweaking the buffer size will give you some control over how responsive the sound is to your changing fr values.
Your issue with fr being undefined is due to your callback being a straight c function. Your fr variables are declared as objective-c instance variables as part of your Singer object. They are not accessible by default.
take a look at this project, and see how he implements access to his instance variables from within his callback. Basically he passes a reference to his instance to the callback function, and then accesses instance variables through that.
https://github.com/youpy/dowoscillator
notice:
Sinewave *sineObject = inRefCon;
float freq = sineObject.frequency * 2 * M_PI / samplingRate;
and:
AURenderCallbackStruct input;
input.inputProc = RenderCallback;
input.inputProcRefCon = self;
Also, you'll want to move your callback function outside of your #implementation block, because it's not actually part of your Singer object.
You can see this all in action here: https://github.com/coryalder/SineWaver
I have a bunch of images on the screen.... UIImageView *s1, s2 ,s3 etc up to *s10
Now suppose I want to update the image each displays to the same image.
Rather than doing
s1.image = sampleimage;
s2.image = sampleimage;
:
s10.image = sampleimage;
How could i write a for loop to go from 1 to 10 and then use the loop var as part of the line that updates the image.
Something like this.
for ( i = 1; i <- 10; ++i )
s(i).image = sample; // I know that does not work
Basic question is how do I incorporate the variable as part of the statement to access the image? Don't get hung up on my example. The main question is how to use a variable as part of the access to some element/object.
Bottom Line... If I can build the name of a UIImageView into a NSString object, How can I then use that NSString object to manipulate the UIImageView.
Thanks!
You can't. That is not the name of the UIImageView — it's the name of a variable that refers to the image view, and those variables do not necessarily even exist at runtime.
It sounds like what you want is an array — either an NSArray or UIImageView *s[10]. (This is assuming there aren't actually more descriptive names you could give the views than "s1" through "s10".)
Hi everybody: i want to take a picture and retrieve the main color analyzing its palette (i think this should be the easiest way), but i don't know really where to start.
Assuming you have a raw 24 bit RGB image and you want to find the number of times each color appears:
there are really 2 simple ways of doing this:
my favourite is just to create an array of ints for each possible color, then just index into that array and ++ that method does use like 64 meg of memory tho.
another method is to create a linked list, adding to it each time a new color is encountered, the structs stored in the list would store the color and the number of times encountered, its slow to do all the accumulating cause you have to search the whole list for each pixel, but it would be quicker to sort by number of times used, as only colors actually used are in the list (making it more ideal for small images too)
I like a compromise between the two:
take say, red and green to index into an array of linked lists, that way the array is only 256k (assuming it just stores a pointer to the list) and the lists to search will be relatively short because its only the blue variants of the Red,Green color. if you were only interested in the SINGLE MOST used color, I would just store this in a "max color" variable, that I would compare with each time I iterated over a pixel and incremented a color, that way you don't have to go through the whole structure searching for the most used at the end.
struct Pixel
{
byte R,G,B;
}
const int noPixels = 1024*768; // this is whatever the number of pixels you have is
Pixel pixels[noPixels]; // this is your raw array of pixels
unsinged int mostUsedCount = 0;
Pixel mostUsedColor;
struct ColorNode
{
ColorNode* next;
unsigned int count;
byte B;
}
ColorNode* RG = new ColorNode[256*256];
memset(RG,0,sizeof(ColorNode)*256*256);
for(int i = 0; i<noPixels; i++)
{
int idx = pixels[i].R + pixels[i].G*256;
ColorNode*t;
for(t=RG[idx]; t; t = t->next)
{
if(t->B == pixels[i].B)
{
break;
}
}
if(!t)
{
t = new ColorNode;
t->next = RG[idx];
RG[idx] = t;
t->B = pixels[i].B;
t->count = 0;
}
t->count++;
if(t->count > mostUsedCount)
{
mostUsedCount = t->count;
mostUsedColor = pixels[i];
}
}
you might consider using a Binary Tree, or Tree of some kind too, rather than just searching through a list like that. but I'm not too knowledgeable on that type of thing...
Oh yeah... I forgot about memory management.
you could just go through the whole array and delete all the nodes that need deleting, but that would be boring.
if possible, allocate all the memory you would possibly need at the beginning, that would be 256k + sizeof(ColorNode) *noPixels ~= 256 + 2 to 3 times the size of your raw image data.
that way you can just pull nodes out using a simple stack method, and then delete everything in one foul swoop.
another thing you could do is also add the nodes to another link list for ALL allocated nodes as well, this increases the iterating process, adds data to Color node, and just saves having to iterate through the entire array to find lists to delete.