SuperAPI AI 工具集

axiom-spritekit

编程与开发

查看项目

更新于 10-15 18:31

技能介绍

用途

axiom-spritekit 是一份 SpriteKit 游戏开发指南,目标是通过掌握场景图、物理引擎、动作系统与渲染管线来构建可靠的 SpriteKit 游戏。资料给出的适用范围包括:构建新的 SpriteKit 游戏或交互式模拟;实现物理(碰撞、接触、力、关节);搭建游戏架构(场景、图层、相机);优化帧率或减少绘制调用;在游戏中实现触摸/输入处理;管理场景过渡与数据传递;将 SpriteKit 与 SwiftUI 或 Metal 集成;排查不触发的物理接触;修正坐标系混淆。

资料同时明确列出不适用的情况:SceneKit 3D 渲染(对应 axiom-scenekit)、GameplayKit 实体组件系统、Metal 着色器编程(axiom-metal-migration-ref)、通用 SwiftUI 布局(axiom-swiftui-layout)。

主要能力与核心概念

坐标系与锚点

SpriteKit 使用左下角为原点、Y 轴向上,这一点与 UIKit(左上角原点、Y 轴向下)不同。锚点(anchorPoint)决定精灵上哪个点对应其 position,默认是 (0.5, 0.5)(中心)。资料示例中,(0, 0) 表示精灵左下角位于 position 处,(0.5, 0) 表示底部中心,适合站在地面上的角色。场景锚点把视图 frame 映射到场景坐标:(0, 0) 为视图左下角(默认),(0.5, 0.5) 为视图中心。

节点树与 zPosition

SpriteKit 中一切都是节点树中的 SKNode,父级变换会传递给子节点。资料给出的结构中,SKScene 下可包含 SKCameraNode、名为 world 的内容层(玩家、敌人、平台等)以及挂在相机上的 hud 层(分数标签、血条等)。zPosition 控制绘制顺序,值越大越在上层;相同 zPosition 的节点按子节点数组顺序渲染,除非 ignoresSiblingOrder 为 true。资料建议用枚举建立清晰的 z 层,例如 background 为 -100、platforms 为 0、items 为 10、player 为 20、effects 为 30、hud 为 100。

场景架构

缩放模式包括 .aspectFill(填满视图并裁切边缘,适用于大多数全屏游戏)、.aspectFit(适配视图并留黑边,适用于要求精确布局的益智游戏)、.resizeFill(拉伸填充,资料称几乎不应使用,会变形)、.fill(精确匹配视图尺寸,场景适配任意比例)。资料建议始终使用 SKCameraNode 控制视口,并将 HUD 元素挂到相机上使其不随场景滚动;可用 SKConstraint.distance 让相机跟随玩家。图层组织上,worldNode 承载游戏对象,hudNode 挂在 camera 下承载 UI。场景过渡可用 SKTransition.fade(withDuration:) 并通过 view?.presentScene(_:transition:) 呈现;跨场景数据传递推荐使用共享的 GameState 对象而非节点属性,资料也提示单例适合简单游戏、需要测试的大型项目可通过场景初始化器传入 GameState 实例以避免隐藏的全局状态。清理可在 willMove(from:) 中调用 removeAllActions()、removeAllChildren() 并将 physicsWorld.contactDelegate 置为 nil。

物理引擎

物理位掩码使用 32 位系统,每位代表一个类别。资料定义了三类位掩码:categoryBitMask 表示该物理体是什么(默认 0xFFFFFFFF)、collisionBitMask 表示它与什么发生反弹(默认 0xFFFFFFFF)、contactTestBitMask 表示什么会触发 delegate 回调(默认 0x00000000)。资料特别指出,collisionBitMask 默认 0xFFFFFFFF 意味着万物互相碰撞,是意外物理行为的最常见来源。示例中通过 PhysicsCategory 枚举定义 player、enemy、ground、projectile、powerUp 等类别并显式赋值。位掩码检查清单要求:每个物理体的 categoryBitMask 只设为一个类别;collisionBitMask 只设为其应反弹的类别(而非 0xFFFFFFFF);contactTestBitMask 设为应触发回调的类别;并已指定 physicsWorld.contactDelegate = self。

