Im trying to update an SKShapeNode's frame after it's been added to the scene but it keeps saying that 'frame' is a get-only property.
I want to make a simple health bar (rect) that changes size based on a health remaining variable.
Im trying to update an SKShapeNode's frame after it's been added to the scene but it keeps saying that 'frame' is a get-only property.
I want to make a simple health bar (rect) that changes size based on a health remaining variable.
As far as I can tell, SKShapeNode is a wrapped version of CAShapeLayer. Only slower, less useful and without the good bits.
The real depressing thing, to me, is that Apple is yet to take 2D game engine design and implementation seriously. One of the key indicators - there's no performant, dynamic, 2D drawing facility in Sprite Kit.
SKShapeNode takes this to the extreme, being immutable and Slow with a capital S.
I didn't know the frame was also immutable, but it wouldn't surprise me if it is.
I think your best bet is to scale a rectangular bitmapped sprite, by placing the origin at the stationary edge so it scales out from there.
There's 9-Slice scaling in SpriteKit, but they named it something weird, and I can't remember what that name is. But using 9-slice scaling means you can add non-deforming graphics elements to edes/outside of the bitmap you use for health, and scale to your hearts content without distortion, only stretching the guts of it.
If you want some **** graphics for this, let me know, and I'll fire you over something appropriate to your game. I can't program to save myself, but I'm ok with graphics, and can then explain and posit where the slices should go to use 9-slice scaling.
The 9-Slice thing you're referring to is the SpriteNode's centerRect property. It defines the region that is scaled in both dimensions. It's broken in iOS 9 (at least for me). Bug hasn't been acknowledged yet.
I gave up on shape nodes a long time ago. Adding only a couple to my scene killed the framerate (from smooth 60 to 40).
Would it be better if I just used UIKit to add a UIImageview and fill it the color I want? I'd be able to modify that how I want and keep it in the scene.
centerRect...
Thank you nilPill!
I'll remember that the next time I want to try something (else) that doesn't work as advertised.
// sideNote: How/where do we start a compendium of fail points to make life easier for those of us silly enough to try do things within SpriteKit, SceneKit, Metal and Core Animation?
From my understanding (and I could be wrong) to use UIKit within a SceneKit game, you need to layer a UIView ontop of SceneKit.
In other words it's not actually "inside" SCNView.
But, as I say... I'm probably wrong. This is just my understanding of how the View Hierarchy "works".
Stick with the original suggestion and set the sprite's anchor point to the edge of the sprite and scale it.
Using a UI-object isn't a great idea. They don't work with scene transitions (since they aren't in the scene) and will sit on top of everything else.
It would take less time to learn Unity, which is the direction I'm leaning after this experience.
Unity isn't without weird issues.
You just have to take your choice when using a framework that ultimately you can't control directly.
This is not entirely true, because Open Sauce options exist. Yes, deliberate miss-spelling.
Open Sores?
More seriously, Cocos2D-X and Unreal are both completely open source, and updated at a breakneck speed.
What I find most refreshing about Unreal is that they recognised two huge problems, and fixed them by going open source.
1. Game engines are evolving things, and used and pressed harder than anything else, in more diverse ways than other frameworks, so bugs are always found, and problems. Open Source is the only correct solution to timely updates because it makes every user a potential fixer. Or, at least, a pointer to the problem.
2. Being Open Source should not mean "community made", because that seems to always lead to stagnation and/or divergence. They didn't sack programmers when they went Open Source, they hired more, and went ballistic updating, at a rate and manner that's (to my knowledge) unprecedented for a framework.
Some of problems of Unreal are:
- it's HUGE, Heavy, and relatively slow even on an iPad Air 2, plus compilation and building takes just short of forever without a dual Xeon rig.
- it runs a LOT better on a Windows machine with a beastly GPU (or two) than it does on a Mac
- There is nothing about it that could be considered lithe
- C++ (granted this is a very script-like use of C++, but it is still C++, and has compile times that mean you'll get in some TV viewing when iterating)
- Visual scripting (initially looks great, turns out it's painful, requires huge knowledge to really use, and is then super tedious
- Iterative design/development loops aren't rapid within this world of enormity
// Sidenote. That Apple doesn't make a modern dual Xeon rig that supports pro-level cards from Nvidia is super annoying. The Mac Pro seems like a Pro-Lite, to me. Wanting to use Unreal means conceding to building a beastly Windows Workstation to get acceptable performance and iteration times.
Cocos2D-X problems:
- Messy. Setting up a project is like untangling a spaghetti pasta dish, and just as dynamic
- It's (seemingly) always in flux
- Most of the great commentary and community is in Chinese (it's a HUGE community if you read/write Chinese)
- C++ is the best of its language options
- It's gots bits and pieces everywhere
However Cocos2D-X is also open source, so fixable whenever/wherever any problems are found, and there's some genius level Chinese developers tinkering with it that can (seemingly) contort it to anything.
---------------
Unity deserves its own special place in ****. It's fantastic for prototyping. Trying to go from there to production quality reliability is a nightmare of garguntuan proportions, even if staying with simplistic presentation. You will have issues. You will need to work around them, never through them, since that's rarely an option with their structure. Many things are broken, most aspects of the engine suffer terrible performance. Most of its community are non-critical, myopic yes-men.
---------------
I had enormous hopes that SceneKit (in particular, but also Sprite Kit for UI etc) would be a lightweight, lithe, enjoyable, performant and stable (and RELIABLE) fun framework to play within.
Sprite Kit shows promise, but somehow never attains it, showstoppers of all sorts always seeming to find their way into the mix. Perhaps it was good/great during the iOS 8 era, and I missed it -- it was shocking during iOS 7, and that put me off it for a generation of iOS. Now it seems to be a wreck, again.
-----------------
Back on topic:
There's no 2D drawing expertise/specialisation in Sprite Kit. It really is SPRITE focused, and not particularly great at/with that... seemingly.
SKShapeNode looks to be (at best) a debug line drawer.
It's immutable. That's probably the single biggest shocker. Making an entirely new 2D game engine without dynamic drawing is... ridiculous?
This, to my way of thinking, is a great shame, because the world could desparately use a truly well thought out, lithe, performant and enjoyable 2D drawing engine, and Sprite Kit seems the obvious place to add that.
Because Apple controls and builds its own stack, and makes Metal, they could do this better than anyone, ever.
Yet they give us SKShapeNode, which is basically a poorly wrapped, less performant and clumsier version of CAShapeLayer.
In fact, if I had to guess, I'd say most of SpriteKit is a wrapping around Core Animation. If you don't need the game loop, or want to write your own with CADisplayLink, you're probably better off using Core Animation directly.
So we're living in a world without a great 2D rendering and game engine, still, despite the touch phone and iPad era being the single greatest era of 2D gaming in history.
So I tried using a UIImageView and updating the frame size based on how much life % was remaining and it made my game VERY choppy. Which is weird because it says my FPS was still great.
You all have had some very informative posts here, but I still haven't found a way to add a mutable rectangle object to my game scene? Was there a good way to do this?
Yes, there is a "good" way left to you.
Make a graphic bar the size you want in Photoshop or other illustrative program, for your health bar. Save it as a bitmap, import it as a texture, and make a sprite that uses it.
Now scale it from one edge, from 0 to 100, along that one axis, depending on the health of your player, as a Sprite.
You can set the origin position from which scaling impacts a sprite, that's how you get it to only scale in one direction.
That's about as good as it gets, since centerRect is apparently broken for doing nicer scaling.
SKShapeNode's frame is determined by the current value of its path property (either supplied directly or generated for you via a constructor).
You can scale a SKShapeNode (like any other node) by using the scale, xScale or yScale properties. You can also generate a scaled path using the CoreGraphics API CGPathCreateCopyByTransformingPath(path, transform) and set the new path on the SKShapeNode.
Hope this helps,
-Tim