用swift 重写 AgentsCatalog

前端之家收集整理的这篇文章主要介绍了用swift 重写 AgentsCatalog前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

AgentsCatalog是Apple的一个例子,他是基于OC的,我认为重写这些例子是个学习语言的好方法。首先,你的目标是正确的,通过观摩源码,你知道如何达到目标,其次你所使用的手段也是正确的,你可以从中学到某个类的用法,几个类的相互关系等等。

前几天我一直纠结一个事情,我打算把工具条合并到窗口的标题栏上去,就像Safari那样,我查了很多资料一直没能解决,但是这个例子无意间解决了这个问题。而且只有一行代码。你建立一个Cocoa应用,就像下面这样。


  1. @NSApplicationMain
  2. class AppDelegate: NSObject,NSApplicationDelegate {
  3.  
  4. @IBOutlet weak var window: NSWindow!
  5.  
  6. @IBOutlet weak var skView: SKView!
  7. @IBOutlet weak var sceneControl: NSSegmentedControl!
  8.  
  9. @IBAction func selectScene(sender: NSSegmentedControl) {
  10. let sceneTYpe = AAPLSceneType(rawValue: sender.selectedSegment)
  11. let scene = AAPLGameScene.sceneWithType( sceneTYpe!,size: CGSizeMake(800,600))
  12. scene.scaleMode = SKSceneScaleMode.AspectFit
  13. self.skView.presentScene(scene)
  14. }
  15. func applicationDidFinishLaunching(aNotification: NSNotification) {
  16. // Insert code here to initialize your application
  17. self.window.titleVisibility = NSWindowTitleVisibility.Hidden
  18. // Configure the view.
  19. self.skView.ignoresSiblingOrder = true
  20. self.skView.showsFPS = true
  21. self.skView.showsNodeCount = true
  22. // Present the scene.
  23. self.selectScene(self.sceneControl )
  24. }
  25.  
  26. func applicationWillTerminate(aNotification: NSNotification) {
  27. // Insert code here to tear down your application
  28. }

你的工具条就合并到window标题栏上去了。其他什么也不用做。接下来你要重写下面这个类:

这是所有后面用到的 Scene 类基类,他本身是SKSence的子类。你会看到 SKComponentSystem(组件系统)和 GKAgent2D(跟踪代理)的用法。这里处理了游戏事件循环和对鼠标的响应。

  1. import Cocoa
  2. import SpriteKit
  3. import GameplayKit
  4.  
  5. enum AAPLSceneType: Int {
  6. case AAPLSceneTypeSeek = 0,AAPLSceneTypeWander,AAPLSceneTypeFlee,AAPLSceneTypeAvoid,AAPLSceneTypeSeparate,AAPLSceneTypeAlign,AAPLSceneTypeFlock,AAPLSceneTypePath,AAPLSceneTypesCount
  7. }
  8.  
  9. let AAPLDefaultAgentRadius: CGFloat = 40.0
  10.  
  11. class AAPLGameScene: SKScene {
  12. var sceneName: String?
  13. required override init(size: CGSize) {
  14. super.init(size: size)
  15. }
  16.  
  17. required init?(coder aDecoder: NSCoder) {
  18. fatalError("init(coder:) has not been implemented")
  19. }
  20. // A component system to manage per-frame updates for all agents.
  21. var agentSystem: GKComponentSystem?
  22. // An agent whose position tracks that of mouseDragged (OS X) or touchesMoved (iOS) events.
  23. // This agent has no display representation,but can be used to make other agents follow the mouse/touch.
  24. var trackingAgent: GKAgent2D?
  25. // YES when the mouse is dragging (OS X) or a touch is moving
  26. var seeking: Bool = false
  27. var stopGoal: GKGoal?
  28. var lastUpdateTime: NSTimeInterval = 0
  29. class func sceneWithType( sceneType: AAPLSceneType,size: CGSize) -> AAPLGameScene {
  30. var sceneClass: AAPLGameScene.Type
  31. switch (sceneType) {
  32. case AAPLSceneType.AAPLSceneTypeSeek:
  33. sceneClass = AAPLSeekScene.self
  34. break;
  35. case AAPLSceneType.AAPLSceneTypeWander:
  36. sceneClass = AAPLWanderScene.self
  37. break;
  38. case AAPLSceneType.AAPLSceneTypeFlee:
  39. sceneClass = AAPLFleeScene.self
  40. break;
  41. case AAPLSceneType.AAPLSceneTypeAvoid:
  42. sceneClass = AAPLAvoidScene.self
  43. break;
  44. case AAPLSceneType.AAPLSceneTypeSeparate:
  45. sceneClass = AAPLSeparateScene.self
  46. break;
  47. case AAPLSceneType.AAPLSceneTypeAlign:
  48. sceneClass = AAPLAlignScene.self
  49. break;
  50. case AAPLSceneType.AAPLSceneTypeFlock:
  51. sceneClass = AAPLFlockScene.self
  52. break;
  53. case AAPLSceneType.AAPLSceneTypePath:
  54. sceneClass = AAPLPathScene.self
  55. break;
  56. default:
  57. sceneClass = AAPLGameScene.self
  58. break;
  59. }
  60. return sceneClass.init(size: CGSizeMake(800,600))
  61. }
  62. override func didMoveToView(view: SKView) {
  63. self.agentSystem = GKComponentSystem( componentClass: GKAgent2D.self )
  64. self.trackingAgent = GKAgent2D()
  65. let x = CGRectGetMidX(self.frame)
  66. let y = CGRectGetMidY(self.frame)
  67. self.trackingAgent!.position = vector_float2( Float(x),Float(y))
  68. }
  69. override func update(currentTime: NSTimeInterval) {
  70. // Calculate delta since last update and pass along to the agent system.
  71. if (lastUpdateTime == 0) {
  72. lastUpdateTime = currentTime;
  73. }
  74. let delta = currentTime - lastUpdateTime
  75. lastUpdateTime = currentTime
  76. self.agentSystem!.updateWithDeltaTime( delta )
  77. }
  78. override func mouseDown(theEvent: NSEvent) {
  79. self.seeking = true
  80. }
  81. override func mouseUp(theEvent: NSEvent) {
  82. self.seeking = false
  83. }
  84. override func mouseDragged(theEvent: NSEvent) {
  85. let position = theEvent.locationInNode(self)
  86. self.trackingAgent!.position = vector_float2 (Float(position.x),Float(position.y))
  87. }
  88. }


下面的代码用于建立一个游戏节点,其实就是一个游戏对象,这里是一条小船。它由一个圆形和一个三角形构成,还添加了粒子水泡。
  1. import Cocoa
  2. import SpriteKit
  3. import GameplayKit
  4.  
  5.  
  6. class AAPLAgentNode: SKNode,GKAgentDelegate{
  7. var agent = GKAgent2D()
  8. var color: SKColor = SKColor.highlightColor()
  9. var drawsTrail: Bool = false
  10. var triangleShape: SKShapeNode!
  11. var particles: SKEmitterNode!
  12. var defaultParticleRate: CGFloat = 0
  13. init( scene: SKScene,radius: CGFloat,position: CGPoint ){
  14. super.init()
  15. self.position = position;
  16. self.zPosition = 10;
  17. scene.addChild(self)
  18. // An agent to manage the movement of this node in a scene.
  19. agent = GKAgent2D()
  20. agent.radius = Float(radius)
  21. agent.position = (vector_float2)( Float(position.x),Float(position.y))
  22. agent.delegate = self;
  23. agent.maxSpeed = 100;
  24. agent.maxAcceleration = 50;
  25.  
  26. // A circle to represent the agent's radius in the agent simulation.
  27. let circleShape = SKShapeNode(circleOfRadius: radius)
  28. circleShape.lineWidth = 2.5
  29. circleShape.fillColor = SKColor.grayColor()
  30. circleShape.zPosition = 1
  31. self.addChild(circleShape)
  32. // A triangle to represent the agent's heading (rotation) in the agent simulation.
  33. var points = Array(count: 4,repeatedValue: CGPoint())
  34. let triangleBackSideAngle = CGFloat((135.0 / 360.0) * (2 * M_PI))
  35. points[0] = CGPointMake(radius,0); // Tip.
  36. points[1] = CGPointMake(radius * cos(triangleBackSideAngle),radius * sin(triangleBackSideAngle)); // Back bottom.
  37. points[2] = CGPointMake(radius * cos(triangleBackSideAngle),-radius * sin(triangleBackSideAngle)); // Back top.
  38. points[3] = CGPointMake(radius,0); // Back top.
  39. let triangleShape = SKShapeNode(points: &points,count: 4)
  40. triangleShape.lineWidth = 2.5;
  41. triangleShape.zPosition = 1;
  42. self.addChild( triangleShape)
  43. // A particle effect to leave a trail behind the agent as it moves through the scene.
  44. particles = SKEmitterNode(fileNamed: "Trail.sks")
  45. defaultParticleRate = particles!.particleBirthRate;
  46. particles!.position = CGPointMake(-radius + 5,0);
  47. particles!.targetNode = scene;
  48. particles!.zPosition = 0;
  49. self.addChild( particles!)
  50. }
  51. required init?(coder aDecoder: NSCoder) {
  52. fatalError("init(coder:) has not been implemented")
  53. }
  54.  
  55. // GKAgentDelegate
  56. func agentWillUpdate(agent: GKAgent){
  57. }
  58. /*
  59. * Called after [GKAgent updateWithDeltaTime:] is called each frame.
  60. */
  61. func agentDidUpdate(agent: GKAgent){
  62. // Agent and sprite use the same coordinate system (in this app),// so just convert vector_float2 position to CGPoint.
  63. let agent2D = agent as! GKAgent2D
  64. self.position = CGPointMake( CGFloat(agent2D.position.x),CGFloat(agent2D.position.y))
  65. self.zRotation = CGFloat(agent2D.rotation)
  66. }
  67. }


这个例子用了八个子类演示 跟踪代理的不同用法。我门这里只做了一个:
  1. //
  2. // AAPLWanderScene.swift
  3. // TestAgents
  4. //
  5. // Created by wuzhiqiang on 15/11/14.
  6. // Copyright © 2015年 wuzhiqiang. All rights reserved.
  7. //
  8.  
  9. import Cocoa
  10. import SpriteKit
  11. import GameplayKit
  12.  
  13. class AAPLWanderScene: AAPLGameScene {
  14.  
  15. override func didMoveToView(view: SKView) {
  16. super.didMoveToView(view)
  17. let pt = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
  18. let wanderer = AAPLAgentNode( scene: self,radius: 40,position: pt )
  19. wanderer.color = SKColor.cyanColor()
  20. wanderer.agent.behavior = GKBehavior( goal: GKGoal( toWander:10),weight: 100)
  21. self.agentSystem!.addComponent( wanderer.agent)
  22. }
  23. }

下面我们来描述一下程序的工作过程。

在AppDelegate里面,我们建立一个Scence,8个中的一个,这里是AAPLWanderScene,漫游型。

这个 AAPLWanderScene 建立一个自己的 Node (一艘船),然后建立并将 GKBehavior 对象赋给了 节点的agent.behavior 属性

最后,将这个节点作为一个组件加入到组件系统。

就是这样。程序就会运行,组件系统会工作,定时循环更新他的每个组件。你的小船会自动出发漫游。

在节点里,甚至还加入了粒子效果,你能看到小船后面的水泡。

猜你在找的Swift相关文章