接触检测通过实现 SKPhysicsContactDelegate 的 didBegin(:) 完成,资料建议先按 categoryBitMask 排序 bodyA 与 bodyB 再分派处理。修改规则:不能在 didBegin/didEnd 内修改物理世界,应设置标记并在 update(:) 中应用变更。物理体类型包括:动态体(init(circleOfRadius:)、init(rectangleOf:)、init(texture:size:) 等,响应力,用于玩家、敌人、抛射物)、静态体(动态体加 isDynamic = false,不响应力但参与碰撞,用于平台、墙壁)、边缘体(init(edgeLoopFrom:)、init(edgeFrom:to:),仅作边界,用于屏幕边界、地形)。防止穿透可为高速物体启用 usesPreciseCollisionDetection,并让墙体足够厚。力与冲量的区别是:applyForce 为持续施加(逐帧累积),applyImpulse 为一次性速度变化(如跳跃),另有 applyTorque(持续旋转)与 applyAngularImpulse(瞬时旋转变化)。

动作系统

动作包括移动(move、moveBy)、旋转(rotate)、缩放(scale)、淡入淡出(fadeOut、fadeIn);SKAction.sequence 实现顺序执行,SKAction.group 实现并行执行,SKAction.repeatForever 实现重复。资料强调使用命名动作(withKey:)以便后续通过 removeAction(forKey:) 取消或替换,并可用 action(forKey:) 检查是否在运行。自定义动作中使用 SKAction.run 时应以 [weak self] 弱捕获避免循环引用,重复动作尤其如此。时间模式包括 .linear(默认,匀速)、.easeIn、.easeOut、.easeInEaseOut。重要限制:绝不要用动作移动受物理控制的节点,动作会覆盖物理模拟,导致抖动和碰撞丢失;物理体应用力或冲量,动作则用于非物理节点(UI、特效、装饰)。

输入处理

关键点:响应节点上 isUserInteractionEnabled 必须为 true;SKScene 默认为 true,其他节点默认为 false。坐标转换方面,touch.location(in: self) 返回场景坐标(最常用),也可指定特定节点;nodes(at:) 可做命中测试。资料提示的常见错误是使用 touch.location(in: self.view) 会返回 UIKit 坐标(Y 翻转),应始终用 touch.location(in: self)。手柄支持通过导入 GameController、监听 .GCControllerDidConnect 通知并遍历 GCController.controllers() 完成配置。

性能

性能优先级包括:节点数量——移除屏幕外节点、使用对象池;绘制调用——使用纹理图集、用预渲染纹理替代 SKShapeNode;物理开销——优先使用简单体形状、限制 usesPreciseCollisionDetection 的使用;粒子——限制出生率、设置有限发射次数。开发期间建议开启调试叠层:showsFPS、showsNodeCount、showsDrawCount、showsPhysics,并设置 ignoresSiblingOrder = true 以优化渲染顺序。纹理图集批处理方面,使用同一图集纹理的精灵可在一次绘制调用中渲染,可用 SKTextureAtlas(named:) 与 textureNamed(:),并通过 SKTextureAtlas.preloadTextureAtlases(:completionHandler:) 预加载以避免掉帧。SKShapeNode 每个实例产生一次绘制调用且无法批处理,只应用于原型与调试可视化;正确做法是先用 SKShapeNode 绘制,再通过 view?.texture(from:) 预渲染为纹理后用 SKSpriteNode 创建。对象池适用于频繁生成/销毁的对象(子弹、粒子、敌人),资料给出 BulletPool 示例,预创建子弹并设置 categoryBitMask、collisionBitMask 与 contactTestBitMask。

使用方式与环境要求

资料标注的适用环境为:iOS 13+(SwiftUI 集成)、iOS 11+(SKRenderer)、Xcode 15+。

适用场景与限制

适用场景包括新建 SpriteKit 游戏或交互模拟、实现物理碰撞与接触、搭建场景与图层架构、优化帧率与绘制调用、处理触摸与手柄输入、管理场景过渡与数据传递、与 SwiftUI 或 Metal 集成、排查物理接触不触发与坐标系混淆等问题。

限制与边界:不用于 SceneKit 3D 渲染、GameplayKit 实体组件系统、Metal 着色器编程与通用 SwiftUI 布局;不要在 didBegin/didEnd 内修改物理世界;不要用动作移动受物理控制的节点;避免使用 SKShapeNode 于生产绘制;resizeFill 缩放模式几乎不应使用。