EDIT: Danger Tank!’s camera feature no longer overrides visit(). Instead, it uses the main layer’s camera object and changes its coordinates to pan around the screen. Zoom is handled by scaling the main layer rather than changing the camera’s zEye value.
After hours of fiddling around and searching forums for a solution to this problem, I’ve worked it out and it’s fairly simple. What needs to be done is to calculate the touch’s screen coordinates as a proportion of the screen’s width and height, then apply that to the visible section of the world (between the horizontal and vertical clipping planes). My game at present does camera plane calculations manually by overriding the visit() function of the main layer and doing some magic with glOrthof(). The camera I use is actually just a dummy layer, using its position for the camera position and the scale property for zoom. Clip planes are then calculated as follows: glOrthof(cameraLayer.position.x – SCREEN_WIDTH / (2 * cameraLayer.scale), cameraLayer.position.x + SCREEN_WIDTH / (2 * cameraLayer.scale), cameraLayer.position.y – SCREEN_HEIGHT / (2 * cameraLayer.scale), cameraLayer.position.y + SCREEN_HEIGHT / (2 * cameraLayer.scale),
The following code will translate a touch to world coordinates using the method described above:
touchRatios.x = currentTouch.x / SCREEN_WIDTH;
touchRatios.y = currentTouch.y / SCREEN_HEIGHT;
currentTouch.x = (clipPlaneLeft + SCREEN_WIDTH / 2) + (clipPlaneRight – clipPlaneLeft) * touchRatios.x;
currentTouch.y = (clipPlaneTop + SCREEN_HEIGHT / 2) + (clipPlaneBottom – clipPlaneTop) * touchRatios.y;
The clipPlaneX values are calculated as shown in the glOrthof() call above, where they are shown in left, right, top then bottom order. -1000 and 1000 are the near and far planes, these seem to work fine for my needs.