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.

Monday, December 20, 2010

Texture atlases in cocos2d

I was just learning about texture atlases in cocos2d in Steffen Ittenheim's (sp?) book. They look very handy, and I can see the advances in memory, code and time efficiency. The question, though, is how to convey this to students who are new to programming? Is it worth worrying about? Do I show them the inefficient way first (as Steffen does), and then show the improved way, or do I just go straight to the "good stuff"? (presuming that a texture atlas is always the better way....) A texture atlas doesn't make as much intuitive sense as a one-file-per-sprite method.

I think that it Is a similar question to actions vs manual animations. What to teach in a limited time?

So, dear reader, what do you think?


- Posted using BlogPress from my iPad

Sunday, November 28, 2010

Trying out new cocos2d book

I am giving Steffen Itterheim's new book "Learn iPhone and iPad cocos2d Game Development" a try. I can't find it in hardcover, so I bought a digital copy.

I am considering it for teaching a three week course on iOS game programming to HS students - right now, it appears to be the only book on the subject out there. (I am looking forward to Rod Strougo's book, but it isn't due until March.)

So far, the books seems like an authoritative resource, but it starts off a bit slow - there are three chapters of background information before we start writing our first real program in Chapter 4. But that program is a good one, and it might be the place to start - with the understanding that we need to take some things at face value and expect explanations later.

There is an interesting point I've found in this chapter of Itterheim - on page 76, he explains why you shouldn't use actions to move a player's sprite if you are going to be making frame-by-frame adjustments: they won't work. By the time the computer is ready to animate the first step in the action, you are telling to quit that action and start another one. So nothing happens. This makes a lot of sense. However, as a teacher, I wonder: why teach actions first then?

Still, it's a good resource so far. I don't know whether we can get hardcopies in time for the class, which starts Jan. 3, but maybe we can get by with the electronic version.

Uploaded (October 1)

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

Tuesday, November 2, 2010

Starting cocos2d

I had a terrific time at the #VTM_iPhone (Voices That Matter) conference in October - one of the best things I got from it (besides great contacts) was a chance to see cocos2d in action. I'd heard of cocos2d, of course, but I hadn't connected with it yet. It looks like exactly what I need.

For what, you ask? Well, I have two needs: 1) I want to write my next game, and I'd like to work in the 2d world this time, instead of fighting with OpenGL. And 2) I've got a 13-day class on writing iPhone games (two 70 minute periods a day) that I am teaching in January. To programming neophytes, and a couple of experienced kids. Actually, I am co-teaching it with one of my older students.

So I need something with a quick entry point and lots of flexibility. Cocos2d looks to be just that. We can get stuff up on the screen and moving on the first day, and perhaps interacting by that afternoon! And with hooks for animations, sprite sheets and tile maps, we can focus on ideas of game design, rather than some of the mechanics of writing all that code.

The one weak point, as I see it, at the moment is documentation. There's some, and it's growing, but at the moment, it is still a bit lean.
Here are some resources I've found:

  • The official Programming Guide at Cocos2d-iphone.org.
  • Ray Wenderlich's excellent blog, which includes some good cocos2d resources.
  • Here are two books:
  • This book by Steffen Itterheim, which has scary fruit on the front, looks promising - it comes out in a month.
  • This book by Rod Strougo, the presenter at VTM, also looks terrific. Sadly, it does not come out until March, which is a couple of months after my class ends.

Still, I'm looking forward to trying Cocos2d and will share what I learn here.


- Posted using BlogPress from my iPad

Sunday, October 17, 2010

#VTM_iPhone notes on moving to 3d

Here are my notes on Michael Daley's presentation on moving to 3D.

A subject that scares the heck out of everybody.

Can do an awful lot without being a genius.

Http://71squared.com
Book: "learning ios game programming"

http://Particledesigner.71squared.com

Sample code is not optimized, for clarity, but still gets good performance.
Prototype project http://tiny url.com/28jp4pm

A turret game - play around with it!

One of first things you need to do to the opengl template is to ad a depth buffer. Added to createframebuffer method. (remove it in delete frame buffer method, too.)

Next must setup the perspective projection to td3dviewcontroller.mm in initOpenGLES1. Then set up the model view matrix. Setup light, fog, etc. In same method.

