Meteoritenalarm

Das Verständnis zur Grundidee und zum Ablauf der Kurse in unserem Classic-Format ist notwendige Voraussetzung zur Durchführung eines Kurses. Unsicher?

Meteoritenalarm

repl.it?

Wie fuktioniert der Editor?

  1. www.repl.it öffnen und einen Account erstellen
  2. Neuen Repl erstellen und JavaScript als Sprache auswählen
  3. Einen sinnvollen Namen für das Projekt auswählen

Worauf sollte beim Kurs geachtet werden?

  1. Je nachdem wie viel Erfahrung die Teilnehmenden mitbringen, sollten die Teams möglichst einheitliche bzw. homogen eingeteilt werden
  2. Die Codebeispiele sind nicht dafür da um sie zu 100% vorzuführen. Es sollte darauf geachtet werden, das die Teilnehmer versuchen mit einigen Tipps des Inspirers die Lösung selber zu finden
  3. Für jeden Teil des Kurses sollte von den Teilnehmern ein „How to“ angelegt werden. Hier soll die Kernfunktionalität des Themas festgehalten werden um zur Not nochmal nachlesen zu können. (Die „How tos“ sollten den Codebeispielen ähnlich sehen und Kommentiert sein)
  4. Für viele Teilnehmer ist dieser Kurs das erste mal, dass mit einer „richtigen“ Programmiersprache gearbeitet wird. Legt also Wert auf die saubere Arbeit. Lesbarkeit des Programms sowie Kommentare und sauberer Code sind ein wichtiger Bestandteil des Kurses auch wenn es hierzu keine eigenen Lektionen gibt.

Kennenlernen

Vorstellungsrunde mit Programmiererfahrung/Motivation

Ihr stellt euch vor und erzählt, wie ihr zur Hacker School und zum Coden gekommen seid.
Nun die Teilnehmer:

  • Wie heißt Du? (Achtet darauf, dass die Kinder sich nur mit Vornamen vorstellen – Datenschutz.)
  • Warum bist Du hier?
  • Hast Du schon mal programmiert?
  • Was willst Du lernen?
Vorstellung interaktiver gestalten? (!Klick mich an!)

In unserem Inspirer Handbuch findet ihr
weitere Spielideen.
Wenn Du die Vorstellung etwas interaktiver gestalten möchtest, empfehlen wir das Spiel “Alle, die”, was im folgenden erklärt wird:

Spielidee und Ziel

  • Wir kommen locker und leicht mit den Teilnehmer*innen ins Gespräch und erfahren, was sie gerne mögen (positiver Beziehungsaufbau).
  • Wir können eine erste Diagnose stellen, was die Schülerinnen und Schüler können, was sie gerne mögen.

Ablauf

  1. Stellt Euch vor die Klasse.
  2. Ein*e Inspirer sagt: “Alle, die”-Frage z.B: “Alle, die Sport in der Freizeit machen?”.
  3. Alle, die sich angesprochen fühlen, stehen von ihrem Platz auf.
  4. Die*der Inspirer stellt Rückfragen und kommt ins Gespräch mit den Teilnehmer*innen, z.B. “Cool, du in der ersten Reihe: Wie heißt du? [Antwort] Welchen Sport machst du denn gerne? [Gespräch entsteht] Super und du in der letzten Reihe…”.
  5. Die*der Inspirer sagt: "Alle wieder setzen".
  6. Die*der Inspirer stellt die nächste Frage: z.B. “Alle, die gerne Spiele auf dem Handy oder Computer spielen!”
  7. Siehe 3.-5.
  8. Spielt das Ganze etwa 5 min (nach Gefühl)
Sammlung möglicher Fragen (!Klick mich an!)

Diese Sammlung kann gern erweitert oder angepasst werden.

IT/Programmieren

  • Wer hat schon mal programmiert?
  • Wer kann sich vorstellen etwas mit Programmieren und IT zu machen?

Hobbies

  • Wer von Euch macht Sport in der Freizeit?
  • Wer spielt ein Instrument?
  • Wer spielt Computerspiele?
  • Wer spielt Handyspiele?

Lustiges

  • Wer hat eine Schuhgröße größer als 35?

Letzte Frage

  • Wer ist schon in repl.it angemeldet?

Spielfeld erstellen

  • Wie legen wir die Breite und Höhe unserer Leinwand fest?
  • Wie funktioniert ein Koordinatensystem?
  • Wie geben wir der Leinwand eine Farbe?
  • Was ist ein String?
