Ooops! This should have been posted on October 1...
It's been a few whirlwind weeks as I put on the final touches - a new "hint" sound effect, a non-proprietary explosion sound for the end, the statistics page, pop-up instructions, fixed graphics on the menu, an updated instructions screen. But last Saturday, I deemed version 1.0 complete.
And that's when frustration really started to kick in. Every step in Apple's App Store submission process is (presumably) reasonable, but it takes a lot of time and internet searching to work through it all.
My first problem was my own fault- when I originally set up my developer account, I used my work address, because I was just planning to teach the program in class. For a personal project (for pay), however, I needed the legal address to be my own. This took an email to request the change. 48 hours later, I got a response requiring me to fax my driver's license in to prove I was who I said I was. (As I said, it's all reasonable; I'm glad they did.) Then it took another 48 hours for that change to go through.
So today I approved the Apple contract, set up my business officers (all of them are just as good looking as the chief programmer), told them where to send the money, and gave them my tax info.
After that, I went to another section of the site to register my application for the App Store. This required setting a price, a description, screenshots, etc. All stuff I was expecting.
So then they told me to "upload your binary." Right. Where is this binary?!.
I remembered that I hadn't yet built the program as a "release" product - just as a "debug" product. So, I switched it over and hit build and run. And all the old settings bugs I'd had to hunt down months ago had to be done again. Ok. Still can't find the binary file.
I hunt around online. After many false leads with people on the Internet telling me to edit the internal files of my project with a text editor - a bad idea, IMHO- I found instructions to "build and archive." Great! But where's the binary file?
A little more poking around, and I discovered online that the build and archive command sends its result to the Organizer window, where there is also a "send to app store" button. After a few false starts where I realized that I had the program set for both iPod and iPad, I got it set to go. (My app is just for the iPad, at least for now.) But when I tried to send it in, I got a message saying that my provisioning profile didn't match up.
So I sent quite a while looking for what that meant. Finally, I found (in yet another part of Apple's website), a page that indicated that I needed a different profile to submit the apps than the one I was using to test them. A little more trial and error, and I got it to upload!
So now my little app is officially uploaded and "waiting for review." There's nothing to do for it now but to wait... In hindsight, there was a lot of this I could have done earlier; I didn't have to wait to finish my program to get started. Still, I am flush with the glow of victory!
But I still don't know where that binary file is.
- Posted using BlogPress from my iPad
Showing posts with label implosion. Show all posts
Showing posts with label implosion. Show all posts
Sunday, November 28, 2010
Saturday, October 16, 2010
Success!
After a week of waiting, my App was approved. If you're reading this, be sure to check out Implosion! On the app store.
- Posted using BlogPress from my iPad
- Posted using BlogPress from my iPad
Saturday, July 10, 2010
Progress, progress, progress!
I got some great stuff done the last day or so...
1) Menus - There is now a starting menu with the logo I showed off in the previous post. It also has a "Play" button and a button for instructions. Clicking the play button starts the game and the instructions button shows a page with rules of the game (a tap on the screen returns to the menu).
2) Pause - based on the same "sio2 widget" technology, there is now a pause feature. During the game, if you flip the ipad to face downwards (or accelerate it downwards at 2g) it will go into pause mode - the clock will stop, but there is a graphic covering up the game board. A single tap resumes.
3) Game over - when the player runs out of time, the selector disappears, all the doors open, and the chips start to fall towards the center. They make a tiny ball, which then explodes outwards. It is very satisfying in the OpenGL 3-d world! It reminds me of the original Tron and (spoiler!) what happens to the MCP at the end.
4) The game moves between the modes pretty fluidly, and you can restart the game.
Along the way, I was getting some distressing messages from the debugger. I use the "NSLog" command quite a bit, so I suspect these have been getting lost in the clutter - they were memory warnings. Somehow, I was running out of RAM space. Mostly, they were just level 1 errors, but I actually got a level 2 one tonight. This didn't seem likely, since my chips are of a finite number, and there just aren't that many polygons and variables in this game, compared to most 3d fare...
So I wondered if I had too many graphics loaded in memory at one time. I rewrote the menus and buttons (widgets) code so they loaded when needed and unloaded when they were done. It was a bit of a pain, and I worry a little bit about the speed at which they will load now. That didn't fix it.
I stumbled upon the answer when a memory warning showed up between two closely spaced NSLogs - in fact the only thing I did between them was move a Chip! It turns out that every time I moved one of the chips, I created a new 3d vector to represent the displacement of the Chip on that animation interval - and I never relinquished the memory. Multiply that by 100 chips and multiply it again by the number of animation steps during the game - it became a pretty big leak! So with one line, I patched that one... I wonder how many more I have missed.
What's left?
1) Menus - There is now a starting menu with the logo I showed off in the previous post. It also has a "Play" button and a button for instructions. Clicking the play button starts the game and the instructions button shows a page with rules of the game (a tap on the screen returns to the menu).
2) Pause - based on the same "sio2 widget" technology, there is now a pause feature. During the game, if you flip the ipad to face downwards (or accelerate it downwards at 2g) it will go into pause mode - the clock will stop, but there is a graphic covering up the game board. A single tap resumes.
3) Game over - when the player runs out of time, the selector disappears, all the doors open, and the chips start to fall towards the center. They make a tiny ball, which then explodes outwards. It is very satisfying in the OpenGL 3-d world! It reminds me of the original Tron and (spoiler!) what happens to the MCP at the end.
4) The game moves between the modes pretty fluidly, and you can restart the game.
Along the way, I was getting some distressing messages from the debugger. I use the "NSLog" command quite a bit, so I suspect these have been getting lost in the clutter - they were memory warnings. Somehow, I was running out of RAM space. Mostly, they were just level 1 errors, but I actually got a level 2 one tonight. This didn't seem likely, since my chips are of a finite number, and there just aren't that many polygons and variables in this game, compared to most 3d fare...
So I wondered if I had too many graphics loaded in memory at one time. I rewrote the menus and buttons (widgets) code so they loaded when needed and unloaded when they were done. It was a bit of a pain, and I worry a little bit about the speed at which they will load now. That didn't fix it.
I stumbled upon the answer when a memory warning showed up between two closely spaced NSLogs - in fact the only thing I did between them was move a Chip! It turns out that every time I moved one of the chips, I created a new 3d vector to represent the displacement of the Chip on that animation interval - and I never relinquished the memory. Multiply that by 100 chips and multiply it again by the number of animation steps during the game - it became a pretty big leak! So with one line, I patched that one... I wonder how many more I have missed.
What's left?
- Reworking the timing of the Ring chips
- Adding in the strange shaped selectors
- Redoing the sound at the end of the game to match up with the animation
- Possibly changing the single-click behavior to a double-click one.
- Auditing for memory leaks
- Figuring out how to get this thing into the store!
Dare I say I'm in the home stretch?
Sunday, July 4, 2010
Weirdness
Ok, so I have the logo from the last post (or something resembling that) show up in my program. And I have an sio2 "widget" with a graphic that says "play" set up to be a button. But now things get weird.
You see, you can't click on the button. But you can click on the button's reflection. The button appears 200 pixels from the bottom of the screen, but it only responds if you click on a point near 200 pixels from the top of the screen. Since I'm not the one who wrote the button code, I am a bit stymied. I can work around it by playing with the same touchscreen code that I used for the rest of the game, but I'd rather not. Alternatively, I could just center the button, but this isn't the only button I plan to use!
I've put in a request at the sio2 forum, and I hope to hear back on what to do about this....
You see, you can't click on the button. But you can click on the button's reflection. The button appears 200 pixels from the bottom of the screen, but it only responds if you click on a point near 200 pixels from the top of the screen. Since I'm not the one who wrote the button code, I am a bit stymied. I can work around it by playing with the same touchscreen code that I used for the rest of the game, but I'd rather not. Alternatively, I could just center the button, but this isn't the only button I plan to use!
I've put in a request at the sio2 forum, and I hope to hear back on what to do about this....
Thursday, July 1, 2010
Logo
I've been on a trip for business lately, so I haven't been able to do much for the last week. To sort of get myself back in the mood, I played around in LineForm to make a logo:
(Yes, there's a reason I don't do graphic design for a living....)
I will probably try to use this graphic in a title page for now, and then I'll see about updating it with something better later. I need to sleep on the graphic a bit.
Saturday, June 19, 2010
Memories...
A bit of a delay since my last post - I've been tilting windmills. (Actually, I've been hunting memory leaks, which are less satisfying.)
But first, I've been trying to make some fans (besides you, dear reader). The fans in question are 8 bladed, fan shaped objects that start off in front of the purple rings, so they are entirely visible. Then, as time goes by, they move backward, so that they gradually sink into the rings and out of sight. I'm not entirely happy with the look, but the idea of a secondary object that will partially obscure the main shape is one I'm pretty settled on. When the timer expires, both the ring and the fan should disappear, and they should be replaced by one of the original shapes.
The issue has been that although I could make the ring go away, and the new shape would appear, the fan didn't disappear. The code to make it do so was placed in the "deallocation" method, and it never was being called. And it wasn't being called because I was having an imbalance in my memory retain/release calls.
Memory management is one of the more annoying parts of the older, C - based language, of which Objective C is one. In Objective C, every time you create an object, add it to a list or tell another object about it, it keeps a count of how many objects know about it (a "retain count".) Whenever you remove an object from a list or another object stops keeping track of it, the retain count should decrease (it should be "released." ) If the retain count ever gets to zero, the computer knows it can safely stop keeping track of it. In my case, it never quite got to zero. And so I spent several evenings trying to hunt down what I had done wrong.
As it turns out, it wasn't the lists I was adding the rings to, nor was it the way I created the rings in the first place. Even the objects I was telling about the rings (the next and previous chips in the sequence) were handling the retain counts properly - I just wasn't ever telling them to let go. I made the new chip follow and lead the old one (which I didn't mean to do), but the preceding and following chips still held the same connections. Once fixed, the chips and rings started working tonight.
I'm still not happy with the fans, though. Because they are angled, the light hits some vanes better than others, so only half of them appear. And because they are almost as thick as the ring itself, there is a definite difference in apparent size of the fans between the leading edges and the rear edges - they show up around the outside and inside of the ring, when they should be exactly the same size - all because of perspective. In short, it looks ugly and distracting.
So, I am going to try tilting the fans to less than 45° to see whether that helps, and if not, we will go for a shrinking disk in the middle, a lá the timer.
But first, I've been trying to make some fans (besides you, dear reader). The fans in question are 8 bladed, fan shaped objects that start off in front of the purple rings, so they are entirely visible. Then, as time goes by, they move backward, so that they gradually sink into the rings and out of sight. I'm not entirely happy with the look, but the idea of a secondary object that will partially obscure the main shape is one I'm pretty settled on. When the timer expires, both the ring and the fan should disappear, and they should be replaced by one of the original shapes.
The issue has been that although I could make the ring go away, and the new shape would appear, the fan didn't disappear. The code to make it do so was placed in the "deallocation" method, and it never was being called. And it wasn't being called because I was having an imbalance in my memory retain/release calls.
Memory management is one of the more annoying parts of the older, C - based language, of which Objective C is one. In Objective C, every time you create an object, add it to a list or tell another object about it, it keeps a count of how many objects know about it (a "retain count".) Whenever you remove an object from a list or another object stops keeping track of it, the retain count should decrease (it should be "released." ) If the retain count ever gets to zero, the computer knows it can safely stop keeping track of it. In my case, it never quite got to zero. And so I spent several evenings trying to hunt down what I had done wrong.
As it turns out, it wasn't the lists I was adding the rings to, nor was it the way I created the rings in the first place. Even the objects I was telling about the rings (the next and previous chips in the sequence) were handling the retain counts properly - I just wasn't ever telling them to let go. I made the new chip follow and lead the old one (which I didn't mean to do), but the preceding and following chips still held the same connections. Once fixed, the chips and rings started working tonight.
I'm still not happy with the fans, though. Because they are angled, the light hits some vanes better than others, so only half of them appear. And because they are almost as thick as the ring itself, there is a definite difference in apparent size of the fans between the leading edges and the rear edges - they show up around the outside and inside of the ring, when they should be exactly the same size - all because of perspective. In short, it looks ugly and distracting.
So, I am going to try tilting the fans to less than 45° to see whether that helps, and if not, we will go for a shrinking disk in the middle, a lá the timer.
Saturday, June 12, 2010
"My God, It's Full of...."
I've added two new features to the Implosion game. First, stars. When the player clears a level he or she earns a star - the purple stars appear under the game grid, and the player may collect quite a few of them. If the player has a star, he or she may use a three-finger swipe to use it - doing so lets them advance to the next selector. This is quite handy if the player is having trouble matching the current shape.
I had a little bit of trouble getting the star to show up. I am getting better at blender - I was able to make the star pretty easily, and got the vertices colored nicely. But no matter what I did, I couldn't get it to show up in the game. Then I realized that I had created the star in a backup copy of the implosion folder - so it wasn't associated with the current version of the game! Doh! This "encouraged" me to learn how to copy objects from one blender file to another. (Here's the online resource I found.)
The second thing I did was add an "on-deck" selector shape to the screen. This lets the player anticipate what is coming next, and make a better decision about whether to use a star. It took a pretty short amount of time to get it working, so that was nice. (Of course, that means there's probably a bug it it that I haven't noticed yet....)
Next up: It's time for me to get the timed obstacle chips up and running. These pieces can't be selected - after a while they "pop" and replace themselves with a random chip of the original four flavors. This is what the original purple ring chips are for, but I want to have a way to indicate the progress of the chip towards popping. Again, I'd like for it to be something that makes sense from any angle, and although I could do a radial effect like the timer, I think I would like it to look different. My current thought is of a "fan-shaped" obscuring object that disappears over time. We shall see.
I had a little bit of trouble getting the star to show up. I am getting better at blender - I was able to make the star pretty easily, and got the vertices colored nicely. But no matter what I did, I couldn't get it to show up in the game. Then I realized that I had created the star in a backup copy of the implosion folder - so it wasn't associated with the current version of the game! Doh! This "encouraged" me to learn how to copy objects from one blender file to another. (Here's the online resource I found.)
The second thing I did was add an "on-deck" selector shape to the screen. This lets the player anticipate what is coming next, and make a better decision about whether to use a star. It took a pretty short amount of time to get it working, so that was nice. (Of course, that means there's probably a bug it it that I haven't noticed yet....)
Next up: It's time for me to get the timed obstacle chips up and running. These pieces can't be selected - after a while they "pop" and replace themselves with a random chip of the original four flavors. This is what the original purple ring chips are for, but I want to have a way to indicate the progress of the chip towards popping. Again, I'd like for it to be something that makes sense from any angle, and although I could do a radial effect like the timer, I think I would like it to look different. My current thought is of a "fan-shaped" obscuring object that disappears over time. We shall see.
Tuesday, June 8, 2010
Time keeps on ticking, ticking, ticking....
Ok! I've got a working timer now. Here's the video, and I'll post details after the jump.
Monday, June 7, 2010
Knowing one's boundaries and reading the writing on the wall...
Oh, boy! A video preview:
Saturday, June 5, 2010
Leveling up
Now that the doors are working (and they show up where they belong - I had forgotten to add the doors to objectsToDraw), it has been short work to make them open when the user removes the chips at the corresponding locations. Next, I have a "level up" mechanism working, so that when a certain number of doors opens, the level advances and the doors all close. (The catch is that there will need to be more doors opened to get to the next level...)
While I was at it, I added in some sounds. I've borrowed the sound effects from the original Flash version I wrote, so the game feels more visceral to me now.
Next up, I am splitting my time between creating a timer and putting some text on the screen. I am trying to come up with a timer that makes sense when viewed from any angle - it needs to be radially symmetric, but still convey both macroscopic and microscopic change. I've got an idea for this - I hope to post it soon. The text will be for such things as "level," "doors remaining," "score," and various hints at the start of the game. It should be pretty easy, so I may add it in before I start on the timer....
While I was at it, I added in some sounds. I've borrowed the sound effects from the original Flash version I wrote, so the game feels more visceral to me now.
Next up, I am splitting my time between creating a timer and putting some text on the screen. I am trying to come up with a timer that makes sense when viewed from any angle - it needs to be radially symmetric, but still convey both macroscopic and microscopic change. I've got an idea for this - I hope to post it soon. The text will be for such things as "level," "doors remaining," "score," and various hints at the start of the game. It should be pretty easy, so I may add it in before I start on the timer....
Thursday, June 3, 2010
One door closes and another one opens
Working on getting the doors to appear under the Chips. It's starting to become familiar territory now. I was able to make a squashed cube in record time, vertex painted it, exported it, and started work on importing it into the program. I've made a custom "Door" class, (updated it to be C++/ObjC), and made mechanisms for opening and closing the doors. Looks good so far, the only problem is that all the doors are showing up in the same place. - I must have missed a parameter somewhere, and it should be a quick fix, but I had to call it a night.
(I had to loan my iPad to somebody last night, too. Lonely!)
(I had to loan my iPad to somebody last night, too. Lonely!)
Monday, May 31, 2010
Progress
Oh, we're cookin' now! (Summer vacation rocks!)
I now have seven different "selectors" - each a different shape. (Think of Tetris and count...) They all show up great, are movable by the player, rotate, and take chips out. Every time you take out a chip, the old selector goes away and a new one is selected. It's working well. I think I may have even ironed out a bug that sometimes required you to wiggle the rotation of a selector to get it to register. I think it was parked at 360°, instead of 0°.
So what's next? In no particular order....
I now have seven different "selectors" - each a different shape. (Think of Tetris and count...) They all show up great, are movable by the player, rotate, and take chips out. Every time you take out a chip, the old selector goes away and a new one is selected. It's working well. I think I may have even ironed out a bug that sometimes required you to wiggle the rotation of a selector to get it to register. I think it was parked at 360°, instead of 0°.
So what's next? In no particular order....
- Sounds
- Scoring
- A timer - what's a little pressure?
- Messages - e.g., hints at first.
- Surprises as the game progresses (sleepers and selectors)
- Doors, so that the game does progress.
- Particle effects, for a little pizzaz.
- A display that rotates based on the orientation of the iPad.
- Icons, name and snazziness
- Pause/Start menu
- High Scores? Maybe with Facebook?
One more strange thing - each of the selectors has a different color, and they are all partially transparent. For reasons that I don't understand, when different selectors appear on the screen, it changes the brightness of what is being displayed. Very odd.
Thursday, May 27, 2010
Progress through Thursday...
It took a bit of a refresher to remember how to initialize multidimensional arrays in C++, but eventually I was able to make it work. I am building an array with the relative coordinates of each of the 4 blocks in the various shapes. So that's 2 coordinates x 4 blocks x ? types of selector shapes.
Once I had that down, I wrote a bit of code to handle the rotation of those coordinates, based on the angle of the selector, as the user has determined (with the two finger rotation method). From that, I was able to respond when the user taps the screen to see whether all four Chips under the selector are the same or all different. If so, the chips will drop away and the screen will fill in. So the game is basically playable! (Though not without its issues.)
Once I had that down, I wrote a bit of code to handle the rotation of those coordinates, based on the angle of the selector, as the user has determined (with the two finger rotation method). From that, I was able to respond when the user taps the screen to see whether all four Chips under the selector are the same or all different. If so, the chips will drop away and the screen will fill in. So the game is basically playable! (Though not without its issues.)
Wednesday, May 26, 2010
Belated posting on Implosion
Whoops! It's been a few days since my last post. I have made some progress.
A quick trip to Starbucks (and a few minutes before school on Monday) and I was able to make my 10x10 grid of Chips appear.
Its looks are deceptive. They actually are chains of Chips, as before, so that if you remove one on the inside, the Chips slide inwards to fill the hole.
I've also been able to write a bit of code to detect a single-click on the screen. Two things are relevant here: the time between the press and release, and the difference between a single click and a double click. Surprisingly, the single/double part is the easy bit - the variable sio2->_SIOwindow->n_tap tells you which it is (1 or 2, or 3, I suppose...). To tell how much time it took between press and release, I created a "clickCounter" variable in my GameManager class. Every render step, it adds the delta time to this variable, and when I press the first finger, I reset the variable. Then when I detect the last finger leaving the screen, I can detect whether a sufficiently short period of time has elapsed to call this a "click."
So, once I have detected a click, I can then remove the Chip at the origin of the Selector and the rest of the Chips fill in. Things are starting to look right...
Saturday, May 22, 2010
Translation and Rotation - third try's the trick
Graduation was yesterday, and I was on campus for most of the afternoon - so I had a chance to work on Implosion for a while, after the students left, but before the ceremony. It was nice having a block of time... when I wasn't exhausted!
I think I have the one-finger drag and two-finger rotate functions working properly to get the selector working properly. This is the third iteration - the first was based on some incorrect assumptions about how the events for the touch screen worked; the second was based on a very limited data structure - I was using variables like "startTouch1" and "startTouch2" - very specific for only one implementation. The third version is using arrays and is a bit more generic, so I can handle more than two fingers on the screen at once (if I ever want to), I've made the variables named consistently, and I've separated the event detection methods from the ones that actually do the work once I have detected the event.
So how does it work, you ask? (A glutton for punishment, Hmm?)
Here's the outline: First of all, I am maintaining an int variable numFingersOnScreen, to track how many fingers the user has on the screen. When the touch event comes into template.mm's templateScreenTap() function, there are three relevant variables:
So, based on _state, you either add or subtract "n_touch" to/from the numFingersOnScreen.
So far so good, right? I'm also keeping track of two arrays of vec2* variables. These will indicate where the the fingers were most recently (lastFingerLocs[]), and where they are this iteration (currentFingerLocs[]). (For touch/untouch events, these will be the same - when the user drags a finger they will have a useful difference.) Adding a finger is easy - just put the locations from the locs array at the next spot in the two "finger" arrays.
However, when you remove a finger, how do we know which finger was lifted? If I put my index finger and thumb on the screen, how can I tell if I then lift one finger which it is? My solution has been to search the "finger" lists and identify which finger was closest to the one that just lifted. I then remove that one from the list and slide the other fingers' locations towards the front of the list. (I'm only keeping track of five fingers, at most, so this isn't too time-intensive.) If I have two fingers lifted, I do this algorithm once for each finger lifted.
I'm trying to come up with situations when this won't work as well - if the fingers are right next to each other, perhaps? But I'm not sure it matters.
Then, if I just tapped or released, I delegate what should happen to another function, which can determine what to do with the information in currentFingerLocs. (Actually, I send it to one of several functions, based on numFingersOnScreen.)
Drag events are the next question. They come into template.mm in another function, but the information is stored in the same n_touch and locs variables - how many fingers moved, and where are they now? I use the same algorithm to identify which fingers on my currentFingerLocs list were moved, and I update their locations in that list (but not in lastFingerLocs, yet). Then I delegate the code to other functions (e.g., handleSingleMove() or handleDualMove()) to deal with what happens now. Finally, I update lastFingerLocs to match currentFingerLocs.
It works, and works well, I think. The next thing I need to do is to check that I am not having memory leaks. I am creating a lot of vec2* and vec3* variables - I need to make sure that I am releasing them again. (I think so, by looking at the code, but I need to check.) The Apple Developer Tools have a program called "Instruments" that should help with this - but I need to learn the program!
I think I have the one-finger drag and two-finger rotate functions working properly to get the selector working properly. This is the third iteration - the first was based on some incorrect assumptions about how the events for the touch screen worked; the second was based on a very limited data structure - I was using variables like "startTouch1" and "startTouch2" - very specific for only one implementation. The third version is using arrays and is a bit more generic, so I can handle more than two fingers on the screen at once (if I ever want to), I've made the variables named consistently, and I've separated the event detection methods from the ones that actually do the work once I have detected the event.
So how does it work, you ask? (A glutton for punishment, Hmm?)
Here's the outline: First of all, I am maintaining an int variable numFingersOnScreen, to track how many fingers the user has on the screen. When the touch event comes into template.mm's templateScreenTap() function, there are three relevant variables:
| sio2->_SIO2window->n_touch | Indicates how many fingers have had their touch status changed |
| _state (a parameter) | Indicates whether the fingers were added or removed. |
| sio2->_SIO2window->locs | An array of where the fingers were that had changed. |
So far so good, right? I'm also keeping track of two arrays of vec2* variables. These will indicate where the the fingers were most recently (lastFingerLocs[]), and where they are this iteration (currentFingerLocs[]). (For touch/untouch events, these will be the same - when the user drags a finger they will have a useful difference.) Adding a finger is easy - just put the locations from the locs array at the next spot in the two "finger" arrays.
However, when you remove a finger, how do we know which finger was lifted? If I put my index finger and thumb on the screen, how can I tell if I then lift one finger which it is? My solution has been to search the "finger" lists and identify which finger was closest to the one that just lifted. I then remove that one from the list and slide the other fingers' locations towards the front of the list. (I'm only keeping track of five fingers, at most, so this isn't too time-intensive.) If I have two fingers lifted, I do this algorithm once for each finger lifted.
I'm trying to come up with situations when this won't work as well - if the fingers are right next to each other, perhaps? But I'm not sure it matters.
Then, if I just tapped or released, I delegate what should happen to another function, which can determine what to do with the information in currentFingerLocs. (Actually, I send it to one of several functions, based on numFingersOnScreen.)
Drag events are the next question. They come into template.mm in another function, but the information is stored in the same n_touch and locs variables - how many fingers moved, and where are they now? I use the same algorithm to identify which fingers on my currentFingerLocs list were moved, and I update their locations in that list (but not in lastFingerLocs, yet). Then I delegate the code to other functions (e.g., handleSingleMove() or handleDualMove()) to deal with what happens now. Finally, I update lastFingerLocs to match currentFingerLocs.
It works, and works well, I think. The next thing I need to do is to check that I am not having memory leaks. I am creating a lot of vec2* and vec3* variables - I need to make sure that I am releasing them again. (I think so, by looking at the code, but I need to check.) The Apple Developer Tools have a program called "Instruments" that should help with this - but I need to learn the program!
Sunday, May 16, 2010
Rotations - success and frustration
re: implosion multitouch...
I had some success last night writing code to rotate the Selector with two-finger rotations. By playing around with the sio2->_SIO2window->n_touch variable in "templateScreenTap()", I could sense multitouch events. I used an algorithm to compare the angle between the two touches and compare it to the angle between the previous two touches to find a delta rotation and rotate the object by that much. If there were two fingers on the screen, things would rotate. If only one was on the screen, it would twist. After a bit of futzing around, it worked great.
At least in the simulator. (Using the option key to simulate multi-touch)
I figured it was about time to try this in the actual iPad, and I realize now that it is more complicated. Even as I tried to rotate the Selector, it would also move about - sometimes skipping between one location and the other. I think that this is a response to the iPads' sensors being a bit more "messy" than the simulator would have us believe! Specifically, I wonder if I am getting some flicker - when I have two fingers on the screen, perhaps the iPad is occasionally only detecting one.
I've also done a bit of exploring and found that the "templateScreenTap()" and "templateScreenMove()" methods in the template.mm file are just relaying the message from the EAGLView.mm file, and that gives me more information about how that works. The "_state" variable in templateScreenTap, for instance, indicates whether the "tap" was a touch or release event, and it seems to me that n_touch is indicating how many fingers changed touch/release state, not how many are remaining on the screen. Likewise, in the templateScreenMove(), the touches it receives are indicating only the ones that have moved, not a comprehensive list of touch points - and the n_touch variable corresponds to how many have moved, not how many there are.
This changes my understanding considerably. Even as I wrote this last paragraph, I realize that my assumption that "flicker" was happening (in the previous paragraph) is likely wrong - I was just moving one finger and that caused the problem.
This will require a rethink about how I implement rotation.... For one thing, at the moment, I have been splitting responsibility for managing these touches between template.mm and GameManager - I need to reconsider that split.
Thursday, May 13, 2010
Moving ahead, or at least "around"
Some good progress tonight on Implosion.
I have made a "Selector" class which will host the Tetris-like shape. It is based on the VisualObject class, and consequently has very little code of its own. I was able to link it to the shape in sio2, so I can clone the shape and it renders.
Next I played around a little with the event handlers in the template.mm file that comes with sio2. After not too much trouble, I was able to get the chip to move around, following the "finger." It doesn't matter whether the finger touches the chip - it still tracks it. (Moving right with the finger by 1 cm moves the selector to the right by 1 cm.) So that's pretty cool.
I've also pulled the camera back about 40%, so everything is a little smaller. This will let me fit a 10x10 grid of chips on the screen.
Coming up next:
I have made a "Selector" class which will host the Tetris-like shape. It is based on the VisualObject class, and consequently has very little code of its own. I was able to link it to the shape in sio2, so I can clone the shape and it renders.
Next I played around a little with the event handlers in the template.mm file that comes with sio2. After not too much trouble, I was able to get the chip to move around, following the "finger." It doesn't matter whether the finger touches the chip - it still tracks it. (Moving right with the finger by 1 cm moves the selector to the right by 1 cm.) So that's pretty cool.
I've also pulled the camera back about 40%, so everything is a little smaller. This will let me fit a 10x10 grid of chips on the screen.
Coming up next:
- Two-finger twisting of the selector. I suspect that this will be more of a challenge. I'm trying to decide between an algorithm comparing the angle of the line between the fingers at the start and at the drag, or one that uses the cross product of the line between the fingers and the relative motion of the second finger. (Although the second option sounds cool and math-y, I think the first will work better.)
- Create the grid of 10 x10 squares. Likely to be tougher than it sounds - I don't just want to make a grid of chips like I did earlier - I need to make outward-pointing chains of chips that nest together effectively.
- Make the selector "snap" to the grid orientation and position. Preferably, this should be animated...
- Start recognizing where the four squares of the selector are, and which Chips they represent. This means that I will have to search a list of 100 Chips. I wonder if it will be worth keeping the list sorted somehow?
- Deciding (and implementing) what the user interface should be when I wish to "select" a group of Chips. Should it be a quick shake (+/- z-axis) of the iPad? A quick tap on the screen? Both?
Fun, fun, fun!
Wednesday, May 12, 2010
Refactoring
The problem with quick prototyping is that while it is great for making sure that the core functionality works, it leads to sloppy coding. So, while was able to get my Implosion chips to show up on the
screen and link together as a sequence, I was breaking a few design rules as I did so.
So last night, I did some refactoring - I realized that much of what I had written for the Chip class was stuff that I would like to generalize. I need to be able to keep track of a 3d object's location and orientation, as well as it's reference in the sio2 resource list.
The second benefit to pulling the graphics object out of the Chip class is that it makes Chip less dependent on SIO2. If I should someday decide to go to a different rendering engine, it will be
easier to make the change.
The new class is called VisualObject, and Chip now inherits from it. I plan to extend VO for several other classes, too.
Oh, and I'm working on documenting my code a bit, too.
screen and link together as a sequence, I was breaking a few design rules as I did so.
So last night, I did some refactoring - I realized that much of what I had written for the Chip class was stuff that I would like to generalize. I need to be able to keep track of a 3d object's location and orientation, as well as it's reference in the sio2 resource list.
The second benefit to pulling the graphics object out of the Chip class is that it makes Chip less dependent on SIO2. If I should someday decide to go to a different rendering engine, it will be
easier to make the change.
The new class is called VisualObject, and Chip now inherits from it. I plan to extend VO for several other classes, too.
Oh, and I'm working on documenting my code a bit, too.
Thursday, May 6, 2010
starting with the four-squares
I need to find a way to make a shape that selects four of these chips. The shape is like a Tetris piece. Since this only glides around, it can be a 2-D piece. I could simply make a solid shape, but I have two problems with that - first, that it affects the visibility of at least one of the five chips I have already made, and second, that I am having trouble adjusting the opacity, so I can't see the chips fall behind it. (Or the status of the squares it covers, which will also be important.)
The other option is an outline of the shape - I am playing with either a very sharp-cornered shape, like the one at right, or a more rounded one, like the one at left.
The other option is an outline of the shape - I am playing with either a very sharp-cornered shape, like the one at right, or a more rounded one, like the one at left.
In either case, I think they hug the green box a bit much, but I rather thought that shape was a little large, anyway. I'm not really thrilled with either option, so far.
In any case, I am learning more about blender as I experiment with the program. Now if I could just remember how I was able to create a mesh by clicking where I wanted points, rather than adjusting an existing shape....
Subscribe to:
Posts (Atom)



