Swift 4: SKActionMoveBy goes left instead of right - swift

i have an SKSpriteNode named MainTank however when i try to move the tank, it goes left instead of what i did, here's my code
let moveRight = SKAction.moveBy(x: MainTank.position.x + 4, y:0, duration:0.1)
MainTank.run(moveRight)
thanks

The moveBy SKAction moves the sprite by the specified amount, so adding your sprite's current position does not make sense. Not sure why it is moving left but perhaps your sprite is already at a negative position?
To move by a distance of 4 use:
let moveRight = SKAction.moveBy(x:4, y:0, duration:0.1)
Or alternatively use the moveTo SKAction.

Related

Adding multiple instances of objects spritekit swift 3

I am trying to add multiple instances of my object (bullet) so the player can shoot the bullet and then shoot another bullet. I am using the following code but it is giving me a thread 1 signal sigbart error. Can someone please explain whats wrong with the code? Thanks!
let bulletmove = SKAction.moveTo(y: self.frame.height, duration: 2)
let bulletremove = SKAction.removeFromParent()
addChild(bullett)
bullett.run(SKAction.sequence([bulletmove, bulletremove]))
if you add an SKSprite multiple times it would an error would occur.
What you need to do is create an SKSpritenode to add each time. You can have a function to do create bullets eachtime
func addBullet(){
var bullet = SKSpriteNode(imagenamed: "bullet")
bullet.position = //Give the point of origin as CGPoint. Maybe same as the shooter..
addChild(bullet)
bullet.run(SKAction.moveTo(y: self.frame.height, duration: 2))
}
So each time you call addBullet(),maybe in touches began , you can create new bullet that moves to end of screen without a crash.
So main point is have var bullet = SKSpriteNode(imagenamed: "bullet") for each addChild.

Why does the physics joint stop working if the object will move out of the view?

I have a construction crane that has a joint with an object. The joint works fine if the crane is stationary.
But I added the ability for the crane to move left to right and whenever the crane is about to leave the view with the object, the object hits the edge of the screen and gets stuck while the crane keeps going. The joint also stops working even after the crane has come back to the view.
Here's an image. The yellow line at the top represents the path the hook follows forever. It goes left to right. The gold block that's around the blue rectangle is what's getting stuck. That's the block that's originally jointed with the crane's gray hook. But when the hook moves to right side of the view, the gold block hits the edge of the screen and stays there forever.
What doesn't make sense to me is that the edge of the view has a category bit mask of 0 while the gold block is at 64. In other levels, the gold blocks NEVER collide with the edge. But here when the crane moves to the edge, the gold block collides with the edge and gets stuck. As you can see, the joints are still there based on the light blue physic lines.
This is the code of the joint being called from the scene and configuring it. Like I said, joint works fine if the hook is stationary.
craneBase.alpha = 0
let path = CGMutablePath()
path.move(to: CGPoint(x: craneBase.position.x, y: craneBase.position.y))
path.addLine(to: CGPoint(x: craneBase.size.width - 100, y: craneBase.position.y + 10))
path.addLine(to: CGPoint(x: craneBase.position.x, y: craneBase.position.y))
craneHook.initializeMovingJoint(withObject: childNode(withName: "HookedObject") as! SKSpriteNode)
hook.run(SKAction.repeatForever(SKAction.follow(path, asOffset: false, orientToPath: false, duration: 10)))
physicsWorld.add(craneHook.joint)
This is the code of the crane's hook class that adds the joint to the block.
private func initHook() {
self.hookSize = CGSize(width: 10, height: 10)
self.physicsBody = SKPhysicsBody(rectangleOf: hookSize)
self.physicsBody?.categoryBitMask = PhysicsBit.none
self.physicsBody?.isDynamic = false
self.physicsBody?.affectedByGravity = false
}
//Creates the joint between the object and the hook
func initializeJoint(withObject object: SKSpriteNode) {
initHook()
hookedObject = object
jointAnchor = CGPoint(x: self.anchorPoint.x, y: self.anchorPoint.y)
joint = SKPhysicsJointFixed.joint(withBodyA: physicsBody!, bodyB: hookedObject.physicsBody!, anchor: jointAnchor)
doesHaveHookedObject = true
}
And the gold block's settings are assigned from the scene editor to a category mask of 64. I've tested the gold blocks and they don't collide with the edge. I'm not sure why it collides with the edge while moving.
I realized it was not working because the joint and the physicsWorld had the same category bit mask. Even though the gold block had a different bit mask, it was part of the joint and thus collided with the same category bit mask as none.

Swift 2: SKAction to change y position

I have a SKAction that changes the y position of a sprite. The sprite is affected by gravity towards the right, and when i set the x position in the SKAction to the sprite's position the sprite movement is slowing down while the Action is running.
How can i change this so that the x movement is not effected by the action running?
let moveDown = SKAction.moveTo(CGPoint(x: player.position.x, y: 0), duration: 0.3)
player.runAction(moveDown)
You could try using linearDamping. I'm not sure this is exactly what you're looking for, but it's a property that reduces the body’s linear velocity.
player.physicsBody!.linearDamping = 0.0
Let me know if this works for you or if this wasn't what you were looking for!
Solved it using this code:
let moveDown = SKAction.moveToY(0, duration: 0.3)
player.runAction(moveDown)

Resetting and changing speed on SKActions

Is there a way to change the velocity/speed of a skaction and also to reset the skaction?
let wait = SKAction.waitForDuration(5.0)
let moveRight = SKAction.moveByX(300, y:0, duration: 1.0)
let sequence = SKAction.sequence([wait, moveRight])
let endlessAction = SKAction.repeatActionForever(sequence)
node.runAction(endlessAction)
This code works but the things i would like to change is how fast the SKSpriteNode moves to the right as at the moment it it quite slow and also to make the SKSpriteNode return to its orignal position rather than keep on moving to right forever?
Thank you
Since velocity = distance / time, decreasing the duration will increase the speed the the sprite will move across the screen.
Regarding your second point, by considering how SKAction.moveByX(300, y:0, duration: 1.0) moves the node to the right; SKAction.moveByX(-300, y:0, duration: 1.0) must therefore move the node to the left, back to its original position.
Hope that helps.

Constraining movement of a SKSpriteNode to a fixed area within a scene

How can I constrain manual movement of an SKSpriteNode to a fixed rectangular area within a scene? This fixed rectangular area a also a SKSpriteNode which is fixed within the scene. In other words, I want to constrain manual movement of an object (SKSpriteNode) to be completely contained within another SKSpriteNode or at least in the same space that it occupies. I have tried several different approaches (e.g. using an SKShapeNode that has an edged-based physics body), but nothing seems to work. This seems like it should be a fairly simple task to accomplish. Thanks for any help or hints you can offer.
Put an if statement around your moving code - so don't carry out the movement if it will take the object past your boundary. e.g.
//check that a positive movement won't take your node past the right boundary
if(node.position.x + yourXMovementValue < boundaryXRight){
//move your node
}
//same for y
let rangeX = SKRange(lowerLimit: CGFloat, upperLimit: CGFloat)
let contraintX = SKConstraint.positionX(rangeX)
let rangeY = SKRange(lowerLimit: CGFloat, upperLimit: CGFloat)
let contraintY = SKConstraint.positionY(rangeY)
yourObject.constraints = [contraintX, contraintY]