Swift für Kinder, Teil I

Meine beiden Kinder, aktuell 9 und 11 Jahre alt, sind wie die meisten ihrer Altersgenossen vernarrt in Smartphone-Spiele. Sie haben gesehen, dass ihr Vater Spiele programmiert, und wollen das nun auch können. Nicht irgendwelche Spiele, die auf einem Computer laufen, nein — es müssen Smartphone-Apps sein.

Update 21.10.2016: ZIP-Code-Archiv aktualisiert für Swift 3 final.

(Als ich vor mehr als 30 Jahren zu programmieren begann, habe ich eine Art PacMan im Textmodus programmiert. In der Programmiersprache Basic auf einem Oric-1, einem Computer mit Ähnlichkeiten zum bekannteren Commodore 64. Da war die Welt noch einfacher, nicht nur, was das Programmieren betrifft …)

Also habe ich mich dazu entschlossen, meinen Kindern, so spielerisch wie möglich, ein bisschen das Programmieren beizubringen. Diese Versuche werde ich hier in diesem Blog dokumentieren.

Intro (die können Sie überspringen …)

Allen, die schon einmal Apps programmiert haben, ist klar: Zwischen der Erwartungshaltung meiner Kinder (»Ist ja ganz einfach!«) und der Wirklichkeit klaffen Welten, ja Galaxien!

  • Die Probleme beginnen damit, dass meine beiden Söhne mit der Tastatur kaum vertraut sind. Näherungsweise dauert die Eingabe einer Code-Zeile mit den vielen Sonderzeichen eine Minute.
  • Die nächste Hürde ist die englische Sprache. Egal, welche Programmiersprache — alle Schlüsselwörter sind englisch. Die Englisch-Kenntnisse meiner Kinder sind aber noch sehr bescheiden.
  • Kommen wir zum Programmieren an sich: Wo anfangen? Das Vorwissen ist 0, und 0 heisst in diesem Fall wirklich 0. Mein älterer Sohn hat in der Schule immerhin schon einfache Gleichungen gesehen (2 x + 12 = 30) und hat insofern vielleicht den Ansatz einer Idee, was eine Variable sein könnte. In Basic konnte man damit loslegen, aber in Java oder C# oder Swift kann man ja keine Zeile schreiben, ohne sich die Konzepte objektorientierter Programmierung zu verinnerlichen.
  • Schließlich kann man heutzutage ohne Entwicklungsumgebung fast nicht mehr arbeiten. Eclipse, Visual Studio, Xcode — für Kinder als Zielpublikum ist das die Wahl zwischen Pest und Cholera. (Meine Python-, bash- und PHP-Scripts, mitunter auch Java-Code, schreibe ich bis heute am liebsten im Emacs. Aber auch dieses Ungetüm ist hier wohl kaum perfekte Wahl …)

Die naheliegende Lösung wäre, eben gerade nicht den klassischen Weg zu beschreiten, sondern mit Logo zu beginnen, oder eventuell mit Python. Diese Sprachen wären in ihren Grundelementen Kids-tauglich, nur können wir dann eben keine Apps programmieren. Scheidet daher vollkommen aus, sorry.

Plan B wäre eine Entwicklungsumgebung speziell zur Spiel-Programmierung, idealerweise für den Unterricht optimiert. Bekannt aus der Raspberry-Pi-Ecke war mir Scratch; der aus meiner Sicht übertrieben kindliche Ansatz hat mich aber gar nicht überzeugt.

Dann bin ich auf GameMaker gestoßen: Das ist eine relativ professionelle IDE zur Spieleentwicklung. Die Basisversion ist kostenlos verfügbar, die Handhabung ist überschaubar. Ich habe mir zwei, drei Stunden lang Videos angesehen: Die Mischung aus interaktivem Zusammenklicken von Funktionen kombiniert da und dort mit wenigen Zeilen sehr einfachem Code — das macht eigentlich einen perfekten Eindruck!

Letztlich haben mich aber zwei Dinge von GameMaker abgehalten:

  • Zum einen ist die IDE an sich zwar kostenlos verfügbar, für die Entwicklung von Apps ist aber das kostenpflichtige »Studio Professional« plus zumindest ein »Export Module« (sprich Plugin) erforderlich.
  • Zum anderen kann man nur unterrichten, was man selbst beherrscht. Ich hätte mir die Mühe machen müssen, GameMaker ein, zwei Wochen lang zu erlernen. Sicher interessant, aber ich habe diese ein, zwei Wochen einfach nicht.

Und so kam es, wie es kommen musste: Meine Unterrichtsbasis besteht aus Xcode 8 mit Swift 3 (erste Beta) in Kombination mit SpriteKit! Ich arbeite momentan intensiv an der Neuauflage meines Swift-Buchs, die hoffentlich noch heuer erscheinen wird. Was liegt also näher, Swift 3 und Xcode 8 zu verwenden?

Es ist nicht notwendig, dass Sie Ihre naheliegenden Einwände hier als Kommentar posten, ich weiß selbst, dass es Wahnsinn ist. Wie auch immer: Wir legen los!

Wie starten?

