How to Make Player Move to Opposite Side While Is in a Path

How to make player move to opposite side while is in a path?

One of the easiest ways to move an object in a circular path is to

  1. Create a SKNode container
  2. Create a sprite
  3. Add the container to the scene
  4. Set the sprite's x position to the radius of the circular path
  5. Add the sprite to the container
  6. Rotate the container

If you want to move the sprite to the other side or change the rotation's radius, simply


  1. change the sprite's x position

If you want to change the direction of the rotation,


  1. reverse the container's rotation

Example Code:

// 1) Create the container node 
let node = SKNode()
// 2) Create a sprite
let sprite = SKSpriteNode(color:SKColor.blueColor(),size:CGSizeMake(20,20))
var rotation:CGFloat = CGFloat(M_PI)
let radius:CGFloat = 50

override func didMoveToView(view: SKView) {
scaleMode = .ResizeFill
node.position = view.center
// 3) Add the container to the scene
addChild(node)
// 4) Set the sprite's x position
sprite.position = CGPointMake(radius, 0)
// 5) Add the sprite to the container
node.addChild(sprite)
// 6) Rotate the container
rotate()
}

// Rotate the container
func rotate() {
let action = SKAction.rotateByAngle(rotation, duration: 4)
node.runAction(SKAction.repeatActionForever(action),withKey: "rotate")
}

// 8) Reverse the direction of the rotation
func reverse() {
rotation = -rotation
}

// Stop rotating the container
func stopRotation() {
if node.actionForKey("rotate") != nil {
node.removeActionForKey("rotate")
}
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* 7) Change the sprite's x-position */
if sprite.actionForKey("move") == nil {
stopRotation()
let opposite = -sprite.position.x * 2
let move = SKAction.moveByX(opposite, y: 0, duration: 3)
let rotate = SKAction.runBlock {
self.rotate()
}
sprite.runAction(SKAction.sequence([move, rotate]), withKey: "move")
}
}

How to move sprite to center while is in a path and then return to the original path?

One of the easiest ways to move an object in a circular path is to

  1. Create a SKNode container
  2. Create a sprite
  3. Add the container to the scene
  4. Add the sprite to the container
  5. Set the sprite's x position to the radius of the circular path
  6. Rotate the container

If you want to move the sprite to the another circle with a different radius,


  1. change the sprite's x position
  2. move the container's position (optional)

If you want to change the direction of the rotation,


  1. reverse the container's rotation

Here's an example:

// Define circle
struct Circle {
var position:CGPoint
var radius:CGFloat
}

class GameScene: SKScene {
// 1. Create container node
let node = SKNode()
// 2. Create a sprite
let sprite = SKSpriteNode(color:SKColor.blueColor(),size:CGSizeMake(10,10))
var rotation:CGFloat = CGFloat(M_PI)
var circles:[Circle] = []

override func didMoveToView(view: SKView) {
scaleMode = .ResizeFill

circles.append(Circle(position: view.center, radius: 80))
circles.append(Circle(position: view.center, radius: 40))
// 3. Add the container to the scene
addChild(node)

// 4. Add the sprite to the container
node.addChild(sprite)
// 5. Set the sprite's x position to the radius of the circular path
if let circle = nextCircle() {
node.position = circle.position
sprite.position = CGPoint(x:circle.radius, y:0)
// 6. Rotate the container
rotate()
}
}

// Rotate the container
func rotate() {
let action = SKAction.rotateByAngle(rotation, duration: 4)
node.runAction(SKAction.repeatActionForever(action),withKey: "rotate")
}

// 9. Reverse the container's rotation
func reverse() {
rotation = -rotation
}

// Stop rotating the container
func stopRotation() {
if node.actionForKey("rotate") != nil {
node.removeActionForKey("rotate")
}
}

// Returns the next circle's parameters and rotates the array
func nextCircle() -> Circle? {
guard let circle = circles.first else {
return nil
}
// Move the current circle to the back of the queue
circles.append(circles.removeAtIndex(0))
return circle
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Change the sprite's x-position */
if sprite.actionForKey("move") == nil {
stopRotation()
// 7. change the sprite's x position
// 8. move the container's position (optional)
if let circle = nextCircle() {
let radius = CGPoint(x:circle.radius, y:0)
let moveCenter = SKAction.moveTo(circle.position, duration: 3)
let move = SKAction.moveTo(radius, duration: 3)
let rotate = SKAction.runBlock {
self.rotate()
}
sprite.runAction(SKAction.sequence([move, rotate]), withKey: "move")
node.runAction(moveCenter, withKey: "move")
}
}
}
}