The math - don't need to be a math or physics genius. But you do need to have some basics, vectors, points, dot produce, cross product, normal. But the work has been done and coded in classes: SSvectorUtil.h,SSMatrixUtil.h
(found in matrix & vector folder in project, if you're curious.)

--------
State management in OpenGL

It will set a state even if the new value is the same as the old. Perhaps encapsulate the OpenGL state machine, which is what Michael has done with OGLState class.
--------
Creating 3d models

Blender. (free)
Jeff lamarche's blog has a great exporter for blender.

Blender can unwrap the shape (to a UV image) or can let you paint the vertices. Export to a png image. Then export the vertices and normals.

Each model's geometry, normal &texture data is loaded into static Vertex buffer objects.
Each model's text is created as an instance of Texture2D

Reuse models and textures where you can.

Michael has created an AssetManager class that keeps track of all these reusable assets.

(A Mipmap contains several images of the same thing that are prescaled down.)

Collisiiion detection - hard to do fast in 3d. But it has been solved. See bullet3d physics engine. (free) put out by a guy at Sony.

When we create an object, we set up it's physics object. In missile.mm class, for instance, initPhysics() method sets up the model for its physics.

Then in the viewcontroller run its initphysics() method. Also sets up a mo course collision detection shape for things - only checks the "tight" collision mesh if the course one has a collision.

Then in the view controller's game loop (update with delta) calculate the physics. Make sure that the physics update is not directly synched to the screen refresh rate.

------
Setting up the camera

To draw objects, you really are moving the world around to center the objects location and drawing it "here" then moving the world to the next object. Then you move the world to center on where the camera is and set it "here."

Ship class - found Internet code on "autonomous steering."

--------
Moving around

When set up game, set up core motion - reads the gyro 1/60 sec. Then in drawFrame method, get the attitude from the gyro and then applying that matrix to the model view.

Q&A: memory management : recommends caching the model. There is no hard/fast rule. Just kept a pool of allocated objects ahead of time and reused over and over again.

- Posted using BlogPress from my iPad

#VTM_iPhone notes on using cocos2d for game development

Here are my notes on the "Using Cocos2D for Game Development" presentation by Rod Stougo

He has a book coming out soon.

Cocs2dbook.com

Free!

OpenGL es rendering and performance without having to learn OpenGL es to get started.

(you get access to full source code)

Www.cocos2d-iPhone.org/download

Recommends the unstable version


Sudo ./install-templates
This puts templates into Xcode. Box2d is physics engine, so is chipmunk.

Comes with two sample programs, for Mac games and ios games.

Lots of samples. Make sure you select both active target and active executable.

Uses a movie metaphor - scenes, director, layers. (ok, the actors are called sprites.)

Z-layers are compositing order, and there are z-values for the objects within the layers.

Layers can subscribe to touch and accelerometer events

Actions are an easy way to apply transitions, effects and animations to the sprites

Moveto, move by,scale by, scale to, fadein, fadeout, rotate,....
Ccsequence combines actions sequentially, ccspawn combines actions simultaneously

Change gears: Optimization
Starting to get complicated sending info if you send images one at a time - make a sprite sheet. Aka a "texture atlas" zwoptex online sprite sheet creator.

Physics engines box2d and chipmunk(newer) pretty similar. Box is c++, chipmunk is c. Wrapped in objc. If you use c++ code, implementation files must have .mm suffix for complier.

Cocsdenshion sound engine- wrapper for Avaudiiplayer and openAL

Simple, synchronous and asynchronous, background and sound effects

Particle systems!

Cocos2dbook.com

Physics world with a graphics world on top. Calculates where the objects are and then moves the graphics on where they should go. The sprite doesn't have any physics logic.

Event handlers: cctouchesbegan

To make the snowballs, find where the touches start and end and find the delta. Create physics object, and create force or impulse. Add a small rotation

Collisions have masks to indicate which things have detectable collisions.

Can animate the appearance of sprites easily




- Posted using BlogPress from my iPad

#VTM_iPhone notes on game center talk

My notes on the game center talk by Jessica Kahn.

Social gaming functionality, provided by apple

- authentication
-leader boards
Achievements
Friendsinvitations and matchmaking
P2p networking
And one other.

Ios 4.1+

Game center is just catching on.
Why bother? Lots of competition, but game center is a free way to raise visibility. Also, game center advertises what your friends are playing, even if you don't own them. Friends can invite you to games you don't own.

Competing solutions: Plus+, OpenFeint, ScoreLoop, Crystal, and 3rd party

Tapulous network (jessica's company) has some things that apple doesn't, some things it does, but lacks some that apple does.

Bundle identifier, game kit linkage, view controller-based user interface, Ability to code with blocks

BundleID (eg. Com.tapulous.gamecenterdemo)

Best to do a weak link, checking for game kit and ios4.1 or later on user's phone

Leaderboards, achievements, and matchmaking all use view controller subclases for their UI.

GameKit often takes blocks as parameters.

The Basics:

Authentication, leader boards, achievements
Auth... Do it as soon as your app can display ui. One line of code, with a block as error handler, triggers a welcome back overlay at top of screen.
With multitasking, might log out while you are in background. Be observer for GKPlayerAuthenticationDidChange

-----> supporting authentication is enough to get the exposure benefits of game center!

Leaderboards
Configure in iTunes connect
Report using GKscore
Display using GKLeaderboardViewController
Or
get the data from the game sever and display, yourself

Reporting - if it fails, stash the data locally, and try again soon. Don't need to tell user, according to apple interface design.

Leaderboards show up in game center, even if you don't display them in your app.

Achievements are just like leaderboards.
--------
Bonus points

(I had to step out, so much of this is omitted)
Matchmaking - came back in the middle. Looks a bit complicated. But then, romance usually is.

Suggested: doing a lot at boot time - but watch out about interfering with user experience.

Peer-to-peer networking
High-level interface.
Start by making the match (see above)
Decide which data to transmit - as little and as rarely as you can.
You can transfer data reliably or unreliably. Send data to all players or to one specific user.
Data must be "byte (sic) sized" (sic)
Read up on two GKMatch methods
SendDataToAllPlayers...

Voice chat
Use GKVoiceChat & GKMatch
First create and make active a playAndRecord AVAudioSession
Then create one or more voice channels using voiceChatWithName
Start and stop ability to talk with methods on GKVoiceChat.

-------
Gotchas

Fragmentation, due to unsupported os versions.
Complexity, if game is OpenGL based
Beware flaky networks!
Prevent cheaters, you can't reset a leaderboard.
- if you are storing scores, save it in a way so that people can't read it.
Invitation handlers can happen at inopportune times.
Network activity can hamper in-game fps and audio performance.

Great questions, but I was distracted by q/a and did not write them down. Some on age-appropriateness, some on testing, some on handling the modality of authentication requests.

She's vp of engineering Disney mobile and is "hiring like crazy"


- Posted using BlogPress from my iPad

Ow... Sore brain. #VTM_iPhone

So here it is, the morning of the second day of the "Voices that Matter" iPhone conference. (way better than the "Irrelevant Noise" convention.)

My brain is sore. It was a very long - but inspiring - day yesterday, and we just heard a great keynote from a guy dressed as a pirate talking about not sucking. I'm looking forward to a series of great talks about stuff I'm really interested - and I hope that I'll be able to absorb it all. I need time to reflect, to tinker, to play, but I also want to be ready for the next great talk, to cleanse the palette, so to speak.

Oops. The next talk is starting!

- Posted using BlogPress from my iPad

Saturday, October 16, 2010

#VTM_iPhone notes on STAssertTrue

Here are my notes on Graham Lee' unit testing presentation. Note: coming into this, I have heard of unit testing and have a general idea of what it means, but I have never seen it done. I presume it means to do an automated process of running a method with different data sets and checking that the answer is what you wanted each time. Probably, it includes boundary cases, but I don't know.

Software engineering goals: make money (sometimes)... By making something that the user wants. - meets their requirements, without being too expensive.

Testing isn't about finding bugs - it's about validating that your code does what it should., finding bugs is a secondary effect.

The earlier a bug is introduced, the more it costs if you find it late. Unit testing helps with the design and build aspects reducing errors.

Undirected unit testing - checking the minutiae of the program, the opposite side from external testing by somebody who doesn't know the program I.e., the user.

test driven development:
*black-box thinking for the developer.
*YAGNI you ain't gonna need it. Only write the code you need.
*Avoid regression bugs. Keep the tests around, so later code doesn't break earlier code without your knowledge.
*assists accurate planning

Find bugs before....
...your customers do.
Zune didn't know about leap year. Ah, they're incredibly rare.
TDD != [bullet silverColor]
you can't assume the developer understood the problem...or that the requirements didn't change, and it doesn't guarantee successful integration
Takes time to write tests, and you actually run them.

How TDD works: RED - GREEN - REFACTOR
What do I test? Anything within reason - time, environmental conditions (ie DBs, filesystem, network - not repeatable)
Evaluate risk - known buggy code, heavily used code, tricky problems
When do I test? At any change, plus before release.


Testable code: short classes with short methods, each with obvious effects, few & predictable side effects, with helper data passed in - not discovered, low "cyclomatic complexity" - don't need to test thousands of combinations.

This means the end of a @interface GodView:UIViewController


OCUnit and XCode3 or XCode4
GHUnit ... Better than OCUnit? (Does it run on the iPod, itself?-HH)
plug of kaleidoscope app?

Fakes and mocks? Fake is dummy input data, and mock is dummy local data, I think.... - HH

Recommends "refactoring: improving the design of existing code", "test-driven development"(Kent beck), "test-driven development: a practical guide", "xUnit test Patterns", et al

Iamleeg at the usual sites, twitter, etc.


Note: I know more than I did, but I still don't know enough that I am ready to go out and start unit testing. A lot of theory here, but I probably needed a more practical demonstration.

- Posted using BlogPress from my iPad

#VTM_iPhone notes on multitasking presentation

Here are my notes on jeff lamarche's presentation, "multitasking the iPhone sdk way"


One of the biggest complaints from developers about early ios.

Actually, it had multitasking from day one - lots of first party apps running once.

Of course, apple just does this to be mean.

Real reason - battery impact and foreground application responsiveness

The audience at this convention - we're the outliers. Most people see computers as an obstacle.

"Devices for the rest of us."

Myth: with ios 4, we have "true multitasking." but don't use it for its own sake if you don't really need them. Will a push notification work?

Basically, you can maintain state, and can't do much (if any) processing in background.

Legacy apps can be set to opt out of multitasking. In info.plist.

Four types of background tasks - background audio, voip, navigation & location tracking, task completion

Playing nicely: application lifecycle
Before 4.0: not running, inactive, active
application delegate fires when state changes
Active --> inactive: applicationWillResignActive
Active ->not running: applicationWillTerminate
At 4.0:
States
foreground: active, inactive
Background: suspended, active
Not running

If you want to keep running in background, keep your (over)head low.

ApplicationDidEnterBackground
ApplicationWillEnterForeground

Problem: if you are in background, will not get notification if the program is killed. Issues for persistence.
--------
Background
Should not run code that does drawing or leverages the gnu
Should close any network listeners
Stop advertising or looking for bonjour services
But make sure you resume when you return tho the foreground

Generally, should dismiss alerts, action sheets.
If multiple buttons, pick the non-destructive option.

Background - hide sensitive info in UI

Shouldn't access shared data APIs - calendar, address book, music/media library

Hint: instruments works fine with background applications - in fact, a very good idea.

You can still set base SDK to 4.x and still target 3.0. Delegate methods just don't get called.

Don't check hardware or OS version!

Task completion API - general purpose. Can request to keep running - to finish a process. Must finish in given time limit, or will be killed. You do have a chance to clean up and save.

How long? Not documented. Simulator gives 5 minutes. You don't have to wait for app event to request time.

See handout for sample code.

Uses blocks.... Get over it, and they are coming. Suddenly, they will click.

Nb: if it's long enough to require task completion, it needs to be off the main thread.

Background audio

It's opt-in. Must identify that you use them in your info.plist file

Your background app will override foreground audio!
Background apps using radios can drain battery. Be sure to close down the connection.
The background audio can also record sound!
Must implement avaudiosessiondelegate - should implement begin interruption and end interruptooonwithflags

In, must override canBecomeFirstResponder to return YES.

Apple has put a lot of thought about this. Balance between developers and users.

If you can't find a way around this: bugreport.apple.com

Stop drawing? Mostly automatic. You do (seem) to get some time after the notification arrives that the app will go inactive

Jeff_lamarche@Mac.com

- Posted using BlogPress from my iPad

#VTM_iPhone notes on around the block with blocks talk

Here are my notes on Bob Clair's "around the block with blocks" talk

I feel kind of foolish about this - I hadn't heard about blocks until today, so I'm glad I'm here for this presentation.

He says there are some typos in original presentation posted , but new one is forthcoming.

Blocks are not in ios3.2 ( which would explain why I haven't heard of them.)

What problem are we trying to solve. How to package up some functionality (some code to be executed) to pass on to somebody else.

In other languages, called "closures" or "anonymous functions"

Blocks are an apple addition to C, objectiveC, c++

New in snowleopard and ios4

Diversion 1: functions calls are jumps, which you can make dynamic by using a pointer to a function.

(ugly) Example: Void (*myFunctionPtr)(int)

See PowerPoint for code with example. Too much to type!

Main use of a function pointers is for callbacks. (hooks? -hh)

This stuff works, but it's a pain in the butt, particularly when passing lots of data.

You can also do this with selectors SEL objects.

Diversion#2: nsinvocation
Bundles up (freeze dries) receiver, method and arguments. Then the invocation can be interrogated to find the return value.

More ugly code as example in PP...

The issue is that these things are a royal pain to set up.


Blocks:
^(arg list) {body};

No return type declared. This is a block literal.

There is no name for this it is anonymous.
A trivial example.
^(int n) {return n*2;};

How do you call this?

Int j = ^(int n) {return n*2;}(9);

But this is dopey. Send it to a block variable.

Declare a variable that is a pointer to a block

Return type (^myBlock. Afasdhjohfoafhgkj

Int (^doubler)(int);
Doubler = ^(int){return n*2;};

Too fast to keep up. See pp.

Funny syntax when trying to pass a block as a function argument.

So what is the big deal?!?

A block has read only access to automatic variables visible in it's enclosing scope! <-------

When you declare the block, it freezes the value of any extra-scope variables it references in the block. The variable is copied into a structure with all the ?

The block is created on the stack, not the heap. Blocks have same lifetime as an automatic variable (local variable?) when the block literal goes out of scope, it is undefined.

A block variable is declared with type edifier __block

__block int myBlockInt

Can be read/write by a block in the near by scope.

Under the hood.
Blocks are actually objectivec objects

Only example of stack based objectivec
A private subclass of nsobject
The header isn't provided so you can't subclass them or monkey around with them.

Passing a block into a function as an argument is safe, in a single thread.
What if you want to pass the block to another thread or pass it back out of a function to use later?
To do this, you must... Copy the block. He mentioned some c methods, but I'm just listing objc techniques here.
In objc, use the [. Copy] method on the block, since it descends from nsobject. The copied block goes to the heap, and moves any __block variables and fixes any links to those variables. ( mostly works)

Memory management in objc, remember doing copy requires a release or autorelease.

Some uses for blocks: collection classes, animation, threading, completion handlers

Also useful in grand central dispatch - give GCD blocks to run for you.

Gripes: 1) block is a word already in use 2) smashes encapsulation 3) function oriented, not object oriented 4) encourages Design Your Own Language Syndrome