Die Grundidee für mein Unterrichts-Experiment sieht so aus: Ich gebe ein bereits funktionsfähiges Projekt vor. Gemeinsam mit meinen Kindern führe ich dann kleine Änderungen durch und erkläre dabei einzelne Details. Ein ganzheitlicher Ansatz also, Verzicht auf ein solides Fundament, stattdessen »Learning by Doing«.

Der Ausgangspunkt für die ersten gemeinsamen Übungen ist ein minimales SpriteKit-Programm, das das aus Apples SpriteKit-Templates bekannte Raumschiff im Weltall platziert.

Der Ausgangspunkt: Ein Raumschiff, unbeweglich im Weltall
Der Ausgangspunkt: Ein Raumschiff, unbeweglich im Weltall

Mit meinen Kindern habe ich nun ausschließlich die didMove-Methode bearbeitet, die anfänglich so aussah:

override func didMove(to view: SKView) {
  // nicht ändern
  setup(view)

  // hier geht's los
  let spaceship = SKSpriteNode(imageNamed: "Spaceship")
  spaceship.position = CGPoint(x:1000, y: 700)
  spaceship.zRotation = winkel(0)
  spaceship.zPosition = 1
  self.addChild(spaceship)
}

Diese Menge Code ist auch für Kinder verdaulich:

  • setup kümmert sich um das Weltall, die Details interessieren uns nicht.
  • let spaceship = SKSpriteNode(imageNamed: "Spaceship") erzeugt ein Raumschiff(-Objekt) und speichert es in einer Variablen.
  • Die nächsten drei Anweisungen verändern Eigenschaften des Raumschiffs.
  • Die letzte Zeile macht das Raumschiff sichtbar, fügt es zum Weltall hinzu.

Erste Einheit

Und jetzt die Aufgaben für die ersten Stunde:

  • Versucht, das Raumschiff in einer Ecke zu platzieren!
  • Versucht, das Raumschiff zu drehen!
  • Versucht, ein zweites Raumschiff zu erzeugen!

Für die erste Fragestellung habe ich das Koordinatensystem erläutern müssen, siehe die folgende Skizze. Außerdem habe ich dazu gesagt, dass Bilder (Sprites) immer über ihren Mittelpunkt positioniert werden.

Koordinatensystem für das Beispielprogramm
Koordinatensystem für das Beispielprogramm

Das Platzieren der Raumschiffs, zuerst links unten, dann rechts oben, gelang nach der Methode »Versuch und Irrtum« recht schnell.

Die zweite Fragestellung konnten meine Kinder ohne Hilfe bewältigen, Winkel in Grad sind ihnen vertraut.

Bei der dritten Fragestellung habe ich mitgeholfen: Code kopieren und einfügen, im neuen Code Variablennamen von spaceship auf spaceship2 ändern, und ein bisschen über den Sinn von Variablen erklären.

Meinem älteren Sohn gelang es dann selbstständig, ein drittes Raumschiff auf den Bildschirm zu zaubern. Bravo!

Natürlich musste ich beiden immer wieder helfen, nach Tippfehlern die unverständlichen Xcode-Fehler zu beseitigen.

Zweite Einheit

Ausgangspunkt war das Programm vom Vorabend, mit zwei Raumschiffen. Ich habe die folgenden neuen Eigenschaften erläutert und dazu ein paar Zeilen Code eingetippt.

  • color: Farbe einstellen
  • colorBlendFactor: wie weit ist die Farbe aktiv
  • xScale: Breite verändern
  • yScale: Höhe verändern

Meine Kinder haben dann eine halbe Stunde damit verbracht, das Aussehen der Raumschiffe zu verändern. Ergebnis:

Bunte, verdrehte Raumschiffe
Bunte, verdrehte Raumschiffe

Ich glaube, dass sie die Idee von Objekten und Eigenschaften schon ein wenig verstehen (ohne, dass ich viel dazu sagen musste).

Auch wenn es anfänglich cool ist, Code zu ändern und dann ein optischen Feedback am Bildschirm zu sehen, auf die Dauer reicht das nicht. Es muss sich etwas bewegen. An dieser Stelle habe ich den Code ein wenig umgebaut, anfänglich so:

class GameScene: SKScene {
  ...
  let spaceship = SKSpriteNode(imageNamed: "Spaceship")
  var meinWinkel = 0

  override func didMove(to view: SKView) {
    // nicht ändern
    setup(view)

    // wie bisher: spaceship-Eigenschaften einstellen
    // ...
  }

  // neu: bei jedem Frame Winkel ändern
  override func update(_ currentTime: TimeInterval) {
    meinWinkel = meinWinkel + 5
    spaceship.zRotation = winkel(meinWinkel)
  }

  ...
}

Wird das Programm jetzt ausgeführt, dreht sich das Raumschiff! Den Unterschied zwischen didMove und update habe ich so erklärt: didMove wird nur einmal beim Start ausgeführt. update wird immer wieder ausgeführt, wenn ich hier etwas ändere, ändert sich das Raumschiff im laufenden Programm.

