使用 SKY SpriteKit 和 Swift 4 移动和旋转精灵
Posted
技术标签:
【中文标题】使用 SKY SpriteKit 和 Swift 4 移动和旋转精灵【英文标题】:Moving and rotating sprite with touches using SKSpriteKit and Swift 4 【发布时间】:2019-03-24 01:31:42 【问题描述】:我希望我的精灵“字符”在我移动时移动和旋转“跟随”我的手指。我让它工作正常,但不知何故设法搞砸了。我不确定我做了什么,但我一生都无法弄清楚。
任何帮助将不胜感激。我确定它是愚蠢的,我只是忽略了。提前致谢。
标记
GameScene.swift
import SpriteKit
import GameplayKit
//MARK: ---------------Global Variables Section
var nodeType: String = String()
var characterNode = Character()
let characterImage: String = String("default_pose")
var characterTexture:SKTexture = SKTexture()
let characterSize: CGSize = CGSize(width: 64, height: 64)
let characterPosition: CGPoint = CGPoint(x: 0, y: 0)
var enemyNode = Enemy()
let enemyImage: String = String("blob1")
var enemyTexture = SKTexture()
let enemySize: CGSize = CGSize(width: 50, height: 50)
let enemyPosition: CGPoint = CGPoint(x: 150, y: 150)
class GameScene: SKScene, SKPhysicsContactDelegate
//MARK: --------------------Class Variables Section
var affectedByGravity: Bool = false
var dynamic: Bool = true
var rotation: Bool = false
var lastUpdateTime: CFTimeInterval = 0
//MARK: --------------------DidMove to View Section
override func didMove(to view: SKView)
var node = SKSpriteNode()
node = addNode(NodeType: "Character")
applyPhysics(physicsNode: node, nodeImage: characterImage, nodeSize: characterSize, nodeName: node.name!)
node.zPosition = 10
addChild(node)
node = addNode(NodeType: "Enemy")
applyPhysics(physicsNode: node, nodeImage: enemyImage, nodeSize: enemySize, nodeName: node.name!)
node.zPosition = 9
addChild(node)
//MARK: -----------------------Add Node Section
func addNode(NodeType: String) -> SKSpriteNode
var node = SKSpriteNode()
switch NodeType
case "Enemy":
node = enemyNode.setupNode(nodeName: "Enemy", nodeImage: "blob1", nodeSize: enemySize, nodePosition: enemyPosition)
default:
node = characterNode.setupNode(nodeName: "Player", nodeImage: "default_pose", nodeSize: characterSize, nodePosition: characterPosition)
return node
//MARK: ------------------------Physics Section
func applyPhysics(physicsNode: SKSpriteNode, nodeImage: String, nodeSize: CGSize, nodeName: String)
let nodeTexture: SKTexture = SKTexture(imageNamed: nodeImage)
physicsNode.physicsBody = SKPhysicsBody(texture: nodeTexture, size: nodeSize)
physicsNode.physicsBody?.isDynamic = dynamic
physicsNode.physicsBody?.affectedByGravity = affectedByGravity
physicsNode.physicsBody?.allowsRotation = rotation
physicsNode.physicsBody?.categoryBitMask = 1
physicsNode.physicsBody?.contactTestBitMask = 1
physicsNode.physicsBody?.collisionBitMask = 1
//MARK: ------------------------Movement and Rotation Section
func moveAndRotate(sprite: Character, toPosition position: CGPoint)
let angle = atan2(position.y - sprite.position.y, position.x - sprite.position.x)
let rotateAction = SKAction.rotate(toAngle: angle - .pi / 2, duration: 0.05, shortestUnitArc:true)
sprite.run(rotateAction)
let offsetX = position.x - (sprite.position.x)
let offsetY = position.y - (sprite.position.y)
let normal = simd_normalize(simd_double2(x: Double(offsetX), y:Double(offsetY)))
characterNode.velocity = CGVector(dx: CGFloat(normal.x) * sprite.movePointsPerSecond, dy: CGFloat(normal.y) * sprite.movePointsPerSecond)
//MARK: ----------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
if let touch = touches.first
let touchLocation = touch.location(in: self)
characterNode.isMoving = true
moveAndRotate(sprite: characterNode, toPosition: touchLocation)
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
if let touch = touches.first
let touchLocation = touch.location(in: self)
moveAndRotate(sprite: characterNode, toPosition: touchLocation)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
characterNode.isMoving = false
//MARK: ------------------Update Section
override func update(_ currentTime: TimeInterval)
let deltaTime = max(1.0/30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(character: characterNode, dt: deltaTime)
func update(character: Character, dt: CFTimeInterval)
if characterNode.isMoving == true
let newX = character.position.x + character.velocity.dx * CGFloat(dt)
let newY = character.position.y + character.velocity.dy * CGFloat(dt)
character.position = CGPoint(x: newX, y: newY)
Character.swift
import SpriteKit
import GameplayKit
class Character: SKSpriteNode
let movePointsPerSecond: CGFloat = 150.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var isMoving = false
var node: SKSpriteNode = SKSpriteNode()
func setupNode(nodeName: String, nodeImage: String, nodeSize: CGSize, nodePosition: CGPoint) -> SKSpriteNode
node = SKSpriteNode(imageNamed: nodeImage)
node.name = nodeName
node.position = nodePosition
return node
【问题讨论】:
忘了说它目前在做什么,什么都没有。 :)。他只是站在那里看起来很愚蠢。 我建议“编辑”来编辑您的问题,而不是发表评论说它什么都不做 您在一个动作中执行它,并且在每一个动作中您都附加一个新动作。这将是危险的,因为每次轮换行动都会相互叠加,这意味着您将浪费循环 【参考方案1】:您的节点不会移动,因为您从未将 characterNode 分配给屏幕上的节点
override func didMove(to view: SKView)
var node = SKSpriteNode()
node = addNode(NodeType: "Character")
applyPhysics(physicsNode: node, nodeImage: characterImage, nodeSize: characterSize, nodeName: node.name!)
node.zPosition = 10
addChild(node)
characterNode = node //ADD THIS LINE
node = addNode(NodeType: "Enemy")
applyPhysics(physicsNode: node, nodeImage: enemyImage, nodeSize: enemySize, nodeName: node.name!)
node.zPosition = 9
addChild(node)
【讨论】:
以上是关于使用 SKY SpriteKit 和 Swift 4 移动和旋转精灵的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 和 SpriteKit 中使用 UISwipeGestureRecognizer 而不是 touchesMoved?
将 AcceptMouseMovedEvents 用于带有 Storyboard 和 Swift 的 SpriteKit 鼠标操作
Swift、SpriteKit 和带有 CGPoint 的多维数组