Plug the book "Learning Objective-C 2.0" by Robert Clair. This is chapter 16.


- Posted using BlogPress from my iPad

#VTM_iPhone notes on memory management talk

Here are my notes on Steve Kochan's talk on "Really, really understanding memory management"

Steve@classroomM.com
Twitter: @skochan

Founder of classroom.com, author

Objectives: to really understand different memory maNagement strategies, et al

Three memory management strategies: automatic garbage collection, autorelease pool, manual allocate. And release of objects

Garbage collection not avail on ios-

RAM space ranges from 128-512 mb on ios objects, but count on much less available. There's no memory paging.

Autorelease pool is created at start of main and drained at the end of main

For cocoa and ios apps, automatically drained at end of event cycle

Multithread apps need separate pools per thread.

Framework objects are (mostly) autoreleased.

Doing example with a fraction class too much to take notes here.

Alloc involves retain - must be released.

If you release the single retained object twice (over released) error message says "released freed object"

Dealloc - never called directly, of course.

Retain count: how many people have dibs on this object?

When retain count hits zero, system invokes dealloc...

Autorelease doesn't affect retain count, but when pool is drained, the object will be released (once). The "pool" isn't a space where objects are stored - it is a list of objects that should be released when you drain the pool.

When is the pool released? Other than when you specifically tell it to? At end of event loop.