1
2
3
4
5
6
function setup() {
// Unsere "Zeichenfläche" (Canvas = Leinwand)
createCanvas(450, 300)
// Wir malen auf schwarzem Hintergrund. Der Weltraum ist
nachher auch schwarz :)
background("grey")}

Formen zeichnen 1

Jetzt wo wir unsere Leinwand erstellt haben, wollen wir auch etwas darauf machen. Wir fangen damit an, ein rotes und ein blaues Viereck zu zeichnen.

  • Was ist ein Parameter?
  • Wie positionieren wir ein Objekt auf unserer Leinwand (x, y)?
  • Was ist eine Funktion und wie programmieren wir sie?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function draw() {
        // So werden Formen ohne Rand gezeichnet
        noStroke()

        // Ein rotes Rechteck (rectangle)
        // rect(x, y, w, [h])
        fill("red")
        rect(0,0,100,50)

        // ohne Höhe wird das Rechteck zum Quadrat [h]ist optional
        fill("blue")
        rect(110,0,50)
}

Formen zeichnen 2

Vierecke können wir jetzt. Also machen wir uns dran auch einen Kreis zeichnen zu können. Zusätzlich gucken wir uns an, wie wir unsere Farbauswahl auf das nächste Level bringen können.

  • Wie funktioniert die Positionierung eines Kreises
  • Wie legen wir die Größe des Kreises fest?
  • Was ist RGB und wie können wir es nutzen?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

// Ein gelber Kreis
// circle(x, y, d)
// d - Durchmesser
fill("yellow")
circle(170,0,50)
//ups, hier ist x,y der Mittelpunkt
// Also 25 nach unten und 25 nach rechts (Koordinatesystem üben ;) )
circle(195,25,50)
//jetzt könnte man den oberen Kreis auch auskommentieren, oder man ändert die Koordinaten gleich im ersten Circle.

// Jetzt ein Rechteck in einer
// https://htmlcolorcodes.com/color-picker/
// Dort kann man mit copy&paste den RGB Wert kopieren
// Alternativ: "colorpicker" googeln
fill(32, 196, 194)
rect(230, 0, 100,50)

Aufgaben zu Teil 1

  • Zeichnet jetzt entlang der y-achse (also senkrecht) die gleichen Formen. Versucht auch immer 10 Pixel Abstand zu lassen.
  • Probiert jetzt frei auf der Fläche verschiedene Formen aus! Lasst Eurer Kreativität freien Lauf!
  • Versucht vorher mit Euren Partner mit dem "Markierungstool"(Wenn die Konferenzsoftware das hat? Oder wenn ihr zusammen vorm Laptop sitzt mit der Maus anzeigen) den Ort der Form zu zeichnen. Liegt Ihr richtig? (Ihr sollt ein Gefühl für die Koordinaten und die Größe bekommen)
  • Man kann schwarz als fill(0) oder fill (0,0,0) oder fill("black") schreiben. Wie kann man weiß auf diese drei Arten schreiben? In der nächsten Übung (5) wird ein weißes Quadrat gemalt. probiert es dort aus.
  • Malt genau in der Mitte ein Quadrat mit einer Seitenlänge von 100 in der Farbe Weiß
  • Malt genau in der Mitte einen Kreis mit dem Durchmesser 100 in der Farbe des Hintergrundes!

Anmerkung: zu 5. und 6. Fällt Euch was auf? Wie sehen die vier "Ecken" aus? (Wie ein Raumschiff ;) )

Raumschiff zeichnen

  • Aufbauend auf der Liste wird jetzt das Konzept der Tupelliste gezeigt. Dabei soll jedes Tupel eine Frage und die dazu passende Antwort enthalten
  • Aufgabe 5: Findet heraus wie man auf der Grundlage der Tupelliste auch einzelne Elemente aus der Tupelliste aufrufen kann.
1
2
3
4
5
6
7
8
9

// Ein oranges Dreieck
// triangle(x1, y1, x2, y2, x3, y3)
fill("orange")
triangle(0,50,25,0,50,50)

// Vielleicht ein bisschen spitzer, dann sieht es so aus
wie ein wendiges Raumschiff
fill(192)
triangle(0,100,15,50,30,100)

Raumschiff und Ränder

Jetzt, wo wir unser Raumschiff gebaut haben, wollen wir ein bisschen mit Umrandungen bzw. strokes rumprobieren.

  • Wie legen wir die Dicke der Umrandung fest?
  • Wie legen wir die Farbe der Umrandung fest?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

// noStroke() sorgte dafür, dass keine "Ränder" um die Formen
gezeichnet werden. Lässt man noStroke() weg, dann tut p5.js so,
als wenn man stroke(0) oder stroke("black") angibt.
//Wollen wir uns mal rote Ränder angucken um das zu visualisieren.
stroke("red")
fill("blue")
rect(60,0,50)

