我正在制作一个简单的游戏,其中物体从屏幕顶部落下并落在屏幕底部的地面上(有点像俄罗斯方块),玩家在地面上避开并摧毁物体土地。我希望玩家能够在接触到左侧和右侧时摧毁物体,并且我希望玩家在物体落到他身上时被杀死。我还希望玩家能够在不破坏物体的情况下跳到物体顶部。
我试图弄清楚正确的坐标,以便为我的物体的每一面制作一个物理体。 (这是我正在尝试执行此操作的一些代码):
let topLeftPoint = CGPointMake(1, (objectSprite.size.height))
let bottomLeftPoint = CGPointMake(1 , 1)
let topRightPoint = CGPointMake((objectSprite.size.width), (objectSprite.size.height))
let bottomRightPoint = CGPointMake((objectSprite.size.width), 1)
self.topSideBody = SKPhysicsBody(edgeFromPoint: topLeftPoint, toPoint: topRightPoint)
self.topSideBody.categoryBitMask = ObstacleSide.topSide.rawValue
self.topSideBody.contactTestBitMask = BodyType.player.rawValue | BodyType.grassObject.rawValue
self.leftSideBody = SKPhysicsBody(edgeFromPoint: topLeftPoint, toPoint: bottomLeftPoint)
self.leftSideBody.categoryBitMask = ObstacleSide.leftSide.rawValue
self.leftSideBody.contactTestBitMask = BodyType.player.rawValue | BodyType.grassObject.rawValue
self.rightSideBody = SKPhysicsBody(edgeFromPoint: topRightPoint, toPoint: bottomRightPoint)
self.rightSideBody.categoryBitMask = ObstacleSide.rightSide.rawValue
self.rightSideBody.contactTestBitMask = BodyType.player.rawValue | BodyType.grassObject.rawValue
self.bottomSideBody = SKPhysicsBody(edgeFromPoint: bottomLeftPoint, toPoint: bottomRightPoint)
self.bottomSideBody.categoryBitMask = ObstacleSide.bottomSide.rawValue
self.bottomSideBody.contactTestBitMask = BodyType.player.rawValue | BodyType.grassObject.rawValue
physicsBody = SKPhysicsBody(bodies: [topSideBody, leftSideBody, rightSideBody, bottomSideBody])
objectSprite.physicsBody = physicsBody
//objectSprite.physicsBody?.categoryBitMask = BodyType.grassObject.rawValue
objectSprite.physicsBody!.friction = 0.0
objectSprite.physicsBody!.dynamic = true
objectSprite.physicsBody!.affectedByGravity = true
objectSprite.physicsBody!.restitution = 0.0
objectSprite.physicsBody!.allowsRotation = false
self.zPosition = 102
我主要不确定我应该使用什么坐标,或者是否有更简单的方法来执行此操作。考虑到我为障碍设置的一些布尔值,我也没有破坏障碍并杀死玩家的问题,我的主要问题是玩家能够在不破坏物体的情况下在物体上行走。
答案 0 :(得分:0)
如果物体是方形或矩形,那么你真的不需要超过1个物理体。这是您将如何做的概述:
请注意,我从this question复制了大部分代码。我建议你阅读它以更好地了解最新情况
在你的didBegin(_ contact:SKPhysicsContact)函数中。
获取对象节点和collisionPoint(假设对象是contact.bodyB.node)并将其传递给下面的函数:
let block = contact.bodyB.node as! SKSpriteNode
let contactPoint = contact.contactPoint
func handleCollision(block:SKSpriteNode, contactPoint:CGPoint){
// find the corners and convert thoes points into the scene coordinate space
let topLeft = convert(CGPoint(x: -block.size.width/2, y: block.size.height/2), from: block)
let bottomLeft = convert(CGPoint(x: -block.size.width/2, y: -block.size.width/2), from: block)
let topRight = convert(CGPoint(x: block.size.width/2, y: block.size.height/2), from: block)
let bottomRight = convert(CGPoint(x: block.size.width/2, y: -block.size.width/2), from: block)
// Then we put these "referencePoints" into an array for easy acces.
// Note that we go in a clockwise direction from the top left
let referencePoints = [topLeft,topRight,bottomRight,bottomLeft]
// ***Find the closest corner relative to the contactPoint.***
// Varible to store the closetCorner
var closestCorner = referencePoints[0]
//We set the prevDistance to something very large.
var prevDistance:CGFloat = 10000000
for corner in referencePoints{
// We check the distance from the contactPoint to each corner.
// If the distance is smaler then the last checked corner we update the closestCorner varible and also the prevDistance.
let distance = hypot(corner.x - contactPoint.x, corner.y - contactPoint.y)
if distance < prevDistance{
prevDistance = distance
closestCorner = corner
}
}
// Now lets find the NextCorner and prevCorner relative to the closestCorner.
var nextCorner:CGPoint
var prevCorner:CGPoint
let index = referencePoints.index(of: closestCorner)
if index == 3{
nextCorner = referencePoints[0]
}
else{
nextCorner = referencePoints[index! + 1]
}
if index == 0{
prevCorner = referencePoints[3]
}
else{
prevCorner = referencePoints[index! - 1]
}
// Distance from closestCorner to nextCorner.
let distToNextCorner = hypot(closestCorner.x - nextCorner.x, closestCorner.y - nextCorner.y)
// Distance from contactPoint to nextCorner
let distFromContactPoint = hypot(contactPoint.x - nextCorner.x, contactPoint.y - nextCorner.y)
let firstSurfacePoint = closestCorner
var secondSurfacePoint:CGPoint
if distToNextCorner > distFromContactPoint{
secondSurfacePoint = nextCorner
}
else{
secondSurfacePoint = prevCorner
}
if firstSurfacePoint == topLeft || firstSurfacePoint == topRight &&
secondSurfacePoint == topLeft || secondSurfacePoint == topRight {
// collision happend on the top side. Do something here to handle that
}
if firstSurfacePoint == topRight || firstSurfacePoint == bottomRight &&
secondSurfacePoint == topRight || secondSurfacePoint == bottomRight {
// collision happend on the right side. Do something here to handle that
}
if firstSurfacePoint == bottomLeft || firstSurfacePoint == bottomRight &&
secondSurfacePoint == bottomLeft || secondSurfacePoint == bottomRight {
// collision happend on the underside. Do something here to handle that
}
if firstSurfacePoint == topLeft || firstSurfacePoint == bottomLeft &&
secondSurfacePoint == topLeft || secondSurfacePoint == bottomLeft {
// collision happend on the left side. Do something here to handle that
}
}
这个答案可能有点草率,但如果有人问我可以改进它。因为这个问题已经11个月了,所以并没有真正打扰:)