当前位置:  开发笔记 > 编程语言 > 正文

如何确定方块是否可以在不与其他精灵接触的情况下到达位置?

如何解决《如何确定方块是否可以在不与其他精灵接触的情况下到达位置?》经验,为你挑选了1个好方法。

在此输入图像描述

从上图中,给定初始位置b0(x,y),b1(x,y)的结束位置和a(x,y)和c(x,y)的位置.如何在不与矩形A和C接触的情况下预先确定方形B0是否从b0(x,y)移动到b1(x,y)?我相信这个角度是必要的.



1> 0x141E..:

一些观察......

如果方框B的初始位置位于结束位置的右侧(在间隙中),则只有当theta是逆时针角度时,方框才能成功移动到结束位置而不与其他方框发生碰撞(见下图).对于此测试,请使用方框B的右上角和C的左下角.

在此输入图像描述

类似地,如果框B的初始位置在结束位置的左侧,那么只有当θ是逆时针角度时,它才能成功地移动到结束位置而不与其他框碰撞(见下图).对于此测试,请使用方框B的左上角和A的右下角.

在此输入图像描述

一些代码......

首先,扩展CGPoint以确定盒子的角落.

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)
    }
}

以下代码允许用户删除/拖动框B.当用户移动框时,代码执行即时测试以查看框是否可以移动到间隙而不与其他框冲突.

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, 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, 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)
    }
}

和视频剪辑......

在此输入图像描述

如果盒B在没有碰撞的情况下移动到间隙中则变为绿色,否则变为红色.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有