我正试图让我的游戏中的玩家精灵根据自己的行为进行动画处理,例如,走路,进攻,休息。
我有以下文件AgentNode和GameScene。
精灵会随我所愿地生成和移动,只是将精灵添加到场景中时就已经执行了初始动作。
例如,如果我添加带有“ restingFrames”动画的精灵,则它会正确生成,但是当移动该精灵时,该动画仍会根据需要使用“ restingFrames”而不是“ walkingFrames”。无法弄清楚,请帮忙。
AgentNode.swift
import SpriteKit
import GameplayKit
class AgentNode: SKNode, GKAgentDelegate {
var agent = GKAgent2D()
var triangleShape = SKShapeNode()
var player = SKSpriteNode()
var walkingFrames: [SKTexture] = []
var restingFrames: [SKTexture] = []
var attackingFrames: [SKTexture] = []
var firstFrameTexture: SKTexture = SKTexture()
var playerSpawned = false
override init() {
super.init()
}
init(scene:SKScene, radius: Float, position: CGPoint) {
super.init()
self.position = position
self.zPosition = 10
scene.addChild(self)
agent.radius = radius
agent.position = simd_float2(Float(position.x), Float(position.y))
agent.delegate = self
agent.maxSpeed = 100 * 2
agent.maxAcceleration = 500 * 4
}
func setupPlayer() {
setupRestingPlayerAnimation()
setupWalkingPlayerAnimation()
setupAttackingPlayerAnimation()
}
func setupWalkingPlayerAnimation() {
let walkingPlayerAtlas = SKTextureAtlas(named: "WalkingPlayer")
let numImages = walkingPlayerAtlas.textureNames.count
for i in 1...numImages {
let walkingPlayerTextureName = "walk_front\(i)"
walkingFrames.append(walkingPlayerAtlas.textureNamed(walkingPlayerTextureName))
}
}
func setupRestingPlayerAnimation() {
let restingPlayerAtlas = SKTextureAtlas(named: "RestingPlayer")
let numImages = restingPlayerAtlas.textureNames.count
for i in 1...numImages {
let restingPlayerTextureName = "still_frame\(i)"
restingFrames.append(restingPlayerAtlas.textureNamed(restingPlayerTextureName))
}
}
func setupAttackingPlayerAnimation() {
let attackingPlayerAtlas = SKTextureAtlas(named: "AttackingPlayer")
let numImages = attackingPlayerAtlas.textureNames.count
for i in 1...numImages {
let attackingPlayerTextureName = "attack_frame\(i)"
attackingFrames.append(attackingPlayerAtlas.textureNamed(attackingPlayerTextureName))
}
}
func animatePlayer() {
var restingSequence = SKAction()
var walkingSequence = SKAction()
var attackingSequence = SKAction()
let restingAnimation = SKAction.animate(with: restingFrames, timePerFrame: 0.15)
let walkingAnimation = SKAction.animate(with: walkingFrames, timePerFrame: 0.1)
let attackingAnimation = SKAction.animate(with: attackingFrames, timePerFrame: 0.1)
restingSequence = SKAction.sequence([restingSequence])
walkingSequence = SKAction.sequence([walkingSequence])
attackingSequence = SKAction.sequence([attackingSequence])
if isSeeking && !isAttacking{
firstFrameTexture = walkingFrames[0]
player.run(SKAction.repeatForever(walkingAnimation), withKey: "walkingAction")
print("walking")
} else if isAttacking && !isSeeking {
firstFrameTexture = attackingFrames[0]
player.run(SKAction.repeatForever(attackingAnimation), withKey: "attackingAction")
print("attacking")
} else {
firstFrameTexture = restingFrames[0]
player.run(SKAction.repeatForever(restingAnimation), withKey: "restingAction")
print("resting")
}
}
func addPlayerToScene() {
player = SKSpriteNode(texture: firstFrameTexture)
player.position = CGPoint(x: (frame.midX), y: (frame.midY))
player.setScale(1.5)
player.zRotation = CGFloat(Double.pi / 2.0)
player.zPosition = 10
self.addChild(player)
playerSpawned = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func agentWillUpdate(_ agent: GKAgent) {
}
func agentDidUpdate(_ agent: GKAgent) {
if playerSpawned == false {
print("player has not spawned")
setupPlayer()
animatePlayer()
addPlayerToScene()
playerSpawned = true
} else {
print("player has spawned")
animatePlayer()
}
print("player isSeeking \(isSeeking)")
print("player isAttacking \(isAttacking)")
guard let agent2D = agent as? GKAgent2D else {
return
}
self.position = CGPoint(x: CGFloat(agent2D.position.x), y: CGFloat(agent2D.position.y))
self.zRotation = CGFloat(agent2D.rotation)
}
}
GameScene.swift
import SpriteKit
import GameplayKit
var isSeeking: Bool = false
var isAttacking: Bool = false
class GameScene: SKScene {
let trackingAgent = GKAgent2D()
var player = AgentNode()
var seekGoal : GKGoal = GKGoal()
let stopGoal = GKGoal(toReachTargetSpeed: 0.0)
var seeking : Bool = false {
willSet {
if newValue {
self.player.agent.behavior?.setWeight(5, for: seekGoal)
self.player.agent.behavior?.setWeight(0, for: stopGoal)
} else {
self.player.agent.behavior?.setWeight(0, for: seekGoal)
self.player.agent.behavior?.setWeight(5, for: stopGoal)
}
}
}
var agentSystem = GKComponentSystem()
var lastUpdateTime: TimeInterval = 0
override func didMove(to view: SKView) {
super.didMove(to: view)
self.trackingAgent.position = simd_float2(Float(self.frame.midX), Float(self.frame.midY))
self.agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)
self.player = AgentNode(scene: self, radius: Float(20.0), position: CGPoint(x: self.frame.midX, y: self.frame.midY))
self.player.agent.behavior = GKBehavior()
self.agentSystem.addComponent(self.player.agent)
self.seekGoal = GKGoal(toSeekAgent: self.trackingAgent)
}
override func update(_ currentTime: CFTimeInterval) {
isSeeking = self.seeking
if lastUpdateTime == 0 {
lastUpdateTime = currentTime
}
let delta = currentTime - lastUpdateTime
lastUpdateTime = currentTime
self.agentSystem.update(deltaTime: delta)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = true
handleTouch(touches: touches)
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
self.seeking = false
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = false
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouch(touches: touches)
}
func handleTouch(touches:Set<UITouch>) {
guard let touch = touches.first
else {
return
}
let location = touch.location(in: self)
self.trackingAgent.position = simd_float2(Float(location.x), Float(location.y))
}
}
答案 0 :(得分:1)
好吧,我知道了。我更新了代码,如下所示,一切正常。
AgentNode.swift
import SpriteKit
import GameplayKit
class AgentNode: SKNode, GKAgentDelegate {
var agent = GKAgent2D()
var triangleShape = SKShapeNode()
var player = SKSpriteNode()
var walkingFrames: [SKTexture] = []
var restingFrames: [SKTexture] = []
var attackingFrames: [SKTexture] = []
var playerSpawned = false
override init() {
super.init()
}
init(scene:SKScene, radius: Float, position: CGPoint) {
super.init()
self.position = position
self.zPosition = 10
scene.addChild(self)
agent.radius = radius
agent.position = simd_float2(Float(position.x), Float(position.y))
agent.delegate = self
agent.maxSpeed = 100 * 2
agent.maxAcceleration = 500 * 4
}
func setupPlayer() {
setupRestingPlayerAnimation()
setupWalkingPlayerAnimation()
setupAttackingPlayerAnimation()
}
func setupWalkingPlayerAnimation() {
let walkingPlayerAtlas = SKTextureAtlas(named: "WalkingPlayer")
let numImages = walkingPlayerAtlas.textureNames.count
for i in 1...numImages {
let walkingPlayerTextureName = "walk_front\(i)"
walkingFrames.append(walkingPlayerAtlas.textureNamed(walkingPlayerTextureName))
}
}
func setupRestingPlayerAnimation() {
let restingPlayerAtlas = SKTextureAtlas(named: "RestingPlayer")
let numImages = restingPlayerAtlas.textureNames.count
for i in 1...numImages {
let restingPlayerTextureName = "still_frame\(i)"
restingFrames.append(restingPlayerAtlas.textureNamed(restingPlayerTextureName))
}
}
func setupAttackingPlayerAnimation() {
let attackingPlayerAtlas = SKTextureAtlas(named: "AttackingPlayer")
let numImages = attackingPlayerAtlas.textureNames.count
for i in 1...numImages {
let attackingPlayerTextureName = "attack_frame\(i)"
attackingFrames.append(attackingPlayerAtlas.textureNamed(attackingPlayerTextureName))
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func agentWillUpdate(_ agent: GKAgent) {
}
func agentDidUpdate(_ agent: GKAgent) {
guard let agent2D = agent as? GKAgent2D else {
return
}
self.position = CGPoint(x: CGFloat(agent2D.position.x), y: CGFloat(agent2D.position.y))
self.zRotation = CGFloat(agent2D.rotation)
}
}
GameScene.swift
import SpriteKit
import GameplayKit
var isSeeking: Bool = false
var isAttacking: Bool = false
class GameScene: SKScene {
let trackingAgent = GKAgent2D()
var player = AgentNode()
var seekGoal : GKGoal = GKGoal()
let stopGoal = GKGoal(toReachTargetSpeed: 0.0)
var seeking : Bool = false {
willSet {
if newValue {
self.player.agent.behavior?.setWeight(5, for: seekGoal)
self.player.agent.behavior?.setWeight(0, for: stopGoal)
} else {
self.player.agent.behavior?.setWeight(0, for: seekGoal)
self.player.agent.behavior?.setWeight(5, for: stopGoal)
}
}
}
var agentSystem = GKComponentSystem()
var lastUpdateTime: TimeInterval = 0
override func didMove(to view: SKView) {
super.didMove(to: view)
self.trackingAgent.position = simd_float2(Float(self.frame.midX), Float(self.frame.midY))
self.agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)
self.player = AgentNode(scene: self, radius: Float(20.0), position: CGPoint(x: self.frame.midX, y: self.frame.midY))
self.player.agent.behavior = GKBehavior()
self.agentSystem.addComponent(self.player.agent)
self.seekGoal = GKGoal(toSeekAgent: self.trackingAgent)
player.setupPlayer()
//player.animatePlayer()
player.player = SKSpriteNode(imageNamed: "default_pose")
player.player.position = CGPoint(x: (frame.midX), y: (frame.midY))
player.player.setScale(1.5)
player.player.zRotation = CGFloat(Double.pi / 2.0)
player.player.zPosition = 10
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.restingFrames, timePerFrame: 0.2)))
player.addChild(player.player)
}
override func update(_ currentTime: CFTimeInterval) {
isSeeking = self.seeking
if lastUpdateTime == 0 {
lastUpdateTime = currentTime
}
let delta = currentTime - lastUpdateTime
lastUpdateTime = currentTime
self.agentSystem.update(deltaTime: delta)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = true
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.walkingFrames, timePerFrame: 0.1)))
handleTouch(touches: touches)
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
self.seeking = false
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = false
player.player.removeAllActions()
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.attackingFrames, timePerFrame: 0.1)))
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouch(touches: touches)
}
func handleTouch(touches:Set<UITouch>) {
guard let touch = touches.first
else {
return
}
let location = touch.location(in: self)
self.trackingAgent.position = simd_float2(Float(location.x), Float(location.y))
}
}