//****************************************************************************// //********************** Arrays - November 9th, 2017 ************************// //**************************************************************************// - NOTE: DON'T initialize static variables in .h files; if you import them twice, then the preprocessor will paste the .h content into all files that #include it BEFORE it compiles; if you import it into 2 or more files, then the compiler will see you declared the same variable twice and freak out - So, our game right now is good - FANTASTIC, in fact...but I can see the looks on your faces: "Bill, we want MOAR!" Well, well, fine. I'll give you more, kids. - What if we made the game have not just ONE bouncing rectangle...but SEVERAL! AND, even better, they're all DIFFERENT COLORS! - Well, several things of the same type...sounds like a job for an array, right? - Now, since we want to (conceptually) have an array of "Squares", let's create a struct for the info we'll need for each Square: typedef struct { int row; int col; int rdel; int cdel; int size; u16 color; } SQUARE; - Notice here that we didn't have to give the struct a "tag" - for simple uses like this, we don't need it (Read the C book for more info) - Now, to initialize our array: SQUARE objs[NUMOBJS]; SQUARE oldObjs[NUMOBJS]; ...or, alternatively, we can declare arrays in general like: int happyNums[] = {1, -3, 5, 7, 12, 12, 12, 16, -434}; int happyNumsLength = sizeof(happyNums) / sizeof(int); //or '/sizeof(happyNums[0])' - ...and instantiate them all u16 colors[] = {RED, GREEN, BLUE, WHITE, PURPLE, FUCIA}; int colorsLength = sizeof(colors) / sizeof(colors[0]); for (int i = 0; i < NUMOBJS; i++) { objs[i].row = 70 + rand() % 20; objs[i].col = 110 + rand() % 20; objs[i].rdel = happyNums[rand() % happyNumsLength]; objs[i].cdel = happyNums[rand() % happyNumsLength]; objs[i].size = 5; objs[i].color = colors[rand() % colorsLength]; oldObjs[i] = objs[i]; } - NOTE: RAND starts with the same seed every time in VBA, so if you get the same random number every time, that's why. You can change the seed with the "srand()" function - Then, we iterate through the "array" (which is just a pointer to the start of a block of memory) and do everything we've been doing for EACH of the SQUAREs - Now, to access the properties of the struct you'd THINK that you'd get them by dereferencin' the pointer *cur.row - ...but it DOESN'T WORK. The dot operator in C has a higher precedence than the dereference operator, so this will try to assign some values to a pointer. So INSTEAD, we do this: (*cur).row - ...or, as syntactic sugar, we can use the ARROW operator as shorthand: cur->row - "Now, you might be saying gee, the dot operator syntax actually makes sense, the arrow seems kinda randmo...get used to it, guys. EVERYONE uses the arrow syntax, which grabs the pointer, dereferences it, and then looks for the item in the struct" - So, we run this now, and it works! Great! BUT, we have to do some minor tweaks to our display code so we're only calling waitForVblank once instead of once for each object - So...that's basically it for the GameBoy part of this class! - "So, what was the point of all this? ...it was NOT to turn you into GameBoy developers, but to introduce you to C development, and the kinds of low-level places that C is actually used for" - On TUESDAY, we'll start going over malloc and dynamic allocation...this tends to be VERY confusing for students, so be sure to come! - "At some point in your life, you're going to have to go to a McDonald's again, and when you pull up to the drive-through and start paying for your Whopper or whatever, the cashier'll see the bumper sticker on your car and say 'Georgia Tech! I went there...yeah, I took 2110 with Leahey, and then we got to malloc. And now I'm here. At McDonald's. Yeah.'"