Create path to move player from current position to new position through a turn circle

Funny, I actually have motion in my game almost exactly as you described except that instead of always going clock-wise when on the right side and counter-clock when on the left, it will pick the closer path.

So I grabbed some of the code and modified it sightly to fit your description. It will move left when the target point is to the left of the player, else it will move right. You can also set the speed of the node, as well as the radius and position of the "orbit."

My implementation however does not use SKActions and paths to move. Everything is done dynamically in real-time which allows for collisions with the moving objects and greater motion control. However if you absolutely need to use paths with SKActions let me know and I'll try to come up with a solution. Essentially what it comes down to is finding the arc to the tangent points (which the code already does to an extent).

The physics calculations come from my two answerers here, and here.

The way the implementation works is that it first determines the final destination point, as well as the angular distance to the best tangent point using a secondary circle to find the tangent points. Then using centripetal motion, the node moves along the path to the tangent point and then switches to linear motion to finish moving to the end destination.

Below is the code for the GameScene:

import SpriteKit

enum MotionState { case None, Linear, Centripetal }

class GameScene: SKScene {
var node: SKShapeNode!
var circle: SKShapeNode!
var angularDistance: CGFloat = 0
var maxAngularDistance: CGFloat = 0
let dt: CGFloat = 1.0/60.0 //Delta Time
var centripetalPoint = CGPoint() //Point to orbit.
let centripetalRadius: CGFloat = 60 //Radius of orbit.
var motionState: MotionState = .None
var invert: CGFloat = 1
var travelPoint: CGPoint = CGPoint() //The point to travel to.
let travelSpeed:CGFloat = 200 //The speed at which to travel.

override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
circle = SKShapeNode(circleOfRadius: centripetalRadius)
circle.strokeColor = SKColor.redColor()
circle.hidden = true
self.addChild(circle)
}
func moveToPoint(point: CGPoint) {
travelPoint = point
motionState = .Centripetal

//Assume clockwise when point is to the right. Else counter-clockwise
if point.x > node.position.x {
invert = -1
//Assume orbit point is always one x radius right from node's position.
centripetalPoint = CGPoint(x: node.position.x + centripetalRadius, y: node.position.y)
angularDistance = CGFloat(M_PI)
} else {
invert = 1
//Assume orbit point is always one x radius left from node's position.
centripetalPoint = CGPoint(x: node.position.x - centripetalRadius, y: node.position.y)
angularDistance = 0
}
}

final func calculateCentripetalVelocity() {
let normal = CGVector(dx:centripetalPoint.x + CGFloat(cos(self.angularDistance))*centripetalRadius,dy:centripetalPoint.y + CGFloat(sin(self.angularDistance))*centripetalRadius);
let period = (CGFloat(M_PI)*2.0)*centripetalRadius/(travelSpeed*invert)
self.angularDistance += (CGFloat(M_PI)*2.0)/period*dt;
if (self.angularDistance>CGFloat(M_PI)*2)
{
self.angularDistance = 0
}
if (self.angularDistance < 0) {
self.angularDistance = CGFloat(M_PI)*2
}
node.physicsBody!.velocity = CGVector(dx:(normal.dx-node.position.x)/dt ,dy:(normal.dy-node.position.y)/dt)

//Here we check if we are at the tangent angle. Assume 4 degree threshold for error.
if abs(maxAngularDistance-angularDistance) < CGFloat(4*M_PI/180) {
motionState = .Linear
}
}

final func calculateLinearVelocity() {
let disp = CGVector(dx: travelPoint.x-node.position.x, dy: travelPoint.y-node.position.y)
let angle = atan2(disp.dy, disp.dx)
node.physicsBody!.velocity = CGVector(dx: cos(angle)*travelSpeed, dy: sin(angle)*travelSpeed)

//Here we check if we are at the travel point. Assume 15 point threshold for error.
if sqrt(disp.dx*disp.dx+disp.dy*disp.dy) < 15 {
//We made it to the final position! Code that happens after reaching the point should go here.
motionState = .None
println("Node finished moving to point!")
}
}

