0

I am trying to get my stationary monster to shoot at my moving player. Both the player position and the monster position are obtaining the right values and this code is written in a function that is called every second. Right now the projectile shows up but doesn't move away from the monster. Is there something else I should be using besides .applyAngularImpulse?

    let deltaX = player.position.x - monster.position.x
    let deltaY = player.position.y - monster.position.y
    let angle = atan2(deltaY, deltaX)

    monProjectile.physicsBody?.applyAngularImpulse(angle)
nick
  • 45
  • 7
  • Have you checked this tutorial? http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners – Rashwan L Dec 11 '15 at 23:35
  • yes I have. Unfortunately, my application of these ideas does not seem to be working, as I am trying to use them in a slightly different situation. Thanks for the help though! – nick Dec 11 '15 at 23:57
  • Something without physics : https://stackoverflow.com/questions/36230619/how-to-move-enemy-towards-a-moving-player/36235426#36235426 ... Still, you could add physics bodies to nodes (just set `node.physicsBody.affectedByGravity = false`, and set `node.physicsBody.collisionBitMask` = 0), in order to have contact detection. – Whirlwind Jan 13 '18 at 17:06

2 Answers2

1

UPDATE

Having looked at the code you provided, I suspect two things are at fault:

1) You are specifying a "projectile" image that I can't see in your project.

2) You are trying to apply angular impulse (i.e. spin) rather than a regular impulse (i.e., direction plus speed).

To fix the first problem add an image for your projectile. To fix the second, consider using applyImpulse() with a CGVector.

Original answer

Off the top of my head, there are a few things that might cause this:

1) How much of an impulse are you applying? Print out the value and see what kind of number you're working with.

2) Does your projectile overlap the monster when it's created? If so, it might be colliding and getting stuck.

3) Is it possible the projectile is colliding with some other node entirely, e.g. a background picture?

You should consider setting showsPhysics to be true for your SKView so you can see what's happening more clearly.

TwoStraws
  • 12,862
  • 3
  • 57
  • 71
  • 1. It says it's applying about a -3 value as a force. I think that's correct because my player is using 3.0 for his shooting and the monster is to the right of the player, which is why I believe I would be getting a negative value. 2. I set up the position of the projectile so that it would not overlap the sprite (I already ran into that issue with the player shooting). 3. I don't think that would be the case either because the player shooting works fine and it's using the same method, just applying a different force. Thanks of the help! – nick Dec 11 '15 at 23:52
  • I just read this same post on /r/swift and another option occurred to me: does your project definitely have a physics body attached to it? Try changing the question mark to an exclamation mark for a moment: if your code crashes, you've slipped up. – TwoStraws Dec 12 '15 at 00:14
  • I tried that already as well, it doesn't make a difference. The app does not crash. – nick Dec 12 '15 at 00:16
  • Are you able to post your project somewhere for us to download and look at? – TwoStraws Dec 12 '15 at 00:17
  • https://github.com/nlooney10/BattleTanks/blob/master/Battle%20Tanks/GameScene.swift – nick Dec 12 '15 at 00:32
  • Where is the "projectile" image coming from? – TwoStraws Dec 12 '15 at 00:37
  • it should be in SpriteKitSimpleGameResources, at least it is on my project – nick Dec 12 '15 at 00:56
  • Do you see the file on GitHub? – TwoStraws Dec 12 '15 at 00:59
  • sorry, idk why it didn't upload at first. but it should be there now. – nick Dec 12 '15 at 01:02