Retaining allows objects to survive after the pool is drained... From one event loop to the next.

When you add an object to an array, it sends a retain to the object. True for most methods that have "add" or "replace" in method name.

Methods with "remove" in name will release.


You can have local autorelease pool, even nested ones.


Alloc, copy*, or new must manually maintain

Autoreleased methods: static methods that return objects e.g. [nsmutabledictionary dictionary] returns an autoreleased object.
[[nsmutabledictionary alloc] init] is not autoreleased. Both have been retained once.

Trouble example: add a view to a superview and release it. Later in program, remove from superview - the view is deallocated.

Strange optimizations: constant string objects and nsnumber objects from -1 to 12 are often higher than they "should" be.

If you don't need an object in a method but are going to return it, now is a good time to autorelease.

Event cycle:

Remember that a new autorelease pool gets created when your app is to process an event. The pool gets drained when that method is done. Event is pressing a button, dragging, etc.

Example of trouble: in viewdidload method, user has said data = [nsarray array] -- it gets deleted at end of view loading event!

Could retain, could use alloc/init, or use synthesized setter method, which retains. ****But don't want to alloc AND use synthesized setter- that double retains! Causes a memory leak****

If you use @property (retain), then setter involves retaining. @property(assign) doesn't retain.

Another example: when you initWithCoder, the stuff in the coder is autoreleased, so you better do something that retains the data!

