Sprite Kit Swift游戏开发新手指导手册(5)

我们创建了忍者精灵和怪兽精灵了, 但是我们的忍者精灵还差一些东西,那就是飞镖, 哈哈, 如果我们将忍者精灵的飞镖添加上去应该会很有趣.那么我们怎么去添加飞镖呢. 我的打算是这样的,当我么点击屏幕的时候.忍者的手里就会发射一个飞镖,飞镖就会飞出去. 飞出去的方向就是忍者的坐标与我们点击的屏幕的坐标之间的向量方向, 至于什么是向量,大家高中都学过的,实在不知道的话就当做是直线方向吧! 图片就大概是下面这个样子

这里写图片描述

为了计算这个方向, 我们需要写一些计算方法, 这些方法Sprite Kit里面是没有的,所以就只有靠我们自己丰衣足食啦.那么我们在GameScene.swift里面的最顶部添加以下代码:

func +(left: CGPoint, right: CGPoint) -> CGPoint {
     return CGPoint(x: left.x + right.x, y: left.y + right.y)
}

func -(left: CGPoint, right: CGPoint) -> CGPoint {
     return CGPoint(x: left.x - right.x, y: left.y - right.y)
}

func * (point: CGPoint, scalar: CGFloat) -> CGPoint {
     return CGPoint(x: point.x * scalar, y: point.y * scalar)
}

func /(point: CGPoint, scalar: CGFloat) -> CGPoint {
     return CGPoint(x: point.x / scalar, y: point.y / scalar)
}

#if !(arch(x86_64) || arch(arm64))
func sqrt(a: CGFloat) -> CGFloat {
     return CGFloat(sqrtf(Float(a)))
}
#endif

extension CGPoint {
  func length() -> CGFloat {
      return sqrt(x*x + y*y)
  }

  func normalized() -> CGPoint {
    return self / length()
  }
}

你可能对这种方法的写法比较奇怪, 如果感觉比较困惑. 可以百度”Swift operator overload”, 然后我们在文件的添加以下方法

override func touchesEnded(touches: Set<NSObject> , withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
    runAction(SKAction.playSoundFileNamed("pew-pew-lei.caf", waitForCompletion: false))
    let touchLocation = touch.locationInNode(self)
    let projectile = SKSpriteNode(imageNamed: "projectile")
    projectile.position = player.position
    projectile.physicsBody = SKPhysicsBody(circleOfRadius: projectile.size.width/2)
    projectile.physicsBody?.dynamic = true
    projectile.physicsBody?.categoryBitMask = PhysicsCategory.Projectile
    projectile.physicsBody?.contactTestBitMask = PhysicsCategory.Monster
    projectile.physicsBody?.collisionBitMask = PhysicsCategory.None
    projectile.physicsBody?.usesPreciseCollisionDetection = true

    let offset = touchLocation - projectile.position
    if (offset.x < 0) { return }

    addChild(projectile)

    let direction = offset.normalized()
    let shootAmount = direction * 1000

    let realDest = shootAmount + projectile.position

    let actionMove = SKAction.moveTo(realDest, duration: 2.0)
    let actionMoveDone = SKAction.removeFromParent()
    projectile.runAction(SKAction.sequence([actionMove, actionMoveDone]))
   }
}

这段代码略显复杂,我们一步一步来说

  1. Sprite Kit包含一个由带有locationInNode(:)previousLocationInNode(:)方法的UITouch集合,通过SKNode的坐标系统,这些方法可以让你找到点击时的具体坐标;
  2. 我们在场景中创建了一些飞镖,但是这些飞镖有一些条件限制,比如我们不能让这些飞镖往后飞.
  3. 然后将飞镖的当前位置与我们点击屏幕的位置坐标进行计算获取飞镖的移动方向;如果X坐标为0,就意味着我们的飞镖需要向后射击,当然,这种情况是不允许存在的.忍者当然不能从后面射击,所以直接return就好了.
  4. 综合以上几点,我们就可以将飞镖添加到场景里面了
  5. 通过normalized()方法.我们将偏移转化成单位向量,这样的话,不管我们的飞镖移动的距离多远,方向都是一致的,因为(1*length = length) ; 数学向量知识,不懂百度)
  6. 最后,创建moveTo(_:,duration:)removeFromParent()方法;

运行之后看到的效果如下

这里写图片描述

查看更多 http://blog.vlian888.com/?p=142

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值