I have three sublayers with the following z-order and dimensions (no offsets) as children of a cocos2d parent layer:
topmost layer: z: -1 width: 2048 height: 2048
mid layer : z: -2 width: 1536 height: 1536
deepest layer: z: -3 width: 1024 height: 1024
Using a UIScrollView (attached to a ViewController) as a subview of the glView used by cocos2d, I translate (and therefore scroll) each layer's position with the following ratios (thus achieving the 3D effect):
topmost layer: dragPt.x * 1 (the same for y)
mid layer : dragPt.x * 0.75 (the same for y)
deepest layer: dragPt.x * 0.5 (the same for y)
I detect user input on each layer as follows:
- attach another subview (let's call it seeThrough) to the glView with the following dimensions 480x320 (the app is in landscape mode)
- using -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
in this subview, I store the point of the touch in an iVar named "touchLocation".
- in my cocos2d-layer I then use the following code to determine the touch location on each layer:
CGPoint pointOnTopMostLayer = ccp(seeThrough.touchLocation.x - topMostLayer.position.x, (320 - seeThrough.touchLocation.y) - topMostLayer.position.y);
CGPoint pointOnMidLayer = ccp(seeThrough.touchLocation.x - midLayer.position.x, (320 - seeThrough.touchLocation.y) - midLayer.position.y);
CGPoint pointOnDeepestLayer = ccp(seeThrough.touchLocation.x - deepestLayer.position.x, (320 - seeThrough.touchLocation.y) - deepestLayer.position.y);
(320 is the screen height and to subtract from it is necessary to convert Y from the UI to the gl coordinate system)
When scrolling the layers, their positions are negative.
By using the seeThrough view as a reference platform to capture the touch on a 480x320 surface, I can successfully determine the touch location on each layer's coordinate system by simply subtracting the negative position values of each layer from the point captured in the seeThrough view.
The problem is when there is no reference point like that at all, for example when I try to get a sprite's position on one of the layers without user input.
Having no reference point, I am finding myself unable to come up with a solution that enables me to determine any specific point on one of the cocos2d layers.
I tried several methods (convertToNodeSpace, convertToWorldSpace, and as the day passed eventually wild maths), none of them with success.
My question therefore is: How can I determine the position of lets say a sprite on one of the layers and convert it into the space of one of the other layers?
Scenarios:
- a sprite is on the deepestLayer, but I want to move it to a location on the midLayer
- a sprite is on the topmostLayer and I want to move it to the deepestLayer
- etc...
What you have implemented is the transformation from screen space to each of the layer's coordinate systems.
If you invert these transformations they will go from the layer coordinate systems back into screen space.
For instance, you have:
pointOnTopMostLayer.x = screenspace.x - topMostLayer.position.x
pointOnTopMostLayer.y = (320 - screenspace.y) - topMostLayer.position.y
Therefore:
screenspace.x = pointOnTopMostLayer.x + topMostLayer.position.x
screenspace.y = 320 - (pointOnTopMostLayer.y + topMostLayer.position.y)
Repeat for each layer.
Now, to go from layer X to layer Y, you take the coordinate in layer X space, transform back to screen space, then transform into layer Y space.