override func update(currentTime: NSTimeInterval) {
if motionState == .Centripetal {
calculateCentripetalVelocity()
} else if motionState == .Linear {
calculateLinearVelocity()
}
}

func calculateMaxAngularDistanceOfBestTangent() {
let disp = CGVector(dx: centripetalPoint.x - travelPoint.x, dy: centripetalPoint.y - travelPoint.y)
let specialCirclePos = CGPoint(x: (travelPoint.x+centripetalPoint.x)/2.0, y: (travelPoint.y+centripetalPoint.y)/2.0)
let specialCircleRadius = sqrt(disp.dx*disp.dx+disp.dy*disp.dy)/2.0
let tangentPair = getPairPointsFromCircleOnCircle(centripetalPoint, radiusA: centripetalRadius, pointB: specialCirclePos, radiusB: specialCircleRadius)
let tangentAngle1 = (atan2(tangentPair.0.y - centripetalPoint.y,tangentPair.0.x - centripetalPoint.x)+CGFloat(2*M_PI))%CGFloat(2*M_PI)
let tangentAngle2 = (atan2(tangentPair.1.y - centripetalPoint.y,tangentPair.1.x - centripetalPoint.x)+CGFloat(2*M_PI))%CGFloat(2*M_PI)
if invert == -1 {
maxAngularDistance = tangentAngle2
} else {
maxAngularDistance = tangentAngle1
}
}

//Not mine, modified algorithm from https://stackoverflow.com/q/3349125/2158465
func getPairPointsFromCircleOnCircle(pointA: CGPoint, radiusA: CGFloat, pointB: CGPoint, radiusB: CGFloat) -> (CGPoint,CGPoint) {
let dX = (pointA.x - pointB.x)*(pointA.x - pointB.x)
let dY = (pointA.y - pointB.y)*(pointA.y - pointB.y)
let d = sqrt(dX+dY)
let a = (radiusA*radiusA - radiusB*radiusB + d*d)/(2.0*d);
let h = sqrt(radiusA*radiusA - a*a);
let pointCSub = CGPoint(x:pointB.x-pointA.x,y:pointB.y-pointA.y)
let pointCScale = CGPoint(x: pointCSub.x*(a/d), y: pointCSub.y*(a/d))
let pointC = CGPoint(x: pointCScale.x+pointA.x, y: pointCScale.y+pointA.y)
let x3 = pointC.x + h*(pointB.y - pointA.y)/d;
let y3 = pointC.y - h*(pointB.x - pointA.x)/d;
let x4 = pointC.x - h*(pointB.y - pointA.y)/d;
let y4 = pointC.y + h*(pointB.x - pointA.x)/d;
return (CGPoint(x:x3, y:y3), CGPoint(x:x4, y:y4));

}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touchPos = (touches.first! as! UITouch).locationInNode(self)
node = SKShapeNode(circleOfRadius: 10)
node.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
node.physicsBody = SKPhysicsBody(circleOfRadius: 10)
self.addChild(node)

moveToPoint(touchPos)
calculateMaxAngularDistanceOfBestTangent() //Expensive!

circle.hidden = false
circle.position = centripetalPoint
}
}


Sample Image

Note that the circle you see is another node I added to the scene to make the motion more visible; you can easily just remove it. When debugging you might also find it useful to add nodes at the tangent points. The tangentPair tuple inside the calculateMaxAngularDistanceOfBestTangent function contains the two tangent points.

Additionally note that finding the tangent points/angles is expensive but it only happens each time you need to move to a new point. If however you game requires constantly moving to a new point, using this algorithm repeatedly on many nodes can be costly (always profile before assuming this though). Another way to check when to move from centripetal motion to linear motion is to check if the velocity vector is approaching the end position as shown below. This is less accurate but allows you to remove the calculateMaxAngularDistanceOfBestTangent function entirely.

let velAngle = atan2(node.physicsBody!.velocity.dy,node.physicsBody!.velocity.dx)
let disp = CGVector(dx: travelPoint.x-node.position.x, dy: travelPoint.y-node.position.y)
let dispAngle = atan2(disp.dy,disp.dx)

