I am developing a cocos2d based IPhone game where a scene replace another with a Left to Right Transition. The new scene has a background a bit bigger than the scene. That is just because I move it according to the device tilt to create a sort of 3D effect.
Unfortunately during the transition of the scene I can see the background outside the scene overlapping the previous one :(
I have then tried to use the z-order in such a way the previous scene should go on top of the new one bug it does not work the way it should.
do you have any suggestion?
Thank you in advance
I think you need do crop your scenes layer by overriding it's -(void)visit method.
That's how I did it:
- (void) visit {
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
glScissor(cropRect.origin.x,
cropRect.origin.y,
cropRect.size.width,
cropRect.size.height);
[super visit];
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}
May be you'll need to play a bit with cropRect origin and size values.
Also you may need to add some device orientation changing support
Related
Let me first introduce you to the node hierarchy:
SKView->SKScene->SKNode
I've added a UIPinchGestureRecognizer to the view so that I can zoom in and out my content. Here's the code in SKScene object:
-(void)handlePinch:(UIPinchGestureRecognizer*)pinchRecognizer{
[self runAction:[SKAction scaleBy:pinchRecognizer.scale duration:0]];
pinchRecognizer.scale = 1;
}
Everything's OK except for two things:
In my node's touch events I check the position of the touch and act accordingly. Everything works fine as long as the scale of the scene is untouched. But if I zoom in or out I can no more do this. It's because even if I seem to touch the same point on the screen it's actually different before and after zooming. In Cocos2D I had exactly the same problem. But I could solve this problem by just converting the touch point to node space with convertToNodeSpace method. There should be an equivalent in Sprite Kit. What is it?
When pinching, anchor point is the lower left corner. Is there a way to make it zoom from where the pinching occurs?
Essentially, when I have one CCLayer for background and platform sprites and another for player sprite and HUD, how should I go about calling CCFollow if I want my camera to always center at the player with the HUD in the same layer moving accordingly as well?
Right now the background layer is a subclass of CCLayer that has a CCSpriteBatchNode for drawing objects in the environment. It contains an instance variable CCLayer *HudLayer that has a CCMenu and another CCSpriteBatchNode for the player animation sprites. They are both direct children of a CCScene, meaning HudLayer is not a children of BackgroundLayer. I'm now calling the CCFollow as [self runAction:[CCFollow actionWithTarget:playerSprite worldBoundary:worldRect]] where self is the BackgroundLayer.
The camera follows the box2d physics body of the player correctly, and the menu moves with it too, but whenever the camera moves, let's say to the right, the player sprite moves twice as fast to the right, leaving its physics body behind. So after moving to the right for a bit the playerSprite is outside of screen. playerSprite.pos and playerSprite.position seem to have nothing wrong though.
I've tried calling the CCFollow in different places but either the HUD refuses to move or the camera won't move or the player moves weirdly. What's wrong with it?
I FIGURED IT OUT! The key here is to put the player sprite in some layer other than the HUD layer. I added my CCSpriteBatchNode for the player sprites as a child of backgroundLayer instead of the HudLayer without changing anything else and it worked.
So basically everything that needs to always stay on screen as the HUD should be in one layer, while the target node for CCFollow should be in a separate layer (in the background in my case). The caller layer of CCFollow should contain the target node as a direct child. This tutorial helped me a great deal: http://www.raywenderlich.com/4666/how-to-create-a-hud-layer-with-cocos2d
I'm looking for help. I'm trying to make some puzzle game and I have thin scrollable layer at the bottom of my main layer which contains some puzzle shapes. I can scroll the layer and see every shape but shapes were positioned manually in code on the scrollable layer and the problem is, if I try to detect if I touched on sprite, which position is greater than 1024(in first iPad) it doesn't work. it doesn't work because touch can have position inside 1024X768 and the position of shape is for example 1500x100. to make it clearer, shapes are sprites and i try to detect them using CGRectContainsPoints method. Is there any other way to make it or have you any ideas? thanks in advance :]
What you could do is subclass your sprite, create a delegate for it and assign your main view/class as the delegate.
Implement the appropriate touch method, and send the message of what sprite was selected to your delegate (Main view or desired controller class).
With this every sprite has the same delegate, and sends a message to your controlling class as to what sprite has been selected and continue with desired functionality. No need for CGRectContainsPoint method.
This is cleaner, and more efficient.
Hope this helps!
I haven't been able to figure this out. Could someone please help me? I am trying to stop one UIView in my app from rotating when the device is turned.
I am working on a drawing app. Right now, when the device is turned, all UI elements turn with it. What I am trying to do is have all the buttons, menus, etc. turn, but have my canvas UIView be static and ignore the rotation of the phone.
If the canvas view is a subview of a view that rotates, then it will rotate as well. It's inescapable.
If you have one element of a view that you do not want to appear to rotate, you have use a rotation transform to programmatically rotate that one view back to the orientation and frame you want it have.
You could use the following to prevent the view itself from rotating:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return false;
}
Then manually rotate the individual elements you want rotated.
OP here. Rotating the view using CGAffineTransformMakeRotate() worked like a charm. Thanks, TechZen!
I'm developing a game. I'm using about 150 UIImageView to hold the graphics. I'm simulating a 3D enviroment, so i would like to change the z-order (how close is an object to the camera).
I know there exists :
[superWindow exchangeSubviewAtIndex:i withSubviewAtIndex:j];
But for some reason it's not working, some of the subviews disappear an re-appear.
Now I just remove all subviews and add it again in the correct z-order, this is ok with 50 subviews (on a 2G iphone) but with 120 it takes half a second so the gameplay sucks (I dont have and 3GS so i didn't try there).
I'm using so many subviews because each one is a square, then i colored it, resize it and move it somewhere in the screen. I'm holding the subviews under a NSMutableArray...
The iPhone documentation often warns about multiple UIViews nested, as it has a large performance hit after a certain point. If you start getting into issues one option is to render your UIViews into an image and using that to lower the number of on-screen views, but if you're simulating 3D that probably isn't going to help much since your composite view would need re-rendering too often.
The iPhone has full support for OpenGL ES, which allows for a real 3D environment. Take a look at some of the samples and/or a good book on the topic and you'll find that it's much easier to simply use OpenGL.
Z-order is an artifact of where your view appears in your superview's list of subviews. The last subview added to the superview is "on top".
So, to move a view to the be "on top", you remove it from its superview, then re-add it -- making it the last one and, therefore, on top.
Here, a view moves himself to the top of the z-order.
// move to the to in the z-order
UIView* superview = [self superview];
[self retain];
[self removeFromSuperview];
[superview addSubview:self];
[self release];
Note the [self retain] to prevent your dealloc if your superview is the only reference to you.
If you don't want to take the plunge to OpenGL ES, as Timothy suggests, you might want to look at replacing the UIViews with CALayers and placing them within a CATransformLayer. CATransformLayer is new in iPhone OS 3.0, and it lets you do a true 3-D layout of the CALayers. You can then set the zPosition property on your CALayers to locate them in the Z plane of the CATransformLayer. For more on 3-D layout of CALayers, I direct you to this article.
You can even add a nice perspective effect on the overall CATransformLayer by setting the m34 element in the CATransform3D applied to that layer.
Changing from UIViews to CALayers is pretty straightforward, because their structures have much in common.
Consider using a 2D game library like Cocos2D. I'm pretty sure that supports Z-ordering, and the performance will be vastly better than using UIViews.
I know this is old, but you can change the z order with bringSubViewToFront.
See this answer: How to set iPhone UI View z index?