// Oder mal die "Standardeinstellung" in schwarz und mal versetzt
über dem vorherigen Quadrat, damit man das auch sieht.
stroke(0)
fill("DARKORCHID")
rect(100,20,50)

// Auch die Dicke des Randes hat einen Standard, der ist 1 und
bedeutet 1 pixel aussen und 1 pixel innen
// Jetzt doppelt so dick machen
strokeWeight(2)
stroke("white")
fill(128,192,64)
rect(180,0,50)

Andere Formen

  • Wie zeichnet man Linien?
  • Wie positioniert man Linien auf der Leinwand?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

/* Durch den Rand werden die Formen größer. Es werden bei
strokeWeight(1) ein Pixel Innen und einer Außen gezeichnet, also
insgesamt ist der Rand 2 Pixel stark. */

// strokeWeight() ist auch die Linienstärke für Punkte und Linien.

// Ein gelber Punkt oben links beim blauen Quadrat
stroke("yellow")
//strokeWeight - Strichstärke
strokeWeight(1)
point(60,0)

//Punkte können auch zu Kreisen werden. Auch hier ist die
Koordinate der Mittelpunkt
stroke("yellow")
strokeWeight(50)
point(325,25)

// Linien haben einen Anfangs- und Endpunkt
// line(x1, y1, x2, y2)
stroke("magenta")
strokeWeight(1)
line(0,150,450,150)
//oder Dicker (Wenn keine neue Farbe angegeben wirde, wird
weiter mit Magenta gemacht)
strokeWeight(5)
line(0,160,450,160)

// Es gibt die Variablen height und width, die Euch p5.js
anhand der Canvas-Größe gibt :)
stroke("cyan")
strokeWeight(1)
// minus Eins weil die Koordinaten ja bei 0 anfangen.
line(0,0, width-1, height-1)

// Und ein Punkt in der Mitte kann man dann mit width/2
und height/2 darstellen. (Anmerkung: height oder width
ungerade sind, dann ist ja die Hälfte irgendwas.5 . Dann
schneidet point() einfach die Nachkommastelle ab )
stroke("white")
strokeWeight(3)
point(width/2, height/2)

Aufgaben zu Teil 2

  • Zeichnet verschieden Formen, mit verschiedenfarbigen Rändern und unterschiedlicher Dicke auf dem gesamtenSpielfeld :)
  • Malt eine grüne Linie (egal welches grün) von rechts oben, nach links unten.
  • Malt eine rote Linie (egal welches rot) von der Mitte in die linke obere Ecke.
  • Malt eine Linie von rechts unten zur Mitte (sucht Euch eine Farbe aus)
  • Zeichnet das Raumschiff (graues Dreieck) in genau der gleichen Größe wie oben. Die Position soll mittig am unteren Rand sein. Dann zeichnet einen Kreis mit dem Mittelpunktauf der Mitte der kurzen unteren Seite des Raumschiffs in der Farbe schwarz (Hintergrundfarbe) Was passiert? Wie sieht das aus?

Anmerkungen: Für 2./3./4.: Versucht die Variablen width und height zu benutzen. (Ihr könnt aber erstmal anhand der CanvasGröße das 450x300 die Koordinaten ausrechnen und danach eine "Formel" entwickeln.)

Meteoriten

Nachdem wir uns jetzt mit den meisten Formen und Positionierungen gut auskennen, wollen wir lernen wie wir unsere Meteoriten programmieren.

  • Was macht die Funktion random?
  • Warum setzen wir width und height als Maximum?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

// mit let werden Variablen erzeugt
// (1) man kann auch erstmal für x_rand und y_rand konkrete
Zahlen einsetzen.
// (2) mit random(von, bis) wird eine zufällige Zahl erzeugt.
Die Zahl "von" kann dabei sein, die Zahl "bis" ist aber nie dabei.
// Info: Genaugenommen wird eine Zahl mit Nachkommastellen
erzeugt. Die werden aber einfach abgeschnitten, wenn man sie
als Farbwerte oder Koordinaten einsetzt :)
let x_rand = random(0,width)
let y_rand = random(0,height)

// (3) Auch zufällige Farben sind möglich
let r_rand = random(0,256)// 256 ist nicht dabei!
let g_rand = random(0,256)
let b_rand = random(0,256)
//let farbe_rand = color(r_rand, g_rand, b_rand)

Meteoriten 2

Was macht eine Liste und wie nutzen wir sie hier?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