//Here we check if we are at the tangent angle. Assume 4 degree threshold for error.
if velAngle != 0 && abs(velAngle - dispAngle) < CGFloat(4*M_PI/180) {
motionState = .Linear
}


Lastly let me know if you need to use paths with SKActions, regardless I think I will update this last part showing how this is done (unless someone beats me to it! And as I mentioned earlier the code I posted does this to an extent.) I don't have time to right now but hopefully I get a chance to soon! I hope something mentioned in this answer helps you. Good luck with your game.

Update including SKActions

The code below shows getting the same exact effect except this time using SKActions to animate a CGPath to the tangent angle then to the final destination point. It is much simpler as there is no longer a manual calculation of centripetal and linear motion, however because it is an animation you lose the dynamic real-time motion control that the solution above provides.

class GameScene: SKScene {

var centripetalPoint = CGPoint() //Point to orbit.
let centripetalRadius: CGFloat = 60 //Radius of orbit.
var travelPoint: CGPoint = CGPoint() //The point to travel to.
var travelDuration: NSTimeInterval = 1.0 //The duration of action.
var node: SKShapeNode!
var circle: SKShapeNode!

override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
circle = SKShapeNode(circleOfRadius: centripetalRadius)
circle.strokeColor = SKColor.redColor()
circle.hidden = true
self.addChild(circle)
}
//Not mine, modified algorithm from https://stackoverflow.com/q/3349125/2158465
func getPairPointsFromCircleOnCircle(pointA: CGPoint, radiusA: CGFloat, pointB: CGPoint, radiusB: CGFloat) -> (CGPoint,CGPoint) {
let dX = (pointA.x - pointB.x)*(pointA.x - pointB.x)
let dY = (pointA.y - pointB.y)*(pointA.y - pointB.y)
let d = sqrt(dX+dY)
let a = (radiusA*radiusA - radiusB*radiusB + d*d)/(2.0*d);
let h = sqrt(radiusA*radiusA - a*a);
let pointCSub = CGPoint(x:pointB.x-pointA.x,y:pointB.y-pointA.y)
let pointCScale = CGPoint(x: pointCSub.x*(a/d), y: pointCSub.y*(a/d))
let pointC = CGPoint(x: pointCScale.x+pointA.x, y: pointCScale.y+pointA.y)
let x3 = pointC.x + h*(pointB.y - pointA.y)/d;
let y3 = pointC.y - h*(pointB.x - pointA.x)/d;
let x4 = pointC.x - h*(pointB.y - pointA.y)/d;
let y4 = pointC.y + h*(pointB.x - pointA.x)/d;
return (CGPoint(x:x3, y:y3), CGPoint(x:x4, y:y4));
}

func moveToPoint(point: CGPoint) {
travelPoint = point

//Assume clockwise when point is to the right. Else counter-clockwise
if point.x > node.position.x {
centripetalPoint = CGPoint(x: node.position.x + centripetalRadius, y: node.position.y)
} else {
centripetalPoint = CGPoint(x: node.position.x - centripetalRadius, y: node.position.y)
}

let disp = CGVector(dx: centripetalPoint.x - travelPoint.x, dy: centripetalPoint.y - travelPoint.y)
let specialCirclePos = CGPoint(x: (travelPoint.x+centripetalPoint.x)/2.0, y: (travelPoint.y+centripetalPoint.y)/2.0)
let specialCircleRadius = sqrt(disp.dx*disp.dx+disp.dy*disp.dy)/2.0
let tangentPair = getPairPointsFromCircleOnCircle(centripetalPoint, radiusA: centripetalRadius, pointB: specialCirclePos, radiusB: specialCircleRadius)
let tangentAngle1 = (atan2(tangentPair.0.y - centripetalPoint.y,tangentPair.0.x - centripetalPoint.x)+CGFloat(2*M_PI))%CGFloat(2*M_PI)
let tangentAngle2 = (atan2(tangentPair.1.y - centripetalPoint.y,tangentPair.1.x - centripetalPoint.x)+CGFloat(2*M_PI))%CGFloat(2*M_PI)

let path = CGPathCreateMutable()
CGPathMoveToPoint(path, nil, node.position.x, node.position.y)
if travelPoint.x > node.position.x {
CGPathAddArc(path, nil, node.position.x+centripetalRadius, node.position.y, centripetalRadius, CGFloat(M_PI), tangentAngle2, true)
} else {
CGPathAddArc(path, nil, node.position.x-centripetalRadius, node.position.y, centripetalRadius, 0, tangentAngle1, false)
}
CGPathAddLineToPoint(path, nil, travelPoint.x, travelPoint.y)

let action = SKAction.followPath(path, asOffset: false, orientToPath: false, duration: travelDuration)
node.runAction(action)
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touchPos = (touches.first! as! UITouch).locationInNode(self)
node = SKShapeNode(circleOfRadius: 10)
node.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
self.addChild(node)

moveToPoint(touchPos)

circle.hidden = false
circle.position = centripetalPoint
}
}

