gpt4 book ai didi

ios - block 快速移动时的意外碰撞行为 - Sprite 通过

转载 作者:可可西里 更新时间:2023-11-01 02:17:32 26 4
gpt4 key购买 nike

我有一个方形框架,允许用户在其中移动一个 block 但不能触摸框架。如果用户触摸方框,游戏结束。目前我有一个问题,如果用户快速 slider ,它会在没有任何碰撞/接触检测的情况下穿过框架。如果玩家缓慢移动方 block 并接触框架,那么它会检测到碰撞。我的代码如下,我无法让它停止通过框架。

// setup play scene
let playScreen = SKSpriteNode(color: .clearColor(), size: CGSize(width: 370, height: 370))
playScreen.position = CGPoint(x: frame.midX, y: frame.midY - CGFloat(yFrame))
// create the rectangle which will represent physics body
let rect = CGRect(origin: CGPoint(x: -playScreen.size.width/2, y: -playScreen.size.height/2), size: playScreen.size)
// apply physics conditions to the play scene
playScreen.physicsBody = SKPhysicsBody(edgeLoopFromRect: rect)
playScreen.physicsBody!.friction = 0
// add play scene to the frame
addChild(playScreen)
playScreen.physicsBody!.categoryBitMask = BitMask.frame
playScreen.physicsBody!.contactTestBitMask = BitMask.player
playScreen.physicsBody!.collisionBitMask = BitMask.player
playScreen.physicsBody!.usesPreciseCollisionDetection = true;

// set up player block
player.position = CGPoint(x:frame.size.width/2, y: frame.size.height/2 - CGFloat(yFrame))
player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 30, height: 30))
player.physicsBody!.dynamic = true
player.physicsBody!.friction = 0
player.physicsBody!.affectedByGravity = false
player.physicsBody!.allowsRotation = false
addChild(player)
player.physicsBody!.categoryBitMask = BitMask.player
player.physicsBody!.contactTestBitMask = BitMask.obstacle | BitMask.frame
player.physicsBody!.collisionBitMask = BitMask.obstacle | BitMask.frame

我有以下接触检测:

func didBeginContact(contact: SKPhysicsContact) {
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}

if (firstBody.categoryBitMask == BitMask.player) && ( (secondBody.categoryBitMask == BitMask.obstacle) || (secondBody.categoryBitMask == BitMask.frame) ) {

self.view?.paused = true

// check if this stops it
player.physicsBody!.velocity.dx = 0
player.physicsBody!.velocity.dy = 0

playerCollided = true

}
}

所以这是我的 touches begind 函数的代码。如果用户触摸播放器 block :

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first! as UITouch
let touchLocation = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(touchLocation)
let name = touchedNode.name

if name == "player" {

// first touch
if playerFirstTouch {
print("New Game")
print("Finger is on player block")
isFingerOnPlayer = true

NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "printDuration:", userInfo: NSDate(), repeats: true)

playerFirstTouch = false
print("\(player.physicsBody!.velocity.dy)")

} else {
print("Finger is on player block after game started")
isFingerOnPlayer = true
print("\(player.physicsBody!.velocity.dy)")
}
}
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first! as UITouch
let touchLocation = touch.locationInNode(self)

// check if user touched the player block
if isFingerOnPlayer {
// get touch location
if let touch = touches.first {
let prevTouchLoc = touch.previousLocationInNode(self)
// calculate new position along x and y
var newXPos = player.position.x + (touchLocation.x - prevTouchLoc.x)
var newYPos = player.position.y + (touchLocation.y - prevTouchLoc.y)
//
newXPos = max(newXPos, self.player.frame.size.width/2)
newXPos = min(newXPos, self.size.width - self.player.frame.size.width/2)
//
newYPos = max(newYPos, self.player.frame.size.height/2)
newYPos = min(newYPos, self.size.height - self.player.frame.size.height/2)
// update player block position
player.position = CGPointMake(newXPos, newYPos)
}
}

}

最佳答案

让玩家使用精确的碰撞检测,而不是场景。玩家是正在移动的节点,需要对其物理计算进行分步执行。所以像这样:

player.physicsBody!.usesPreciseCollisionDetection = true;

您可以从 playScene 中删除精确的碰撞检测,因为启用它只会使物理引擎陷入困境。

编辑

我正在扩展它以涵盖如何使用 SKAction 移动节点而不是设置位置。我很确定这会起作用,但请告诉我。查看the documentation for the moveBy method我将要使用的。

你要做的第一件事是删除这一行:

player.position = CGPointMake(newXPos, newYPos)

我们将用这一行替换它:

player.runAction(SKAction.moveTo(CGPointMake(newXPos, newYPos), 0.01))

这应该可以让玩家非常快速地移动到所需位置(我认为)。

关于ios - block 快速移动时的意外碰撞行为 - Sprite 通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35529682/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com