@property (copy) always makes an immutable copy, not a mutable one, even if the instance variable is of a mutable type.

When memory gets low in iPhone:
Application did receive memory warning
Release data you don't need!

Didreceivememorywarning is sent to all view controllers.
By default, views will be released if not in a superview
When view is released, viewdidunload is sent to the viewcontroller


Finding memory leaks
Put breakpoint or slog in dealloc

Use static analyzer- build and analyze puts blue icons in bak point bar. Click on blue boxes for more and more helpful info! Very neat!

Instruments - get guide from apple's website

More resources on PowerPoint that Steve posted.

- Posted using BlogPress from my iPad

Voices that matter keynote #VTM_iPhone

Here are notes from The keynote at the conference I am attending:
Aaron Hillegass keynote on independence vs interdependence

The rachael Ray of objective c.

Microwave programming (30 rock reference) - how do you get to the point where there is no more innovation? The golden age was when the cost of innovating exceeded the benefit of innovation.

Sign #1: when unit cost approaches unit price.

Sign #2: no substantial innovation in iMac since 2006 iMac, except speed... So average age of active unit approaches the half time to broken or worn out

Sign #3: trialware. Dell computer is an advertising model annoy user to become advertising source. When profits from selling something pleasing people want drops below selling things that annoy people.

Sign #4: open source tech becomes competition

Innovation free tech: microwave ovens, server os, desktop and laptop hardware, mp3 players, television