An dieser Stelle sind erstmals Verständnisproblem aufgetaucht. Warum muss die spaceship-Variable jetzt außerhalb von didMove platziert werden? (Hätte ich wahrscheinlich von vorne herein machen sollen.) Was soll das mit let und var?

Meine nächste Aufgabe war: Versucht, das Raumschiff nicht nur zu drehen, sondern auch zu verschieben!

Bei der Lösung habe ich kräftig mithelfen müssen, aber als der Code einmal dastand, haben die Kinder schon wieder begonnen, eigene Änderungen einzubauen (z.B. das Raumschiff nicht diagonal zu verschieben, das Raumschiff so zu drehen, dass es in Bewegungsrichtung zeigt etc.).

var meinX = 0
var meinY = 0

...

override func update(_ currentTime: TimeInterval) {
  meinWinkel = meinWinkel + 5
  spaceship.zRotation = winkel(meinWinkel)

  meinX = meinX + 10
  meinY = meinY + 10
  spaceship.position = CGPoint(x: meinX, y: meinY)
}

Hintergründe

setup richtet nicht nur den Weltall-Hintergrund ein, sondern auch die Größe des SKView-Objekts. Dessen Breite wird unveränderlich mit 2000 festgelegt. Die Höhe ergibt sich je nach iOS-Gerät. Auf einem iPad-Simulator ergibt sich 1500, auf iPhones etwas weniger.

winkel rechnet von Grad in Bogenmaß um. (Sonst muss ich erklären, was Pi ist, und warum Pi/2 soviel wie 90 Grad ist.)

Wie ist es gelaufen?

Wir haben nun zwei Abende jeweils eine Stunde herumgespielt. Bis jetzt ist die Begeisterung meiner Kinder groß, außerdem haben sie das Gefühl, dass sie schon programmieren können. Stimmt ja auch!

PS: Warum keine Playgrounds?

Zusammen mit Swift hat Apple die Idee von Playgrounds realisiert. Das sind spezielle Xcode-Projekte, die ein interaktives Ausprobieren von kleinen Code-Schnipseln ermöglichen — eigentlich perfekt für meine Zwecke!

So gut das Konzept von Playgrounds ist — die aktuelle Implementierung ist aus meiner Sicht unbrauchbar. Ich habe ein wenig experimentiert, um zumindest einfache SpriteKit-Spielereien damit zu realisieren, aber ich bin gescheitert — sowohl unter Xcode 7.3 als auch unter Xcode 8. Auch die neue Playground-App für iPads hat mich nicht vom Gegenteil überzeugen können.

Ich sehe das riesige Potential der Playgrounds für Unterricht und Lehre, Apple arbeitet ganz offensichtlich in diese Richtung, aber der aktuelle Zustand ist selbst für meine Begriffe ein bisschen zu »beta«.

Wenn Sie Playgrounds doch eine Chance geben wollen, verweise ich Sie auf die ultimative Playground-Expertin Erica Sadun: Auf ihrem Blog finden Sie eine Menge Playground-Beiträge (auch zur neuen Playground-App), im iTunes Bookstore gibt es das von ihr verfasste eBook Playground Secrets and Power Tips. Empfehlenswert!

Download

Die ZIP-Datei enthält die Raumschiff-App in vier verschiedenen Stadien. Die Dateien sind jetzt (ab 21.10.2016) aktuell zu Swift 3 / Xcode 8.

ZIP-Datei

3 Gedanken zu „Swift für Kinder, Teil I“

  1. Finde es großartig, dass sie sich für Swift entschieden haben.
    Ihre Kinder sind sicher voller Stolz danach gewesen.
    Hat mir viel Freude gemacht ihre Lehrstunde zu lesen.
    Vielen Dank für die Einblicke. :)

  2. Meine Kinder wollen ebenfalls Apps für ihre Applegeräte programmieren. Bei Kickstarter fand ich „Tickle“ https://tickleapp.com/ , ähnlich wie Scratch, hier kann das aus Bausteinen zusammengeklickte Programm auch als Swiftcode betrachtet werden. Bin gespannt ob es funktioniert.

  3. „(Als ich vor mehr als 30 Jahren zu programmieren begann, habe ich eine Art PacMan im Textmodus programmiert. In der Programmiersprache Basic auf einem Oric-1, einem Computer mit Ähnlichkeiten zum bekannteren Commodore 64. Da war die Welt noch einfacher, nicht nur, was das Programmieren betrifft …)“

    Ja, bei dem Kommentar musste ich auch grinsen.
    Zu Atari (ST/TT) Zeiten hat mir Programmieren auch noch Spaß gemacht. Da war das alles noch „einfach“ mit Assembler/C/Pascal/Modula-2, aber heute… nichts mehr für mich. Ich habe mich da ganz auf die Administration, etc. pp., verlegt. Damals war ich noch mit SPC Modula-2 involviert (Reset-Resist RamDisk… in Assembler geschrieben, etc. pp.). Da konnte man so etwas noch einfach in Assembler machen.

    Aber ich finde es schön, wenn sich Kinder schon für so etwas interessieren und es auch einfach Möglichkeiten für sie gibt. Schöner Artikel!

Kommentare sind geschlossen.