我有點麻煩建模移動我的球員節點的方式 我想要的正確方法。模擬零重力風格的球員運動
這是我首次涉足Spritekit和我有基礎和運行(我有一個靜態的背景,加入播放器節點,並與邊界檢查可玩的邊界矩形)
我已經加入我的球員的方式運動是跟蹤開始的觸摸位置,並將其存儲在場景類scoped變量(稱爲beginningTouchPosition)中,並存儲當前的觸摸位置(稱爲currentTouchPosition)。 我還跟蹤玩家精靈節點位置(currentPlayerPosition)
我要做的就是onTouchesBegan我更新「beginningTouchPosition」,然後內onTouchesMoved我更新「currentTouchPosition」,這樣我可以知道用戶想要他的船移動的方向通過在他/她移動手指時獲得相對於'beginningTouchPosition'的方向。 「currentTouchPosition」距'beginningTouchPosition'的距離決定了船舶移動的速度。
我通過使用上述點創建CGVector並使用SKAction.MoveBy調用來移動更新中的播放器。
我這樣做是因爲我希望用戶能夠觸摸屏幕上的任何位置來控制移動。
我想讓玩家移動。我寧願讓船在特定的方向上以設定的加速度施加一定的設定速度。因此,當手指移動時,玩家將在1/2秒的空間內從零加速到1,並沿該方向繼續,直到手指再次移動或擡起。
如果手指擡起,則船舶應該繼續沿最後方向移動,但開始減速直到速度回到零。
我基本上是試圖模擬一個物體如何在零重力下移動,具有明顯的減速非現實功能。
我發現了一些教程,展示瞭如何將對象移動到手指觸摸,但是這並不是我想要的,因爲我正在嘗試製作一款側滾動空間射擊遊戲,玩家可以在可玩的任何地方區域,而不是簡單地上下。類似於舊的復古遊戲「復仇女神」,見下圖:
我們已經附上我的播放器類的代碼和場景代碼的更好的可視化如何我目前做這一切。
任何指針文學如何在特定的方向加速申請速度會有所幫助:)
場景文件 - Level_1.swift
import SpriteKit
// Global
/*
Level_1 set up and control
*/
class Level_1: SKScene {
// Instance variables
var lastUpdateTime:NSTimeInterval = 0
var dt:NSTimeInterval = 0
var player = Player() // Sub classed SKSpriteNode for all player related stuff
var currentTouchPosition: CGPoint!
var beginningTouchPosition:CGPoint!
var currentPlayerPosition: CGPoint!
let playableRectArea:CGRect
override init(size: CGSize) {
// Constant - Max aspect ratio supported
let maxAspectRatio:CGFloat = 16.0/9.0
// Calculate playable height
let playableHeight = size.width/maxAspectRatio
// Determine margin on top and bottom by subtracting playable height
// from scene height and then divide by 2
let playableMargin = (size.height-playableHeight)/2.0
// Calculate the actual playable area rectangle
playableRectArea = CGRect(x: 0, y: playableMargin,
width: size.width,
height: playableHeight)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToView(view: SKView) {
/* Setup your scene here */
currentTouchPosition = CGPointZero
beginningTouchPosition = CGPointZero
let background = SKSpriteNode(imageNamed: "background1")
background.position = CGPoint(x: size.width/2, y: size.height/2)
background.zPosition = -1
self.addChild(background)
currentPlayerPosition = CGPoint(x: 100, y: size.height/2)
player.position = currentPlayerPosition
self.addChild(player)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
currentTouchPosition = touch.locationInNode(self)
}
let dxVectorValue = (-1) * (beginningTouchPosition.x - currentTouchPosition.x)
let dyVectorValue = (-1) * (beginningTouchPosition.y - currentTouchPosition.y)
player.movePlayerBy(dxVectorValue, dyVectorValue: dyVectorValue, duration: dt)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
player.removeAllActions()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch: AnyObject in touches {
beginningTouchPosition = touch.locationInNode(self)
currentTouchPosition = beginningTouchPosition
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
currentPlayerPosition = player.position
if lastUpdateTime > 0 {
dt = currentTime - lastUpdateTime
}else{
dt = 0
}
lastUpdateTime = currentTime
player.boundsCheckPlayer(playableRectArea)
}
}
球員節點 - Player.swift
import Foundation
import SpriteKit
struct PhysicsCategory {
static let None : UInt32 = 0
static let All : UInt32 = UInt32.max
static let Player : UInt32 = 0b1 // 1
static let Enemy : UInt32 = 0b10 // 2
}
class Player: SKSpriteNode{
init(){
// Initialize the player object
let texture = SKTexture(imageNamed: "ship1")
super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
self.xScale = 2
self.yScale = 2
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.zPosition = 1
// Player physics
self.physicsBody?.allowsRotation = false
self.physicsBody?.dynamic = false
self.physicsBody?.categoryBitMask = PhysicsCategory.Player
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// Check if the player sprite is within the playable area bounds
func boundsCheckPlayer(playableArea: CGRect){
let bottomLeft = CGPoint(x: 0, y: CGRectGetMinY(playableArea))
let topRight = CGPoint(x: playableArea.size.width, y: CGRectGetMaxY(playableArea))
if(self.position.x <= bottomLeft.x){
self.position.x = bottomLeft.x
// velocity.x = -velocity.x
}
if(self.position.x >= topRight.x){
self.position.x = topRight.x
// velocity.x = -velocity.x
}
if(self.position.y <= bottomLeft.y){
self.position.y = bottomLeft.y
// velocity.y = -velocity.y
}
if(self.position.y >= topRight.y){
self.position.y = topRight.y
// velocity.y = -velocity.y
}
}
/*
Move the player in a certain direction by a specific amount
*/
func movePlayerBy(dxVectorValue: CGFloat, dyVectorValue: CGFloat, duration: NSTimeInterval)->(){
let moveActionVector = CGVectorMake(dxVectorValue, dyVectorValue)
let movePlayerAction = SKAction.moveBy(moveActionVector, duration: 1/duration)
self.runAction(movePlayerAction)
}
}
科瑞嗨。完全沒有期待你的深入如何,我很欣賞這個immensly,因爲它確實解釋了我很多,並嘗試第一次嘗試。我還沒有實現速度部分,但今天晚些時候將會完成。非常感謝,非常感謝。 –