gpt4 book ai didi

swift - 对象位置不匹配(Spritekit)

转载 作者:行者123 更新时间:2023-11-28 14:25:37 28 4
gpt4 key购买 nike

我正在构建一个 spritekit 游戏并且刚刚开始这个项目。我在屏幕上有一个从中心开始的圆圈,当我从圆圈向外拖动手指时,它会显示一条连接到球的虚线/贝塞尔曲线路径,这将帮助用户看到它瞄准球的位置。当用户抬起手指时,球将朝瞄准线的相反方向射出。 (想想足球明星或 table 球之类的游戏)。问题是当一切都从中间开始时,这个 Action 第一次起作用:我拖动我的手指,球向相反的方向射击然后停止。但是当我再次尝试时,瞄准线的位置说它与球相同(应该是),但随后它在屏幕上显示离球一英寸远。我觉得这可能是物体后面的场景大小可能不同的问题?但我很困惑,因为我认为我只使用了一个场景。

GameViewController viewDidLoad:

override func viewDidLoad() {
super.viewDidLoad()

if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
scene.size = view.bounds.size
//scene.anchorPoint = CGPoint(x: 0.0, y: 0.0)


// Present the scene
view.presentScene(scene)
}

view.ignoresSiblingOrder = true

view.showsFPS = true
view.showsNodeCount = true
}
}

GameScene 代码(怀疑您是否需要所有这些代码,但无论如何):

import SpriteKit
import GameplayKit

class GameScene: SKScene {

var ball = SKShapeNode(circleOfRadius: 35)
var touchingBall = false
var aimLine = SKShapeNode()

var startAimPoint = CGPoint()
var endAimPoint = CGPoint()

let damping:CGFloat = 0.94

override func didMove(to view: SKView) {

ball.fillColor = SKColor.orange
ball.name = "ball"

let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)

var physicsBody = SKPhysicsBody(circleOfRadius: 35)
ball.physicsBody = physicsBody
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.friction = 10.0

ball.position = CGPoint(x: frame.midX, y: frame.midY)

self.addChild(ball)
}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("TOUCHES BEGAN.")
for touch in touches {
print("TB: \(touchingBall)")
let location = touch.location(in: self)
let node : SKNode = self.atPoint(location)
if node.name == "ball" {
// touched inside node
if ball.physicsBody!.angularVelocity <= 0.0{
touchingBall = true

startAimPoint = ball.position

print(touchingBall)
}
}
}

}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
print("TOCUHES MOVED.")
for touch in touches {
let location = touch.location(in: self)
if touchingBall{
endAimPoint = location

assignAimLine(start: startAimPoint, end: endAimPoint)
print("Moving touched ball")

}
}

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
print("Touches ended. \(touchingBall)")
if touchingBall == true{

ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x - startAimPoint.x) * 3, dy: -(endAimPoint.y - startAimPoint.y) * 3))

}

touchingBall = false
aimLine.removeFromParent()
print(touchingBall)

}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {

print("Touches cancelled. \(touchingBall)")
if touchingBall == true{

ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x - startAimPoint.x) * 3, dy: -(endAimPoint.y - startAimPoint.y) * 3))

}

touchingBall = false
aimLine.removeFromParent()
print(touchingBall)

}


override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered

