Welcome to my Programming Blog...

I am currently working on a couple of projects: An original game called "Implosion" which I am porting from Flash to the iPad, and a remake of Q*bert in Python (pygame), as part of the class I am teaching. Please feel free to use the "Labels" (at right) to follow a specific project or theme. If you are one of my Python students, I recommend that you check out the Python thread.

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:
sio2->_SIO2window->n_touchIndicates how many fingers have had their touch status changed
_state (a parameter)Indicates whether the fingers were added or removed.
sio2->_SIO2window->locsAn array of where the fingers were that had changed.
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!


No comments:

Post a Comment