如何抛出SKSpriteNode?
how to throw SKSpriteNode?
所以基本上在我的游戏中我需要投掷或投掷一个物体。到目前为止我有一个精灵,它可以被拖动但不能被抛出。游戏的想法是抛出一个精灵与另一个精灵碰撞。我想要我们将称为 testNode 的精灵,以移动用户将其扔到的位置
意思是,当我释放精灵时,我希望它继续沿着我移动它的方向前进。我花了很长时间试图解决这个问题,但我做不到。我正在为 iOS 8+ 使用 SpriteKit。如果有人可以帮忙,请帮忙。
我看过一个视频,但它是关于 GameSalad 的,这是另一个故事。你可以看看
(如果您可能需要进一步联系,请回复)
import Foundation;
import SpriteKit;
class Level:SKScene {
TestNode:Test? //Test is a class I made
//Removed the update and touches began due to it being irrelevant to what I need help with.
override func didMoveToView(view: SKView){
testNode = Fruit(imageNamed: "apple_idle")
testNode?.position = CGPointMake(60, 294)
testNode?.xScale = 0.5
testNode?.yScale = 0.5
self.addChild(testNode!)
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
var nodeTouched = SKNode()
var currentNodeTouched = SKNode()
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
nodeTouched = self.nodeAtPoint(location)
testNode?.position = location
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
var touch: UITouch = touches.anyObject() as UITouch
var location: CGPoint = touch.locationInNode(self) as CGPoint
}
如果您要拖动精灵,那么这应该不会太难。听起来您需要在游戏中添加一些物理特性。
设置 yScale 后将其添加到 testNode
testNode.physicsBody = SKPhysicsBody(rectangleOfSize: testNode.size)
现在 运行 游戏。您应该看到 testNode 落到屏幕底部。你不希望这种情况发生,所以我们将把屏幕的边框作为一个物理体。
将此添加到 didMoveToView
的顶部
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
这将使屏幕的边缘包含您的测试节点。你现在应该可以拿起它并放下它
您可能需要稍微调整一下这个公式才能真正使精灵四处走动。
您可能需要比较上次触摸位置与当前触摸位置,获取它们之间的角度并对精灵应用脉冲。
这是我写的一个快速示例,通过在 game-loop 中模拟其速度而不是直接设置位置来移动带有触摸的精灵。这使得精灵更加动态(即你可以 "throw" 它,并让它在你拖动精灵时与其他物理物体相互作用)。不需要角度计算,我只是计算在一段时间内将精灵移动到触摸位置所需的速度。在这种情况下,我将时间设置为 1/60,以便立即应用运动,因此对象看起来非常灵敏。
import SpriteKit
class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
override func didMoveToView(view: SKView) {
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 50))
sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
self.addChild(sprite)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
if sprite.frame.contains(location) {
touchPoint = location
touching = true
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
touchPoint = location
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touching = false
}
override func update(currentTime: CFTimeInterval) {
if touching {
let dt:CGFloat = 1.0/60.0
let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
sprite.physicsBody!.velocity=velocity
}
}
}
您可以 fine-tune 自己进行物理计算以获得您想要的效果。但这段代码应该足以让您入门。我能想到的一些增强功能可能会限制速度,因此对象在释放时不会移动得太快。向 touch-drag 添加延迟,以便移动精灵但随后不小心在末尾短暂停止会继续抛出对象。
这里是Swift3.0/4.0版本的答案
class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
override func didMove(to view: SKView) {
let physicsFrame = CGRect(x: 0, y: 50, width: self.frame.size.width, height: self.frame.size.height - 100)
self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: physicsFrame)
sprite = SKSpriteNode(color: UIColor.red, size: CGSize(width: 50, height: 50))
sprite.physicsBody = SKPhysicsBody.init(rectangleOf: sprite.size)
sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
self.addChild(sprite)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let location = touch.location(in:self)
if sprite.frame.contains(location) {
touchPoint = location
touching = true
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let location = touch.location(in: self)
touchPoint = location
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touching = false
}
override func update(_ currentTime: TimeInterval) {
if touching {
let dt:CGFloat = 1.0/60.0
let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
sprite.physicsBody!.velocity=velocity
}
}}
所以基本上在我的游戏中我需要投掷或投掷一个物体。到目前为止我有一个精灵,它可以被拖动但不能被抛出。游戏的想法是抛出一个精灵与另一个精灵碰撞。我想要我们将称为 testNode 的精灵,以移动用户将其扔到的位置
意思是,当我释放精灵时,我希望它继续沿着我移动它的方向前进。我花了很长时间试图解决这个问题,但我做不到。我正在为 iOS 8+ 使用 SpriteKit。如果有人可以帮忙,请帮忙。
我看过一个视频,但它是关于 GameSalad 的,这是另一个故事。你可以看看
(如果您可能需要进一步联系,请回复)
import Foundation;
import SpriteKit;
class Level:SKScene {
TestNode:Test? //Test is a class I made
//Removed the update and touches began due to it being irrelevant to what I need help with.
override func didMoveToView(view: SKView){
testNode = Fruit(imageNamed: "apple_idle")
testNode?.position = CGPointMake(60, 294)
testNode?.xScale = 0.5
testNode?.yScale = 0.5
self.addChild(testNode!)
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
var nodeTouched = SKNode()
var currentNodeTouched = SKNode()
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
nodeTouched = self.nodeAtPoint(location)
testNode?.position = location
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
var touch: UITouch = touches.anyObject() as UITouch
var location: CGPoint = touch.locationInNode(self) as CGPoint
}
如果您要拖动精灵,那么这应该不会太难。听起来您需要在游戏中添加一些物理特性。
设置 yScale 后将其添加到 testNode
testNode.physicsBody = SKPhysicsBody(rectangleOfSize: testNode.size)
现在 运行 游戏。您应该看到 testNode 落到屏幕底部。你不希望这种情况发生,所以我们将把屏幕的边框作为一个物理体。
将此添加到 didMoveToView
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
这将使屏幕的边缘包含您的测试节点。你现在应该可以拿起它并放下它
您可能需要稍微调整一下这个公式才能真正使精灵四处走动。
您可能需要比较上次触摸位置与当前触摸位置,获取它们之间的角度并对精灵应用脉冲。
这是我写的一个快速示例,通过在 game-loop 中模拟其速度而不是直接设置位置来移动带有触摸的精灵。这使得精灵更加动态(即你可以 "throw" 它,并让它在你拖动精灵时与其他物理物体相互作用)。不需要角度计算,我只是计算在一段时间内将精灵移动到触摸位置所需的速度。在这种情况下,我将时间设置为 1/60,以便立即应用运动,因此对象看起来非常灵敏。
import SpriteKit
class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
override func didMoveToView(view: SKView) {
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 50))
sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
self.addChild(sprite)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
if sprite.frame.contains(location) {
touchPoint = location
touching = true
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
touchPoint = location
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touching = false
}
override func update(currentTime: CFTimeInterval) {
if touching {
let dt:CGFloat = 1.0/60.0
let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
sprite.physicsBody!.velocity=velocity
}
}
}
您可以 fine-tune 自己进行物理计算以获得您想要的效果。但这段代码应该足以让您入门。我能想到的一些增强功能可能会限制速度,因此对象在释放时不会移动得太快。向 touch-drag 添加延迟,以便移动精灵但随后不小心在末尾短暂停止会继续抛出对象。
这里是Swift3.0/4.0版本的答案
class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
override func didMove(to view: SKView) {
let physicsFrame = CGRect(x: 0, y: 50, width: self.frame.size.width, height: self.frame.size.height - 100)
self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: physicsFrame)
sprite = SKSpriteNode(color: UIColor.red, size: CGSize(width: 50, height: 50))
sprite.physicsBody = SKPhysicsBody.init(rectangleOf: sprite.size)
sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
self.addChild(sprite)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let location = touch.location(in:self)
if sprite.frame.contains(location) {
touchPoint = location
touching = true
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let location = touch.location(in: self)
touchPoint = location
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touching = false
}
override func update(_ currentTime: TimeInterval) {
if touching {
let dt:CGFloat = 1.0/60.0
let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
sprite.physicsBody!.velocity=velocity
}
}}