Einige Beobachtungen ...
Wenn Box B Ausgangsposition rechts von der Endposition ist (in dem Spalte), dann kann die Box in die Endposition bewegt erfolgreich mit den anderen Boxen nur, ohne kollidieren, wenn Theta ist ein gegen den Uhrzeigersinn Winkel (siehe Abbildung unten). Für diesen Test verwenden Sie die Box B oberen rechten Ecke und der linken unteren Ecke von C.
Und falls Feld B Ausgangsposition links von der Endposition ist, dann kann es erfolgreich Bewegen Sie sich in die Endposition, ohne mit den anderen Boxen zu kollidieren, nur wenn Theta gegen den Uhrzeigersinn ist (siehe Abbildung unten). Für diesen Test verwenden Sie die Box B linken oberen Ecke und der rechten unteren Ecke von A.
Einige Code ...
Zuerst erweitern CGPoint
die Ecken eines Kastens zu bestimmen .
extension CGPoint {
func bottomLeftCorner(size:CGSize) -> CGPoint {
return CGPoint (x:x - size.width/2.0, y:y - size.height/2.0)
}
func bottomRightCorner(size:CGSize) -> CGPoint {
return CGPoint(x:x + size.width/2.0, y:y - size.height/2.0)
}
func topLeftCorner(size:CGSize) -> CGPoint {
return CGPoint (x:x - size.width/2.0, y:y + size.height/2.0)
}
func topRightCorner(size:CGSize) -> CGPoint {
return CGPoint(x:x + size.width/2.0, y:y + size.height/2.0)
}
}
Der folgende Code ermöglicht es der Benutzer löschen/Drag Box B. Während der Benutzer das Feld bewegt, führt der Code einen On-the-fly-Test, um zu sehen, wenn die Box in den Spalt bewegen kann, ohne kollidieren die anderen Boxen.
class GameScene: SKScene {
let size1 = CGSize(width: 100, height: 50)
let size2 = CGSize(width: 50, height: 50)
let size3 = CGSize(width: 100, height: 50)
var boxA:SKSpriteNode!
var boxB:SKSpriteNode!
var boxC:SKSpriteNode!
var center:CGPoint!
override func didMove(to view: SKView) {
// This is box B's ending position
center = CGPoint (x:0,y:0)
// Define and add the boxes to the scene
boxA = SKSpriteNode(color: SKColor.yellow, size: size1)
boxB = SKSpriteNode(color: SKColor.red, size: size2)
boxC = SKSpriteNode(color: SKColor.blue, size: size3)
boxA.position = CGPoint(x: -size1.width, y: 0)
boxB.position = CGPoint(x: 0, y: 0)
boxC.position = CGPoint(x: size3.width, y: 0)
boxB.zPosition = 1
addChild(boxA)
addChild(boxB)
addChild(boxC)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
// Allow user to drag box to a new location
boxB.position = location
// Find the appropriate corners
var cornerA:CGPoint!
var cornerB:CGPoint!
var cornerC:CGPoint!
if (boxB.position.x < center.x) {
cornerA = boxA.position.bottomRightCorner(size: boxA.size)
cornerB = boxB.position.topLeftCorner(size: boxB.size)
cornerC = center.topLeftCorner(size: boxB.size)
}
else {
cornerA = center.topRightCorner(size: boxB.size)
cornerB = boxB.position.topRightCorner(size: boxB.size)
cornerC = boxC.position.bottomLeftCorner(size: boxC.size)
}
// Test if box B can move in the gap without colliding
if isCounterClockwise(A: cornerA, B: cornerB, C: cornerC) {
boxB.color = SKColor.green
}
else {
boxB.color = SKColor.red
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// Move box B to the ending position
let action = SKAction.move(to: center, duration: 2)
boxB.run(action)
}
// Test direction of angle between line segments AB and AC
func isCounterClockwise (A:CGPoint, B:CGPoint, C:CGPoint) -> Bool {
return (C.y-A.y)*(B.x-A.x) > (B.y-A.y)*(C.x-A.x)
}
}
und ein Videoclip ...
Box B wird grün, wenn es in die Lücke nicht, ob rot, ohne kollidieren und dann bewegen kann.
Kein Winkel wird benötigt, Sie kennen Ihre Startbox, und Ihre Endbox, machen Sie einfach Linien von jedem Punkt auf B0 zu seinem jeweiligen Punkt auf B1, und sehen, ob diese Linien mit A oder C schneiden – Knight0fDragon
@ Knight0fDragon bitte I ' Ich bin mir nicht sicher, wie man einfach Linien von jedem Punkt auf B0 zu seinem jeweiligen Punkt auf B1 macht und ob diese Linien sich mit A oder C schneiden. – ItsMeAgain
Das ist grundlegende Mathematik, google wie man eine Linie mit 2 Punkten macht und wie Um zu überprüfen, ob eine Linie mit einer Box – Knight0fDragon