print(ball.physicsBody!.velocity)
let dx2 = ball.physicsBody!.velocity.dx * damping
let dy2 = ball.physicsBody!.velocity.dy * damping
ball.physicsBody!.velocity = CGVector(dx: dx2, dy: dy2)


}
func assignAimLine(start: CGPoint, end: CGPoint){

aimLine.removeFromParent()

var bezierPath = UIBezierPath()
bezierPath.move(to: start)
bezierPath.addLine(to: shortenedEnd(startPoint: start, endPoint: end))

var pattern : [CGFloat] = [10.0, 10.0]
let dashed = SKShapeNode(path: bezierPath.cgPath.copy(dashingWithPhase: 2, lengths: pattern))

aimLine = dashed
aimLine.position = ball.position

aimLine.zPosition = 0

self.addChild(aimLine)



}
func hypotenuse(bp: UIBezierPath) -> Double{
var a2 = bp.cgPath.boundingBox.height * bp.cgPath.boundingBox.height
var b2 = bp.cgPath.boundingBox.width * bp.cgPath.boundingBox.width
return Double(sqrt(a2 + b2))
}
func hypotenuse(startP: CGPoint, endP: CGPoint) -> Double{
var bezierPath = UIBezierPath()
bezierPath.move(to: startP)
bezierPath.addLine(to: endP)
return hypotenuse(bp: bezierPath)
}
func shortenedEnd(startPoint: CGPoint, endPoint: CGPoint) -> CGPoint{

var endTemp = endPoint
//while hypotenuse(startP: startPoint, endP: endTemp) > 150{
endTemp = CGPoint(x: endTemp.x / 1.01, y: endTemp.y / 1.01)
//}
return endTemp
}
func addTestPoint(loc: CGPoint, color: UIColor){
var temp = SKShapeNode(circleOfRadius: 45)
temp.fillColor = color
temp.position = loc
self.addChild(temp)

}
}

我尝试打印场景的帧大小,它说 400 x 700(我正在 iPhone 6 Plus 上测试),它说 UIScreen 大小相同,所以我不知道是什么问题。总的来说,我只需要瞄准线在圆心上,而不是第一次尝试这个 Action 时。谢谢。

最佳答案

就像我在评论中提到的,您的问题是您如何布置路径。下面的代码使路径相对于球而不是绝对的场景。我还解决了每次创建新形状的问题。

import SpriteKit
import GameplayKit

class GameScene: SKScene {

var ball = SKShapeNode(circleOfRadius: 35)
var touchingBall = false
var aimLine = SKShapeNode()

var endAimPoint = CGPoint()


override func didMove(to view: SKView) {

ball.fillColor = SKColor.orange
ball.name = "ball"

let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
ball.position = CGPoint(x: frame.midX, y: frame.midY)

let physicsBody = SKPhysicsBody(circleOfRadius: 35)
physicsBody.affectedByGravity = false
physicsBody.friction = 10.0
physicsBody.linearDamping = 0.94
ball.physicsBody = physicsBody

self.addChild(ball)
}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("TOUCHES BEGAN.")
for touch in touches {
print("TB: \(touchingBall)")
let location = touch.location(in: self)
let node : SKNode = self.atPoint(location)
if node.name == "ball" {
// touched inside node
if ball.physicsBody!.angularVelocity <= 0.0{
touchingBall = true
aimLine.path = nil
self.addChild(aimLine)

print(touchingBall)
}
}
}

}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
print("TOCUHES MOVED.")
for touch in touches {
let location = touch.location(in: self)
if touchingBall{
endAimPoint = self.convert(location, to: ball)
assignAimLine(end: endAimPoint)
print("Moving touched ball")

}
}

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
print("Touches ended. \(touchingBall)")
if touchingBall == true{
ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x) * 3, dy: -(endAimPoint.y) * 3))
}

touchingBall = false

aimLine.removeFromParent()
print(touchingBall)

}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {

print("Touches cancelled. \(touchingBall)")
if touchingBall == true{

ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x) * 3, dy: -(endAimPoint.y) * 3))

}

touchingBall = false
aimLine.removeFromParent()
print(touchingBall)

}


override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered

print(ball.physicsBody!.velocity)
//let dx2 = ball.physicsBody!.velocity.dx * damping
//let dy2 = ball.physicsBody!.velocity.dy * damping
//ball.physicsBody!.velocity = CGVector(dx: dx2, dy: dy2)


}
func assignAimLine(end: CGPoint){


let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint.zero)
bezierPath.addLine(to: end)

let pattern : [CGFloat] = [10.0, 10.0]


aimLine.position = ball.position
aimLine.path = bezierPath.cgPath.copy(dashingWithPhase: 2, lengths: pattern)
aimLine.zPosition = 0



}

func addTestPoint(loc: CGPoint, color: UIColor){
var temp = SKShapeNode(circleOfRadius: 45)
temp.fillColor = color
temp.position = loc
self.addChild(temp)

}
}

关于swift - 对象位置不匹配(Spritekit),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51613696/

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