GameplayKit的GKStateMachine用法与实例
玩家进入GameScene场景中 -> 通过GKStateMachine进入到指定的游戏状态GKState
在GameScene场景中 -> 根据不同的逻辑调用GKStateMachine -> 在各个不同的游戏状态GKState之间进行切换
源码如下:
一、GameScene.swft
import SpriteKit
import GameplayKit
class GameScene: SKScene,SKPhysicsContactDelegate {
//MARK: - StateMachine 场景中各个舞台State
lazy var stateMachine:GKStateMachine = GKStateMachine(states: [
WaitingState(scene: self),
PlayState(scene: self),
GameOverState(scene: self)])
override func didMove(to view: SKView) {
stateMachine.enter(MenuState.self) // 进入MenuState
}
func restartGame(){
let newScene = GameScene(fileNamed: "GameScene")!
newScene.size = CGSize(width: SCENE_WIDTH, height: SCENE_HEIGHT)
newScene.anchorPoint = CGPoint(x: 0, y: 0)
newScene.scaleMode = .aspectFill
let transition = SKTransition.crossFade(withDuration: TimeInterval(0.5))
view?.presentScene(newScene, transition:transition)
//reload GameScene 直接进入游戏状态;
newScene.stateMachine.enter(PlayState.self)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
// 当 physicsWorld.body(at: touchLocation)为nil时
// 采用atPoint 取得场景中的的精灵
let touchLocation = touch.location(in: self) ///获得点击的位置
let nodeAtPoint = self.atPoint(touchLocation) //返回SKNode
/// 判断目前的GameScene场景舞台是哪个state
switch stateMachine.currentState {
case is WaitingState:
/// 判断是否是点击了PlayButton
if nodeAtPoint.name == "playButton" {
stateMachine.enter(PlayState.self)
}
if nodeAtPoint.name == "learnTemp" {
print("weird")
UIApplication.shared.open(URL(string: "http://www.iFIERO.com")!, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: { (error) in
print("jump to http://www.iFiero.com")
})
}
case is PlayState:
//挑战:判断是否是点击了暂停按钮 PauseButton
// if nodeAtPoint.name == "pauseButton" {
// stateMachine.enter(PauseState.self)
// }
break;
case is GameOverState:
if nodeAtPoint.name == "tapToPlay" {
restartGame()
}
default:
break;
}
}
//MARK: - 时时更新
override func update(_ currentTime: TimeInterval) {
/// 获取时间差
if lastUpdateTimeInterval == 0 {
lastUpdateTimeInterval = currentTime
}
dt = currentTime - lastUpdateTimeInterval
lastUpdateTimeInterval = currentTime
stateMachine.update(deltaTime: dt) // 调用所有State内的update方法
}
}
二、MenuState.swft
//
// MenuState.swift
// Copyright © 2018 iFiero. All rights reserved.
//
import SpriteKit
import GameplayKit
class MenuState:GKState {
// 必须引入场景(如:GameScene)
unowned let scene:GameScene
// 执行didEnter前,可在init()初始化代码
init(scene:SKScene){
self.scene = scene as! GameScene
super.init()
print("Menu State")
}
// 进入当前状态时触发
override func didEnter(from previousState: GKState?) {
}
// 离开当前状态时触发
override func willExit(to nextState: GKState) {
}
/* 返回一个布尔值
* 该值指示当前处于该状态的状态机是否允许转换到指定状态
* 通俗点讲就是:如果stateMachine(状态机)的状态是PlayState,那么就从MenuState状态转到PlayState状态
*/
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return stateClass is PlayState.Type
}
// Execute Update Per Frame,游戏运行过程中的每一帧都会执行
// 但须在GameScene update内调用stateMachine.update()
override func update(deltaTime seconds: TimeInterval) {
}
}
三、PlayingState.swft
import SpriteKit
import GameplayKit
class PlayState:GKState {
unowned let scene:GameScene
init(scene:SKScene){
self.scene = scene as! GameScene
super.init()
print("Play State")
}
override func didEnter(from previousState: GKState?) {
}
// 挑战:创建游戏暂停GKState状态 PauseState.swift
// return (stateClass == PauseState.self) || (stateClass == GameOverState.self)
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return stateClass is GameOverState.Type
}
// Excute Update Per Frame
override func update(deltaTime seconds: TimeInterval) {
// update 用于判断球的速度是否过快,如果太快了则设置linearDamping的阻力
}
}
四、GameOverState.swft
import SpriteKit
import GameplayKit
class GameOverState:GKState {
unowned let scene:GameScene
init(scene:SKScene){
self.scene = scene as! GameScene
super.init()
}
override func didEnter(from previousState: GKState?) {
print("GameOver State 游戏结束")
}
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return stateClass is PlayState.Type
// return (stateClass == PlayState.self) || (stateClass == MenuState.self)
}
}
更多游戏教学:http://www.iFIERO.com -- 为游戏开发深感自豪
源码传送门:https://github.com/apiapia/BreakOutGameVansVTutorial
GameplayKit的GKStateMachine用法与实例的更多相关文章
- HTML常用标签用法及实例
HTML常用标签用法及实例1.<!--1.注释-->2.<!--2.DOCTPYE 声明文档类型-->3.<!--3.a--> <a href="h ...
- C# Timer用法及实例讲解
摘自:http://www.cnblogs.com/xcsn/archive/2013/05/10/3070485.html 1.C# Timer用法及实例详解 http://developer.51 ...
- C# Timer用法及实例详解
C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助. 关于C# Timer类 在C#里关于 ...
- 【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析
一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为( ...
- shell脚本学习之case用法及实例
case语句和判断语句[if...elif...else]功能类似;当在逻辑判断比较简单的情况下,比后者的代码量要少许多.case用法,用变量来匹配某值,如果匹配成功则执行它下面的命令,直到 ;;为止 ...
- matlab sign函数用法及实例
在MATLAB科学计算过程当中,我们经常需要对我们的计算公式或者计算结果检验其符号,,sign函数就给我们提供了这种方便,下面就通过实例介绍一下matlab sign函数 的用法,希望能够给您带来帮助 ...
- java中static、this、super、final用途、用法及实例
一.static 请先看下面这段程序: public class Hello { public static void main(String[] args){ //(1) System.out.pr ...
- crontab用法与实例
导读 在Linux系统的实际使用中,可能会经常碰到让系统在某个特定时间执行某些任务的情况,比如定时采集服务器的状态信息.负载状况:定时执行某些任务/脚本来对远端进行数据采集等.这里将介绍下cronta ...
- mysql事务处理用法与实例详解
来源:转载 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID事务.行级锁.并发 3.Berke ...
随机推荐
- POST接口底层方法
对于POST请求的接口,我们如何调用它获取到数据,这其中自然少不了底层代码 底层公共类的书写 public class ThirdOpenAPIService { public static Thir ...
- 在js中获取request域中的内容
1.可以使用小脚本<%%>实现: var pro_id=<%request.getPro_id()%>; 2.使用隐藏域实现: <input type="hid ...
- Swift_类和结构体
Swift_类和结构体 点击查看源码 struct Resolution { var width = 0 var height = 0 } class VideoMode { var resoluti ...
- python 创建虚拟环境
创建一个文件夹:mkdir tf_env 进入到文件夹内:cd tf_env 创建虚拟环境:python3 -m venv tensorflow-dev 激活虚拟环境:source tensorflo ...
- chromium之message_pump_win之一
写了22篇博文,终于到这里了———— MessagePumpWin!!! MessagePumpWin这个类还是挺复杂的,可以分成好几部分.接下来分块分析 从介绍看,MessagePumpWin 是M ...
- Zabbix——部署(DB与web分离)
前提条件: 两台centos7设备 两台设备可以相互访问 Zabbix-Servser版本为4.0 mysql版本为8.0 关闭防火墙 Zabbix部署(包含server,web,agent) rpm ...
- jQuery语法、选择器、效果等使用
1.jQuery语法 1.1 基础语法:$(selector).action( ) 美元符号定义 jQuery 选择符(selector)“查询”和“查找” HTML 元素 jQuery 的 acti ...
- angular.js-1初识
初识AngularJS AngularJS 为了克服HTML在构建页面上的不足,通过新的属性和表达式扩展了 HTML(AngularJS 通过指令扩展了 HTML,且通过表达式绑定数据到 HTML). ...
- 【Keil】Keil5的安装和破...
档案的话网上很多的,另外要看你开发的是哪种内核的芯片 如果是STC的,就安装C51 如果是STM的,就安装MDK 当然市面上有很多芯片的,我也没用过那么多种,这里也就不列举了 至于注册机,就是...恩 ...
- python学习笔记:第5天 基本数据类型之字典
目录 字典的介绍 补充 字典的介绍 字典(dict)是python中唯一的一个映射的数据类型,它是以一对一对的键值对的形式组成的一个容器,在python中字典也是可变的,我们也可以在字典中存放各种类型 ...