I am working on my first spritekit app and had a quick question on how to handle something I had in mind. I am working on a prototype of a board game I had in mind and wanted to do some brainstorming in an iOS Map.
The main scene is a world map that the user can pan around. I have this working at the moment. My next step is to create some overlay that would appear with a bunch of actions/cards available for the user to activate.
Do you guys have any tips on how to set this up? Would this overlay be another scene? I don't think that is correct since the SKView can only present 1 scene at a time. In addition, I currently have a UIPanGestureRecognizer, I would want this to stop working in the region my overlay is in.
Any help is appreciated!
You can create an SKNode and add your actions/cards to that node. You can then add the node to your world map node (so it pans appropriately) as an overlay. You should set the zPosition of the overlay node to a value larger than your world map's zPosition so it appears over the map.
Related
I am contemplating a simple app that has four characters that you can drag around on the screen. While dragging they "wiggle" — that's the animation. And they snap to a position if they get close enough to it... like in a puzzle. Without the animation, this is all simple in UIKit.
My first thought is to render each character in its own SKView inside a plain old UIView. I could attach UIGestureRecognizers to each SKView to track tapping and dragging. But I think this implies individual GameScenes for each character/SKView. That seems go go against the grain of SpriteKit.
The alternative is a single GameScene with the four sprites. But I would still need to track & drag them and I don't see how to do that within an all-SpriteKit app.
Is either approach better practice than the other?
You should implement the one that has a single scene and separate sprites for each character. The sprites will be SKSpriteNode instances which are SKNode instances, which descend from UIResponder and can, therefore, respond to touch events.
Look at the documentation for SKNode. It is a wealth of information that applies to sprites as well as to any other kind of node. In particular it says:
All nodes are responder objects that can respond directly to user interaction with the node onscreen…
And then later has a section on "The Hit-Test Order is the Reverse of Drawing Order" etc.
I'm having trouble finding this answer. If I have a settings scene that I want to slide down over another scene, how do I do this without removing the original scene. I want to be able to transition the settings scene overtop of the game and when they click "Back" have the settings scene scroll back up and disappear.
Not sure why everyone is talking about view controllers here, but the easiest way to achieve what you want to do does not involve multiple scenes.
In SpriteKit, you can only have 1 scene at a time going.
So what you do, is you have an SKNode that will be used for your settings scene, and an SKNode for your main content.
Place all of your settings nodes into this setting SKNode as you would for the scene.
Place all of your main content into the main SKNode.
Add the main node to your scene for normal game functionality.
Give a high z position to the settings node so that it is on top.
Then when you need to present the settings node, you set its position to the screen height + 1/2 the SKNodes height (unless you change the anchor point).
Pause the main node if needed.
Use an SKAction on the settings node to have it move down to the spot on the screen you need it to go. (SKAction.moveToX(x:y:) should work for you).
Then when you need to leave, just call the reverse of the SKAction and unpause the main node.
I'm following this question's advice on how to create my game world for a scroller game with camera centered on the player. However, the advice says to use an SKShapeNode; I don't know how I feel about that.
Are there any advantages/disadvantages to using either a shape node or an skscene (or another type of object/node)? Is there a node that is considered best practice to use as a world?
Also, is it possible to create an skscene inside an skscene, or is that bad practice/discouraged?
Thank you!
You can't put a scene inside a scene per-say but you could stagger view controllers and place a view controller on top of another and then put the scene on top of that inset view controller.
The way I implement my scroller games is to put the player in the center and then move the background around. (Checking for bounds of course.)
As far as your advantages/disadvantages I'm not sure what you mean by the SKNodes; that's how you should do it if you're working just in SpriteKit. But don't add another SKScene unless you have something that you can't implement in just one SKScene.
I'm building a tower defence game using SpriteKit and I'm relatively new to this.
My map basically consists of tile Nodes that are touchable. Once a user touches the node, I can place a tower on that node (I have this part working so far). What I want to do moving forward, is instead of directly placing a tower, I'd like a circular menu to pop up around the tile Node to let the user pick the tower that they wish to place in this tile node.If the user clicks anywhere other than the circular menu, the menu should disappear.
So something like this:
http://imgur.com/QvCsM8Q
I'm wondering what the best way to do this is. I have two possible solutions but they seem hacky:
1) Creating a custom UIView consisting of the menu and 4 buttons and then adding it to my scene (but then how do I detect button presses in this menu from the scence?)
2) Extending a SKShapeNode to create a circle and adding in 4 SpriteNodes around the circle, then verifying if a touch location corresponds to one of the 4 SpriteNode locations.
Any suggestions/code examples of how best to approach this?
I would suggest you create a separate class for your tile nodes (which inherit SKSpriteNode) and add the functionality within that.
For the approach for the menu, I think something along the lines of point (2) would be better. By subclassing the tile node, you can make the tile detect the selection by itself.
Expand the tile using SKShapeNode or a SKSpriteNode with a circular image using animation.
Place the four buttons on the expanded part.
Implement the touch for the selection within the tile node class.
For closing the menu, a tap on the scene can trigger a NSNotification for which the tileNode could become a listener on expansion.
Here's my current situation:
I created a CCScene named StoreScene.
Within that scene, I've initialized a CCLayer and just named it Store layer.
Now, I want a scrollable layer that contains content which the user can touch.
To do this, I created another CCLayer named Store Container.
I create an instance of this layer and add it as a child to StoreScene.
In StoreContainer, I've added multiple sprites, each with a unique tag.
The scrolling is done within the StoreScene and touches will move the entire Storecontainer layer up or down.
I have added 4 sprites to my scrolling layer (store container)
Initially,
sprite 1 is located at 0,10
sprite 2 is located at 0,20
sprite 3 is located at 0,30
sprite 4 is located at 0,40
Obviously, as the entire storecontainer layer shifts, the sprite positions shift as well.
However,
when I do this in the TouchesEnded method:
if (CGRectContainsPoint(sprite1.boundingBox, touchpoint)){
NSLog(#"TouchedSprite1");
}
... and so on for each sprite
The touch locations of each sprite remain in the same place!!!
Visually, the sprites are moving up and down nicely.
but their locations when receiving touches stay constant..
is there a reason for this?
Any other way for approaching a scrolling layer?
I've already looked at the UIKit's scrollview and I've looked at CCScrollLayer and both aren't good enough for me.
My way may be simpler but it doesn't work as planned.
Thanks in advance! ^_^
I'm guessing you've implemented touchesEnded in your StoreContainer. In that case the touches' coordinates will be relative to that layer, which explains why their coordinate system is following the layer around the screen. You could implement touchesEnded in the scene instead, or put the StoreContainer instance inside a new and immobile layer whose purpose is only to handle touches.
Alternatively you could keep your current setup and use your answer to this question to get the touch coordinates in the world... :)
Check out CCKit, there is a nice CCScrollLayer implementation included.