I am trying to figure out what is the best way to draw a line between two SKNodes in SpriteKit, nodes that move each frame. [Example sketch below... the red line is what I want to draw]
I can draw a line. At the moment I override the update call and every frame I detect the position of the two nodes (P1 and P2), and then simply draw a line [using an SKShapeNode and creating the path that goes from P1 to P2 then setting the shape node's path to it...].
It works and it performs well. However, that is handling two nodes, one line that visually connects them. What I am going to need is two draw multiple lines between multiple nodes. I feel like it'll be cumbersome to do so for N nodes to loop through each case every frame and remove and redraw lines.
I am wondering if there is a way to leverage physics body and joint to "add" a line between two nodes once and then have sprit kit handle the updates as the nodes move.
So, what is the best way to show lines between nodes that moves around every frame instead of having to loop through them each frame to redraw the line nodes as I get more nodes to handle?
Related
I am using GameplayKit to create paths around obstacles in a given map boundary (lets say a rectangle 1000x1000).
I know that you can make certain nodes avoid "obstacles" when pathfinding, which I am using quite nicely. What I am curious about however is such:
Is there a way to use this same logic and count anything not in the map boundary as an "obstacle"?
A work around would be to create 2 SKNodes and fit them together to create an inner "hole" which becomes 1000x1000, but I am trying to avoid unnecessary addition of nodes if there is a better way. Below I am showing what I could do.
Ideally I want to make the red and black area treated as an obstacle so that all paths remain inside the main square.
UPDATE:
I am using GameplayKit as I have already said, and the pathfinding algorithm can not count regions that are NOT included in a given physics body as an obstacle. It can only count obstacles to be closed polygons that lie within a region. Creating the 2 nodes as shown above works because the pathfinding will now not be able to create any points that lie outside the green rect.
Just have your game layered like this
Scene
SKNode topshape
SKNode bottomshape
SKNode innerbox <-- This is the size of your inner square
SKNode gamenodes <-- Place all inner nodes here
...
Then attach a SKPhysicsBody using an edge loop rectangle the size of innerbox, to the innerbox SKNode and make it a wall category, this will keep all your nodes inside, providing your nodes do not move at insane speeds breaking the engine.
You would be adding 1 additional node instead of 2 (Technically you could make bottomshape and topshape 1 node, making it 0 nodes added), but all processing would get done within the inner node, so not much overhead gets added.
I want to have a path that my node can travel around on demand.
For example, I want to have a circle in the middle of the screen and when i tap the left side of the screen, my SKSpriteNode will move in a counter-clockwise direction on the circle (and the same if i tap the right side of the screen).
From what I've researched, I can create the circular path using SKShapeNode, CGPathRef, or even UIBezierPath. Creating the path isn't the issue. In all the instances I've seen researching this topic, most people just use [SKAction followPath:path duration:1.0] and this makes the node go around the the circular path ENTIRELY in 1.0 seconds. I want to be able to tap left/right and only move incremental amount of space per tap. (If anyone's played Super Hexagon, think of the fluid circular motion of that game)
*Note: I only use a circular path as an example so I don't particularly need specific pointers on how to move around a circle per se, but more of ANY path of any shape.
You can create any kind path shape you want using CGPath. This gives you the ability to create only the path for which you need to move your node. To use your circle example, create a 90 degree arc path and your node will move 4 separate times to complete a full circle.
If you do not want to use a path, you can also use the SKAction moveBy x,y,duration command. Tie a couple of those together and use them in a block sequence and you have yourself a generic path function.
I hope you all can help with this. I'm working on app of a board game. I have hex shaped tiles which are called randomly and laid out at the start of the game. Each of these tiles has four sides with a value of 1 and the other two sides have values of 2 and 3.
Each tile is a SKSpriteNode with transparent rectangle Nodes on the edges. There are 5 different types of tiles and they need to be separate Sprites with child nodes because in addition to being randomly laid out they area also randomly rotated. So I need to know programmatically which tile edges are touching which edges of other tiles.
Like this:
https://app.box.com/s/nnym97st3xmrsx979zchowdq1qwsmpoo
(I tried to post an image of what I'm trying to accomplish, but apparently I don't have a high enough of a rating.) ;-)
For example: If a "2" is touching a "3", etc.
I first tried Collision detection, but of course that only works with dynamic, moving objects.
I tried an IF statement to compare if the other nodes were touching and then remembered that the coordinates where specific to the Parent Node, so that didn't work.
I then tried intersectsNode, but that seems to only work with nodes under the same parent.
I am currently working with convertPoint in order to get the coordinates to match the scene and thus be comparable. But I can't seem to get it work the way I need.
There must be something simple that I am not seeing. Any ideas?
Certainly not simple.
One solution would be to start all your shapes slightly spaced out from each other. Add invisible child nodes with physics bodies to all six sides and give each physics body an appropriate category based on their rating (1, 2 or 3).
When you start the game, move all the outer nodes into their proper position (sides touching) by using whatever movement method your prefer. This will give you contact messages as each hex side touches another. The contact messages will tell you what side number is touching its neighbor.
The exact coding of this idea depends on your current code, game play, etc...
I currently have a scene which contains a central node at the root of the scene with earth-like geometry and a node representing a flying vehicle.
However I cannot find the right approach to control the movement of the vehicle. I need the ability to turn left and right while orbiting at a static altitude and speed.
I have tried many combinations of animations and physics body forces all leading to undesirable results.
The closest I've come is:
Setting the pivot property of the vehicle to the centre of the scene
Then setting an Action like below to control moving forward
[_vehicleNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:-1 y:0 z:0 duration:10.0]]];
Then finally applying forces for turning left and right with
[_vehicleNode.physicsBody applyTorque:SCNVector4Make(0, 1, 0, 1) impulse:YES];
However I cannot seem to set the pivot and/or position to the right value to get the desired result.
Edit: It appears as the above method would be the solution I'm looking for, however for some reason when I add geometry to the vehicle node, it's position in the scene graph gets changed dramatically. When I add hardcoded buttons to change it's position to where it belongs it appears correct for only that single frame then straight back to being in the middle of nowhere.
Edit 2: After replacing all geometry with a primitive sphere for testing the node is now rotating as intended but is now unaffected by physics forces appearing to ignore it's declaration as a dynamicBody.
If I understand what you are trying to achieve correctly, you can try this:
add a first node to your scene, positioned at (0,0,0) and make it rotate forever along the Y axis using an SCNAction
add your ship node as a child of the first node. Position it at (X,0,0) so that it orbits around the earth
rotate your ship node along the X axis with an action or an animation
The game I'm designing uses multiple nested CCSprites, so that when the parent sprite moves, rotates, scales, etc. the child sprite does as well, automatically, and so do its grandchildren.
It works great but bogs down very quickly since I haven't implemented batch nodes, currently it's making over 4000 draw calls at once which is obviously not optimal.
However as far as I know the only way to use batch nodes is to make all the sprites a child of the batch node. I thought maybe I could add each parent to the batch node and then add the rest as children of that one but that doesn't work.
Any ideas? I'd like to avoid having to manually calculate the position, rotation, scale, etc of each child sprite every time its parent moves, which at the moment seems to be the only way I can think of to make this work.
Looks like you CAN in fact nest children inside a ccsprite and have them be a part of the batch node, as long as the parent is a child of the batch node. When I first tried this I'd simply forgotten to change "spriteWithFile:" to "spriteWithSpriteFrameName:" when I created the children of one of the sprites. Now it works perfetly, all in one batch node, with one draw call. Hooray!