Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测

Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测,第1张

概述物理推力 为了避免monkey“落下”,需要用物理推力让它重新跳起来。 这时要在spawnEnemy()后添加一个新的method: func jumpPlayer() { // 1 let impulse = CGVector(dx: 0, dy: 75) // 2 player.physicsBody?.applyImpulse(impulse) } 再回顾一 物理推力

为了避免monkey“落下”,需要用物理推力让它重新跳起来。

这时要在spawnEnemy()后添加一个新的method:

func jumpPlayer() {    // 1   let impulse =  CGVector(dx: 0,dy: 75)    // 2   player.physicsBody?.applyImpulse(impulse)  }

再回顾一下上述步骤:

首先创建一个固定数值推动力的CGVector,规定monkey跳起的距离。我也是尝试了多次才总结出具体数值的。
用applyImpulse()制造推力,再转化为线速度和角速度推力。理论上,monkey在穿行太空的时候还会旋转,所以刚刚才要将physics body设定为不旋转。
代码在被调用之前,monkey是不能跳起来的;要使monkey跳起来,就要重写点击屏幕时调用的那个method。在jumpPlayer()底下复制这些代码:

overrIDe func touchesBegan(touches: Set<NSObject>,withEvent event: UIEvent) { jumpPlayer() }

点击屏幕时,自动调用这些method。

现在就差一步了——在 dIDMovetoVIEw(_:)后添加如下代码:

// 1 let collisionFrame = CGRectInset(frame,0,-self.size.height * 0.2)  // 2 physicsBody = SKPhysicsBody(edgeLoopFromrect: collisionFrame)

代码会在屏幕边缘产生一个特殊的physics body,避免monkey飞出或者坠落在太空中。现在回顾一下上述代码:

首先创造一个可通过CGRectInset()扩大或缩小至多20%的矩形,即monkey的活动范围。monkey的轮廓可以稍微消失在屏幕外,但不能完全消失不见。
然后设定场景本身的physics body。刚刚创建的physics body是圆的,此处将它变为一个循环边,即“矩形的边缘”,不过听上去更简洁些。
编写完成后运行,就能看到如下场景:

一只蹦蹦跳跳的小monkey出现啦!

碰撞检测

到目前为止,如果monkey遇到敌人,可以跳过去;但是跟敌人相撞的话,什么效果都没有,所以需要在游戏中添加碰撞检测(collision detection),有如下几步:

为所有sprite创建physics body:现在monkey已经有了一个physics body,但是敌人还没有,所以先完成这一步。 为每个physics body设定category(类别)和contact(接触点):这一步为sprite分类,比如为monkey和敌人设定不同的类别;同样可以在特定的physics body和其他类别的physics body之间设定“contact(接触点)”。 设置Contact Delegate:设定两个physics body何时接触。要搞清不同的physics body属于哪个类别,是敌人还是monkey。大功告成!
还记得怎么给monkey添加physics body吗?现在轮到为敌人的sprite添加physics body了,来制造碰撞效果。

首先将如下所示添加至GameScene.swift最顶端:

enum BodyType: UInt32 {    case player = 1    case enemy = 2    case ground = 4  }

这里要做的就是为每个sprite创建类别。ground number不是针对sprite,而是针对应用边框设定的,所以当monkey碰到屏幕边缘时会d起,而不是落到屏幕之外!

接下来,执行SKPhysicsContactDelegate协定,标记GameScene(游戏场景):

class GameScene: SKScene,SKPhysicsContactDelegate { 

协议的作用是保证代码执行特定的method。此处执行针对两个physics body相撞的method。然后调整contactDelegate的值,将如下代码添加到dIDMovetoVIEw(_:)末尾:

physicsWorld.contactDelegate = self 

完成后,两个physics body碰撞时,物理世界就会自动调用代码中的method。

在spawnEnemy()末尾添加如下代码:

// 1  enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.wIDth/4)  // 2  enemy.physicsBody?.dynamic = false  // 3  enemy.physicsBody?.affectedByGravity = false  // 4  enemy.physicsBody?.allowsRotation = false  // 5  enemy.physicsBody?.categoryBitMask = BodyType.enemy.rawValue  // 6  enemy.physicsBody?.contactTestBitMask = BodyType.player.rawValue  // 7  enemy.physicsBody?.collisionBitMask = 0

此处稍稍解释一下:

为敌人创建physics body。physics body不一定要跟sprite的形状完全吻合,近似就好。这里用的是圆形,半径设为sprite的1/4,免得碰撞效果太猛。 把dynamic关掉,实现物理控制sprite。 防止引力对sprite的影响。这一步不言自明,主要让敌人的sprite避免物理引力的干扰。 这一步是为了避免sprite在physics body碰撞时旋转。 将类别位掩码设为之前设置过的敌人类别。 敌人和monkey接触时,Sprite Kit发出提醒。 为monkey设置 collisionBitMask后,当接触到敌人时,两者会互相d开;如果不想要这种效果,将值设为0。

将如下所示添加到dIDMovetoVIEw(_:)的后面:

physicsBody?.categoryBitMask = BodyType.ground.rawValue  player.physicsBody?.categoryBitMask = BodyType.player.rawValue  player.physicsBody?.contactTestBitMask = BodyType.enemy.rawValue  player.physicsBody?.collisionBitMask = BodyType.ground.rawValue

这里为monkey和ground设置类别和碰撞位掩码,让两者彼此碰撞;在monkey和敌人之间设置“contact(接触点)”。

现在到了最重要的一步,完善碰撞检测,执行之前提到的method来处理“contacts”:

func dIDBeginContact(contact: SKPhysicsContact) {    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask    switch(contactMask) {    case BodyType.player.rawValue | BodyType.enemy.rawValue:      let secondNode = contact.bodyB.node      secondNode?.removeFromParent()      let firstNode = contact.bodyA.node      firstNode?.removeFromParent()    default:      return    }  }

因为之前已将场景设置为物理世界的contactDelegate,两个physics body碰撞时会自动调用这个method。

它将两个位掩码结合成一个单个的接触点掩码,检验是否是monkey和敌人相撞,如果是,就将两者从屏幕上移除。

编写完成后运行,效果如下:

转自:http://www.csdn.net/article/2015-05-26/2824772-sprite-kit-for-kids-with-swift/3

总结

以上是内存溢出为你收集整理的Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测全部内容,希望文章能够帮你解决Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1087556.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存