I am doing this spritekit game.
I have this object that I want to move up and down when the user touches it. It is an object that has to slide in a rail, up and down or in another case left and right.
So, when the user touches the object I do something like this
CGVector force = CGVectorMake(0.0f, 5000.0f);
[object.physicsBody applyForce:force];
it is a vertical force applied up.
but when the object collide with others it rotates. Is there a way to prevent the object from rotating?
Try object.physicsBody.allowsRotation = NO. This ignores all angular impulses and forces that would make the body rotate.
Related
I am new to SceneKit and I could use your help with the following:
I have two SCNViews
- a large one (skView) showing the scene for the user which can be manipulated by the user with the standard allowsCameraControl option enabled
- another small one (coordinateCrossView) in the left corner which shows a coordinate cross that I would like to mirror any camera navigation the user performs in the large SCNView
I implemented it by making the ViewController which holds both SCNViews a SCNRendererDelegate and by updating the cross' orientation in the renderer: updateAtTime: method like so:
- (void)renderer:(id<SCNSceneRenderer>)renderer updateAtTime:(NSTimeInterval)time {
[self.coordinateCrossView.scene.rootNode childNodeWithName:#"cross" recursively:YES].orientation = self.skView.pointOfView.orientation;
[self.coordinateCrossView setNeedsDisplay];
}
So far so good. However, this only works when the user is manipulating the large SCNView with a finger on the screen. After as swipe gesture when the finger leaves the screen the object in the large SCNView continues to rotate a bit - but the coordinate cross is not updated.
Any ideas why this behavior is not captured by the pointOfView.orientation changes?
I found out what the problem was: the small coordinateCrossView was not continuously updated and therefore even though the coordinate cross' orientation was changed, the view didn't show it - even though setNeedsDisplay was called.
I fixed the issue by setting the isPlaying property of the coordinateCrossView which forces it to be updated.
I'm create a SKNode to the scene and logging touch events on each individual SKNode. I can add as many as I want and the touches work as expected, if I touch the node and only the visible node do I see the log messages. Now, if I add another SKShapeNode to any of the previous SKNode's the touch area expands to be more of a rectangle and now I see the log message even if I touch outside the origin SKNode.
The first picture shows the original touch area of the SKNode and the second is the new touch area after adding a child SKShapeNode to that SKNode. The SKShapeNode being added is 20x20 so it fits within the 20x100 bar.
The problem is I now get multiple touch events when touching the other bars since they overlap. Is there any way around this?
You appear to be using separate graphics for each angle of your line. Instead try using the same graphic with your line at 0 degrees and then using the zRotation to angle it. I have not tried this myself but I think it will fix your issue.
Alternately try using containsPoint for your touch recognition in the touchesBegan method. You can check if the touch is within any of the nodes and process accordingly.
I'm currently creating a 2D game in Swift using SpriteKit and I'm having a problem with the collision detection.
Let's say I have SKSpriteNode Foo in the game. Then let's say SKSpriteNode Bar spawns on top of Foo, but does NOT have the contactTestBitMask to trigger a contact. Then after a short moment (let's say 1 second) Bar changes its contactTestBitMask to detect contact with Foo.
Currently, Foo will have to actually move around a little bit OR move out from under Bar and return back to it to detect contact with it. I need Bar to immediately trigger contact with Foo when it changes its contactTestBitMask.
Maybe there's a different way to do this without changing the contactTestBitMask?
Thanks!
If you create a physics body object intersecting another physics body object, no collision will register. It has something to do with the way SK registers a collision through movement only.
You have the option of using intersectsNode: when creating your object to see if it intersects another object and handle any subsequent code accordingly.
I'm messing around with Swift for the first time and have a square on the screen. The square starts by moving to the right. When I tap on it I want it to go up. I don't want it to continue to the right at all, I want it to just go straight up. Unfortunately the physics and gravity make it curve to the right some more before it goes up. What can I do to completely stop the gravity pull and acceleration of my object, before setting the gravity to the new value?
This turns the object in the right direction, but I need it to come to an instant stop before doing this.
if(self.gravity.gravityDirection.dx == 1){
self.gravity.gravityDirection = CGVectorMake(-1.0, 0.0)
}
The way to stop an item being affected by a behavior is to remove the item from the behavior or remove the behavior from the animator. For example, here you might remove self from the existing gravity behavior.
I have a sprite kit physics body that I want to be controlled by touching by moving it towards the location where the user touched in touchesBegan and touchesMoved. I have tried the SKAction move and let's just saw it didn't suit my purposes. I have tried applyImpulse and it suited my purpose, but each time it overshot cause the velocity cause it to go through the location every time, and if I made new locations the object went flying around back and forth. I would like it to follow the current touch somewhat fast, and not slowly crawl toward the user's finger. Is there an easy way to make the object follow the touch when the user is touching and stop moving when the user lets go that will go well with the psrite kit physics engine? I want the object to bounce other objects off it but not bounce itself.
Add a few things:
a Boolean flag to set whether or not the Sprite has been assigned a new location
a CGPoint storing the new desired location
a method that checks if the location of the sprite is close enough to the CGPoint to be considered as arrived
When the touch is issued, store the point and set the Boolean to YES then initiate the force on the sprite.
Inside the update method put a call to that checker method that is called if the Boolean you made is YES.
If that check returns true, set the velocity to zero (or otherwise stop the sprite how you see fit) and set the Boolean back to NO so that check method stops firing.