I have multiple SKEffectNodes I use as layers to represent different screens e.g. main menu screen, game screen, game result screen. I attach children nodes to represent buttons, labels, etc... to their respective layers.
When one layer is visible, the previous is blurred with a low alpha in the background so it's slightly visible. When transitioning, the foreground will blur and tween the alpha to 0 while the background will blur and tween the alpha to 1. The foreground does not get recycled (I realize this may be part of the issue).
When the Game Screen is behind the Main Menu Screen, the Play button (Button: SKSpriteNode with isUserInteractionEnabled = true") on the main menu overlays an SKSpriteNode with "isUserInteractionEnabled = false" from the Game Screen. When I try tapping on the middle of the Play Button, it does not trigger the touchesEnded(...) method. But when I tap anywhere where the SKSpriteNode is not behind it, it triggers the Play button's touchesEnded(...) method.
I have a transitionInComplete and a transitionOutComplete methods I use to determine when a layer is fully visible / invisible and is active / inactive. I thought that this issue had something to do with the zPositioning, so I set the current layer's zPosition to 100 when transitionInComplete is called and zPosition to 0 when transitionOutComplete is called but this did not solve the problem. I do not touch any of the layer's components' (buttons, labels, etc) zPositions at this time.
Any ideas?
Edit (09/25/2018 # 3:23 PM PST):
It's worth to note I do have swipe gestures enabled on the scene. The SKSpriteNodes react to swipe gestures.
It was an issue with zPositioning.
The following post made me realize that there was overlap because of how zPositioning is calculated from parent to child:
zPosition of SKNode relative to its parent?
Related
I am implementing a horizontal scrolling menu for a SpriteKit game and have become stuck as to how to go about this. My strategy was originally to add all of my menu items to the scene and just pan the camera horizontally according to swipes.
The problem with this is that the menu is revolving/circular (last item links to the first, etc) so even if I repeated the menu items infinitely, after swiping constantly one direction, I imagine a coordinate limit would be reached and the app would crash.
My next solution is to add one menu item in my camera view, one to the left, and one to the right. Then upon swiping the correct item would move into my camera view via SKAction and the original item would move away. I would then removechild the farthest node from the camera, and add the next item to the scene in the direction toward which I swiped. This way my x range (in points) would only be -displayWidth to displayWidth. The problem with this is that I would need to animate all of the menu items at the same time, and as they are separate nodes I have not seen a way to synchronize their animation.
Also I need to check the position of elements on the menu items and change their shaders when they reach the border of the screen. SKActions seem to block the SKScene update method so I am ideally trying to avoid SKActions.
Is there any viable strategy that I am missing here?
Since this is only a menu, it is ok to be a little inefficient.
What you do is have your menu cloned 2 times (so you have a total of 3). You place one of the clones to the left, and one to the right.
You then add all 3 of these into a parent SKNode. You should now have one SKNode with the 3 menu items in a long string. Make sure your anchor point is (0.5,0.5)
You then run the animation to pan left or right on the parent SKNode, with the condition that whenever you pass the edge of your original main menu, you jump in the opposite direction the width of the menu.
So let's say our menu is 400 (-199,200) points wide, and our screen is 300 points wide (-149,150). Once the parent point -200 (menu point 200 or right side of menu) aligns with screen point -150, you move the parent point to 200 (so menu point is -200 or left side of menu).
Since you are moving the parent node, all the clones will follow suit, and you only need to run 1 action.
I recommend using UIKit to create such a menu instead of SpriteKit. UICollectionView should be good for such a task.
In my ViewController, I have a background view and a bunch of collision views. I have added gravity behavior to those collision views, so that they will fall from their original positions. But I want to let these views stop falling when they reach the bottom of the screen. So I add collision behavior to each collision view. Meanwhile I don't want them to collide with each other. In another word, each collision view can overlap with other collision views. I have tried
[_collision setTranslatesReferenceBoundsIntoBoundaryWithInsets:NO]
But it does't work, and I guess I'm using the wrong method. So how can I achieve this?
I'm as beginner as you can get when it comes to iOS animation.
I know you can do fixed (non-gesture-controlled) animations, where you animate a property of a view over a fixed period of time. This however is entirely different than using a gesture to control the animation.
You know how you fold a sheet of 8x11 paper to put it in an envelope and mail it... you fold it in thirds. Well basically, my boss wants an interface such that 2/3rds of it is shown on the screen at a time, and the other third is slid on/off screen with a gesture. So basically, the screen would show either thirds 1 and 2, or thirds 2 and 3 depending on whether you swipe left or right.
Now this also means doing things like snapping/rubberbanding, bouncing, acceleration/deceleration, sticky. I have no clue where to even start to do something like this. I'm assuming those types of motions are not already built into any of the iOS framework and if you want snapping/rubberbanding, bouncing, acceleration/deceleration, you'd have to program that entirely from scratch.
Like how would a view know my artificial snap/bounce points are, and sticky behavior, such that you remove your finger from the screen before an arbitrary position is reached, and the view bounces back to it's previous position.
Where would you suggest I start on researching how to drive animations with gestures?
I suggest you take a look at Core Animation. You can do some really complex animations including accelerations, deceleration, bounce and others.
You could easily create a UIPanGestureRecognizer to track when someone has dragged their finger across the screen. Attach an action wasDragged to your gestureRecognizer
From the documentation:
A panning gesture is continuous. It begins (UIGestureRecognizerStateBegan) when the minimum number of fingers allowed (minimumNumberOfTouches) has moved enough to be considered a pan. It changes (UIGestureRecognizerStateChanged) when a finger moves while at least the minimum number of fingers are pressed down. It ends (UIGestureRecognizerStateEnded) when all fingers are lifted.
In wasDragged check what state the gestureRecognizer is in. If state is UIGestureRecognizerStateChanged, then you can adjust the size or position of your UIView so that it appears like you are dragging it out. If state is UIGestureRecognizerStateEnded, check whether the point at which the gesture ended is greater than your threshold point (e.g. halfway across the screen). If it isn't, then snap the view back using an animation, if it is then snap the view into where you want it.
Hope this makes sense.
At the moment, I'm animating a UIWebView from the bottom of the screen to the top. As the UIWebView animates upwards it becomes untouchable for 50-80% of the duration time.
If I tap the UIWebviews ending destination, or model layer, the taps are registered and the Webview responds appropriately.
Why is this? And what solutions are there for tapping moving/animating UIWebViews?
To further exemplify this, I have created a side project that shows a UIWebView animating upwards. The purple squares represent touch events on the presentation layer, while the blue squares represent touch events outside of the presentation layer.
https://github.com/AdamBCo/UIWebView-Animation-Issues
As seen in the example, UIViewAnimationOptionAllowUserInteraction is set in the UViewAnimation block.
A UIWebView is complicated layout of web elements. To redraw that during animation there is simply not enough time available to entirely redraw the UIWebView, keep the controls in it available for interaction and do the animation.
However there are some settings for this inside a CALayer on what to do with its contents when animating it. I would start looking into that.
How can I pop up alert when an bouncing image touches a draggable image the same way it's done in this app: http://tinyurl.com/kspnh6
Example: there is an image that is going up and down the screen and it touches an image that we can drag around. How can we show an alert view when that image touches the moving image?
When you move the dragged view around, check the updated frame property against that of the other items.
You can use a function such as CGRectIntersectsRect to determine if the frame of any two views overlap each other (i.e. when it's time to show the alert).
This acheives a rectangular "hit test", there would be more work involved if you wanted the hit test to respect rounded shapes etc.