// (4) wollt Ihr nur aus ein paar Farben auswählen, geht das auch so:
//Achtet auf die eckigen Klammern []
let farbname_rand = random(["gold", "silver"])
//let farbe_rand = color(farbname_rand)

// Mit stroke("white") wird ein Sternenhimmel erzeugt.
(Leider können wir den nicht als Hintergrund nehmen,
weil das zu nachher zu kompliziert wird)
// Hier 2 für den Sternenhimmel und 10 für die bunte Punktewolke
strokeWeight(2)
// (1)(2)
stroke("white")
//(3)(4)
//stroke(farbe_rand)

point(x_rand,y_rand)

Meteoriten Bewegung

Wir wollen nun versuchen unsere Meteoriten in Bewegung zu bringen.

  • Wie funktioniert die Punktnotation?
  • Wie können wir die Position eines Objekts verändern?
  • Wie funktioniert eine Schleife?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/*
Die Funktion draw() wird dauernd (mehrmals pro Sekunde) ausgeführt.
So können wie später ein Spiel programmieren
*/
function draw() { // (1) immer wieder das Canvas "löschen" background("black") noStroke() fill(255) circle(meteor.X, meteor.Y, 20) // man kann auch + 2 oder + 3 machen um den meteor schneller zu machen. meteor.Y = meteor.Y + 1 //print(meteor.Y)
}

Meteoriten Bewegung 2

Hier wollen wir die Position unsere Meteoriten im Blickbehalten um ihn rechtzeitig verschwinden zu lassen. Dazu brauchen wir eine Abfrage.

  • Was ist eine If-Abfrage?
  • Wie lassen wir den Meteoriten wieder verschwinden?
  • Was ist ein Integer?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

// (2) ups wo ist er hin?
//print(meteor)
//(3)(1) ohne +10
//(3)(2) Man sollte dann auch height +10 (also plus
Durchmesser_vom_Meteor/2 vergleichen damit der Meteor
unten auch verschwindet)
// false && ist einfacher als auskommentieren
if(meteor.Y > height + 10){ //(3)(1) un (3)(2) print(meteor.Y) //noLoop() // Wenn er also verschwunden ist, dann erscheint ein neuer Meteorit oben. Ja, ist eigentlich der alte, aber Pssst! 😆 meteor.Y = 0 //(3)(3) // Und jetzt kommt der Zufall ins Spiel: meteor.X = random(0,width) //print(meteor.X) //Damit wir das alles besser lesen können, schneiden wir selber die Nachkommastellen mit int() ab. (Wurde ja schon erwähnt) meteor.X = int(meteor.X) //print(meteor.X)
}

//noLoop()

Aufgaben zu Teil 4

  • Lasst den ersten Meteoriten auch an einer zufälligen Position erscheinen. Es gibt verschiedene Möglichkeiten, hauptsache es funktioniert!
  • Wie kann man Meteoriten diagonal fliegen lassen?

Mehr Meteoriten

Weil wir jetzt wissen, wie wir einen Meteoriten erstellen und sich bewegen lassen, können wir das Konzept auf mehr Meteoriten übertragen um unserem Ergebnis näher zu kommen

  • Wie erstellen wir eine Variable der wir direkt eine X und Y Wert vermitteln?
  • Wie fügen wir bestehende Variablen in ein Array ein?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

// Oben haben wir schon meteors definiert, das soll eine
Auflistung aller Meteoriten sein
// Und einzelne Meteoriten sehen dann so aus
let meteor1 = {X: 10, Y:0}
let meteor2 = {X: 65, Y:0}
let meteor3 = {X: 180, Y:0}
let meteor4 = {X: 200, Y:0}
let meteor5 = {X: 400, Y:0}

// mit push() werden die dann in Auflistung aller Meteoriten
(ein Array) angefügt.
meteors.push(meteor1)
meteors.push(meteor2)
meteors.push(meteor3)
meteors.push(meteor4)
meteors.push(meteor5)

// Tipp: meteor1, meteor2 sind nur Hilfsvariablen gewesen.
Mann kann auch direkt auf das Array pushen:
// meteors.push({X: 10, Y:0}) usw.

  • Wie lassen wir uns einzelne Elemente aus einem Array ausgeben?
  • Wie können wir den Inhalt eines Arrays lesen und verstehen?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// So sieht die Datenstruktur dann aus (Achtung,
