Having acquired an iPhone, I've been playing around with it to see just how much can be done with the "SDK" that is the MobileSafari browser. I thought it would be fun to see if I could make a simple game for it, since that's different enough from the kind of UI coding I do at work.
Most of the games for the iPhone that I've encountered thus far were of the puzzle/card variety, and there wasn't anything too exciting/button-mashing/mindless. It seemed like this was mainly caused by the limitations of the events that the browser exposes. With no real
mousemove events, and with
mousedown events actually firing when the cursor was lifted (i.e. at the same time as
mouseup), it was hard to get anything to happen on the screen quickly in response to a user action. One avenue that I tried was to have the screen covered in narrow vertical
<div>'s, and to listen for click events on each of them. Unfortunately, while this worked when each was clicked separately (piano key-style), it didn't work when the user dragged his finger from one to another, since this would switch the browser into panning mode, even if the page/viewport was set to be only 320 pixels wide (i.e. no scrolling could actually occur).
Since the viewport panning does not seem to expose any events, I thought that maybe there could be other ways of catching this user action. When scrolling quickly, the iPhone renders newly-visible areas with a checkerboard pattern before actually displaying their contents. I wondered if this meant that images contained in these areas would not be loaded until they were scrolled into view and rendered. If so, it would be possible to use a
load event listener as a notification that the user had scrolled to a particular part of the screen. Unfortunately this didn't seem to be the case, images are loaded as soon as the document is displayed, even if they are off the screen.
I then remembered that the iPhone supports an additional gesture, a two-fingered scroll that can be used to scroll text-areas, elements with
overflow: auto and possibly other nodes. It would appear that
scroll events trigger for this scrolling motion, meaning that it's possible to detect and get continuous updates for this. Though having to use two fingers seemed a bit clumsy, this seemed pretty promising insofar as it allowed for quick responses to user input.
I had lofty goals for my iPhone game (I thought a vertical scrolling shooter was a good fit for the dragging input method and the vertical screen layout), but I decided that I should do something simple for my first attempt. I thought I would recreate aa racing game that I hard first played on my TI-82 calculator, where a car that can only be moved left or right moves at a constant vertical speed through a winding, narrowing road, with the objecting being to avoid hitting the sides. I thought this would map well to a horizontal scrolling motion that I could get with a
scroll event handler as mentioned above.
After writing a simple random road generator and the animation code, I was about to add collision detection. Out of curiosity, I tried to move the "car" left/or right as road moved by, even without collision detection, to see if the speed was too high. To my surprise, the road stopped moving as soon as I put my two fingers on the screen. It appeared that intervals (set up with
window.setInterval) do not fire when two-finger scrolling mode is engaged. I thought that maybe I could refresh the animation from the
scroll event handler, but that only seems to fire when there is actual motion, thus smooth animation can't be ensured.
My failed attempt is visible here. Before pressing the "Start" button, use the two-fingered scrolling motion left and right to confirm the the "car" (the blue square) moves as expected. Then press "Start" and obverse the reasonably smooth animation. Unfortunately it all stops when placing two fingers on the screen again.
This is rather disappointing, since there doesn't seem to be any fundamental technical reason why this should be the case. We're not talking about Mac OS 9 here (there, due to the way UI events were processed, normal event loop execution would be suspended while a menu was held open or a scrollbar thumb was dragged). It's quite clear, given what native iPhone apps can do, that the platform has quite a lot of CPU and graphics leeway. It's therefore unfortunate just how constrained the MobileSafari browser is, since just a few additional hooks would allow much richer interactions with the user.