Ios 检查两个节点相互接触时是否具有相同的颜色
我是斯威夫特的新手,所以如果我犯了新手错误,我向你道歉。我试图让两个盒子在接触时消失,如果两个盒子颜色相同。到目前为止,我有以下代码: 此代码设置游戏:Ios 检查两个节点相互接触时是否具有相同的颜色,ios,swift,sprite-kit,swift3,skspritenode,Ios,Swift,Sprite Kit,Swift3,Skspritenode,我是斯威夫特的新手,所以如果我犯了新手错误,我向你道歉。我试图让两个盒子在接触时消失,如果两个盒子颜色相同。到目前为止,我有以下代码: 此代码设置游戏: import SpriteKit import GameplayKit class GameScene: SKScene, SKPhysicsContactDelegate { override func didMove(to view: SKView) { physicsBod
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.contactDelegate = self
let background = SKSpriteNode(imageNamed: "background.jpg")
background.size = self.frame.size;
background.position = CGPoint(x: 0, y: 0)
background.blendMode = .replace
background.zPosition = -1
addChild(background)
}
生成随机颜色的代码:
enum Color {
case ColorRed
case ColorGreen
case ColorBlue
public var color: UIColor {
switch self {
case .ColorRed: return UIColor(red: 255, green: 0, blue: 0, alpha: 1)
case .ColorGreen: return UIColor(red: 0, green: 255, blue: 0, alpha: 1)
case .ColorBlue: return UIColor(red: 0, green: 0, blue: 255, alpha: 1)
}
}
static var all: [Color] = [.ColorRed, .ColorGreen, .ColorBlue]
static var randomColor: UIColor {
let randomIndex = Int(arc4random_uniform(UInt32(all.count)))
return all[randomIndex].color
}
}
这是重要的部分-对象之间的实际接触:
func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
let firstBody = contact.bodyA.node as! SKSpriteNode!
let secondBody = contact.bodyB.node as! SKSpriteNode!
if firstBody!.color == secondBody!.color {
firstBody!.removeFromParent()
secondBody!.removeFromParent()
}
} else {
let firstBody = contact.bodyB.node as! SKSpriteNode!
let secondBody = contact.bodyA.node as! SKSpriteNode!
if firstBody!.color == secondBody!.color {
firstBody!.removeFromParent()
secondBody!.removeFromParent()
}
}
}
func didbeagin(uu联系人:skphysiccontact){
如果contact.bodyA.categoryBitMask
最后是用户触摸屏幕时的代码:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
box.color = Color.randomColor
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
box.position = location
addChild(box)
}
}
override func touchsbegind(touch:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
box.color=color.randomColor
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
box.position=位置
addChild(框)
}
}
我已经提供了所有的代码,所以你知道设置。提前感谢您的帮助。首先,为
类别BitMask
声明一个结构:
struct ColorMask {
static let Red: UInt32 = 0x1 << 0
static let Green: UInt32 = 0x1 << 1
static let Blue: UInt32 = 0x1 << 2
}
我只是将上面的代码改为返回Color
,而不是UIColor
第三,将didbeagin
修改为:
func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask == contact.bodyB.categoryBitMask {
let firstBody = contact.bodyA.node as! SKSpriteNode!
let secondBody = contact.bodyB.node as! SKSpriteNode!
firstBody!.removeFromParent()
secondBody!.removeFromParent()
}
}
在上面的代码中,只需比较categoryBitMask
就足够了,因为我稍后将使用相同的categoryBitMask
设置具有相同颜色的主体
最后,使用以下代码将categoryBitMask
设置到框中:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
let color = Color.randomColor
box.color = color.color
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
if color == Color.ColorRed {
box.physicsBody?.categoryBitMask = ColorMask.Red
} else if color == Color.ColorGreen {
box.physicsBody?.categoryBitMask = ColorMask.Green
}else if color == Color.ColorBlue {
box.physicsBody?.categoryBitMask = ColorMask.Blue
}
box.physicsBody?.contactTestBitMask = ColorMask.Red | ColorMask.Green | ColorMask.Blue
box.position = location
addChild(box)
}
}
override func touchsbegind(touch:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
让color=color.randomColor
box.color=color.color
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
如果颜色==color.ColorRed{
box.physicsBody?.categoryBitMask=彩色Mask.Red
}如果color==color.ColorGreen,则为else{
box.physicsBody?.categoryBitMask=彩色Mask.Green
}如果color==color.ColorBlue,则为else{
box.physicsBody?.categoryBitMask=ColorMask.Blue
}
box.physicsBody?.contactTestBitMask=ColorMask.Red | ColorMask.Green | ColorMask.Blue
box.position=位置
addChild(框)
}
}
您未正确设置contactBitMask,因此未检测到任何联系人。。。默认情况下,由于性能原因,此掩码的默认值为零:
当两个实体共享同一空间时,每个实体的类别遮罩为
通过执行逻辑测试,针对另一个身体的接触面具进行测试
和操作。如果其中一个比较结果为非零值,则
SKPhysicContact对象被创建并传递给物理世界的
代表。为获得最佳性能,仅在联系人掩码中设置
你感兴趣的互动
默认值为0x00000000(所有位均已清除)
要解决此问题,请将contact和category位掩码都设置为适当的值,如下所示:
class GameScene: SKScene,SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.contactDelegate = self
}
func didBegin(_ contact: SKPhysicsContact) {
if let bodyA = contact.bodyA.node as? SKSpriteNode,
let bodyB = contact.bodyB.node as? SKSpriteNode{
//Of course this is simple example and you will have to do some "filtering" to determine what type of objects are collided.
// But the point is , when appropriate objects have collided, you compare their color properties.
if bodyA.color == bodyB.color {
bodyA.run(SKAction.removeFromParent())
bodyB.run(SKAction.removeFromParent())
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
box.color = Color.randomColor
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
box.physicsBody?.contactTestBitMask = 0b1
box.physicsBody?.categoryBitMask = 0b1
box.position = location
addChild(box)
}
}
}
类游戏场景:SKScene,skphysiccontactdelegate{
覆盖func didMove(到视图:SKView){
self.physicsWorld.contactDelegate=self
physicsBody=SKPhysicsBody(edgeLoopFrom:frame)
physicsWorld.contactDelegate=self
}
func didbegen(uu联系人:skphysiccontact){
如果让bodyA=联系.bodyA.node作为?SKSpriteNode,
设bodyB=contact.bodyB.node为?SKSpriteNode{
//当然,这是一个简单的示例,您必须进行一些“过滤”以确定碰撞的对象类型。
//但关键是,当适当的对象发生碰撞时,可以比较它们的颜色属性。
如果bodyA.color==bodyB.color{
bodyA.run(SKAction.removeFromParent())
bodyB.run(SKAction.removeFromParent())
}
}
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
box.color=color.randomColor
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
box.physicsBody?.contactTestBitMask=0b1
box.physicsBody?.categoryBitMask=0b1
box.position=位置
addChild(框)
}
}
}
现在,当两个实体之间发生接触时,如文档中所述,通过执行逻辑“与”运算,每个实体的类别位掩码将与另一个实体的接触掩码一起测试。如果结果为非零,则会出现联系人通知。在本例中,这将是1&1=1。当您运行代码时,实际看到的是什么,以及它与您期望的有什么不同。还有一半的func didbeagin是多余的,因为无论节点以何种方式进入函数,都会删除它们。它与您要求的内容无关,但为什么要为颜色创建枚举?为什么不创建静态计算属性“随机”
class GameScene: SKScene,SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.contactDelegate = self
}
func didBegin(_ contact: SKPhysicsContact) {
if let bodyA = contact.bodyA.node as? SKSpriteNode,
let bodyB = contact.bodyB.node as? SKSpriteNode{
//Of course this is simple example and you will have to do some "filtering" to determine what type of objects are collided.
// But the point is , when appropriate objects have collided, you compare their color properties.
if bodyA.color == bodyB.color {
bodyA.run(SKAction.removeFromParent())
bodyB.run(SKAction.removeFromParent())
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
box.color = Color.randomColor
box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
box.physicsBody?.contactTestBitMask = 0b1
box.physicsBody?.categoryBitMask = 0b1
box.position = location
addChild(box)
}
}
}