[英]SKSpriteNode bouncing of something I didn't create in Swift
我试图从屏幕顶部放一个正方形。 但是当它下降一半时,它会不断从屏幕上跳下来。 我没有在屏幕中间创建对象。 我不明白为什么它会在屏幕中间弹起。
这是我运行代码的视频的链接: http : //sendvid.com/enm9l1np
这是代码:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var animator : UIDynamicAnimator?
let BlueSquare = SKSpriteNode()
let RedSquare = SKSpriteNode()
var scorenumber = 0
var Ground = SKSpriteNode()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
physicsWorld.gravity = CGVector(dx: 1.0, dy: -9.0)
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
// 2. Set the friction of that physicsBody to 0
borderBody.friction = 0
// 3. Set physicsBody of scene to borderBody
self.physicsBody = borderBody
let width = UInt32(self.frame.size.width)
let X = arc4random() % width
Ground = SKSpriteNode(imageNamed: "Ground")
Ground.setScale(1.0)
Ground.position = CGPoint(x: self.frame.width / 2, y: 5)
Ground.physicsBody = SKPhysicsBody(rectangleOfSize: Ground.size)
Ground.physicsBody!.affectedByGravity = false
Ground.physicsBody!.dynamic = false
Ground.zPosition = 3
self.addChild(Ground)
//INizialize
animator = UIDynamicAnimator(referenceView: self.view!)
//Add Gravity
//animator?.addBehavior(gravity, sprite)
BlueSquare.size = CGSize(width: 100, height: 100)
BlueSquare.position = CGPoint(x: CGFloat(X), y: 1000)
BlueSquare.physicsBody?.affectedByGravity = true
BlueSquare.physicsBody?.dynamic = false
BlueSquare.name = "bluecube"
BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20)
BlueSquare.color = SKColor.blueColor()
// BlueSquare.physicsBody?.velocity = CGVectorMake(0, 0)
//BlueSquare.physicsBody?.applyImpulse(CGVectorMake(0, -90))
self.addChild(BlueSquare)
let X2 = arc4random() % width
RedSquare.size = CGSize(width: 100, height: 100)
RedSquare.position = CGPoint(x: CGFloat(X2), y: 1000)
RedSquare.physicsBody?.affectedByGravity = true
RedSquare.physicsBody?.dynamic = true
RedSquare.name = "redcube"
RedSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20)
RedSquare.hidden = false
RedSquare.color = SKColor.redColor()
self.addChild(RedSquare)
var gameTimer = NSTimer!()
gameTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "spawning1", userInfo: nil, repeats: true)
}
func spawning1() {
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
// let location = touch.locationInNode(self)
let currentPoint = touch.locationInNode(self)
let currentNode = nodeAtPoint(currentPoint)
let nodeName: String? = currentNode.name
if nodeName == "bluecube" {
BlueSquare.hidden = true
score()
}
if nodeName == "redcube" {
RedSquare.hidden = true
score()
}
}
}
func score () {
scorenumber++
print(scorenumber)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if CGRectIntersectsRect(RedSquare.frame, Ground.frame) {
RedSquare.position = CGPoint(x: RedSquare.position.x, y: RedSquare.position.y + 10)
}
}
}
您的代码有点混乱,所以让我们来看一下
1)首先,在GameViewController.swift中,应在调用第一个场景之前设置此属性
skView.showsPhysics = true
在测试时帮助您直观地看到物理身体。
2)不要将NSTimers用于SpriteKit游戏,而应使用SKActions.waitForDuration。
let timerAction1 = SKAction.waitForDuration(0.5)
let timerAction2 = SKAction.runBlock(spawning1)
let timerSequence = SKAction.sequence([timerAction1, timerAction2])
runAction(SKAction.repeatActionForever(timerSequence))
如果您需要在游戏过程中的某个时候使计时器无效,而不是简单地给runAction一个键
runAction(SKAction.repeatActionForever(timerSequence), withKey: "SpawnTimer")
而不是像这样删除它
removeActionForKey("SpawnTimer")
乍一看,这似乎是更多代码,但请相信我,这是spriteKit游戏的更好方法。 当您暂停场景时,NSTimers不会暂停,否则它们可能会导致场景过渡时出现问题。 总是尽可能多地使用spriteKit API。
3)在某些子画面上,您必须解开物理物体
....physicsBody!.affectedByGravity....
用一个 ? 代替。
....physicsBody?.affectedByGravity....
通常,在Swift中,当您处理可选内容时(例如本例中的physicsBody),请始终使用? 只要编译器允许。
4)在某些物体上,您要先设置物理属性,然后再为对象赋予物理物体
BlueSquare.physicsBody?.affectedByGravity = true
BlueSquare.physicsBody?.dynamic = false
BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20) // WRONG SPOT
它应该看起来像这样
BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20)
BlueSquare.physicsBody?.affectedByGravity = true
BlueSquare.physicsBody?.dynamic = false
现在到实际问题,我相信您的问题在于场景大小。 如果您不按比例缩放场景以适合设备,则给场景赋予的物理边界将不会达到您期望的大小。 默认场景大小(GameScene.sks)为1024x768(iPad纵向分辨率)。 您的游戏处于横向模式,并且在iPhone上,因此场景会被裁剪/拉伸。 要了解有关场景比例模式的更多信息,请查看以下文章
http://blog.infinitecortex.com/2014/01/spritekit-understanding-skscene-scalemode/
https://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1
我最近在场景大小方面回答了类似的问题,它可能也对您有所帮助
作为进一步的提示,如果您快速学习,则遵循文档是个好习惯,因此,例如,BlueSquare之类的属性不应以大写字母开头。 仅类,结构和协议应以大写字母开头。
希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.