0
func makeShoot() {
    let Shoot:ShootClass = ShootClass.init()
    Shoot.physicsBody = SKPhysicsBody(texture: Shoot.texture!,
                                     size: Shoot.texture!.size())
    Shoot.position = (self.Shoot?.position)!
    Shoot.currentPosition = (self.Shoot?.position)!
    Shoot.physicsBody?.isDynamic = true
    Shoot.physicsBody?.allowsRotation = false
    Shoot.physicsBody?.affectedByGravity = false
    Shoot.physicsBody?.friction = 0
    Shoot.physicsBody?.restitution = 1
    Shoot.physicsBody?.mass = 1
    Shoot.physicsBody?.linearDamping = 0.0
    Shoot.physicsBody?.angularDamping = 0.0
    Shoot.physicsBody?.categoryBitMask = ShootCategory
    Shoot.physicsBody?.collisionBitMask = BorderCategory
    Shoot.physicsBody?.contactTestBitMask = BorderCategory

    PlayingView.addChild(Shoot);

    Shoot.physicsBody?.applyImpulse(CGVector(dx: 100, dy: 100))

    self.moveNodeToLocation(Shoot: Shoot)
}



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let curTouch = touches.first!
    let curPoint = curTouch.location(in: self)
    if ((curPoint.x > 103.5 && curPoint.y > 50.0) || (curPoint.x < 840.0 && curPoint.y > 50.0)) {
        StartingPoint = touches.first?.location(in: self)
        direction?.isHidden = false
        direction?.setScale(0.50)
        FirstTouchLocater = SKSpriteNode(imageNamed: "ic_Shootz");
        FirstTouchLocater.position = curPoint
        FirstTouchLocater.alpha = 0.5
        self.addChild(FirstTouchLocater);

    }
    else{
        self.direction?.isHidden = true
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    let point:CGPoint = (touches.first?.location(in: self))!

    if point.y < 40 {
        return
    }

    if !(isTouch!) {
        isTouch = true
    }


    let dy:CGFloat = StartingPoint!.y - point.y

    let size:CGFloat = dy*10/self.frame.height

    if size < 2 && size > 0.50 {
        direction?.setScale(size)
    }
     print("size ======> \(size)")




    let curTouch = touches.first!
    let curPoint = curTouch.location(in: self)

    if (curPoint.x <= ((StartingPoint?.x)! + 20.0)) &&  ((curPoint.x + 20.0) >= (StartingPoint?.x)!) && (curPoint.y <= ((StartingPoint?.y)! + 20.0)) &&  ((curPoint.y + 20.0) >= (StartingPoint?.y)!){
        self.direction?.isHidden = true
        FirstTouchLocater?.isHidden = true
    }
    else if ((curPoint.x > 103.5 && curPoint.y > 50.0) || (curPoint.x < 840.0 && curPoint.y > 50.0)) {
        let deltaX = (self.direction?.position.x)! - curPoint.x
        let deltaY = (self.direction?.position.y)! - curPoint.y
        let angle = atan2(deltaY, deltaX)

        let DegreesToRadians = CGFloat.pi / 180

        self.direction?.zRotation = angle + 90 * DegreesToRadians
        self.direction?.isHidden = false
        FirstTouchLocater?.isHidden = false
    }
    else{
        self.direction?.isHidden = true
        FirstTouchLocater?.isHidden = true
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if direction?.isHidden == false {
        FirstTouchLocater.removeFromParent()
        direction?.isHidden = true
        direction?.setScale(0.1)
        if timeThrow == nil && isTouch!
        {
            isTouch = false
            counterY = 0;

            let touch = touches.first
            let touchLocation = touch?.location(in: self)
            lastTouch = touchLocation
            lastTouch1 = touchLocation

            ShootThrow = 2

            timeThrow = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.loadScreen), userInfo: nil, repeats: true)
        }
    }
}

func moveNodeToLocation(Shoot:SKSpriteNode) {
    let dx = (lastTouch?.x)! - Shoot.position.x
    let dy = (lastTouch?.y)! - Shoot.position.y

    let speed1:CGFloat = 424
    let hypo = hypot(dx, dy)

    let newX = (speed1 * dx) / hypo
    let newY = (speed1 * dy) / hypo
    Shoot.physicsBody?.velocity = CGVector(dx:newX, dy: newY)

}

}