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.
Showing posts with label sio2. Show all posts
Showing posts with label sio2. Show all posts

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?

  • 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....

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....

  • 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.)

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:
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!


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:

  • 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.

Saturday, May 8, 2010

It's always the little things....

As you may know, I am trying to teach myself two things at once for this iPhone App I am working on - blender, and the SIO2 code library that lets me put blender objects on the iPhone screen. (Actually, I'm aiming for the iPad.)

I've been wanting to make my 4-square selector shapes be translucent - that is, I'd like for them to have an Alpha level of about 50% or so. They will mostly appear behind the Chips, but when a chip drops, I'd like it to be seen, and there may be some artwork behind the chips that is important, also.

I watched the SIO2 tutorial #4 several times, and I even found a correction to the tutorial online since the tutorial hasn't kept up with a few updates. But even though I was doing what the tutorial said, I couldn't get objects to show up with any kind of transparency. I'd create an object that was opaque, and it would show up fine. I'd switch the color blending mode in blender to "Value" or (the new version) "Color," and it would disappear when I tried to view it in the iPhone simulator. What gives?

I was just about to start complaining that the Tutorial didn't work, the support forums weren't very helpful and the only book on SIO2 wasn't much help, when I realized that I hadn't actually looked in the book for this... sure enough, a quick peek in the index led me to a page that indicated the problem wasn't in Blender - it was a one line change I needed to make in my code in XCode. I was only rendering solid objects - I needed to tell it to render the solid objects and the objects with alpha transparency. I needed to change:

sio2ResourceRender( sio2->_SIO2resource, sio2->_SIO2window, 
                        sio2->_SIO2camera,
                        SIO2_RENDER_SOLID_OBJECT |
                        SIO2_RENDER_LAMP);

to

sio2ResourceRender( sio2->_SIO2resource, sio2->_SIO2window, 
                        sio2->_SIO2camera,
                        SIO2_RENDER_SOLID_OBJECT |
                        SIO2_RENDER_ALPHA_TESTED_OBJECT |
  SIO2_RENDER_TRANSPARENT_OBJECT|
    SIO2_RENDER_LAMP);

and everything instantly started working. Sigh.

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.
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....

Tuesday, April 27, 2010

The grid

I wanted to share a picture - a 7 x 7 grid of "Chips" - a random selection of four types, rendered on the iPhone simulator with OpenGL, via SIO2.
Now we're cookin! The game will involve removing some of these pieces and allowing the remaining ones to fall in.

Ah, the memories...

Boy, my C is rusty.

Last night, I was working on the Implosion project with SIO2. I am still fighting with the C++/Objective C interaction. My problem last night was that in my Objective-C class, I had an array of NSString objects. I needed to select one of these strings and send it to a method in SIO2 that was expecting a C-style "char *" variable.

It wasn't hard to find a method in NSString called "UTF8String" that does a conversion - but it converts the NSString to a "const char *" string, instead of a "char *" string. And this is where I got bogged down. This is all C/C++ code, and I haven't done that in a few years. The const keyword meant that the string can't be modified, and although there were some sites on the web that suggested that I cast it as a non-const variable, I really don't want to modify the original string in the NSString variable - I will need it again!

Eventually, the magic typing monkeys in my computer that make up the Internet gave me a series of websites that brought me closer and closer to the answer. I ended up at a site that gave me the final piece. Here is what I wound up doing:

    const char* tmp = [typeString UTF8String];
    char* typeCString = new char[strlen(tmp)+1];
    strcpy(typeCString,tmp);

... and that worked just fine. With this, I can make multiple shapes in a 7x7 grid. I have two new short-term goals:
  1. In blender, I need to reduce the size of the shapes (again) - they are still too big and overlap each other. (I also need to make sure that the triangles are centered on their own local origin.)
  2. I need to find a way that I can make the chips "fall" in when a chip is removed.

Monday, April 26, 2010

A Row of Rings

I think I'm starting to get the hang of this objective-c vs. c++ stuff. I was able to create a obj-c class that can keep an NSMutableSet of objects - I was able to clone a row of purple rings. Progress!

Sunday, April 25, 2010

Cross-language issues in SIO2

There are some interesting issues trying to combine the SIO2 library with an objective-c core. Most of the SIO2 library is written in C++; using XCode, however, I am more familiar with Objective-C. My plan has been to write my main program in Objective-C and just use the SIO2 library for rendering. The two programming languages are cousins, and I knew that in theory, XCode and its gcc compiler could handle both. It certainly did a fine job of handling them separately....

Well, I was right, it can, but getting the computer to do so was more of a challenge than I expected. There is a trick - there is a setting associated with each source code file that says what language it speaks. When I wrote a file that spoke both C++ and Obj-C, I needed to specifically tell the compiler that it was a multi-lingual program - and I didn't know how to do that (or even that I needed to). Now that I've got that settled, though, things are working much better. In my Obj-C file, I can move an object to any location I want.

I find that if I move it away from the camera, it gets a lot dimmer, however. I think this is a trick of the lights in blender - perhaps if I create a "sun" light, it will work better. That's what I am going to try next. Also, I could stand to shrink the original objects a bit!

So I'm making progress, but it is largely behind-the-scenes stuff - not much to look at. But still, it is pretty important. Hopefully, I'll have cool stuff to show soon.

Thursday, April 22, 2010

Graphics on the iPad (simulator)

Hooray! I've got a screenshot here of the various shapes showing up on the iPad Simulator:
Yeah, they're a little dim right now, but they should do the job nicely. I'm going to clone them and fill a grid with these guys!

The next thing I need to do is to really get my mind around how to use these objects as object-oriented graphics. All of these graphics live in a common "_SIO2resource" variable - sort of a set of 3D objects to draw. That's where the shapes live. They have "transformations" associated with each one - they determine the location, size and orientation of the object, but that information lives with the graphics in the _SIO2resource. But I want to be able to have individual objects - instances of custom classes - that have variables and methods beyond those involving their graphical layout. How to reconcile these two schema?

I think that what I will do when I create a new piece is to first duplicate the graphic from the master graphic, which both installs the graphic in _SIO2resource and gives me a variable that I can use to directly refer to the graphic. I'll initialize an instance of a corresponding class and pass the graphic along in the constructor (or a modifier method). That way, both the _SIO2resource and the graphic can both access the transformations for the graphic - the instance object can modify them, and on the next graphical update, the _SIOresource will read the transformations and use them to position, resize and orient the graphics. It'll be great. (If it works.)

Shapes and pads

File under: sio2 and implosion
Just some thoughts about what I've been working on the last few evenings. (I have been advised not to work on my private project during school hours, and I intend to honor that.) I've managed to accomplish two things:
  1. I think I have created a working SIO2 project template that works on the iPad. That's important, because my implosion game is a bit too detailed for the iPod/iPhone screen, IMHO. I took the template provided by the folks at SIO2 and converted the .xcode project and the .xib file to iPad versions.
  2. I've gotten more practice with blender and have created a set of five shapes: a ring, a box, a triangle, a cross, and an X. Ok. The X is just the cross, rotated. They all look good in blender, but for some reason, my app seems to be pulling from an earlier version of object data, so my changes aren't showing up. I suspect that the file it is pulling from is not the one I think it is! A project for this evening, no doubt.

Sunday, April 18, 2010

Aha!

Ok, I found it. (How to dynamically clone objects in SIO2...) I'll post it here, in case I need it again. (Dear reader, don't worry about these details... just know that it works.)
In the code for SIO2's Tutorial061, in template.mm, lines 310-328 show how to do it. Specifically, provided that _SIO2Parent is not a pseudo instance, (I.e., it doesn't end with ".001"), then you can say

_SIO2Duplicate = sio2ObjectSoftCopy (_SIO2Parent, name)

...where "name" is the new name of the object, and "_SIO2Duplicate" is the variable that receives the object.

Cool. This might be doable after all.

Sio2 revelations

The more I see of SIO2, the more I understand what all the fuss is about. You really can set up a lot of aspects in blender not just the appearance, but the mass, solidity, friction, coefficient of restitution, etc. The tutorial I just watched showed the trainer creating things in blender floating in the air. He exported the file and moved to Xcode. Immediately, the objects fell down and bounced around on the contoured surface he had created. Very cool.

Still, I have to wonder whether I can clone the objects I create in Blender on the fly or not. If so, I haven't seen how to do it yet. If not, I suppose I could create all the objects i could possible need at one time and keep them off screen (behind the camera). But that would be a pain, and I wonder whether all those extraneous objects would slow the system down.
I will keep playing around with it.....