Tag: Spritekit

SpriteKit场景—使用didMove加载内容(以查看:SKView)

使用SpriteKit的iOS游戏中的所有内容内容都在SKScene类内。 SKScene是“场景图的根对象”,这意味着您可以近距离观察活动中的树木! 是的 我对SKScene和SKView之间的区别感到有些困惑,但是SKView只是UIView子类。 不太肉! 您可以完成我们的大多数属性分配,并在SKScene didMove(to: SKView)方法中didMove(to: SKView)编程方式进行设置。 以编程方式添加子级 这是最好的方法,因为所有内容都在代码中,但是可能要花很长时间。 如果设计师无法编写代码,您也将无法与他们轻松共享场景。 我喜欢Scene编辑器,因为它提供了很多复杂的选项,例如SpriteKit TileMap和动画,但它并不太复杂,您在编辑器中所做的任何事情都可以用代码完成。 请注意,在这种情况下,SKView不会调用场景编辑器文件,而是会调用GameViewController。

TIL:如何在SpriteKit游戏中使用SKCameraNode

在过去的好时光中,过去常常需要花费大量的数学才能产生一种幻觉,即玩家正在向更大的“世界”移动。 我最近一直在玩SpriteKit,今天我了解了使用SKCameraNode实际创建该效果有多么容易。 什么是SKCameraNode 苹果的文档很好地解释了这一点。 SKCameraNode对象用于指定场景中可以从中渲染场景的位置。 换句话说,它可以用于在游戏世界中滚动玩家的视图。 如何使用它 俗话说,一张图片值得一千个字。 通过一个示例,了解SKCameraNode工作方式将更加容易。 我们将建立一个游戏场景,让玩家能够通过点击屏幕来浏览世界。 世界观将始终以主角为中心。 为了给事情增添趣味,我们还将添加一个得分计数器叠加层。 让我们首先使用SpriteKit创建一个新的iOS游戏。 默认项目模板包括带有一些示例行为的GameScene 。 由于我们专注于相机行为,因此我们将从头开始创建自己的SpriteKit Scene 。 让我们在场景编辑器中放置一些Color Sprites : 我将其中一个尺寸缩小(50×50),并给它命名一个名称player ,以后我们可以用它来从代码中引用该对象。 这将是精灵对象,它将响应触摸事件并在世界范围内移动。 我们的“相机”(播放器的视图)将以该对象为中心。 通过足够的拖放操作,让我们打开游戏场景swift文件并开始编写一些代码。 声明类型为SKCameraNode的可选变量: var cam: SKCameraNode? 这将是我们对相机的参考。 场景进入视野后,我们将初始化变量: 覆盖func didMove(以查看:SKView){ super.didMove(查看) cam = SKCameraNode() self.camera =凸轮 self.addChild(cam!) } 这里要注意的重要一点是,相机节点具有自己的框架,该框架占据屏幕的大小。 设置相机效果的位置会转换为设置可见屏幕的中心。 为了演示这一点,让我们首先尝试让我们的“玩家”在屏幕上移动以响应触摸事件。 为此,我们将在场景首次进入视野时获得对玩家对象的引用,并在触摸屏幕后使其移动: var cam:SKCameraNode? var播放器:SKSpriteNode? 覆盖func didMove(以查看:SKView){ super.didMove(查看) cam = SKCameraNode() […]

SpriteKit与SceneKit

。로중심으로글입니다。 。다있습니。 오역이나정보에대한정은언제든지환영합니다🙂 개발할때개발할때OpenGL OpenGL OpenGL나나나의그래픽그래픽그래픽매김매김매김매김매김。。 이러한API들은GPU와와다。 만지만full graphics택스택(결과를기만들어내공동의기달성하기달성하)것들이있다。 API应用程序框架API框架图形渲染引擎 ,图形渲染基础架构,图形渲染基础设施,SpriteKit 과SceneKit유이등장이다。 动画,Core Animation框架,QuartzCore,GLKit和iOS版本的사용된다。 SceneKit核心动画框架,SpriteKit产品和主题。 SceneKit的高级3D图形框架,渲染引擎和描述性API的交互。 金属较低级别的API보다는다。 (水果忍者양한양한카메라가고3D게임을보생각해) SceneKit은Loin OS배포되었으며sc sc sc sc sc션만scription de D D D D D D D D 3D되었되었다de다 이것의“场景图”의의의의션을션을션을션을높인다。 的Objective-C,斯威夫特 斯威夫特游乐场 Quartz,Core Animation,GL Kitworks发行中的内容양한양한얻얻위해른른술들과술들과술들과술들과통합됨 킬을로그래밍스킬을지요구하 SceneKit알아보기 Apple入门指南和SceneKit最佳做法。 SpriteKit发行了2D发行版。 (Candy Crush나愤怒的小鸟배터배터리를이않는지않는较低级别的2D애니메이션을보생각해) SpriteKit的SceneKit版本(iOS 7版本),2D的版本版本,Sprite的版本,OpenGL的图形API和图形版本。 rite sprites웹페나나파일파일이이파일파일비개발자들에게비개발자들에게이이이이。 sprite운운위치하는데위치하는데위치하는데위치하는데위치하는데위치하는데위치하는데션을。。필요필요필요없음을。다 rite SpriteKit그저rite rite한리한다。 SpriteKit본본원나나션션션능을능을게임에게임에공게임에공。 […]

RainCat:第5课

下一个场景 那就对了! 我们正在转移到另一个场景。 实际上,完成后,这将是我们应用程序的第一个屏幕。 创建新场景,将其放置在Scenes文件夹下,并将其命名为MenuScene 。 在MenuScene.swift文件中输入以下代码: 按钮状态! 在SpriteKit中,按钮可能比较棘手。 有很多可用的第三方选项(我甚至自己做了一个),但是从理论上讲,您只需要知道三种触摸方法即可: touchesBegan(_ touches:with event 🙂 touchesMoved(_ touchs:with event 🙂 touchesEnded(_ touches:with event 🙂 我们在更新保护伞时简要介绍了这一点,但是现在我们需要知道:触摸了哪个按钮; 我们是释放水龙头还是单击该按钮; 如果我们仍在触摸它。 这就是我们的selectedButton变量起作用的地方。 当我们开始触摸时,我们可以捕获使用该变量开始单击的按钮。 如果将其拖动到按钮之外,则可以对其进行处理并为其提供适当的纹理。 释放触摸时,我们可以查看是否仍在触摸按钮内部。 如果是,那么我们可以处理与其相关的动作。 将以下代码行添加到MenuScene.swift的底部: 采取行动了! 现在,我们已经掌握了基本的按钮行为,我们需要一个事件来触发它们的点击。 易于实现的按钮是startButton 。 单击时,我们只需要展示GameScene即可 。 将MenuScene.swift函数中的handleStartButtonClick()更新为以下代码: func handleStartButtonClick(){ let transition = SKTransition.reveal(with:.down,duration:0.75) 让gameScene = GameScene(size:size) gameScene.scaleMode = scaleMode view?.presentScene(gameScene,过渡:过渡) } 如果您现在运行该应用程序并按按钮,游戏将开始! 现在我们需要实现静音切换。 我们已经有一个声音管理器,但是现在我们需要能够告诉它是否静音。 […]

揭秘SKWarpGeometry

tl; dr :我构建了一个编辑器来使用本机SpriteKit扭曲图像 看起来像我所需要的,但是设置需要手动输入float2的数组-我实在太懒了,无法手动找出所有输入。 我需要一个小工具来调整输入,查看结果并导出。 听起来很简单… 要求 我希望能够加载图像,设置列和行,拉动控制点并将结果导出为Swift代码。 我打开了Xcode,并使用Game项目和SpriteKit&Swift创建了一个新的macOS项目。 我花了几个小时来整理所需的框架,使用NSSplitView和容器视图将视图控制器分离出来,第一个版本如下所示: 在这一点上,我可以加载磁盘映像,显示一个简单的检查器,并在时间轴上显示一个项目…。什么都没有用,因为它是伪造的,您无法选择图像上的黄色手柄,因此检查员的物品什么也没做。 但是我知道我必须证明移动控制点会扭曲精灵。 我在晚上和周末进行此操作,因此在短时间后,我可以拖动控制点并扭曲图像……它开始慢慢融合在一起。 我知道我希望能够单击控制手柄(黄色正方形)并四处移动,并查看精灵的变化。 考虑到这一点,我知道我必须拥有一个Inspector……就像在Xcode中一样,无论您选择什么,都可以拥有一个上下文相关的属性列表,您可以每周两次。 我还知道,通过阅读Apple文档,我可以按顺序应用任意数量的扭曲,因此我决定使用时间轴/图层系统。 同样,这应该是上下文相关的。 除此之外,我还知道整个场景可以具有列*行的任意组合,因此需要一个总体模型来存储它们,因此我填写了一个数据模型,如下所示: 文件模型 — WarpModel — — ControlPointModel DocumentModel将存储: *要使用的图片(实际上只是图片的URL) *控制点的列数和行数。 *经层 WarpModel将存储 * ControlPoints列表 ControlPointModel将存储 *位置,简单的X,Y坐标 我希望我的工具能够保存我决定变形的任何图像的结构,因此我需要实现Swift 4的新Codable接口。 它非常易于使用,并且可以轻松地将数据编码和解码为JSON。 “很容易看到一个简单的想法如何变成许多功能” 然后,我需要(那里不存在很多)来证明我可以从一个几何图形动画到下一个几何图形。 那意味着必须有多层。 每个图层都有自己的一组控制点…但是我想在它们之间设置动画。 图层应具有不同的起点/终点。 如果它们同时启动,您将获得混合结果。 导出代码是应用程序最重要的功能,我不想只看到变形的结果,我需要将其导出并在另一个项目中使用。 每当我对数据进行更改时,该应用程序都会重新生成Swift代码,您可以根据需要复制/粘贴该代码。 选单 再一次,我发现自己要添加要素,在某些位置添加图层,如果您想随时间推移稍微移动控制点,则可以复制图层。 上下移动控制点,旋转控制点。 撤销重做 我不打算构建的另一个功能是撤消/重做,但这确实使您可以将代码结构化为可重用的组件。 我很高兴我做到了。 网格切换 在开发应用程序时,我发现我想像在回放模式下那样打开和关闭网格,或者在擦拭时间轴时希望看到结果,而不是网格使子画面模糊。 我还想查看经线与原始源图像的偏离程度,因此我添加了一个洋葱皮类型的功能,可以在其中看到原始图像,但是在需要时将其关闭 容器视图 容器视图允许您将视图控制器引用嵌入到另一个视图中,这可以使您分离视图。 […]

带有Sprite Kit的过程图块贴图

我最近开始了一个新项目:建立一个城市建筑/模拟游戏。 我想使用SpriteKit及其SKTileMapNode类创建程序性地形。 我开始在网上寻找并阅读文档,但是关于如何以编程方式进行操作的内容并不多。 因此,我决定写本教程系列,介绍我在构建新游戏时所学的知识。 首先,按程序创建基本的瓷砖网格! SpriteKit和图块 苹果公司创造了一种非常简单的方法来管理一整块瓷砖及其在SKScene中的放置,但是,这不允许我们(至少不是我发现的)以程序方式生成我们的瓷砖地图。 因此,我们必须更深入地研究它们的实现。 首先,让我们使用“游戏”模板创建一个新的Xcode项目,并将引擎设置为SpriteKit。 接下来,我们添加一个Apple的默认图块集。 所以我们去File-> New-> File。 然后转到“资源”部分,然后选择“ SpriteKit Tile Set”。 然后选择您要查找的任何图块类型(Apple支持Grid,Isometric和Hexagonal),在此示例中使用哪种类型都没关系。 这将创建一个SKTileSet,其中包含所有平铺图像。 然后将集合分成不同的SKTileGroups。 这些组将是不同的地形,因此水,草,沙等。在这些组中是SKDefinitions,它们定义了放置瓷砖的位置。 我们现在不需要为此担心很多,但有关更多信息,请参见WWDC 2016视频:“ SpriteKit的新功能,Session 610”。 GK噪声 该地图最重要的部分是它是按程序生成的,为了做到这一点,我们将使用GKNoise创建一个“地图”,以说明我们如何布局平铺的世界。 苹果有几种不同类型的预建噪声源(GKNoiseSource),但是对于我们的用例,我们将使用GKPerlinNoiseSource。 此来源旨在为我们提供自然的地形。 func createNoiseMap()-> GKNoiseMap { //获取我们的噪声源,可以进一步自定义 let source = GKPerlinNoiseSource()//使用我们的源代码初始化GKNoise对象 let noise = GKNoise.init(source)//创建地图, // sampleCount =到网格中的图块数(行,列) let map = GKNoiseMap.init(噪声,大小:vector2(1.0,1.0),原点:vector2(0,0),sampleCount:vector2(50,50),Seamless:true) 返回地图 } 首先,我们基于GKPerlinNoiseSource创建噪声源。 然后使用我们的源代码创建一个新的GKNoise对象。 最后,我们使用该噪声对象创建地图。 确保将sampleCount参数设置为与稍后将用于SKTileMapNode的行和列数相同的数量。 […]

RainCat:第2课

创造运动! 我们将更新雨伞以响应触摸。 在GameScene.swift中 ,查看空函数touchesBegan(_ touches :,带有event 🙂和touchesMoved(_ touches :,带有event 🙂 。 在这里,我们将告诉雨伞与游戏进行交互的位置。 如果我们基于当前触摸之一在这两个功能中都设置了伞形节点的位置,它将锁定到位并从屏幕的一侧转移到另一侧。 另一种方法可能是在UmbrellaSprite对象中设置目标,然后在调用update(dt :)时 ,我们可以朝该位置移动。 第三种方法可能是将SKActions设置为在touchesBegan(_ touches :,带有event 🙂或touchesMoved(_ touches :,带有event 🙂上移动UmbrellaSprite ,但是我不建议这样做。 这将导致我们频繁创建和销毁这些SKAction ,并且可能性能不高。 我们将选择选项#2。 更新UmbrellaSprite中的代码,使其看起来像下面的代码: 检测我们的碰撞! 现在,我们不需要担心很多冲突。 我们可能在雨滴,雨滴和雨伞以及雨滴和地板之间发生碰撞。 但是,我们确实需要检测雨滴何时击中了某些东西,因此我们可以告诉它被删除。 我们将需要创建一些变量来对每个SKPhysicsBody进行分类,以便我们找出它们碰撞时该怎么办。 为此,我们应该创建另一个名为Constants.swift的文件。 右键单击“支持”组下的,单击“ 新建文件” >“ Swift文件” ,然后单击“下一步”按钮。 将文件重命名为Constants ,然后单击Create 。 该文件应包含以下代码: 让RainDropCategory:UInt32 = 0x1 << 1 让FloorCategory:UInt32 = 0x1 << 2 让UmbrellaCategory:UInt32 = […]

tvOS 10:SpriteKit和Focus Engine入门

大约一年前,Apple发布了AppleTV 4,并通过tvOS 9首次为开发人员开放了该平台。tvOS和iOS之间最大的区别可能是用户与系统的交互方式。 在iOS上,他们通常使用手指,但在tvOS上,使用游戏控制器或iPhone的“ Remote”应用可通过随附的遥控器取消互动。 为了管理这种新的输入法,苹果公司创建了一种叫做焦点引擎的东西。 在焦点引擎内,屏幕上的任何一个元素都具有当前焦点,并且焦点在用户导航时在一个元素和另一个元素之间移动。 如果用户按下按钮,则输入将定向到当前关注的元素。 在tvOS 9中,焦点引擎仅在UIKit中受支持,因此SpriteKit开发人员可以滚动自己的系统。 在tvOS 10中,焦点引擎已扩展为支持SpriteKit,目的是使SpriteKit游戏中的交互性更符合UIKit和基于TVML的应用程序。 我目前正在将我的iOS游戏Mazy移植到tvOS,并且其中一部分采用了新的Focus引擎来为游戏菜单提供动力。 我想在这里分享我的经验,希望您在从事类似工作时能从中受益。 有2个WWDC视频,介绍SpriteKit中新的焦点引擎集成。 在tvOS上进行焦点交互(SpriteKit位从15:20开始,但是如果您不熟悉焦点引擎,则值得观看整个视频)。 SpriteKit的新增功能中也介绍了该引擎(焦点位从39:15开始)。 我有一个github存储库,您可以克隆以遵循以下示例。 你可以在这里找到它。 由于需要tvOS 10,它需要Xcode 8 beta,它也是使用Swift 3编写的。下面的每个部分都有一个场景。 只需在GameViewController.swift中更新此行以选择相关场景即可: 让场景= SimpleMenuScene(大小:view.frame.size) SimpleMenuScene 首先让我们得到一个简单的菜单。 SimpleMenuButton是SKNode的子类,将显示一个字符串,并在聚焦时更改颜色。 我们将从垂直列表中的3个SimpleMenuButton开始。 为了使项目可聚焦,它必须实现UIFocusItem。 SKNode已经实现了此功能,因此我们可以在SimpeMenuButton子类中重写它,如下所示: 覆盖public var canBecomeFocused:Bool { 得到{ 返回真 } } (请注意,在Swift 2.3中,canBecomeFocused是函数而不是属性)。 现在我们需要处理焦点更改,我们通过实现UIFocusEnvironment中的didUpdateFocus来实现。 您可以在关注的项目或其父项之一上实施此操作。 在这里,我已经在SimpleMenuScene上实现了它 覆盖func didUpdateFocus(在上下文中:UIFocusUpdateContext,与协调者:UIFocusAnimationCoordinator){ 让prevItem = context.previouslyFocusedItem 让nextItem = context.nextFocusedItem 如果让prevButton […]

RainCat:第4课

如何在Swift 3中制作一个简单的SpriteKit游戏 再一次问好! 如果您错过了上一课,可以在这里查看。 如果您没有第3课中的代码,当前可在GitHub上获得。 在上一课中,我们添加了大部分资产,最后使用zPosition属性正确定位了它们。 我们增加了猫的功能,以及在猫掉到屏幕上造成一定危险时重新生成猫的功能。 接下来,我们在屏幕上的任意位置生成食物,但是在屏幕的两侧都留有边距,因此不会太靠近屏幕边缘。 我们为这两个精灵添加了碰撞,并且只在用伞将猫推到那里时,猫才能够收集食物。 也就是说,直到今天! 在本课程中,我们将重点关注: 将猫移向食物 动画猫 遇雨会损坏猫 添加声音效果 添加音乐 获取您的资产! 今天的资产可在GitHub上找到。 就像之前三课中一样,将图像再次拖到Assets.xcassets中 。 稍后我们将添加声音效果和音乐。 让我们继续前进! 让我们的猫动起来并不难。 我们不会通过触摸屏幕来与猫互动,这是我们当前移动雨伞的方式。 相反,猫会根据食物的当前位置移动。 目前,我们的食物精灵已添加到场景中并被遗忘,但是每次调用更新时我们都需要知道食物的确切位置,以使猫指向正确的方向移动。 回到我们的GameScene.swift ,让我们在文件顶部的本地cat变量下面添加一个变量: 私人食品:FoodSprite! 然后,我们可以更新spawnFood函数以在每次生成食物时设置此变量。 在spawnFood函数中,替换为: 让食物= FoodSprite.newInstance() 与: 食物= FoodSprite.newInstance() 这会将food变量的范围从spawnFood函数更改为GameScene文件的范围。 现在,我们需要编辑CatSprite文件,以了解它朝食物移动的方向。 要获得食物,我们需要知道我们可以朝着什么速度前进。 在CatSprite.swift文件的顶部,我们可以在newInstance函数上方添加以下代码行。 私人让步速度:CGFloat = 100 这条线是我们的移动速度,它是对非常复杂的问题的非常简单的解决方案。 我们在这里仅使用一个简单的线性方程,而忽略了摩擦或加速度会带来的任何复杂性。 现在,我们需要使用update(deltaTime 🙂方法做一些事情。 因为我们将知道食物在哪里,所以我们需要朝该位置移动。 用以下代码替换CatSprite.swift中的更新函数: 接下来,我们可以添加行走动画! 之后,我们将向后转圈以修复猫受到打击后的旋转。 您可能已经注意到,有一个名为“ cat_two”的未使用资产。 我们需要拉动该纹理并将其交换出去,以使其看起来就像猫在走路。 为此,我们将添加第一个SKAction! […]

SKCameraNode和Xcode调试视图层次结构

当我刚刚开始SpriteKit之旅时,我确实发现了许多问题。 当然,最常见的原因是我缺乏对Swift和Apple框架的经验,因此寻找解决方案可以帮助我学习和发展。 有时我会遇到不必要的事情,就像我前一天进入Xcode的Debug View Hierarchy 。 当涉及到SpriteKit , SKCameraNode和当前版本的Xcode v9.3.1中的调试器时,我确实遇到了一些特殊的行为。 我设置了一个非常基本的SpriteKit项目,以清楚地显示行为。 在这里,我们在SpriteKit编辑器中只有8个精灵。 正如我们所期望的,运行该应用程序将为我们提供与编辑器中完全相同的视图。 因此,让我们在运行应用程序时输入视图调试器,瞧,我们在调试器中也获得了完全相同的视图,就像在应用程序和编辑器中一样。 到目前为止,到目前为止,我们现在将SKCameraNode添加到场景中并再次执行相同的测试。 添加了SKCameraNode并再次运行该应用程序后,我们仍然可以获得预期的结果。 相机会看到我们定义的场景,并且应用程序中的视图正确。 因此,让我们再次输入Debug View Hierarchy … 哇! 这不是我期望的。 运行该应用程序时的视图是正确的,与编辑器中的视图相同,但是在调试器中获得的视图是不同的。 该视图似乎偏移了半个屏幕。 在将摄像机添加到场景(包括在开始新项目时添加到默认SpriteKit场景)后,就会始终发生这种情况。 通过SpritKit编辑器添加相机,或者以编程方式通过代码添加相机,这没有什么区别。 我发现通过将场景的锚点从默认值(0.5, 0.5) 0.5,0.5 (0.5, 0.5)更改为(0, 0)解决此问题,然后调试视图可以与SKCameraNode一起使用。 更改锚点会使调试器在使用相机时按预期显示视图,但除非场景的锚点(0,0)对我而言似乎不正确,否则无法将调试视图与SpriteKit和SKCameraNode一起使用,或成为预期的行为。 我希望调试器在运行应用程序时显示与我看到的视图相同的视图,无论我在场景中使用的锚点是什么。 这是Xcode v9.3.1中的错误吗? 还是我错过了什么? 最初于 2018 年5月16日 发布在 code.bitbebop.com 。