Ich habe mein eigenes sehr einfaches Testspiel basierend auf Breakout erstellt, während ich SpriteKit (mit iOS Games by Tutorials von Ray Wenderlich et al.) Erlerne, um zu sehen, ob ich mich bewerben kann Konzepte, die ich gelernt habe. Ich habe mich entschieden, meinen Code zu vereinfachen, indem ich eine .sks-Datei verwende, um die Sprite-Knoten zu erstellen und meine manuellen Grenzen, die Überprüfung und Kollision mit physikalischen Körpern zu ersetzen.SpriteKit Physik in Swift - Ball gleitet gegen die Wand anstatt zu reflektieren
Allerdings läuft mein Ball immer parallel zu Wänden/anderen Rechtecken (wie in, einfach auf und ab gleiten), immer wenn er in steilem Winkel mit ihnen kollidiert. Hier wird der entsprechende Code - Ich habe die Physik Körpereigenschaften in Code bewegt, um sie besser sichtbar:
import SpriteKit
struct PhysicsCategory {
static let None: UInt32 = 0 // 0
static let Edge: UInt32 = 0b1 // 1
static let Paddle: UInt32 = 0b10 // 2
static let Ball: UInt32 = 0b100 // 4
}
var paddle: SKSpriteNode!
var ball: SKSpriteNode!
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector.zeroVector
let edge = SKNode()
edge.physicsBody = SKPhysicsBody(edgeLoopFromRect: frame)
edge.physicsBody!.usesPreciseCollisionDetection = true
edge.physicsBody!.categoryBitMask = PhysicsCategory.Edge
edge.physicsBody!.friction = 0
edge.physicsBody!.restitution = 1
edge.physicsBody!.angularDamping = 0
edge.physicsBody!.linearDamping = 0
edge.physicsBody!.dynamic = false
addChild(edge)
ball = childNodeWithName("ball") as SKSpriteNode
ball.physicsBody = SKPhysicsBody(rectangleOfSize: ball.size))
ball.physicsBody!.usesPreciseCollisionDetection = true
ball.physicsBody!.categoryBitMask = PhysicsCategory.Ball
ball.physicsBody!.collisionBitMask = PhysicsCategory.Edge | PhysicsCategory.Paddle
ball.physicsBody!.allowsRotation = false
ball.physicsBody!.friction = 0
ball.physicsBody!.restitution = 1
ball.physicsBody!.angularDamping = 0
ball.physicsBody!.linearDamping = 0
physicsWorld.contactDelegate = self
}
vergessen dies vor zu erwähnen, aber ich hinzugefügt, um eine einfache touchesBegan Funktion die Bounces zu debuggen - es passt einfach die Geschwindigkeit der Kugel an dem Berührungspunkt Punkt:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let moveToward = touch.locationInNode(self)
let targetVector = (moveToward - ball.position).normalized() * 300.0
ball.physicsBody!.velocity = CGVector(point: targetVector)
}
die normalisierte() Funktion reduziert es den Ball/Berührungsposition Delta zu einem Einheitsvektor, und es gibt eine Überschreibung des minus-Operator, der für CGPoint Subtraktion ermöglicht .
Die Kugel/Kanten Kollisionen sollten immer den Ball in einem genau entgegengesetzten Winkel reflektieren aber aus irgendeinem Grund scheint der Ball wirklich etwas für rechte Winkel zu haben. Ich kann natürlich eine Workaround implementieren, um den Winkel des Balls manuell zu reflektieren, aber der Punkt ist, dass ich das alles mit der eingebauten Physik-Funktionalität in SpriteKit machen möchte. Gibt es etwas Offensichtliches, dass ich vermisse?
Sie müssen das Sprit bewegen, indem eine Kraft oder einen Impuls auf seinen Physikkörper anwenden oder seine Geschwindigkeitseigenschaft einstellen. Das Sprite nimmt nicht an der Physiksimulation teil, wenn Sie es mit einer Aktion bewegen oder seine Position direkt setzen. – 0x141E
Entschuldigung, ich hatte meine Geschwindigkeitsanpassung weggelassen. Ich habe es gerade bearbeitet, aber im Grunde ist es ein Berührungsereignis, das die Ballgeschwindigkeit in Richtung des Berührungspunkts in der SKScene einstellt. –
Tippen und lösen Sie Ihren Finger oder halten Sie ihn gedrückt, wenn der Kontakt auftritt? – 0x141E