axiom-spritekit-ref

安装量: 100
排名: #8302

安装

npx skills add https://github.com/charleswiltgen/axiom --skill axiom-spritekit-ref
SpriteKit API Reference
Complete API reference for SpriteKit organized by category.
When to Use This Reference
Use this reference when:
Looking up specific SpriteKit API signatures or properties
Checking which node types are available and their performance characteristics
Finding the right physics body creation method
Browsing the complete action catalog
Configuring SKView, scale modes, or transitions
Setting up particle emitter properties
Working with SKRenderer or SKShader
Part 1: Node Hierarchy
All Node Types
Node
Purpose
Batches?
Performance Notes
SKNode
Container, grouping
N/A
Zero rendering cost
SKSpriteNode
Textured sprites
Yes (same atlas)
Primary gameplay node
SKShapeNode
Vector paths
No
1 draw call each — avoid in gameplay
SKLabelNode
Text rendering
No
1 draw call each
SKEmitterNode
Particle systems
N/A
GPU-bound, limit birth rate
SKCameraNode
Viewport control
N/A
Attach HUD as children
SKEffectNode
Core Image filters
No
Expensive — cache with
shouldRasterize
SKCropNode
Masking
No
Mask + content = 2+ draw calls
SKTileMapNode
Tile-based maps
Yes (same tileset)
Efficient for large maps
SKVideoNode
Video playback
No
Uses AVPlayer
SK3DNode
SceneKit content
No
Renders SceneKit scene
SKReferenceNode
Reusable .sks files
N/A
Loads archive at runtime
SKLightNode
Per-pixel lighting
N/A
Limits: 8 lights per scene
SKFieldNode
Physics fields
N/A
Gravity, electric, magnetic, etc.
SKAudioNode
Positional audio
N/A
Uses AVAudioEngine
SKTransformNode
3D rotation wrapper
N/A
xRotation, yRotation for perspective
SKSpriteNode Properties
// Creation
SKSpriteNode
(
imageNamed
:
"player"
)
// From asset catalog
SKSpriteNode
(
texture
:
texture
)
// From SKTexture
SKSpriteNode
(
texture
:
texture
,
size
:
size
)
// Custom size
SKSpriteNode
(
color
:
.
red
,
size
:
CGSize
(
width
:
50
,
height
:
50
)
)
// Solid color
// Key properties
sprite
.
anchorPoint
=
CGPoint
(
x
:
0.5
,
y
:
0
)
// Bottom-center
sprite
.
colorBlendFactor
=
0.5
// Tint strength (0-1)
sprite
.
color
=
.
red
// Tint color
sprite
.
normalTexture
=
normalMap
// For lighting
sprite
.
lightingBitMask
=
0x1
// Which lights affect this
sprite
.
shadowCastBitMask
=
0x1
// Which lights cast shadows
sprite
.
shader
=
customShader
// Per-pixel effects
SKLabelNode Properties
let
label
=
SKLabelNode
(
text
:
"Score: 0"
)
label
.
fontName
=
"AvenirNext-Bold"
label
.
fontSize
=
24
label
.
fontColor
=
.
white
label
.
horizontalAlignmentMode
=
.
left
label
.
verticalAlignmentMode
=
.
top
label
.
numberOfLines
=
0
// Multi-line (iOS 11+)
label
.
preferredMaxLayoutWidth
=
200
label
.
lineBreakMode
=
.
byWordWrapping
Part 2: Physics API
SKPhysicsBody Creation
// Volume bodies (have mass, respond to forces)
SKPhysicsBody
(
circleOfRadius
:
20
)
// Cheapest
SKPhysicsBody
(
rectangleOf
:
CGSize
(
width
:
40
,
height
:
60
)
)
SKPhysicsBody
(
polygonFrom
:
path
)
// Convex only
SKPhysicsBody
(
texture
:
texture
,
size
:
size
)
// Pixel-perfect (expensive)
SKPhysicsBody
(
texture
:
texture
,
alphaThreshold
:
0.5
,
size
:
size
)
SKPhysicsBody
(
bodies
:
[
body1
,
body2
]
)
// Compound
// Edge bodies (massless boundaries)
SKPhysicsBody
(
edgeLoopFrom
:
rect
)
// Rectangle boundary
SKPhysicsBody
(
edgeLoopFrom
:
path
)
// Path boundary
SKPhysicsBody
(
edgeFrom
:
pointA
,
to
:
pointB
)
// Single edge
SKPhysicsBody
(
edgeChainFrom
:
path
)
// Open path
Physics Body Properties
// Identity
body
.
categoryBitMask
=
0x1
// What this body IS
body
.
collisionBitMask
=
0x2
// What it bounces off
body
.
contactTestBitMask
=
0x4
// What triggers didBegin/didEnd
// Physical characteristics
body
.
mass
=
1.0
// kg
body
.
density
=
1.0
// kg/m^2 (auto-calculates mass)
body
.
friction
=
0.2
// 0.0 (ice) to 1.0 (rubber)
body
.
restitution
=
0.3
// 0.0 (no bounce) to 1.0 (perfect bounce)
body
.
linearDamping
=
0.1
// Air resistance (0 = none)
body
.
angularDamping
=
0.1
// Rotational damping
// Behavior
body
.
isDynamic
=
true
// Responds to forces
body
.
affectedByGravity
=
true
// Subject to world gravity
body
.
allowsRotation
=
true
// Can rotate from physics
body
.
pinned
=
false
// Pinned to parent position
body
.
usesPreciseCollisionDetection
=
false
// For fast objects
// Motion (read/write)
body
.
velocity
=
CGVector
(
dx
:
100
,
dy
:
0
)
body
.
angularVelocity
=
0.0
// Force application
body
.
applyForce
(
CGVector
(
dx
:
0
,
dy
:
100
)
)
// Continuous
body
.
applyImpulse
(
CGVector
(
dx
:
0
,
dy
:
50
)
)
// Instant
body
.
applyTorque
(
0.5
)
// Continuous rotation
body
.
applyAngularImpulse
(
1.0
)
// Instant rotation
body
.
applyForce
(
CGVector
(
dx
:
10
,
dy
:
0
)
,
at
:
point
)
// Force at point
SKPhysicsWorld
scene
.
physicsWorld
.
gravity
=
CGVector
(
dx
:
0
,
dy
:
-
9.8
)
scene
.
physicsWorld
.
speed
=
1.0
// 0 = paused, 2 = double speed
scene
.
physicsWorld
.
contactDelegate
=
self
// Ray casting
let
body
=
scene
.
physicsWorld
.
body
(
at
:
point
)
let
bodyInRect
=
scene
.
physicsWorld
.
body
(
in
:
rect
)
scene
.
physicsWorld
.
enumerateBodies
(
alongRayStart
:
start
,
end
:
end
)
{
body
,
point
,
normal
,
stop
in
// Process each body the ray intersects
}
Physics Joints
// Pin joint (pivot)
let
pin
=
SKPhysicsJointPin
.
joint
(
withBodyA
:
bodyA
,
bodyB
:
bodyB
,
anchor
:
anchorPoint
)
// Fixed joint (rigid connection)
let
fixed
=
SKPhysicsJointFixed
.
joint
(
withBodyA
:
bodyA
,
bodyB
:
bodyB
,
anchor
:
anchorPoint
)
// Spring joint
let
spring
=
SKPhysicsJointSpring
.
joint
(
withBodyA
:
bodyA
,
bodyB
:
bodyB
,
anchorA
:
pointA
,
anchorB
:
pointB
)
spring
.
frequency
=
1.0
// Oscillations per second
spring
.
damping
=
0.5
// 0 = no damping
// Sliding joint (linear constraint)
let
slide
=
SKPhysicsJointSliding
.
joint
(
withBodyA
:
bodyA
,
bodyB
:
bodyB
,
anchor
:
point
,
axis
:
CGVector
(
dx
:
1
,
dy
:
0
)
)
// Limit joint (distance constraint)
let
limit
=
SKPhysicsJointLimit
.
joint
(
withBodyA
:
bodyA
,
bodyB
:
bodyB
,
anchorA
:
pointA
,
anchorB
:
pointB
)
// Add joint to world
scene
.
physicsWorld
.
add
(
joint
)
// Remove: scene.physicsWorld.remove(joint)
Physics Fields
// Gravity (directional)
let
gravity
=
SKFieldNode
.
linearGravityField
(
withVector
:
vector_float3
(
0
,
-
9.8
,
0
)
)
// Radial gravity (toward/away from point)
let
radial
=
SKFieldNode
.
radialGravityField
(
)
radial
.
strength
=
5.0
// Electric field (charge-dependent)
let
electric
=
SKFieldNode
.
electricField
(
)
// Noise field (turbulence)
let
noise
=
SKFieldNode
.
noiseField
(
withSmoothness
:
0.5
,
animationSpeed
:
1.0
)
// Vortex
let
vortex
=
SKFieldNode
.
vortexField
(
)
// Drag
let
drag
=
SKFieldNode
.
dragField
(
)
// All fields share:
field
.
region
=
SKRegion
(
radius
:
100
)
// Area of effect
field
.
strength
=
1.0
// Intensity
field
.
falloff
=
0.0
// Distance falloff
field
.
minimumRadius
=
10
// Inner dead zone
field
.
isEnabled
=
true
field
.
categoryBitMask
=
0xFFFFFFFF
// Which bodies affected
Part 3: Action Catalog
Movement
SKAction
.
move
(
to
:
point
,
duration
:
1.0
)
SKAction
.
move
(
by
:
CGVector
(
dx
:
100
,
dy
:
0
)
,
duration
:
0.5
)
SKAction
.
moveTo
(
x
:
200
,
duration
:
1.0
)
SKAction
.
moveTo
(
y
:
300
,
duration
:
1.0
)
SKAction
.
moveBy
(
x
:
50
,
y
:
0
,
duration
:
0.5
)
SKAction
.
follow
(
path
,
asOffset
:
true
,
orientToPath
:
true
,
duration
:
2.0
)
Rotation
SKAction
.
rotate
(
byAngle
:
.
pi
,
duration
:
1.0
)
// Relative
SKAction
.
rotate
(
toAngle
:
.
pi
/
2
,
duration
:
0.5
)
// Absolute
SKAction
.
rotate
(
toAngle
:
angle
,
duration
:
0.5
,
shortestUnitArc
:
true
)
Scaling
SKAction
.
scale
(
to
:
2.0
,
duration
:
0.5
)
SKAction
.
scale
(
by
:
1.5
,
duration
:
0.3
)
SKAction
.
scaleX
(
to
:
2.0
,
y
:
1.0
,
duration
:
0.5
)
SKAction
.
resize
(
toWidth
:
100
,
height
:
50
,
duration
:
0.5
)
Fading
SKAction
.
fadeIn
(
withDuration
:
0.5
)
SKAction
.
fadeOut
(
withDuration
:
0.5
)
SKAction
.
fadeAlpha
(
to
:
0.5
,
duration
:
0.3
)
SKAction
.
fadeAlpha
(
by
:
-
0.2
,
duration
:
0.3
)
Composition
SKAction
.
sequence
(
[
action1
,
action2
,
action3
]
)
// Sequential
SKAction
.
group
(
[
action1
,
action2
]
)
// Parallel
SKAction
.
repeat
(
action
,
count
:
5
)
// Finite repeat
SKAction
.
repeatForever
(
action
)
// Infinite
action
.
reversed
(
)
// Reverse
SKAction
.
wait
(
forDuration
:
1.0
)
// Delay
SKAction
.
wait
(
forDuration
:
1.0
,
withRange
:
0.5
)
// Random delay
Texture & Color
SKAction
.
setTexture
(
texture
)
SKAction
.
setTexture
(
texture
,
resize
:
true
)
SKAction
.
animate
(
with
:
[
tex1
,
tex2
,
tex3
]
,
timePerFrame
:
0.1
)
SKAction
.
animate
(
with
:
textures
,
timePerFrame
:
0.1
,
resize
:
false
,
restore
:
true
)
SKAction
.
colorize
(
with
:
.
red
,
colorBlendFactor
:
1.0
,
duration
:
0.5
)
SKAction
.
colorize
(
withColorBlendFactor
:
0
,
duration
:
0.5
)
Sound
SKAction
.
playSoundFileNamed
(
"explosion.wav"
,
waitForCompletion
:
false
)
Node Tree
SKAction
.
removeFromParent
(
)
SKAction
.
run
(
block
)
SKAction
.
run
(
block
,
queue
:
.
main
)
SKAction
.
customAction
(
withDuration
:
1.0
)
{
node
,
elapsed
in
// Custom per-frame logic
}
Physics
SKAction
.
applyForce
(
CGVector
(
dx
:
0
,
dy
:
100
)
,
duration
:
0.5
)
SKAction
.
applyImpulse
(
CGVector
(
dx
:
50
,
dy
:
0
)
,
duration
:
1.0
/
60.0
)
// ~1 frame
SKAction
.
applyTorque
(
0.5
,
duration
:
1.0
)
SKAction
.
changeCharge
(
to
:
1.0
,
duration
:
0.5
)
SKAction
.
changeMass
(
to
:
2.0
,
duration
:
0.5
)
Timing Modes
action
.
timingMode
=
.
linear
// Constant speed
action
.
timingMode
=
.
easeIn
// Slow → fast
action
.
timingMode
=
.
easeOut
// Fast → slow
action
.
timingMode
=
.
easeInEaseOut
// Slow → fast → slow
action
.
speed
=
2.0
// 2x speed
Part 4: Textures and Atlases
SKTexture
// From image
let
tex
=
SKTexture
(
imageNamed
:
"player"
)
// From atlas
let
atlas
=
SKTextureAtlas
(
named
:
"Characters"
)
let
tex
=
atlas
.
textureNamed
(
"player_run_1"
)
// Subrectangle (for manual sprite sheets)
let
sub
=
SKTexture
(
rect
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
0.25
,
height
:
0.5
)
,
in
:
sheetTexture
)
// From CGImage
let
tex
=
SKTexture
(
cgImage
:
cgImage
)
// Filtering
tex
.
filteringMode
=
.
nearest
// Pixel art (no smoothing)
tex
.
filteringMode
=
.
linear
// Smooth scaling (default)
// Preload
SKTexture
.
preload
(
[
tex1
,
tex2
]
)
{
/ Ready /
}
SKTextureAtlas
// Create in Xcode: Assets.xcassets → New Sprite Atlas
// Or .atlas folder in project bundle
let
atlas
=
SKTextureAtlas
(
named
:
"Characters"
)
let
textureNames
=
atlas
.
textureNames
// All texture names in atlas
// Preload entire atlas
atlas
.
preload
{
/ Atlas ready /
}
// Preload multiple atlases
SKTextureAtlas
.
preloadTextureAtlases
(
[
atlas1
,
atlas2
]
)
{
/ All ready /
}
// Animation from atlas
let
frames
=
(
1
...
8
)
.
map
{
atlas
.
textureNamed
(
"run_
(
$0
)
"
)
}
let
animate
=
SKAction
.
animate
(
with
:
frames
,
timePerFrame
:
0.1
)
Part 5: Constraints
// Orient toward another node
let
orient
=
SKConstraint
.
orient
(
to
:
targetNode
,
offset
:
SKRange
(
constantValue
:
0
)
)
// Orient toward a point
let
orient
=
SKConstraint
.
orient
(
to
:
point
,
offset
:
SKRange
(
constantValue
:
0
)
)
// Position constraint (keep X in range)
let
xRange
=
SKConstraint
.
positionX
(
SKRange
(
lowerLimit
:
0
,
upperLimit
:
400
)
)
// Position constraint (keep Y in range)
let
yRange
=
SKConstraint
.
positionY
(
SKRange
(
lowerLimit
:
50
,
upperLimit
:
750
)
)
// Distance constraint (stay within range of node)
let
dist
=
SKConstraint
.
distance
(
SKRange
(
lowerLimit
:
50
,
upperLimit
:
200
)
,
to
:
targetNode
)
// Rotation constraint
let
rot
=
SKConstraint
.
zRotation
(
SKRange
(
lowerLimit
:
-
.
pi
/
4
,
upperLimit
:
.
pi
/
4
)
)
// Apply constraints (processed in order)
node
.
constraints
=
[
orient
,
xRange
,
yRange
]
// Toggle
node
.
constraints
?
.
first
?
.
isEnabled
=
false
SKRange
SKRange
(
constantValue
:
100
)
// Exactly 100
SKRange
(
lowerLimit
:
50
,
upperLimit
:
200
)
// 50...200
SKRange
(
lowerLimit
:
0
)
// >= 0
SKRange
(
upperLimit
:
500
)
// <= 500
SKRange
(
value
:
100
,
variance
:
20
)
// 80...120
Part 6: Scene Setup
SKView Configuration
let
skView
=
SKView
(
frame
:
view
.
bounds
)
// Debug overlays
skView
.
showsFPS
=
true
skView
.
showsNodeCount
=
true
skView
.
showsDrawCount
=
true
skView
.
showsPhysics
=
true
skView
.
showsFields
=
true
skView
.
showsQuadCount
=
true
// Performance
skView
.
ignoresSiblingOrder
=
true
// Enables batching optimizations
skView
.
shouldCullNonVisibleNodes
=
true
// Auto-hide offscreen (manual is faster)
skView
.
isAsynchronous
=
true
// Default: renders asynchronously
skView
.
allowsTransparency
=
false
// Opaque is faster
// Frame rate
skView
.
preferredFramesPerSecond
=
60
// Or 120 for ProMotion
// Present scene
skView
.
presentScene
(
scene
)
skView
.
presentScene
(
scene
,
transition
:
.
fade
(
withDuration
:
0.5
)
)
Scale Mode Matrix
Mode
Aspect Ratio
Content
Best For
.aspectFill
Preserved
Fills view, crops edges
Most games
.aspectFit
Preserved
Fits in view, letterboxes
Exact layout needed
.resizeFill
Distorted
Stretches to fill
Almost never
.fill
Varies
Scene resizes to match view
Adaptive scenes
SKTransition Types
SKTransition
.
fade
(
withDuration
:
0.5
)
SKTransition
.
fade
(
with
:
.
black
,
duration
:
0.5
)
SKTransition
.
crossFade
(
withDuration
:
0.5
)
SKTransition
.
flipHorizontal
(
withDuration
:
0.5
)
SKTransition
.
flipVertical
(
withDuration
:
0.5
)
SKTransition
.
reveal
(
with
:
.
left
,
duration
:
0.5
)
SKTransition
.
moveIn
(
with
:
.
right
,
duration
:
0.5
)
SKTransition
.
push
(
with
:
.
up
,
duration
:
0.5
)
SKTransition
.
doorway
(
withDuration
:
0.5
)
SKTransition
.
doorsOpenHorizontal
(
withDuration
:
0.5
)
SKTransition
.
doorsOpenVertical
(
withDuration
:
0.5
)
SKTransition
.
doorsCloseHorizontal
(
withDuration
:
0.5
)
SKTransition
.
doorsCloseVertical
(
withDuration
:
0.5
)
// Custom with CIFilter:
SKTransition
(
ciFilter
:
filter
,
duration
:
0.5
)
Part 7: Particles
SKEmitterNode Key Properties
let
emitter
=
SKEmitterNode
(
fileNamed
:
"Spark"
)
!
// Emission control
emitter
.
particleBirthRate
=
100
// Particles per second
emitter
.
numParticlesToEmit
=
0
// 0 = infinite
emitter
.
particleLifetime
=
2.0
// Seconds
emitter
.
particleLifetimeRange
=
0.5
// ± random
// Position
emitter
.
particlePosition
=
.
zero
emitter
.
particlePositionRange
=
CGVector
(
dx
:
10
,
dy
:
10
)
// Movement
emitter
.
emissionAngle
=
.
pi
/
2
// Direction (radians)
emitter
.
emissionAngleRange
=
.
pi
/
4
// Spread
emitter
.
particleSpeed
=
100
// Points per second
emitter
.
particleSpeedRange
=
50
// ± random
emitter
.
xAcceleration
=
0
emitter
.
yAcceleration
=
-
100
// Gravity-like
// Appearance
emitter
.
particleTexture
=
SKTexture
(
imageNamed
:
"spark"
)
emitter
.
particleSize
=
CGSize
(
width
:
8
,
height
:
8
)
emitter
.
particleColor
=
.
white
emitter
.
particleColorAlphaSpeed
=
-
0.5
// Fade out
emitter
.
particleBlendMode
=
.
add
// Additive for fire/glow
emitter
.
particleAlpha
=
1.0
emitter
.
particleAlphaSpeed
=
-
0.5
// Scale
emitter
.
particleScale
=
1.0
emitter
.
particleScaleRange
=
0.5
emitter
.
particleScaleSpeed
=
-
0.3
// Shrink over time
// Rotation
emitter
.
particleRotation
=
0
emitter
.
particleRotationSpeed
=
2.0
// Target node (for trails)
emitter
.
targetNode
=
scene
// Particles stay in world space
// Render order
emitter
.
particleRenderOrder
=
.
dontCare
// .oldestFirst, .oldestLast, .dontCare
// Physics field interaction
emitter
.
fieldBitMask
=
0x1
Common Particle Presets
Effect
Key Settings
Fire
blendMode: .add
, fast
alphaSpeed
, orange→red color, upward speed
Smoke
blendMode: .alpha
, slow speed, gray color, scale up over time
Sparks
blendMode: .add
, high speed + range, short lifetime, small size
Rain
Downward
emissionAngle
, narrow range, long lifetime, thin texture
Snow
Slow downward speed, wide position range, slight x acceleration
Trail
Set
targetNode
to scene, narrow emission angle, medium lifetime
Explosion
High birth rate, short
numParticlesToEmit
, high speed range
Part 8: SKRenderer and Shaders
SKRenderer (Metal Integration)
import
MetalKit
let
device
=
MTLCreateSystemDefaultDevice
(
)
!
let
renderer
=
SKRenderer
(
device
:
device
)
renderer
.
scene
=
gameScene
renderer
.
ignoresSiblingOrder
=
true
// In Metal render loop:
func
draw
(
in
view
:
MTKView
)
{
guard
let
commandBuffer
=
commandQueue
.
makeCommandBuffer
(
)
,
let
rpd
=
view
.
currentRenderPassDescriptor
else
{
return
}
renderer
.
update
(
atTime
:
CACurrentMediaTime
(
)
)
renderer
.
render
(
withViewport
:
CGRect
(
origin
:
.
zero
,
size
:
view
.
drawableSize
)
,
commandBuffer
:
commandBuffer
,
renderPassDescriptor
:
rpd
)
commandBuffer
.
present
(
view
.
currentDrawable
!
)
commandBuffer
.
commit
(
)
}
SKShader (Custom GLSL ES Effects)
// Fragment shader for per-pixel effects
let
shader
=
SKShader
(
source
:
"""
void main() {
vec4 color = texture2D(u_texture, v_tex_coord);
// Desaturate
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(vec3(gray), color.a) * v_color_mix.a;
}
"""
)
sprite
.
shader
=
shader
// With uniforms
let
shader
=
SKShader
(
source
:
"""
void main() {
vec4 color = texture2D(u_texture, v_tex_coord);
color.rgb *= u_intensity;
gl_FragColor = color;
}
"""
)
shader
.
uniforms
=
[
SKUniform
(
name
:
"u_intensity"
,
float
:
0.8
)
]
// Built-in uniforms:
// u_texture — sprite texture
// u_time — elapsed time
// u_path_length — shape node path length
// v_tex_coord — texture coordinate
// v_color_mix — color/alpha mix
// SKAttribute for per-node values
Part 7: SwiftUI Integration
SpriteView
import
SpriteKit
import
SwiftUI
// Basic embedding
struct
GameView
:
View
{
var
body
:
some
View
{
SpriteView
(
scene
:
makeScene
(
)
)
.
ignoresSafeArea
(
)
}
func
makeScene
(
)
->
SKScene
{
let
scene
=
GameScene
(
size
:
CGSize
(
width
:
1024
,
height
:
768
)
)
scene
.
scaleMode
=
.
aspectFill
return
scene
}
}
// With options
SpriteView
(
scene
:
scene
,
transition
:
.
fade
(
withDuration
:
0.5
)
,
// Scene transition
isPaused
:
false
,
// Pause control
preferredFramesPerSecond
:
60
,
// Frame rate
options
:
[
.
ignoresSiblingOrder
,
.
shouldCullNonVisibleNodes
]
,
debugOptions
:
[
.
showsFPS
,
.
showsNodeCount
]
// Debug overlays
)
SpriteView Options
Option
Purpose
.ignoresSiblingOrder
Enable draw order batching optimization
.shouldCullNonVisibleNodes
Auto-hide offscreen nodes
.allowsTransparency
Allow transparent background (slower)
Debug Options
Option
Shows
.showsFPS
Frames per second
.showsNodeCount
Total visible nodes
.showsDrawCount
Draw calls per frame
.showsPhysics
Physics body outlines
.showsFields
Physics field regions
.showsQuadCount
Quad subdivisions
Communicating Between SwiftUI and SpriteKit
// Observable model shared between SwiftUI and scene
@Observable
class
GameState
{
var
score
=
0
var
isPaused
=
false
var
lives
=
3
}
// Scene reads/writes the shared model
class
GameScene
:
SKScene
{
var
gameState
:
GameState
?
override
func
update
(
_
currentTime
:
TimeInterval
)
{
guard
let
state
=
gameState
,
!
state
.
isPaused
else
{
return
}
// Game logic updates state.score, state.lives, etc.
}
}
// SwiftUI view owns the model
struct
GameContainerView
:
View
{
@State
private
var
gameState
=
GameState
(
)
@State
private
var
scene
:
GameScene
=
{
let
s
=
GameScene
(
size
:
CGSize
(
width
:
1024
,
height
:
768
)
)
s
.
scaleMode
=
.
aspectFill
return
s
}
(
)
var
body
:
some
View
{
VStack
{
Text
(
"Score:
(
gameState
.
score
)
"
)
SpriteView
(
scene
:
scene
,
isPaused
:
gameState
.
isPaused
)
.
ignoresSafeArea
(
)
}
.
onAppear
{
scene
.
gameState
=
gameState
}
}
}
Key pattern
Use
@Observable
model as bridge. Scene mutates it; SwiftUI observes changes. Avoid recreating scenes in view body — use
@State
to persist the scene instance.
Resources
WWDC
2014-608, 2016-610, 2017-609
Docs
/spritekit/skspritenode, /spritekit/skphysicsbody, /spritekit/skaction, /spritekit/skemitternode, /spritekit/skrenderer
Skills
axiom-spritekit, axiom-spritekit-diag
返回排行榜