如何使用 CoreMotion 向左或向右移动精灵?
How to move sprite just left or right using CoreMotion?
对于我正在创建的这款游戏,我希望 Sprite "Character" 通过向左或向右倾斜设备来向左或向右移动。
我查看了它并更改了代码,但它似乎不起作用。
当我 运行 它时,"Character" 只朝一个方向移动,并且仍然向上或向下移动。
我只想 "Character" 只向左或向右移动,而不是向上或向下移动。
有什么帮助吗?
下面是 GameScene.swift 文件:
import SpriteKit
import CoreMotion
class GameScene: SKScene {
let motionManager = CMMotionManager()
var Ground = SKSpriteNode()
var Character = SKSpriteNode()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
Character = SKSpriteNode(imageNamed: "NinjaGhost")
Character.physicsBody = SKPhysicsBody(circleOfRadius: Character.size.height)
Character.size = CGSize(width: 200, height: 200)
Character.physicsBody?.allowsRotation = false
Character.zPosition = 2
Character.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
self.addChild(Character)
Ground = SKSpriteNode(imageNamed: "Dirt Background")
Ground.size = CGSize(width: 1920, height: 1080)
Ground.zPosition = 1
Ground.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
self.addChild(Ground)
motionManager.startAccelerometerUpdates()
motionManager.accelerometerUpdateInterval = 0.1
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue() ) {
(data, error) in
self.physicsWorld.gravity = CGVectorMake(CGFloat((data?.acceleration.x)!) * 1, 0)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
您应该遵循 swift 指南,您的属性不应以大写字母开头,只有 类、结构、枚举和协议应该。它使堆栈溢出时的代码更难阅读(代码标记为蓝色但不应该)并且通常这不是好的做法。
将您的代码更改为此,因为有一些错误。
character = SKSpriteNode(imageNamed: "NinjaGhost")
character.size = CGSize(width: 200, height: 200) // Better to call this before positioning
character.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2) // Give pos before physics body
character.physicsBody = SKPhysicsBody(circleOfRadius: character.size.width / 2) // You have to divide by 2 when using circleOfRadius to get proper size in relation to the sprite
character.physicsBody?.allowsRotation = false
character.physicsBody?.affectedByGravity = false // Stop falling
character.zPosition = 2
self.addChild(character)
在您的运动队列代码中,您正在操纵场景本身,因此这将不起作用。
试试这个代码,它使用物理体来移动精灵。这是我比较喜欢的做法,因为与直接操纵精灵位置 属性 相比,它使精灵移动更自然,尤其是在改变方向时(如果你想直接操纵精灵位置 属性阅读这篇文章。http://www.ioscreator.com/tutorials/move-sprites-accelerometer-spritekit-swift)
if let error = error { // Might as well handle the optional error as well
print(error.localizedDescription)
return
}
guard let data = motionManager.accelerometerData else { return }
if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft {
character.physicsBody?.applyForce(CGVectorMake(-100 * CGFloat(data.acceleration.y), 0))
} else {
character.physicsBody?.applyForce(CGVectorMake(100 * CGFloat(data.acceleration.y), 0))
}
这将使精灵在x轴上移动。我使用 data.acceleration.y 因为在这个例子中游戏是横向的所以你必须使用 Y 数据在 x 轴上移动它。
我也在检查设备的横向方向,以便运动在两个方向上都有效。
根据精灵的大小调整此处的 100 以获得所需的力(力越大)。大精灵需要几千秒才能移动。
对于我正在创建的这款游戏,我希望 Sprite "Character" 通过向左或向右倾斜设备来向左或向右移动。
我查看了它并更改了代码,但它似乎不起作用。
当我 运行 它时,"Character" 只朝一个方向移动,并且仍然向上或向下移动。
我只想 "Character" 只向左或向右移动,而不是向上或向下移动。
有什么帮助吗?
下面是 GameScene.swift 文件:
import SpriteKit
import CoreMotion
class GameScene: SKScene {
let motionManager = CMMotionManager()
var Ground = SKSpriteNode()
var Character = SKSpriteNode()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
Character = SKSpriteNode(imageNamed: "NinjaGhost")
Character.physicsBody = SKPhysicsBody(circleOfRadius: Character.size.height)
Character.size = CGSize(width: 200, height: 200)
Character.physicsBody?.allowsRotation = false
Character.zPosition = 2
Character.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
self.addChild(Character)
Ground = SKSpriteNode(imageNamed: "Dirt Background")
Ground.size = CGSize(width: 1920, height: 1080)
Ground.zPosition = 1
Ground.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
self.addChild(Ground)
motionManager.startAccelerometerUpdates()
motionManager.accelerometerUpdateInterval = 0.1
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue() ) {
(data, error) in
self.physicsWorld.gravity = CGVectorMake(CGFloat((data?.acceleration.x)!) * 1, 0)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
您应该遵循 swift 指南,您的属性不应以大写字母开头,只有 类、结构、枚举和协议应该。它使堆栈溢出时的代码更难阅读(代码标记为蓝色但不应该)并且通常这不是好的做法。
将您的代码更改为此,因为有一些错误。
character = SKSpriteNode(imageNamed: "NinjaGhost")
character.size = CGSize(width: 200, height: 200) // Better to call this before positioning
character.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2) // Give pos before physics body
character.physicsBody = SKPhysicsBody(circleOfRadius: character.size.width / 2) // You have to divide by 2 when using circleOfRadius to get proper size in relation to the sprite
character.physicsBody?.allowsRotation = false
character.physicsBody?.affectedByGravity = false // Stop falling
character.zPosition = 2
self.addChild(character)
在您的运动队列代码中,您正在操纵场景本身,因此这将不起作用。
试试这个代码,它使用物理体来移动精灵。这是我比较喜欢的做法,因为与直接操纵精灵位置 属性 相比,它使精灵移动更自然,尤其是在改变方向时(如果你想直接操纵精灵位置 属性阅读这篇文章。http://www.ioscreator.com/tutorials/move-sprites-accelerometer-spritekit-swift)
if let error = error { // Might as well handle the optional error as well
print(error.localizedDescription)
return
}
guard let data = motionManager.accelerometerData else { return }
if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft {
character.physicsBody?.applyForce(CGVectorMake(-100 * CGFloat(data.acceleration.y), 0))
} else {
character.physicsBody?.applyForce(CGVectorMake(100 * CGFloat(data.acceleration.y), 0))
}
这将使精灵在x轴上移动。我使用 data.acceleration.y 因为在这个例子中游戏是横向的所以你必须使用 Y 数据在 x 轴上移动它。
我也在检查设备的横向方向,以便运动在两个方向上都有效。
根据精灵的大小调整此处的 100 以获得所需的力(力越大)。大精灵需要几千秒才能移动。