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.

(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. Achtung, getestet nur unter Xcode 8 Beta 1.

ZIP-Datei

Erste Tests mit Xcode 8 und Swift 3

Mitglieder des Apple Developer Programs können seit gestern die erste Xcode-8-Beta herunterladen. Sie enthält erwartungsgemäß die erste offizielle Prerelease-Version von Swift 3. Aufgrund des Confidentiality-Regeln, die für Teilnehmer am Apple Developer Program gelten, kann ich hier keine Screenshots zeigen und nur über Dinge schreiben, die ohnedies schon öffentlich bekannt sind (z.B., weil Apple auf der WDDC darüber berichtet hat oder entsprechende Dokumente veröffentlicht hat). Aber auch mit diesen Einschränkungen gibt es ein wenig zu berichten.

Erste Tests mit Xcode 8 und Swift 3 weiterlesen

Swift: Komfortabler mit CGFloat, CGPoint und CGRect arbeiten

In den letzten Wochen habe ich recht intensiv unter Swift 2.n mit dem SpriteKit gearbeitet. Ein großes Ärgernis ist dabei das umständliche Hantieren mit CGPoint, CGSize, CGRect– und CGVector-Strukturen. Lästig sind auch die ständig erforderlichen Typumwandlungen zwischen den im SpriteKit üblichen CGFloat-Zahlenformat und »gewöhnlichen« Integer- und Fließkommazahlen. Das ist umso absurder, als CGFloat auf 64-Bit-Plattformen ohnedies eine Double-Zahl ist. Einzig auf 32-Bit-Architekturen ist CGFloat tatsächlich ein Float.

Wie auch immer: Swift wäre nicht Swift, könnten wir uns das Leben nicht mit ein paar neuen Operatoren, nachträglichen Erweiterungen vorhandener Strukturen sowie mit globalen Funktionen leichter machen.

Swift: Komfortabler mit CGFloat, CGPoint und CGRect arbeiten weiterlesen

Swift 3 Preview 1 in Xcode 7.3.1 ausprobieren

Apple stellt seit Ende Mai auf https://swift.org/download/#snapshots einen Snapshot der ersten Preview-Version von Swift 3 zur Verfügung. Dieser Snapshot — die offizielle Bezeichnung lautet »Swift 3.0 Preview 1 Snapshot 2016-05-31« — kann nun mit gewissen Einschränkungen unter Xcode 7.3.1 getestet werden.

Update 2.6.2016: Der Preview-Snapshot ist wieder von der Download-Seite verschwunden. Angeblich war es gar kein Preview. Oder kann es sein, dass das Preview-Spektakel erst mit der WWDC über die Bühne gehen soll?

Swift 3 Preview 1 in Xcode 7.3.1 ausprobieren weiterlesen

Ubuntu 16.04 nach einem Monat

Vor ca. einem Monat wurde Ubuntu 16.04 freigegeben. In den Release Notes und in diversen Tests wurde damals auf etliche Probleme und Kinderkrankheiten hingewiesen. Heute habe ich nochmals eine Neuinstallation von Ubuntu 16.04 vom offiziellen ISO-Image durchgeführt, wobei ich die Installationsoption Herunterladen der Aktualisierungen aktiviert habe, damit ich von Anfang an ein möglichst aktuelles und fehlerfreies Ubuntu erhalte. Das Ergebnis ist leider ernüchternd.

Ubuntu 16.04 nach einem Monat weiterlesen

Pläne für Swift 3.0

Mit der Geheimniskrämerei ist es vorbei: Da Swift ein Open-Source-Projekt ist, verläuft die Entwicklung nun deutlich transparenter. Dieser Beitrag fasst zusammen, wie Swift 3 voraussichtlich aussehen wird. Diese Pläne ändern sich momentan laufend. Dieser Beitrag wird deswegen regelmäßig aktualisiert. (Erste Version 11.12.2015, letztes Update: 15.6.2016.)

PS: Die Liste der Änderungen hat inzwischen schon fast epische Ausmaße angenommen. Dieser Blogbeitrag ist eine Zusammenfassung der Neuerung, die mir am wichtigsten erscheinen, aber keine vollständige Referenz. Werfen Sie gegebenenfalls einen Blick auf die Seite https://github.com/apple/swift-evolution!

Pläne für Swift 3.0 weiterlesen

Excel 2016 programmieren

Wenige meiner Bücher haben zehn Auflagen erreicht — das Excel-VBA-Buch (1. Auflage 1994) mit dem aktuellen Titel Excel 2016 programmieren gehört jetzt dazu. Schon zum vierten Mal hat Ralf Nebelo eine Menge Zeit, Mühe und Praxiswissen investiert und das Buch vollständig überarbeitet, erweitert und verbessert. Darüber bin ich ausgesprochen glücklich!

excel2016

Excel 2016 programmieren weiterlesen

Parallax-Icons für tvOS-Apps

Die Steuerung von tvOS erfolgt durch eine Art Cursor, der mit der Fernbedienung über Objekte am Bildschirm bewegt wird. Wenn es beispielsweise drei nebeneinanderliegende Buttons am Bildschirm gibt, dann gibt es horizontal nur drei mögliche Cursorpositionen. Ohne weitere Maßnahmen wäre die Cursorbewegung sehr ruckartig.

Um den Übergang von einen zum nächsten Objekt feiner darzustellen und damit die Cursorposition exakter aufzulösen, kippt tvOS die Buttons während sich der (an sich unsichtbare) Cursor darüber bewegt. Diese Kippbewegung wird durch 3D-Effekte und Schatten visualisiert. Das war Apple aber nicht genug: Auch die Icons an sich sollen sich beim Kippen verändern.

Während sich der unsichtbare Cursor über das Icon bewegt, ändert sich nicht nur der Schatten, sondern auch die Position der Zahnräder zueinander. (GIF-Animation)
Während sich der unsichtbare Cursor über das Icon bewegt, ändert sich nicht nur der Schatten, sondern auch die Position der Zahnräder zueinander. (GIF-Animation)

Parallax-Icons für tvOS-Apps weiterlesen