How to reverse the direction of path followed by sprite in an SKAction midway?

I'm assuming your trying to get it to go in the opposite direction on when the player touches the screen. Try creating a function for both of the directions, one for clockwise and anti-clockwise in these functions add your method of making the path. I would use this code to complete this task as I don't find any errors:

 func moveClockWise() {

let dx = Person.position.x - self.frame.width / 2
let dy = Person.position.y - self.frame.height / 2

let rad = atan2(dy, dx)

let Path = UIBezierPath(arcCenter: CGPoint(x: self.frame.width / 2, y: self.frame.height / 2), radius: 120, startAngle: rad, endAngle: rad + CGFloat(M_PI * 4), clockwise: true)
let follow = SKAction.followPath(Path.CGPath, asOffset: false, orientToPath: true, speed: 200)
Person.runAction(SKAction.repeatActionForever(follow).reversedAction())

}

This is just my preferred way, and for anti-clockwise, just create another function just reversing the code.

Now above the didMoveToView add these variables:

var Person = SKSpriteNode()

var Path = UIBezierPath()

var gameStarted = Bool()

var movingClockwise = Bool()

These basically define your Person as a SKSpriteNode() your Path as a UIBezierPath() etc. Of course you would have your Person.position = position and Person = SKSpriteNode(imageNamed: "name") under your didMoveToView to create the sprite.

After this, under the override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {, you want to use the gameStarted bool variable to detect wether it is running, if it is set the bool to true and change it's direction.

if gameStarted == false {

moveClockWise()
movingClockwise = true
gameStarted = true

}
else if gameStarted == true {

if movingClockwise == true {

moveCounterClockWise()
movingClockwise = false

}
else if movingClockwise == false {

moveClockWise()
movingClockwise = true

}
}

Basically the first line of code checks whether the bool is false (which it is because nothing has happened to it and it has just loaded), and runs the moveClockwise function and sets the moveClockwise bool to true and the gameStarted bool to true as well. Everything else is pretty self explanatory.

Player object moving one direction but turned a different direction

I made several improvements:

  1. When you do Cos and Sin, you must convert the degrees to Radians, as those functions take Radians (radians are a different unit for degrees).
  2. I changed the - and + of the right and left key. It's conventional that counter clockwise is increasing not the other way around ;)
  3. I modified the turn method as it had some slight mistakes (-180 is 0 in trig)

Comment if there are more errors and I'll take another look :)
Good luck!

public void move() {
x += speed * Math.cos(Math.toRadians(direction));
y += speed * Math.sin(Math.toRadians(direction));
}

@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT){
turn(-.6);
//this is meant to turn the player int a clockwise direction by 0.6
} else if (key == KeyEvent.VK_RIGHT){
turn(.6);
//counterclockwise by 0.6
}
.....//rest of code}

private void turn(double degrees) {
direction += degrees;
if(direction > 180) direction = 180;
else if(direction < 180) direction = 0;
}

Make player follow a waypoint path but still be able to control player movement

The below may not be the best solution to this problem, but shall help go further

You can setup the player as below

Player object with script and the character(capsule) as child
please check below image

player_heirarchy

and then with below code you will be allowed to move character side ways keeping the main object follow the waypoint.
Later you can add some limit to max side movement.

void Update()
{
//made a similar situation from your code
if (waypoints.Length > 0)
{
Transform currentNode = waypoints[currentNodeCount].transform;

transform.position = Vector3.MoveTowards(transform.position, currentNode.position, 10f * Time.deltaTime);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(currentNode.position - transform.position), 1 * Time.deltaTime);

float distance = Vector3.Distance(transform.position, currentNode.position);
if (distance < 1f)
{
if (currentNodeCount < waypoints.Length - 1)
currentNodeCount++;
}
}

