So, I wish I were younger and still smart. :p
I suppose the following isn't the most elegant solution, and admittedly the framerate drops, but this is what I did to make pinch zooming work alongside my existing camera code.
Note that I have 2 methods that are used in CCActions, setZoom, and setCameraToGameboardPos. They don't do much other than first clamp the values so you can't see outside of the world, before setting the layer's scale and position parameters:
// this gets called by touch events and is a special case since scaling occurs based on anchorPoint, so we need to compensate for that.
-(void)changeZoomBy:(float)deltaZoom{
CGPoint pos0 = [self positionOnBoard]; // position of camera before zoom change.
_zoomLevel += deltaZoom;
_zoomLevel = _zoomLevel < _winSize.width/_worldBounds.size.width ? _winSize.width/_worldBounds.size.width : _zoomLevel; // prevents from zooming too far.
CGPoint pos1 = [self positionOnBoard]; // position of camera after zoom change.
CGPoint deltaPos = cpvsub(pos0, pos1); // change in camera position
pos0 = cpvadd(pos1, deltaPos);
[worldCam setScale:_zoomLevel]; // sets the new zoom on the cam's layer
[self setCameraToBoardPos:pos0]; // sets the camera to this new compensated position.
}
I can't believe how much frustration and hours of madness this caused, when the solution I came up with was so empirical. It moves? Well then, move it back!
So much for theory... I still don't know why it does what it does, but this fixed it well enough....