Ein SpriteKit-Spiel ohne eine einzige Bild- oder Audiodatei: so haben wir Street Legends gebaut

Street Legends kommt ohne eine einzige Bild- oder Audiodatei aus. Jedes Trikot, jeder Ball, jedes Spielfeld und jeder Pfiff entsteht im Code. So geht es, und deshalb könnten Sie es genauso machen wollen.

Mustafa GüderGründer, GuderTech4 Min. Lesezeit
spritekit-game-without-asset-files.md

Street Legends ist unser schnelles Fünf-gegen-fünf-Straßenfußballspiel für das iPhone, mit einer Liga zum Aufsteigen, einem Kader aus neun Spielern und Trikots zum Freischalten. Öffnen Sie das App-Bundle, finden Sie keine einzige PNG- oder Audiodatei. Jedes Bild und jeder Ton entsteht zur Laufzeit in Swift.

Warum ein Spiel so bauen?

  • Winziger Download: keine Textur-Atlanten oder Soundpakete, die App ist in Sekunden installiert
  • Scharf in jeder Größe: Formen werden für genau diesen Bildschirm gezeichnet, vom kleinsten iPhone bis zum iPad
  • Unendliche Varianten: ein neues Trikot ist ein paar Farben, kein neuer Satz Bilder
  • Schnelles Iterieren: Eine Zahl ändern, und das ganze Spiel aktualisiert sich, ohne Exportschritt

Der Preis: Sie können keiner Illustratorin eine Datei übergeben. Der Ansatz passt zu stilisierter, geometrischer Grafik, genau dem Look, den wir wollten.

Sprites mit Core Graphics zeichnen

Komplexe Formen in jedem Frame mit SKShapeNode zu zeichnen ist teuer. Stattdessen zeichnen wir einmal mit UIGraphicsImageRenderer in ein Bild und machen daraus eine Textur:

import SpriteKit
import UIKit

func ballTexture(diameter: CGFloat) -> SKTexture {
    let size = CGSize(width: diameter, height: diameter)
    let image = UIGraphicsImageRenderer(size: size).image { context in
        let rect = CGRect(origin: .zero, size: size)
        UIColor.white.setFill()
        context.cgContext.fillEllipse(in: rect)

        UIColor.black.setFill()
        let patch = rect.insetBy(dx: diameter * 0.34, dy: diameter * 0.34)
        context.cgContext.fillEllipse(in: patch)
    }
    return SKTexture(image: image)
}

let ball = SKSpriteNode(texture: ballTexture(diameter: 28))

Texturen werden nach ihren Parametern zwischengespeichert, sodass jede einmal gezeichnet und von jedem Node wiederverwendet wird, der sie braucht. Trikots funktionieren genauso: eine Trikotform in den Teamfarben und eine darübergezeichnete Nummer.

Sound mit AVAudioEngine synthetisieren

Soundeffekte sind kurze Wellenformen mit einer Hüllkurve. Mit AVAudioSourceNode schreiben Sie Samples direkt:

import AVFoundation

final class Synth {
    private let engine = AVAudioEngine()
    private var phase = 0.0
    private var frequency = 0.0
    private var amplitude = 0.0

    init() {
        let sampleRate = engine.outputNode.inputFormat(forBus: 0).sampleRate
        let source = AVAudioSourceNode { [unowned self] _, _, frameCount, bufferList -> OSStatus in
            let buffers = UnsafeMutableAudioBufferListPointer(bufferList)
            for frame in 0..<Int(frameCount) {
                let sample = Float(sin(phase) * amplitude)
                phase += 2 * .pi * frequency / sampleRate
                if phase > 2 * .pi { phase -= 2 * .pi }
                amplitude *= 0.9993 // quick decay, like a plucked sound
                for buffer in buffers {
                    buffer.mData?.assumingMemoryBound(to: Float.self)[frame] = sample
                }
            }
            return noErr
        }
        let format = AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: 1)
        engine.attach(source)
        engine.connect(source, to: engine.mainMixerNode, format: format)
        try? engine.start()
    }

    func kick() {
        frequency = 90
        amplitude = 0.7
    }
}

Ein Schuss ist ein tiefer Ton, der schnell abfällt. Ein Pfiff ist ein hoher Ton mit etwas Vibrato. Publikumslärm ist gefiltertes Rauschen, das nach einem Tor anschwillt. Eine Handvoll solcher Generatoren deckt jeden Sound im Spiel ab.

Schnell bleiben

  • Texturen einmal beim Laden zeichnen, nie in update(_:)
  • Nodes für wiederkehrende Effekte wiederverwenden, statt neue zu erzeugen
  • SpriteKit-Physikkörper mit einfachen Formen nutzen, Kreise für Spieler und Ball
  • Auf dem ältesten unterstützten Gerät profilen, nicht auf dem neuesten

Wann prozedurale Grafik die richtige Wahl ist

Sie glänzt bei Arcade-Spielen, Puzzlespielen und stilisierten Welten, in denen Geometrie die Ästhetik ist. Für malerische oder figurenlastige Grafik sind eine Künstlerin und ein Textur-Atlas weiterhin das bessere Werkzeug; unser Match-3-Spiel Paw & Home ist ein gutes Beispiel für diese Seite.

Sie möchten ein Spiel entwickeln lassen? Erzählen Sie uns davon. Wir entwickeln mit SpriteKit, SceneKit und Unity.

Häufige Fragen

Ist SpriteKit 2026 noch eine gute Wahl für iOS-Spiele?

Ja, für 2D-Spiele auf Apple-Plattformen. Es ist leicht, nativ und gut mit Game Center und StoreKit integriert. Für Cross-Platform- oder 3D-lastige Spiele passt meist Unity besser.

Klingt prozedurales Audio schlechter als aufgenommenes?

Bei kurzen Effekten wie Schüssen, Klicks und Pfiffen kann es großartig klingen und bleibt winzig. Für Musik und Stimmen sind Aufnahmen weiterhin die bessere Wahl.

Verlangsamt das Erzeugen von Texturen den App-Start?

Nur wenn Sie sie in jedem Frame zeichnen. Einmal beim Start gezeichnet und zwischengespeichert, brauchen einfache Texturen Millisekunden.

Wie klein kann ein SpriteKit-Spiel sein?

Ohne Bild- und Audiodateien kann ein vollständiges Spiel nur wenige Megabyte groß sein, das meiste davon kompilierter Code.

TeilenXLinkedInWhatsApp
Mustafa Güder

Über den Autor

Mustafa Güder

Mustafa Güder ist Gründer von GuderTech und iOS-Entwickler. Nach zwei Jahren Studium in Australien kehrte er nach Adana zurück und entwickelte Scevia, Paw & Home und Street Legends.

Studium in Australien, 2 Jahre Adana, Türkei

Alle Artikel