// side movement to child object, in m case it is Player Object's second child
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.GetChild(1).Translate(Vector3.left * 5f * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.RightArrow))
{
transform.GetChild(1).Translate(Vector3.right * 5f * Time.deltaTime);
}
}

Also attaching the output video
Follow_waypoint_along_with_manual_side_movement

P.S. : This is my first answer, please forgive if not answered in correct format.

How to prevent player movement outside of given area map?

Yes, an if would work. Check where the user wants to go to. If it is invalid, print a message and don't move the player. Else move them.

def player_move(player_action):
ask = "Where would you like to move?\n"
dest = input(ask).lower()
if dest in ['up', 'north']:
destination = UP
elif dest in ['down', 'south']:
destination = DOWN
elif dest in ['left', 'west']:
destination = LEFT
elif dest in ['right', 'east']:
destination = RIGHT
else:
print("Bad entry")
return

if "" == zonemap[myPlayer.location][destination]:
print("Can't go there")
else:
movement_handler(zonemap[myPlayer.location][destination])

Move canvas image across circular path

You almost have the solution.

You need to go at 90 deg to the forward vector. To rotate a vector 90cw you swap the x,and y and negate the new x.

EG

dx = ?;  // forward direction
dy = ?;
// rotate 90 clockwise
dx1 = -dy;
dy1 = dx;

Thus you can update your code as follows

   var dX = (GAME.mouse.position.x - this.playerCenter[0]);
var dY = (GAME.mouse.position.y - this.playerCenter[1]);
var radius = Math.sqrt(dX * dX + dY * dY);
//normalise
if(radius > 0){
dX = (dX / radius) * this.movementSpeed * delta;
dY = (dY / radius) * this.movementSpeed * delta;;
}else{
dX = dY = 0; // too close need to set this or you will get NaN propagating through your position variables.
}

if(GAME.keyDown[87] && radius >= 50){ // Movement Forward
this.x += dX;
this.y += dY;
}
if(GAME.keyDown[83]){ // Movement Backward
this.x -= dX;
this.y -= dY;
}
if(GAME.keyDown[65]){ // Strafe left
this.x += -dY; // swap x and y negate new x to rotate vector 90
this.y += dX;
}
if(GAME.keyDown[68]){ // Strafe right
this.x -= -dY; // swap x and y negate new x to rotate vector 90
this.y -= dX;
}

Let an Enemy follow a path with the same speed

All you need to do is define the speed of movement of the enemy inside the enemy class.

When it works out the next point to move to then create a direction vector by subtracting the current position from the new position.

Normalize the direction vector (so it is length 1) then multiply it by the speed and the tpf (time per frame).

Move by that amount instead of jumping to the next point.

(Note if the points are very close together or the framerate is low this can cause it to overshoot a bit, it should be fine though).

How can I make a sprite object set it's moving direction at the point of a touch?

You have to calculate the slope from the spawning point to the player and then interpolate to somewhere outside the screen.

func add(location:CGPoint)
{
let bee = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(10, 10))
bee.name = "Bee"
bee.position = location
self.addChild(bee)

let slopeToPlayer = (bee.position.y - player.position.y) / (bee.position.x - player.position.x)
let constant = bee.position.y - slopeToPlayer * bee.position.x

let finalX : CGFloat = bee.position.x < player.position.x ? 500.0 : -500.0 // Set it to somewhere outside screen size

let finalY = constant + slopeToPlayer * finalX

let distance = (bee.position.y - finalY) * (bee.position.y - finalY) + (bee.position.x - finalX) * (bee.position.x - finalX)
let beeSpeed : CGFloat = 100.0
let timeToCoverDistance = sqrt(distance) / beeSpeed

let moveAction = SKAction.moveTo(CGPointMake(finalX, finalY), duration: NSTimeInterval(timeToCoverDistance))
let removeAction = SKAction.runBlock { () -> Void in
bee.removeFromParent()
println("removed")
}
bee.runAction(SKAction.sequence([moveAction,removeAction]))

}


Related Topics



Leave a reply



Submit