//print("Datenstruktur:\n",meteors)
// Zugegriffen wir dann mit eckigen Klammern und zwar wird hier
von 0 an gezählt:
print("\nUnd die Meteoriten sehen wie im Code aus:")
print(meteors[0])
print(meteors[1])
print(meteors[2])
print(meteors[3])
print(meteors[4])
// Das klingt erstmal komliziert, ist aber gewöhnungssache.
Arrays sind flexibler als wenn man meteor1, meteor2 usw.
als Variablen hat

Mehr Meteoriten in Bewegung

Ähnlich wie bei der ursprünglichen Meteoritenbewegung, wollen wir jetzt auch die anderen Meteoriten gleichzeitig bewegen.

  • Was ist eine for Schleife und wofür können wir sie hier nutzen?
  • Wie nutzen wir eine for Schleife in Verbindung mit einem Array um alle Objekte in nur einer Schleife bewegen zu können?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function draw() {
        background("black")
        noStroke()
        fill(255)
        // meteors.length ist die Länge des Arrays
        // Mit dieser Schleife wird in der variablen i gezählt
        und zwar von 0 bis 2, also 0,1,2
        for (let i = 0; i < meteors.length; i  = i + 1){
                // Hier definieren wir mit current_meteor, den
                aktuellen Meteor in diesen Schleifendurchlauf
                let current_meteor = meteors[i]

                // Der Meteor wird gezeichnet
                circle(current_meteor.X, current_meteor.Y, 20)
                // Und lassen ihn nach unten wandern indem wir
                die y-koordinate um eins nach oben zählen.
                current_meteor.Y = current_meteor.Y + 1

                // Warum =10 und -10? Einfach mal "P" im richtigen
                Moment drücken :)
                if(current_meteor.Y > height + 10){//Warum +10

                        current_meteor.Y = - 10 //Warum -10?
                        current_meteor.X = random(0,width)
                        // int() schneidet die Nachkommastellen ab,
                        die random() liefert.
                        current_meteor.X = int(current_meteor.X)
                }
        }
}

Aufgaben zu Teil 5

  • "Versetzte Meteoriten": Wie kann man die Meteoriten auch horizontal versetzen, damit sie nacheinander unten ankommen?
  • "Farbige Meteoriten": Weist den Meteoriten eine zufällige Farbe zu.

Tipp: Das ist mit Fleißarbeit verbunden, den Anfangsmeteoriten Farben zu geben. Hier muss man keine zufälligen mit random() wählen, sondern kann wie die Anfangskoordinaten auch selbst was "zufälliges" auswählen.

Ihr könnt neue "Untervariablen" in meteors einfügen. Entweder R,G und B oder einfach nur color, wo ihr mit color() die Farbe schon in eine p5-Farbe in einer Variablen speichert.

Erst in der if-Bedingung kommt neben der neuen x-Koordinate die Zufallsfarbe hinzu.

Raumschiff Bewegung 1

Jetzt müssen wir noch unser Raumschiff einfügen..

  • Was ist die Framerate?
  • Wo wird unser Raumschiff erstellt, wenn wir es an x:width/2 einfügen?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

let ship = {}

// Die Funktion setup() wird einmalig am Anfang des Programms ausgeführt
function setup() { createCanvas(450, 300) // Wir machen die Bewegungen erstmal langsam // framerate bedeutet "Wiederholungen pro Sekunde" // (0) Hier erstmal 30 oder so einsetzen frameRate(60) background("black") //erst hier ist width definiert // Und so kann ship initialisiert werden ship = { X: width/2 }
}

Raumschiff Bewegung 2

Nachdem unser Raumschiff erstellt wurde wollen wir es noch in Bewegung bringen.

  • Was macht die Funktion keyIsDown(key)
  • Wie können wir das Raumschiff mit Tasten bewegen?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

function draw() { background("black") noStroke() // *** Schiffscode ANFANG *** fill(255) // Keycodes kann man hier ausprobieren: // https://keycode.info/ // '<-' pressed if (keyIsDown(37)) { if (ship.X > 0) { // wenn man hier 2 anstatt 1 wird"s schneller ship.X = ship.X - 1 } } // '->' pressed if (keyIsDown(39)) { if (ship.X < width + 1) { // auch hier natürlich 2 anstatt 1 ändern ship.X = ship.X + 1 } } drawShip() // *** Schiffscode ENDE***
}

function drawShip(){ // Die 295 kommt daher, dass 5 pixel Luft unter dem Raumschiff natürlicher wirken. (Bei 299 wäre es ja direkt unten am Rand kleben!) triangle(ship.X-8, 294, ship.X, 269, ship.X+8, 294) // Kannst Du die Geometrie des Raumschiffs erklären? Tipp: ship.X ist die x-Koordinate dees Raumschiffs, gemeint ist hier die Spitze.
}