问题
apple documentation gives a physics bodies velocity as in meters per second.
If this is true is there a relationship between pixels and meters? and if there is, what is it?
or is this an error in the documentation and its really pixels per second?
回答1:
I wrote a small program to try to work this out and got an answer of 135 points to the metre.
https://stackoverflow.com/a/37523818/1430420
Edit: Here is the program for anyone to check to see if my maths is off
//
// GameScene.swift
// gravityTest
//
// Created by Steve Ives on 30/05/2016.
// Copyright (c) 2016 Steve Ives. All rights reserved.
//
import SpriteKit
class GameScene: SKScene {
// var elapsedTime: CFTimeInterval = 0.0
var timeOfLastUpdate: CFTimeInterval = 0.0
var updateCount = 0
let sprite = SKSpriteNode(imageNamed:"Spaceship")
override func didMove(to view: SKView) {
/* Setup your scene here */
// physicsWorld.gravity = CGVectorMake(-9.8, 0)
let location = CGPoint(x: (scene?.frame.midX)!, y: (scene?.frame.midY)!)
sprite.xScale = 0.5
sprite.yScale = 0.5
sprite.physicsBody = SKPhysicsBody(rectangleOf: sprite.size)
sprite.physicsBody?.isDynamic = true
sprite.position = location
self.addChild(sprite)
}
override func update(_ currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
updateCount += 1
if (currentTime - timeOfLastUpdate) < 1 {return}
// if (timeOfLastUpdate - currentTime > 1.0) {
print("\(updateCount) - Time : \(currentTime) \(currentTime-timeOfLastUpdate) Location is : \(sprite.position) Velocity is : \(sprite.physicsBody!.velocity)")
// }
timeOfLastUpdate = currentTime
}
}
回答2:
I used playground to calculate my distance. I am getting around 150
We know distance is d = (gt^2)/2 where g is gravity and t is time.
d = (9.8m/t^2)(t^2)/2 d = (9.8m)/2 d = 4.9m
In 1 second, we would travel 4.9m
In our case, we travelled 765.9298706054688 points.
765.9298706054688/4.9 gets us around 156.312218491.
Ideally, we would have travelled 735 points, not sure what in my code could cause a 30 point difference, I suspect it has to do with SKAction
//: A SpriteKit based Playground
import PlaygroundSupport
import SpriteKit
class GameScene: SKScene {
private var testNode = SKSpriteNode(color: .red, size: CGSize(width: 20, height: 20))
private var flag = false
private var time : CGFloat = 0
private var beginTest = false
override func didMove(to view: SKView) {
}
@objc static override var supportsSecureCoding: Bool {
// SKNode conforms to NSSecureCoding, so any subclass going
// through the decoding process must support secure coding
get {
return true
}
}
func touchDown(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
testNode = SKSpriteNode(color: .red, size: CGSize(width: 20, height: 20))
let physicsBody = SKPhysicsBody(rectangleOf: testNode.size)
physicsBody.angularDamping = 0
physicsBody.linearDamping = 0
physicsBody.friction = 0
testNode.physicsBody = physicsBody
let action = SKAction.customAction(withDuration: 2)
{
node,elapsedTime in
if elapsedTime >= 1 && !self.flag && self.time == 0{
self.flag = true
self.time = elapsedTime
}
}
testNode.run(action)
beginTest = true
}
override func update(_ currentTime: TimeInterval) {
if beginTest{
beginTest = false
addChild(testNode)
}
}
override func didFinishUpdate() {
}
override func didApplyConstraints() {
if flag{
let position = CGPoint(x:testNode.position.x,y:-testNode.position.y)
print("Node traveled \(position.y) points over \(time) seconds with a velocity of \(testNode.physicsBody!.velocity)")
let pointsPerMeter = -testNode.physicsBody!.velocity.dy/9.8
print("Node traveled \(pointsPerMeter) points per meter over \(time) seconds with a velocity of \(testNode.physicsBody!.velocity)")
flag = false
testNode.removeFromParent()
time = 0
}
}
}
// Load the SKScene from 'GameScene.sks'
let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
if let scene = GameScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
sceneView.presentScene(scene)
}
PlaygroundSupport.PlaygroundPage.current.liveView = sceneView
Node traveled 765.9298706054688 points over 1.0 seconds with a velocity of (0.0, -1494.4998779296875)
Node traveled 152.49998754384566 points per meter over 1.0 seconds with a velocity of (0.0, -1494.4998779296875)
回答3:
An answer to anyone and myself
There is nothing to really define a pixel within apples SKSpriteKit, this is a misnomer in my question. A point on the other hand is well defined.
Everybody probably already knows this but if you attach a SKPhysicsBody to a Node and assign the following properties:
seg.physicsBody?.isDynamic = true
seg.physicsBody?.affectedByGravity = false
seg.physicsBody?.allowsRotation = false
seg.physicsBody?.usesPreciseCollisionDetection = true
seg.physicsBody?.mass = 0
seg.physicsBody?.restitution = 1
seg.physicsBody?.linearDamping = 0
Then applying a velocity dy component of 200 results in the object moving at 200 points per second. This says to me that with all external forces remove Sprite kits physics world translates to 1m/s = 1point/s.
来源:https://stackoverflow.com/questions/57824964/velocity-meters-per-second-or-pixels-per-second