What about mobile? Mobile os?

"apple ios is significantly more mature than android."-A.H.

"who cares?"- china mobile, verizon, sprint, vodaphone, orange, t-mobile, AT&T

Mobile apps?
If we were trying to create an industry where the end of innovation came hurtling towards us?

Apps must be simple, games must be inexpensive. (games $1.22, non games $2.85),

Visiting 1998-imagine we could go back and talk to self at start of Internet. Crash left us with JavaScript, HTML looking bad in browsers, flash, silverlight. If you have an idea, now is the time to do it.

Dependence vs independence vs interdependence:

Benefits of independence: deep knowledge/control of product, flexible location and time, motivating, low burn rate, sense of ownership, lots of learning opportunities

But independence = adolescence. No synergy. References steven covey.

Specialization of labor - maybe bring more people into the fold, domain expertise, the tangible connecting to software, access to customers, camaraderie - people to talk with makes it more fun.

So get interdependent now.


- Posted using BlogPress from my iPad

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

Tuesday, September 14, 2010

For want of a nail...

"Hubris!" a friend of mine exclaimed as he watched the pomp and circumstance of a recent pep rally at our school as we prepared to face a team better prepared than our previous opponents. "Hubris!"

I mention this, because I was congratulating myself on how clean my code was. When I wanted to add a new feature - hints for the player who is stuck - it was a relatively easy addition to make because my code was broken down well and documented. "Hubris!"

As you might guess, I've been hunting a bug, and finding others along the way...

The bug I was after was one that was causing the program to freeze and crash whenever the chips needed to disappear from the back of the screen. I had just been adding in the hints code and was in the process of fixing a glitch where some pieces wouldn't stop spinning. I looked all over the game manager code where I had been working, ran the debugger to isolate the line, checked and double-checked the memory management code, even ran instruments!

I found two tiny memory leaks in Instruments, but they didn't fix my bug. Finally, after the better part of a week of searching, I found it tonight. It was a change inside the Chip class, where I had been modifying the "description" method to add one mo piece of information - and pit the new code outside of the square brackets. Somehow, it escaped the debugger, and caused me nightmares.

Once that tiny line was repaired the problem went away, and I was able to fix my unstoppable spinning chips in no time at all. Fixing the leaks seems to have made some memory warnings go away, as well!

Sure enough, our football team was down by 16 points going into the fourth quarter. (I must confess, I had gone home already....) But you know what?

They rallied back and won.

Just like they are going to next week, too.

- Posted using BlogPress from my iPad

Monday, September 6, 2010

The joys of a long weekend

Got some work done this weekend - labor day has been good to me. I got the advanced pieces finished in blender and started in on a hints system.

The pieces came together faster than I had expected, and I have come to realize that I was dreading the fight with Blender more than I realized. I was avoiding the project. I am glad to get over that hurdle!

At Clay's suggestion, I added in a feature to show possible moves to people who were stuck. Right now, it scans the current selector through the whole grid, in every orientation to see whether there are moves. Whenever it finds a working move, it picks one square at random from the four selected and starts it spinning.

Clay's original suggestion was to make this happen when the player does a three finger double-tap. However, I am finding that this interferes with the single-finger double-tap that is used to make a selection, usually resulting in a scratch. It also sometimes got interpreted as a swipe, selecting the next chip. I think I will change the controls so that a horizontal three-finger swipe passes the selector, and a vertical three-finger swipe shows the hint. I may also have the spinning "time out" after a little while.

I still need to balance the difficulty level - the rings are a non-issue in the game - they disappear too quickly. At the same time, I don't want to stress out the beginning player.

I have a couple of lingering bugs: the spinning chips don't fall inwards when the time runs out, and occasionally don't stop spinning when there is a new selector. But we are closing in!

Wednesday, September 1, 2010

Back in the swing...

I had a great trip last week with the freshmen- on the drive home I gave a colleague a preview of Implosion. Rave reviews! (He even foisted it on some freshmen...)

He also gave me an opportunity to talk up some ideas for balancing the difficulty level and aiding the beginning player. Clay had some great ideas!

Tonight, I finally had some time to work on it again, and I've been tackling blender once more. I now have the shapes drawn for the extra selectors. I just need to add in the fills via Photoshop, and we'll be in very good shape.

I had hoped to get this app to market by the end of summer, but that just wasn't meant to be. I'm glad to get some of this blender business behind me - it will be good to get back to my element.

- Posted using BlogPress from my iPad

Tuesday, August 17, 2010

Getting back...

Between work and trips, I've had to step away from. My programming lately. Every time I start getting back into it, I have to spend an hour or two updating my iPad or Xcode. Tonight I'm going to have to redo the provisioning in my iPad.

So I'm having a hard time getting back in the swing of things. In particular, I left off some stuff in blender, and I have to figure out how to do that again. I'm starting to wonder if sio2 and blender were a mistake.


