用物理学创建下雨动画
Posted
技术标签:
【中文标题】用物理学创建下雨动画【英文标题】:Creating rain animation with physics 【发布时间】:2015-02-08 16:38:11 【问题描述】:我目前正在开发一个使用 SpriteKit 游戏技术以 Swift 编写的 ios 应用程序。在这个游戏中,雨滴从屏幕顶部落到底部。当它们到达底部时(由physicsBody
表示),它们应该返回到屏幕顶部的原始位置,从而使动画在游戏的整个生命周期中继续播放。
因为我只需要几滴,所以我这样制作它们:
let drop = SKSpriteNode(imageNamed: "drop")
drop.position = CGPointMake(x,y)
drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
addChild(drop)
然后我创建位掩码:
drop.physicsBody!.categoryBitmask = DropCategory
bottom.physicsBody!.categoryBitmask = BottomCategory
drop.physicsBody!.contactTestBitmask = BottomCategory
我添加了 didBeginContact 函数,当下降到达底部时我会收到通知。然后我的控制台显示“命中”。
func didBeginContact(contact: SKPhysicsContact)
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask
firstBody = contact.bodyA
secondBody = contact.bodyB
else
firstBody = contact.bodyB
secondBody = contact.bodyA
if firstBody.categoryBitMask == BlockCategory && secondBody.categoryBitMask == GroundCategory
println("hit ground")
firstBody.node?.removeFromParent()
let drop = SKSpriteNode(imageNamed: "drop")
drop.name = "testNode"
drop.position = CGPointMake(self.frame.width - self.frame.width/3*2, self.frame.height) // At start Position
drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
drop.physicsBody?.categoryBitMask = BlockCategory
drop.physicsBody?.contactTestBitMask = GroundCategory
addChild(drop)
但是,drop 的位置不会改变。没有语法错误,那我的问题是什么?
如果我替换这个:
firstBody.node!.position = CGPointMake(x, y)
用这个:
firstBody.applyImpulse(CGVector)
它给了下降的冲动。我怎样才能使第一个选项也起作用?
【问题讨论】:
您是否尝试过设置水滴物理体的质量? 为什么不使用粒子发射器?在 XCode 中创建新粒子文件时,甚至可以选择下雨模板。 此外,即使我认为使用物理系统对于您正在尝试做的事情来说太过分了,但下落不应该需要冲动。水滴只会受到重力的影响。 我想在水滴击中我的角色时得到通知,所以我需要物理系统。 是的,为什么不直接使用粒子发射器? 【参考方案1】:您可以尝试在触及底部时删除节点,然后再次在顶部添加新节点。将纹理加载到单独的SKTexture
变量中以供重复使用。像这样
let dropTexture = SKTexture(imageNamed: "drop.png")
这样使用
let drop = SKSpriteNode(texture: dropTexture)
然后在didBeginContact
里面
func didBeginContact(contact: SKPhysicsContact)
println("collided")
var bodyA : SKPhysicsBody!
var bodyB : SKPhysicsBody!
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask
bodyA = contact.bodyA!
bodyB = contact.bodyB!
else
bodyB = contact.bodyA!
bodyA = contact.bodyB!
if bodyA.categoryBitMask == bottomCategoryBitMask && bodyB.categoryBitMask == raindropCategoryBitMask
if bodyB.node?.parent != nil // Added line
bodyB.node?.removeFromParent()
let drop = SKSpriteNode(imageNamed: "1.png")
drop.name = "testNode"
drop.position = CGPointMake(self.frame.width - self.frame.width/3*2, self.frame.height) // At start Position
drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
drop.physicsBody?.categoryBitMask = raindropCategoryBitMask
drop.physicsBody?.contactTestBitMask = bottomCategoryBitMask
addChild(drop)
【讨论】:
每次水滴落到底部时,水滴的数量都会乘以 2,所以我最终有数百个。如果我删除了drop,然后告诉它添加一个新的drop,它怎么能得到两个。 是的,我认为当你使用图片作为drop时会更清晰。然后它会成倍增加。 即使我用图像尝试它也能正常工作。你能展示你更新的代码吗? firstBody.node?.removeFromParent() let block1 = SKSpriteNode(imageNamed: "block") block1.name = "testNode" block1.position = CGPointMake(self.frame.width - self.frame. width/3*2, self.frame.height) // 在开始位置 block1.physicsBody = SKPhysicsBody(rectangleOfSize: block1.size) block1.physicsBody?.categoryBitMask = BlockCategory block1.physicsBody?.contactTestBitMask = GroundCategory addChild(block1) 我更新了我的代码。添加 if 条件也if firstBody.node?.parent != nil
以上是关于用物理学创建下雨动画的主要内容,如果未能解决你的问题,请参考以下文章