ios - 如何在复杂的SpriteKit仿真中解决不必要的碰撞?

标签 ios swift sprite-kit skphysicsbody

(如果您想切入正题,请转到粗体部分)。

我的模拟中发生了意外碰撞。我的模拟分为以下几组:

TeethTop(这是一组对象)
牙齿底部(这是一组对象)
球(游戏中移动的主要对象)
线(偶尔绘制的一条线仅用于检测用户是否刷到牙齿)
边界(屏幕边界)

这是我需要的规则

  • 我需要何时生成SKcontacts
  • 球碰到任何牙齿(顶部或底部)
  • TeethTop碰到任何牙齿
  • 线碰到任何牙齿
  • 就身体的接触和反应(谁能击中谁并进行物理模拟)
  • 该线不能阻碍运动或击球
  • 球必须落在牙齿上,但切勿移动牙齿
  • 由于物理原因,任何牙齿都不得物理移动
  • 没有牙齿必须对与另一颗牙齿的接触做出反应
  • 球永远不要越过边界
  • 生病引力
  • 球是唯一对重力有反应的东西
  • 动态的事物(不在代码中)
  • 球是动态的,因为它会对重力产生反应并击中其他牙齿
  • 无论如何,其他一切都保持不变(但是我必须告诉牙齿它们是动态的,这样当顶部碰到底部时我可以拥有SKPhysicsContacts)

  • 基本上发生的是它们是两排牙齿,顶部和底部。他们做自己的事,成为一个舞台。墙壁是一样的。球在嘴里四处移动,就像平台游戏击中并划定牙齿。

    滑动后,会在滑动后创建一条SKPhysicsNode线,并检测用户朝哪个牙齿滑动(****也许他们是比将SKPhyiscsNode制成滑动线更好的方法...我仍然需要检测用户是否向内滑动牙齿的方向)。一切都花了一段时间,然后当顶部的牙齿碰到底部的牙齿时,嘴巴就会闭合并停止。

    我把一切都安排好了
    BottomTeethGroup = 10
    TopTeethGroup = 31
    playergroup = 2
    wallgroup = 1
    lineleart = 99
    
  • 拔牙
  • 受重力影响=假
  • 冲突位掩码= 0
  • categorybitmask = BottomTeethGroup
  • contacttTest = TopTeethGroup
  • dynamic =假
  • 底部牙齿
  • 受重力影响=假
  • 冲突位掩码= 0
  • categorybitmask = TopTeethGroup
  • contacttTest = BottomTeethGroup
  • dynamic =假

  • 受重力影响=假
  • 从未设置碰撞位掩码,因此它与
  • 的所有内容发生冲突
  • categorybitmask =玩家组
  • contacttTest =玩家组
  • 动态=真
  • 边界
  • categorybitmask =墙组
  • dynamic =假
  • 线
  • 冲突位掩码= 0
  • categorybitmask = lineleart
  • 我尝试将物理属性设置为疯狂的值,但是我无法让球通过

  • 我添加该行时出现问题。在添加行之前,所有带有检测的功能都可以正常工作。不幸的是,球与线碰撞产生了物理反应,这是不好的!球不应该与直线碰撞!

    我的看法是,他们有一些选择:
  • Make是使球通过线,或忽略两个
  • 之间的碰撞
  • 寻找一种不同的方法来检测玩家挥动哪颗牙齿(无论如何,当前方法还是有缺陷的,因为该行会检测到多个牙齿,只是因为它有一个坡度,并且一旦碰到第一个就不会停止)。如果有人有更好的方法,我将掌握起点和终点的坐标以及方向。
  • 如果我们能够做到这一点,那么使上齿和下齿仅与另一侧的齿进行物理接触,则事情会变得更加容易。
  • 使其看起来像球正在通过
  • 线

    编辑:也许我对事物的定义是有缺陷的,所以这就是我认为联系的工作方式:
  • 碰撞位掩码:只会与其他具有您在其后指定编号的对象碰撞。如果为0,则不与任何对象碰撞;如果未设置,则与所有
  • 碰撞
  • categorybitmask:定义什么类别,如果一个对象具有带有该值的类别测试位掩码,则将创建一个SKPhysics联系人,但是它们不一定是物理反应
  • contactTest:如果命中,并且另一个对象具有与此处设置的对象相同的categorybitmask,将与SKphysics进行联系
  • 动态对象碰到其他动态对象或非动态对象时会有物理反应。 SKPhysicsContacts为所有碰撞编写
  • 非动态对象不会在任何碰撞中移动,并且仅在另一个对象为静态对象时才会写出SKPhysicscontacts。预计两个非动态对象会发生碰撞。

  • 我尝试过的解决方案列表:
  • 未设置行碰撞位掩码(相同问题)
  • 腔碰撞位掩码设置为0(通过随机齿掉落,但是它不会与直线碰撞,但仍会生成SKPhysicsContact)
  • 所有牙齿的碰撞位掩码设置为4(A BIIG MESS)
  • 顶部牙齿碰撞位掩码设置为2,底部设置为4(几乎没有混乱,当空腔碰到牙齿时,它的偏移量就像0 g(0 g)一样)

  • 编辑:

    我一直在尝试一堆东西,但都没有用。我受够了,创建了一个有四个球的新项目。基本上,您将每个球设置为特定的组类型并运行模拟。我有它,所以它们是所有类别顶部的变量。如果正确设置了模拟(我认为是正确的),则程序WI将模拟如果顶部的所有值正确都将发生的情况。

    您也可以在下面找到代码
    //
    
    //  GameScene.swift
    
    //  CollisionTesting
    
    //
    
    //  Created on 8/13/15.
    
    //  Copyright (c) 2015 BroccoliPresentations. All rights reserved.
    
    //
    
     
    
    import SpriteKit
    
    enum type
    
    {
    
        case _toptooth
    
        case _bottomtooth
    
        case _ball
    
        case _line
    
        case _boundary
    
        case _none
    
    }
    
    class GameScene: SKScene {
    
        override func didMoveToView(view: SKView) {
    
            
    
            //The physics categories for each of them
    
            var topteethcategory:UInt32 = (0x01 << 1)
    
            var bottomteethcategory:UInt32 = (0x01 << 2)
    
            var ballcategory:UInt32 = (0x01 << 3)
    
            var boundriesgroup:UInt32 = (0x01 << 4)
    
            var linegroup:UInt32 = (0x01 << 5)
    
            
    
            //When collision reports should be written up
    
            var topteethcolisionreport:UInt32 = bottomteethcategory
    
            var bottomteethcollisionreport:UInt32 = topteethcategory
    
            var ballcollisionreport:UInt32 = bottomteethcategory | topteethcategory
    
            var boundriescollisionreport:UInt32 = 0
    
            var linecollisionreport:UInt32 = topteethcategory | bottomteethcategory
    
            
    
            //When they should bounce off of eachother
    
            var topteethphysics:UInt32 = bottomteethcategory
    
            var bottomteethphysics:UInt32 = topteethcategory
    
            var ballphysics:UInt32 = bottomteethcategory | topteethcategory | boundriesgroup
    
            var boundriesphysics:UInt32 = boundriesgroup
    
            var linecollisionphysics:UInt32 = linegroup
    
            
    
            
    
            //Here you can set what tope of object each color is
    
            var blue:type = type._toptooth
    
            var red:type = type._bottomtooth
    
            var yellow:type = type._ball
    
            var green:type = type._none
    
            
    
            
    
            var xy = CGRectGetMidX(self.frame) * 1.5
    
            var ball1 = SKSpriteNode(texture: SKTexture(imageNamed: "Blue"))
    
            ball1.position = CGPoint(x: xy, y:CGRectGetMidY(self.frame));
    
            ball1.size = CGSizeMake(100, 100)
    
            ball1.physicsBody?.affectedByGravity = false
    
            ball1.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    
            ball1.physicsBody?.velocity = CGVector(dx: -100, dy: 0)
    
            
    
            var ball2 = SKSpriteNode(texture: SKTexture(imageNamed: "Red"))
    
            ball2.position = CGPoint(x:xy / 2, y:CGRectGetMidY(self.frame));
    
            ball2.size = CGSizeMake(100, 100)
    
            ball2.physicsBody?.affectedByGravity = false
    
            ball2.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    
            ball2.physicsBody?.velocity = CGVector(dx: 100, dy: 0)
    
            
    
            var ball3 = SKSpriteNode(texture: SKTexture(imageNamed: "Yellow"))
    
            ball3.position = CGPoint(x:((xy / 4) + xy) / 2, y:CGRectGetMidY(self.frame) / 2);
    
            ball3.size = CGSizeMake(100, 100)
    
            ball3.physicsBody?.affectedByGravity = false
    
            ball3.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    
            ball3.physicsBody?.velocity = CGVector(dx: 0, dy: 100)
    
            
    
            var ball4 = SKSpriteNode(texture: SKTexture(imageNamed: "Green"))
    
            ball4.position = CGPoint(x:((xy / 4) + xy) / 2, y:CGRectGetMidY(self.frame) * 1.5);
    
            ball4.size = CGSizeMake(100, 100)
    
            ball4.physicsBody?.affectedByGravity = false
    
            ball4.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    
            ball4.physicsBody?.velocity = CGVector(dx: 0, dy: -100)
    
            self.addChild(ball1)
    
            self.addChild(ball2)
    
            self.addChild(ball3)
    
            self.addChild(ball4)
    
            
    
            
    
            switch (blue)
    
            {
    
            case type._toptooth:
    
                    ball1.physicsBody?.categoryBitMask = topteethcategory
    
                    ball1.physicsBody?.collisionBitMask = topteethphysics
    
                    ball1.physicsBody?.contactTestBitMask = topteethcolisionreport
    
            case type._bottomtooth:
    
                ball1.physicsBody?.categoryBitMask = bottomteethcategory
    
                ball1.physicsBody?.collisionBitMask = bottomteethphysics
    
                ball1.physicsBody?.contactTestBitMask = bottomteethcollisionreport
    
            case type._ball:
    
                ball1.physicsBody?.categoryBitMask = ballcategory
    
                ball1.physicsBody?.collisionBitMask = ballphysics
    
                ball1.physicsBody?.contactTestBitMask = ballcollisionreport
    
            case type._boundary:
    
                ball1.physicsBody?.categoryBitMask = boundriesgroup
    
                ball1.physicsBody?.collisionBitMask = boundriesphysics
    
                ball1.physicsBody?.contactTestBitMask = boundriescollisionreport
    
            case type._line:
    
                ball1.physicsBody?.categoryBitMask = linegroup
    
                ball1.physicsBody?.collisionBitMask = linecollisionphysics
    
                ball1.physicsBody?.contactTestBitMask = linecollisionreport
    
            case type._none:
    
                ball1.position = CGPointMake(100000, 10000)
    
            }
    
            
    
            switch (red)
    
            {
    
            case type._toptooth:
    
                ball2.physicsBody?.categoryBitMask = topteethcategory
    
                ball2.physicsBody?.collisionBitMask = topteethphysics
    
                ball2.physicsBody?.contactTestBitMask = topteethcolisionreport
    
            case type._bottomtooth:
    
                ball2.physicsBody?.categoryBitMask = bottomteethcategory
    
                ball2.physicsBody?.collisionBitMask = bottomteethphysics
    
                ball2.physicsBody?.contactTestBitMask = bottomteethcollisionreport
    
            case type._ball:
    
                ball2.physicsBody?.categoryBitMask = ballcategory
    
                ball2.physicsBody?.collisionBitMask = ballphysics
    
                ball2.physicsBody?.contactTestBitMask = ballcollisionreport
    
            case type._boundary:
    
                ball2.physicsBody?.categoryBitMask = boundriesgroup
    
                ball2.physicsBody?.collisionBitMask = boundriesphysics
    
                ball2.physicsBody?.contactTestBitMask = boundriescollisionreport
    
            case type._line:
    
                ball2.physicsBody?.categoryBitMask = linegroup
    
                ball2.physicsBody?.collisionBitMask = linecollisionphysics
    
                ball2.physicsBody?.contactTestBitMask = linecollisionreport
    
            case type._none:
    
                ball2.position = CGPointMake(100000, 10000)
    
            }
    
            
    
            switch (blue)
    
            {
    
            case type._toptooth:
    
                ball3.physicsBody?.categoryBitMask = topteethcategory
    
                ball3.physicsBody?.collisionBitMask = topteethphysics
    
                ball3.physicsBody?.contactTestBitMask = topteethcolisionreport
    
            case type._bottomtooth:
    
                ball3.physicsBody?.categoryBitMask = bottomteethcategory
    
                ball3.physicsBody?.collisionBitMask = bottomteethphysics
    
                ball3.physicsBody?.contactTestBitMask = bottomteethcollisionreport
    
            case type._ball:
    
                ball3.physicsBody?.categoryBitMask = ballcategory
    
                ball3.physicsBody?.collisionBitMask = ballphysics
    
                ball3.physicsBody?.contactTestBitMask = ballcollisionreport
    
            case type._boundary:
    
                ball3.physicsBody?.categoryBitMask = boundriesgroup
    
                ball3.physicsBody?.collisionBitMask = boundriesphysics
    
                ball3.physicsBody?.contactTestBitMask = boundriescollisionreport
    
            case type._line:
    
                ball3.physicsBody?.categoryBitMask = linegroup
    
                ball3.physicsBody?.collisionBitMask = linecollisionphysics
    
                ball3.physicsBody?.contactTestBitMask = linecollisionreport
    
            case type._none:
    
                ball3.position = CGPointMake(100000, 10000)
    
            }
    
            
    
            switch (green)
    
            {
    
            case type._toptooth:
    
                ball4.physicsBody?.categoryBitMask = topteethcategory
    
                ball4.physicsBody?.collisionBitMask = topteethphysics
    
                ball4.physicsBody?.contactTestBitMask = topteethcolisionreport
    
            case type._bottomtooth:
    
                ball4.physicsBody?.categoryBitMask = bottomteethcategory
    
                ball4.physicsBody?.collisionBitMask = bottomteethphysics
    
                ball4.physicsBody?.contactTestBitMask = bottomteethcollisionreport
    
            case type._ball:
    
                ball4.physicsBody?.categoryBitMask = ballcategory
    
                ball4.physicsBody?.collisionBitMask = ballphysics
    
                ball4.physicsBody?.contactTestBitMask = ballcollisionreport
    
            case type._boundary:
    
                ball4.physicsBody?.categoryBitMask = boundriesgroup
    
                ball4.physicsBody?.collisionBitMask = boundriesphysics
    
                ball4.physicsBody?.contactTestBitMask = boundriescollisionreport
    
            case type._line:
    
                ball4.physicsBody?.categoryBitMask = linegroup
    
                ball4.physicsBody?.collisionBitMask = linecollisionphysics
    
                ball4.physicsBody?.contactTestBitMask = linecollisionreport
    
            case type._none:
    
                ball4.position = CGPointMake(100000, 10000)
    
            }
    
            
    
            
    
            
    
            physicsWorld.gravity = CGVector(dx: 0, dy: 0)
    
        }
    
        
    
     
    
        override func update(currentTime: CFTimeInterval) {
    
            /* Called before each frame is rendered */
    
        }
    
    }
    
     
    
    //nothing set they collide to eachother
    
    //contactTestbitmask has nothing to do with bumping against eachother
    
    //Category is the most important it gives it a type
    
    //The other two decide when reactions happen, either physical or in code
    
    //Collision bitmask is a list of groups that it actually should collide with
    
    //Contacttestbitmask is list of groups that can trigger the code
    

    最佳答案

    我想通了!我的问题是我使事情变得过于复杂。我实际上不需要所有这些小组!这就是我所做的!

    var stage:UInt32 = (0x1 << 1)
    var player:UInt32 = (0x1 << 2)
    var sensors:UInt32 = (0x1 << 3)
    
    //Physics collision bitmask
    var p_stage:UInt32 = 0
    var p_player:UInt32 = 0 | stage
    var p_sensors:UInt32 = 0
    
    //Test bitmask
    var t_stage:UInt32 = stage
    var t_player:UInt32 = stage
    var t_sensors:UInt32 = stage
    

    实际上,我并不需要我想的那么多小组!但是,我确实必须在节点名称中存储一些数据,以便告诉它是从顶部还是底部还是从哪一行开始的,但是总体来说,它很棒!

    谢谢大家仔细检查了一切,这确实意义重大!

    我发现奇怪的是
    (0x1 << 1)
    (0x1 << 2)
    (0x1 << 3)
    

    那就好了
    1
    2
    3
    

    我想我真的不知道我在用(0x1 << 1)做什么,但是我在其他地方看到了并复制了它!

    关于ios - 如何在复杂的SpriteKit仿真中解决不必要的碰撞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31982711/

    相关文章:

    ios - 我如何知道哪个场景称为特定场景?

    ios - 如何从标签数组中快速更改 Collection View 中特定单元格标签的颜色

    android - react Native TextInput 数字键盘在 android 上没有正确显示

    ios - Swift iOS 尝试动态更改 UITextAutocapitalization 类型

    swift - 指示tableView的indexPath何时为最后一个

    ios - 使用 Apple 登录 : How to know if user is signing up or signing in

    ios - "Failure to deallocate CLLocationManager on the same runloop as its creation may result in a crash"

    arrays - 类型 'Bool' 不符合协议(protocol) 'Sequence'

    macos - Spritekit OS X 如何使用自定义字体

    swift - 使节点以相同的速度从不同的起点移动到终点