- Posted using BlogPress from my iPad

Monday, July 26, 2010

Memory problems...

I have been having a frustrating time with implosion. I had to take a week off for a conference, but even then, I've been avoiding it a little, in the hopes that something would come to me. And because I am frustrated.

As soon as my program starts, I get a memory warning, level 1. Soon thereafter, I get a level 2 warning, and the game crashes.

I finally got Instruments to show my memory leaks - it didn't find any. But it did show some large allocations at the beginning of the program. I found some code to tell me the remaining memory (http://adeem.me/blog/2009/04/01/get-the-amount-of-free-memory-available) and inserted into my startup routines.

Pretty quickly, I found that loading my main logo image, which was 1024 x1024 pixels, took up 5MB of my available 28MB. A bit steep-the file size was about a quarter of that, but I suppose it was compressed. So I reduced the file to 512x512, which reduced the memory used.

But I still got a memory warning.

A little investigation revealed that the memory warning was coming the second time the menu rendered. I soon found out that the first time the logo and buttons were drawn on the screen, it ate another 5MB, and the second time it ate an additional 5MB. But not the third. (I am guessing that this is a result of double-buffeting?)

So a quick loss of 15MB over a few seconds on a system where I start with only 28MB? No wonder the iPad was freaking out.

But there are two things bothering me at the moment.
1) something must be wrong with my numbers - the iPad I have is supposed to be 32GB, not MB. -- oops. I'm confusing storage space with RAM. It's pretty late as I write this.
2) when I take out the code that draws my logo and buttons, it still takes 5MB of RAM each time, even though it is not drawing anything! I am starting to think this is not my fault...

So I will have to research this online. Perhaps there is a fix for this, perhaps I can find a workaround, or perhaps... I don't know.

As I said, I am frustrated.
- 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?

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

Monday, July 5, 2010

Fix it, yourself

Ah, the Internet. You can usually find the answer there (if you know what to search for). Elsewhere in the discussion board, I found the answer - it was a cheat of sorts. You need to invert the y-component in the portion of the code that calculates where you touched. This fixed the widget button problem perfectly, but it meant that I had to invert the way I handled the y-coordinate in the rest of my code. As it turns out, this was a small thing - I had already inverted it to compensate months ago, so now I just needed to change three lines to undo my previous inversions. That's working much better now.

But now, as I test my program, I have found a bug. Sometimes, the chips aren't sliding all the way in, or are just disappearing so that there is a blank spot in the grid - which never goes away - the user is in a bind. I need to figure out what is going on! (I wonder if this has to do with the timed pieces I just added recently- I'll start there.)

Presuming I get that fixed, coming up are (in no particular order):

  • an instruction screen
  • a pause menu
  • animation on the title screen
  • in-game instructions
  • a second green ring in the timer
  • improved timer chip placement
  • a game over animation
  • scores on the title screen
  • additional selectors for higher levels
... and I think I can post the game! W00t!

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

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

Fans...

Whaddaya know? A shallower fan works. Onto the next windmill....

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.

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.

Tuesday, June 8, 2010

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

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

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!


Thursday, May 20, 2010

Graphical improvements

I'm working on a few little things in Q*Bert this morning. Several of
my graphics were antialiased - that is, the used a light gradations
around their edges to make the curves look smoother. This is usually a
very good thing, but if you change background colors, or use
transparency, you get a light grey outline around the object, which
looks terrible. So I cleaned up some of my graphics.
I've also just updated the coily falling routine so that if you can
trick him off the edge of the pyramid, it clears all onscreen enemies,
and you get 700 points. You are also immune to attack when you are on
a platform now.
Next up: dealing with the death of a Q*Bert.

Sunday, May 16, 2010

Qbert levels

Ok. As of Friday, I have the levels system working, though I have only
created two levels to date. I had a little bout of "forgot to call the
loading function-iris," but I am doing much better now. It's time for
slick and sam, and maybe some scoring.

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

Q*bert progress

By the way, I haven't made too much progress recently on Q*bert. I'm happy to say that I have been answering a lot of good questions and having productive conversations about algorithms for everything from rendering laser beams to differentiating between collisions with horizontal vs. vertical obstacles constructing AI for moving about a maze.
Good stuff, student-initiated, and what they pay me for! (I suspect that somebody has written Q*bert before....)
Yes, I am just writing Q*bert for two reasons:

  1. To keep me occupied a little so that I don't meddle with students during class - otherwise, I start to give unwanted advice and solving problems before the students even understand what the problems are, let alone try to figure them out! (And that's not good teaching.)
  2. To model the process of writing the program like the ones they are writing, for which this blog is a help.
I have made a little bit of progress, however. I am midway through writing a function in my main class that will read a file of level data. One line per level. This will determine what colors appear on the screen, the frequency of enemy appearances, the number of colors the cube tops cycle through, and the type of cycle they have. So that's a work in progress.

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.

