If you make a new game template project in Xcode, the default GameViewController will use the following initializer to instantiate the game scene:
let scene = SKScene(fileNamed: "GameScene")
The initializer's use in the template file suggests that this is Apple's recommended way for creating an SKScene. However, I have seen many examples on Stack Overflow that use the init(size:) initializer or simply SKScene().
I am wondering which is the best way to create an instance of SKScene and what are the advantages/disadvantages of each way, as well as various pitfalls to look out for when using one approach versus another.
My reason for asking is that I used init(fileNamed:) to create my game's scene and build level 1. When I later tried to create another instance of the scene for level 2 using init(size:), I ran into problems. Namely, some positional calculations using UIScreen and the scene's frame seem to produce different results if I create the scene using init(size:) instead of init(fileNamed:).
In a more general sense, I would like to hear the opinion of someone who is very familiar with using iOS and SpriteKit about their preferred way of initializing a new SKScene and the pros & cons of using different approaches.
I very strongly recommend not using init(size:) when it comes to creating your scenes that you use as a part of your game. You really should try to keep design separate from structure. This allows for you to change how the layout of your game is, without changing any code, thus reducing the potential for bugs.
With that being said, there is a very common practice tutorials use that looks like this init(size:view.size). This one causes all kinds of trouble with game designers, and destroys the simple handling of multiple devices that SpriteKit offers. People tend to end up in a 0..1 coordinate system, placing divides everywhere when positioning their nodes, and this too leads to bugs because people may end up forgetting a divide somewhere, or using width when they meant height.
SKScenes have 4 scale modes that handle how a scene should look on every device, and it should always be taken into consideration when developing a game with this tool. It really should be the first thing that gets discussed so that people can understand the power behind it.
The only time I would recommend using init(size:) is when you need to create a dynamic scene that cannot be achieved via the sprite kit builder, and when you already have a static size of the window established.
Related
I've seen this concept mentioned around the internet but can't find any specifics on how to do it.
I want to lay out my entire level in an .sks file but load only whats in the view of the player/frame at any given moment. In my game I have platforms that go up and down forever, simple roving enemies, and collectable coins that float in the air while bobbing up and down. Since these actions are using
SKAction.repeatForever
They are continuously going even when not in view of player. The only other option I see is giving every action a "key" and then placing invisible sprites through out the level that when contacted start and stop certain actions. While doable it seems it could get very convoluted very fast.
Is there a more straightforward way to lay out my entire scene, but only load what's currently in view? I'm not sure what to call this concept which is probably the reason I can't find much on it.
Any insight is appreciated!
There is no easy way to do it. My personal method is to load your SKS into an SKScene that is not attached to the root node at all (the SKView) and use SKCameraNode's containedNodeSet to move all nodes from the loaded scene over to the scene that is viewable to the user. You would then need to implement methods to continuously swap between the two scenes.
If your concern is only actions, then you can avoid the swapping and just pause all nodes not in the containedNodeSet and unease the ones that are inside of it.
Weird crazy question I know. My current setup is a SCNScene with a camera controlled by the device's gyroscope. I'm able to add and light normal nodes, however I would like to add 2D UIView objects into the scene like UITextViews or maybe some buttons. The views would need to be inside the scene and thus become no longer visible if the camera moves away from them.
Firstly, is this even possible? Or would this be way more difficult to implement than rebuilding an editable textview as a node? Could this be achieved by categories or...?
I just talked to the scenekit people here at WWDC. He said that as of now it is completly impossible to do it in a nice, functional way. The only options he offered as a possible solution is to create the UIView element somewhere off screen or behind the scene and continuously take screenshots of the object and apply those images as a texture to a SCNNode. He also pointed out the performance will be very poor with this because taking screenshots is heavy and you can't get going very quick with it. So I guess this is a no-go until UIView adds support because, according to the engineer, it's impossible to implement this because of a UIView limitation and not a SceneKit one.
Several years ago I was curious about creating some objects (spoon, ball, tv, ...) in 3d modeling program, export the textures, and then have a screen in iOS app, that can open one object at a time with a possibility to rotate and zoom it. This seemed quite basic and most used case but I didn't find any simple and ready to use solutions/libraries/plugins, just raw OpenGL ES (GlKit), so I refused to use it, as it would require too much knowledge and time as I haven't done any 3d stuff before and my primary work is not related with 3d.
There are also Unity and Cocos3d engines, and it looks like they allow to extend the code by using iOS plugins (xibs/storyboards, navigation with view controllers and etc), but this means you have to make your app project as Unity/Cocos3d first, and only then add your usual UIKit stuff as a plugin. Now that is not acceptable because the project should be written using UIKit first, and I expect to add 3d viewing stuff as a separate component that encapsulates all the necessary stuff inside it as a black box, because I don't want to mess my project up, as this 3d stuff is an optional feature.
Now, after several years I'v searched for the thing again looking for simple 3d viewing plugins/solutions for UIKit, but the situation is pretty much the same imho. I saw iOS8 there will add Scene Kit, but I'm not sure will it be something close to what I expect. So, still I'm not sure is there any solution that would require minimum time efforts, or is OpenGL ES the best solution for this need.
Check out the CC3DemoMultiScene demo app in the latest version of Cocos3D. It demonstrates how to include a Cocos3D scene in a standard UIKit storyboard, and to have the GL view only a component of a larger UIView.
I am in talks with a client to do an app, but in it, they are wanting it to revolve around a little character that follows you throughout the app (think Clippy, from the old days of Microsoft Word :)).
One thought I had was, can I use an SKSprite/Node inside an iOS app not using the SpriteKit framework?
Or is this a matter of animating through an array of UIImages?
Those were my first thoughts - does anyone know the best direction to go in for something like this? I need basic animations for a character throughout the whole app.
Depending on the detail of animation needed, you could do it with just CoreAnimation and possibly selectively choosing the image to display in an UIImageView. For example, see the answers to this question: rotate a UIView around its center but several times
Simple answer is, No, out of the box you can't use a class from a framework and choose to not use the framework. Though I'm not exactly sure what that question means. An SKSpriteNode renders via an SKScene node, and an SKScene node renders via an SKView, which is rendered by a View Controller.
You could do something fancy like dedicate the SKView as only part of the screen, and have a standard UIKit view as the other part, or only have the SKView appear on the screen when you needed it I guess.
I am attempting to determine the best way and most efficient way to handle the following tasks in a game written with the Corona SDK. It seems like there are so many ways to do things that it becomes quite confusing, so I am hoping someone here can help!
I am creating an adventure type game that will have an inventory system/puzzles etc. The thought process I've developed so far involves using separate "classes" to handle each specific aspect of the game. Such as InventoryManagement.lua, ObjectManagement.lua, PuzzleManagement.lua etc.
Just a side note - this game really doesn't involve Physics, but I would like to have static images with animations that occurs (Think opening a door or picking up an object):
Here is an example of what I am trying to accomplish:
Say you start a new game and it loads the first scene. I need to setup the player's inventory, the objects in the room, their state, images for these things etc. which I assume could be defaulted on first game load, and loaded subsequently ...
Then the player clicks on a key to pick it up - at this point the key needs to appear in their inventory so now it will be removed from the scene, added to their inventory (Via InventoryManagement?), and the scene will be updated (Via SceneManagement?)...
From now on the key should no longer show in the scene.
Now say they click the key and use it on a door, the door should animate open and remain open from now on.
If the player leaves the room and comes back, the key should not appear.
Now to me it makes sense to load/unload the scene every time you enter/leave the scene, but ... won't this become memory intensive etc. if you do it this way? ... Is there a better way to handle a scene if it has say, 30 objects on screen?
Hopefully that is clear - It is hard to find specific information related to each one of these elements. Everything seems to be related to physics games and I can't seem to find something on how to "Add a key to the scene if, but not if, and if it's been used then animate that door" :(
Thanks!
Had the same problem with unexpected results when jumping between storyboards. One thing I found out was
Always make sure to Runtime:remove and stop the timers you use. One alternative when you want to reset everything is to make a reset.lua file and on enterScene you use storyboard.removeScene or storyboard.purgeScene (If you just want to get rid of all display objects you have rigged up in memory in scene:createScene).
Also check out storyboard.RemoveAll() or purgeAll()
You need to make some stuff in Global space (using _G) to use them between scenes.
To change between scenes, "Storyboard" is very nice.
But mind you, you will need to use some manual memory hacking if you make things too much memory intensive, mainly, you might need to before loading a scene, do several calls of "collectgarbage" after cleaning the last scene, otherwise you will hit a curious problem:
You loaded scene "A".
You switch to scene "B".
The game 'unloads' "A", but the garbage collector don't, then loads "B", the end result is memory use of "A" + "B".
On this adventure game I was making in Corona, it resulted in several crazy crashed until I figured the "collectgarbage" trick.