How to move an object towards a direction without stopping - swift

I'm developing a small game in Swift 3 with SpriteKit and I want to move the enemies to the direction of the character, but at all times the enemies stop when they arrive at the character's initial position.
I'm doing this:
enemigo.name = "enemigo"
enemigo.position = CGPoint(x: 280, y: 100)
enemigo.xScale = 1/1
enemigo.yScale = 1/15
addChild(enemigo)
let movement1 = CGVector(
dx: (enemigo.position.x - personaje.position.x)*10,
dy: (enemigo.position.y - personaje.position.y)*10
)
let actionTransaction = SKAction.move(by: movement1, duration: 20)
enemigo.run(actionTransaction)
How should I move the enemies to a specific direction without stopping at the initial position of the character?

You've done all the hard work figuring out the vector of direction.
Now you can repeat this moveBy action as often as you like, and the enemy will keep moving in the same direction, further and further, because move(by: CGVector) is relative, not absolute:
let actionTransaction = SKAction.move(by: movement1, duration: 20)
So all you need do is run this forever with a key, so you can then seek it out from anywhere, and stop it whenever you like.
run(SKAction.repeatForever(actionTransaction), withKey: "movingEnemy")

Alternatively, you could consider using GameplayKit together with SpriteKit. GameplayKit provides standard implementations of common algorithms for games and can be used together with SpriteKit.
Unfortunately I'm not too familiar with it, so I can't give you code. I would suggest having a look at Apple's GameplayKit programming guide. There are functions available for setting a goal of an agent (e.g. an enemy) to move toward a specific location, avoid obstacles, intercept another agent, or flee from an agent, etc.
So while your player moves, some enemies could be programmed to try and catch the player, while other enemies could try to run away from the player. Other enemies could be made to wander around randomly, etc.
So in a nutshell, GameplayKit can add quite powerful functionality to a SpriteKit game. This could mean spending a bit more time upfront thinking about the architecture of your game, but in the end it could be worth it if you will also use the other functionalities of GameplayKit.

Related

How to make an auto scroller game using sprite Kit?

I am trying to make an auto scroller game. I have my Character and my ground as two separate nodes. My problem is that I don't if I should make the character or my ground move indefinitely, and how.
I did try moving my player indefinitely but I don't think I am doing it right.
let move = SKAction.repeatForever(SKAction.moveTo(x: player.position.x + 10, duration: 1))
player.run(move)
For the moment the player kinda trips on the ground. I am completely lost, I hope someone has done this before and can give me the answer. Thank You Very Much
ok found the answer myself
I should have tried this before
anyway what I did Is make my ground run the move action
let move = SKAction.repeatForever(SKAction.moveBy(x: -200, y: 0, duration: 1))
GroundNode.run(move)

Does collision work during animation for SceneKit?

I wanted to do a simple asteroids games where the asteroids go from far to bypass you (z>0) in SceneKit.
let moveAction = SCNAction.move(to: SCNVector3(0, -10, 10), duration: 2)
rockNode.runAction(moveAction)
Says I have a spaceship in Z axis 0, even though I can visually see the asteroids pass through the spaceship, the collision detection does not occurred. The collision only happened if the end point of the moveAction ends in Z axis 0 and in the same location as the spaceship.
Does detection only occurred after the moveAction ended (thus will not detect collision)? If yes, what solution do I have in detecting the collision during the asteroids movement?
did you set the isDynamic to true on both of your objects? and they both need to have different categoryBitmasks otherwise SceneKit will treat them as the same objects (can't comment don't have 50 rep yet) if not then do so collision should happen even when moving an object programmatically
Make the physics body as: kinematic. So it can detect collision even during SCNAction.
eg:
rockNode?.type = .kinematic
Or you can set it from Physics Inspector
Keep coding....... :)

Random Downwards Motion of SKSpriteNode with Constraints in Swift