Tuesday, May 11, 2010

python info

I just found a cool thing for Q*bert - an instructional manual for somebody who owns a coin-op version of the game. Page 7 of the pdf shows statistics about the game and graphics for the characters.

I think I will move on to the file loading portion of the game to make levels.

Platforms

A late update on the Q*bert front - yesterday, I got the platforms working - Q*bert can land on one of them and they will carry him to the top of the screen. It's working surprising smoothly. Next up - I need to create a green guy who jumps down the pyramid like the balls do and resets the cubes' colors. I also need to start thinking about how I will manage levels....

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

Platforms

I'm working on creating the two hovering platforms that sit on either side of the pyramid and carry Q*bert to the top of the pyramid if he jumps on them. Not too much to show for it right now, though. I am borrowing a lot from the Cubes - so that I can position the platforms the way I would a cube and so I can detect when Q*bert has landed on one.

The other thing I am doing is going back and reviewing whether I am documenting my functions. I realize that I have been a little sloppy, making up functions without putting leading comments before them to remind me what they do. And that's not setting a very good example!

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

Monday, May 3, 2010

... Foiled again!

If you are not familiar with the game of Q*bert, you may not know that he has a bit of a potty mouth. In the game, when he gets hit by a ball or enemy, a speech balloon appears above his head with some curse characters, and a sound file plays that is sort of a grumble. I have the visual part of it working now, when he gets hit by a ball.
I don't have the snakes getting him yet, just the balls - but it shouldn't be too hard. I wonder, though, whether the snakes will be too hard to dodge. I'll have to calibrate it a bit later.

... but will anyone listen?

You know, when you are a teacher, you have to expect (and accept) that some of the things you tell your students are going to in one ear and out the other. Teachers know that we are going to have to repeat ourselves or find new ways to get the ideas we are trying to express to stick. Every year, I talk to my AP students about the difference between primitives and objects and the ideas of pointers.

You would think I'd be paying attention, myself.

I got bogged down in a puzzle this weekend - I had Chip objects that had a set of coordinates for their current position, and another set of coordinates for their destination. I'd start them off the same, but if they were ever different from each other, they would move a tiny little bit towards the destination, until they arrived there. Except when I changed the destination coordinates, they would just jump to the new location - they wouldn't glide; they'd teleport!

If you understand pointers, you can probably tell what my problem was - but it took me a couple of hours to puzzle it out (and find some other bugs along the way, but that's another story). Because I had set the myLoc and myDest variables to point to the same object, when I changed the coordinates of myDest, it changed the coordinates of myLoc, too. When I went back and changed my setter methods to make clean copies of the (x, y, z) coordinates that weren't the same object, suddenly things startes working right.

I wonder what else I was saying that I didn't listen to? I'll bet I need to do a better job documenting my code....

Sunday, May 2, 2010

Chain, chain, chain....

Some good success this weekend - I have gotten the chain of chips to work properly. Each chip is part of a sequence now. If one of the chips is removed, the ones past it glide in and replace it, and a new chip is dropped into the mix. (Your view is from above.) Here's a quick video - every time I click, a random chip is dropped:

The way this works is that each Chip has a "follower" and a "leader" - it is essentially a node in a doubly-linked list. Each chip also has two sets of coordinates - where it is now and where it is moving to, as well as a boolean that indicates whether it is in the process of moving. When a chip is removed, it sends its location to its follower, which uses it as its destination, and starts the chip animating. It also removes itself from the doubly linked list, as you would expect - tying its follower and leader together.

This is a major hurdle in the game, and one of the first things that looks great in OpenGL that I couldn't do with the Quartz commands - check out how the chips flip around as they fall away!

Thursday, April 29, 2010

Coily AI

I've been working a bit on making the snake, "Coily," chase Q*bert around the pyramid. I came up with an algorithm for deciding on which way the snake should jump, based on where he is and where Q*bert (his prey) is:
Deciding whether Q*bert is above or below the snake is pretty easy - I just compared row numbers. But picking between the left and right was more of a challenge. Eventually, I came up with an expression:
leftRightCriteria = coilyRow-preyRow - 2*(coilyRowPos-preyRowPos)
I found that if this "leftRightCriteria" was less than zero, then Q*bert was to the left of Coily; if it was greater than zero, then Q*bert was to the right of Coily; if it was zero, Q*bert was directly above or below Coily. So now I could apply this to the decision tree.

                

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

Bouncing Balls

Well, I was able to get some balls to show up on the Q*Bert grid and start bouncing down the cubes. In fact, I cranked up the drop frequency so that they fell almost every frame - it looked a little bit like water flowing. After that, though, I throttled back on the balls and let them come in multiple colors:
They now come in red, green and purple (not shown).

Next up - collisions with the balls and Q*Bert, followed by spawning other critters.

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!