I am making a small SpriteKit game in Swift playgrounds and it is an asteroid defence type of game. Basically,the player is defending the spacecraft with a cannon and has to destroy approaching rocks. The image link below is my scene without the gun added yet, but basically I want the rocks to move slowly down from the top towards the spacecraft at the bottom (Sorry, it's too big to add in here).
https://www.dropbox.com/s/pisgazar4jaxra0/Screenshot%202017-03-18%2011.23.17.png?dl=0
The rocks will be SKSpriteNodes and I want to speed them up for each successive rock to increase difficulty over time.
How would I be able to implement this. I have seen some answers elsewhere about using UIBezierPaths but how do I make it random but with the constraint that the rocks only fall from above?
Thanks in advance!
If you only need them to go from top to bottom without any special curvy trajectory then you don't need to deal with splines.
Let's address the gradual acceleration first. You want them to fall slowly in the beginning and speed up during game progress. One approach would be to do track level time and do some duration math based on elapsed level time. An easier one would be to decrease the duration of time taken by the asteroid to reach the bottom. In your scene declaration section, declare those:
fileprivate let startingDuration: TimeInterval = 6.0 // Put here whatever value you feel fit for the level start falling speed
fileprivate let difficultyIncrease: TimeInterval = 0.05 // Put here whatever value you feel fit for how much should each next asteroid accelerate
fileprivate let collisionPosition = CGPoint(x: 300, y: 200) // Put here the onscreen location where the asteroids should be heading to
fileprivate var asteroidCounter = 0 // Increase this counter every time you spawn a new asteroid
Now, let's get down to the actual asteroid movement. There are different ways to approach it. The easiest one and recommended by Apple is to use an action for that. Add this code to your asteroid spawn method:
// Implement here your spawning code ...
// It's best to choose random starting points (X axis) a bit higher than the upper screen boundary
let fallingDuration: TimeInterval = startingDuration - difficultyIncrease * TimeInterval(asteroidCounter)
let fallingAction = SKAction.move(to: collisionPosition, duration: fallingDuration)
asteroid.runAction(fallingAction)
If you need a function for random integer generation, try this:
func RandomInt(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max-(min-1)))) + min
}

Moving a Sprite Swift

What I'm trying to do is moving a sprite in a random direction or a random point and have it continue moving - with the affects of physics. I tried moving a sprite to a random point and although it worked, it just stopped if the random point was in the middle of the screen. I'm just hoping for the basics so any code/help from someone would be helpful. Also if you think theres a post already on this, can you list the hyperlink? I spent some time researching and I couldn't figure it out. Thanks in advance!
See SKPhysicsBody and methods like applyImpulse.
In short, you create and configure an SKPhysicsBody; assign it to the sprite; and then apply force vectors to the body. Procedural example:
let sprite = SKShapeNode(circleOfRadius: 10)
sprite.physicsBody = SKPhysicsBody(circleOfRadius: 10)
sprite.physicsBody.friction = 0.2
sprite.physicsBody.restitution = 0.75
sprite.physicsBody.mass = 0.5
sprite.physicsBody.applyImpulse(CGVector(1, 1))
Much of this you can configure declaratively, rather than procedurally, with the SpriteKit scene editor in Xcode.

How to have a character moved around the screen?

I already have a joystick programmed (finally) and I was wondering how I would get a 'hero' to move about the screen based on where the joystick is? I am using Cocos2d and any help would be greatly appreciated!
The simplest way to do this is to subclass CCNode for your player object and then manipulate it as you would any other CCNode. To start with, you can change the player's position struct like so:
player.position = ccp( player.position.x + [joystick xValue],
player.position.y + [joystick yValue]);
This is making some assumptions about how you want your joystick and player to behave, as well as some properties of the joystick class, but hopefully you get my drift. If it isn't clear, [joystick xValue] and [joystick yValue] would be some bounded value (between -1 and 1, say) representing the touch's position on the joystick. Depending on the range of values, you may want to then scale this by some constant to move the player faster or more slowly.
The cocos2d web site has a great tutorial for beginners that I'd highly recommend. You might want to read up on the CCAction class as well for more complicated maneuvers.