====== Tipps und Informationen zum Programmieren von Interatkionen ====== Es gibt viele Möglichkeiten, wie man Interaktionen in Minecraft einsetzen kann: * Wenn ein Spieler ein bestimmtes Feld betritt, erscheinen Gegner oder er wird zum nächsten Level teleportiert, er tappt in eine Falle und stirbt etc. * Wenn ein Spieler einen Hebel betätigt, einen Knopf drückt oder ein Item verwendet, passiert etwas. * Nur wenn ein Spieler einen bestimmten Gegenstand gefunden hat, lässt sich eine Tür öffnen. * etc. ===== 1. Command-Blocks ===== Eine Möglichkeit, Interaktionen zu realisieren sind Command-Blocks. Dies sind "normale" Blocks, die man jedoch nicht im Inventar findet. Man muss sich Command-Blocks mit dem Chat-Befehl ''/give @p command_block'' ins Inventar legen. Wird ein Command-Block mit Strom aktiviert (dazu kann man einen Hebel, einen Knopf oder auch eine Platte verwenden), dann führt er einen Befehl aus, den man auch im Chatfenster verwenden kann. Diesen Befehl und weitere Einstellungen kann man vornehmen, wenn man mit der rechten Maustaste auf den Command-Block klickt. Gebt ihr für den Befehl (Command-Input) z.B. ''teleport @p 100 100 100'' ein, dann wird der nächste Spieler (@p) zum den Koordinaten (100/100/100) teleportiert, sobald der Command-Block aktiviert wird. Diese Aktivierung kann man z.B. mit einer Pressure_Plate machen, die man auf den Command-Block baut (wenn man auf den Block bauen will, muss man die Shift-Taste drücken, da der normale Rechtsklick ja die Eigenschaften des Blocks öffnet). Man kann mit Command-Blocks auch Python-Code ausführen lassen. Dies wird unten unter Punkt x.x erklärt. ===== 2. Python-Funktionen bei bestimmten Ereignissen ausführen ===== Man kann auch Python-Funktionen ausführen, wenn bestimmte Bedingungen erfüllt sind. Dazu verwendet man sogenannte "Listeners". Das sind Funktionen, die im Hintergrund mitlaufen und darauf warten, dass etwas Bestimmtes passiert. Ist dies der Fall, so wird eine weitere Funktion aufgerufen. Du kennst dies bereits von der Funktion ''player.on_chat'': ==== 2.1 Wenn etwas Bestimmtes in den Chat geschrieben wird, eine Aktion ausführen ==== Wenn der Spieler "baue_Goldhaus" in den Chat tippt, soll der ausgehöhlte Goldblock erstellt werden: def baue_Goldhaus(): blocks.fill(GOLD_BLOCK, pos(1, 1, 1), pos(10, 10, 10)) blocks.fill(AIR, pos(2,2,2), pos(9, 9, 9)) player.on_chat("baue_Goldhaus", baue_Goldhaus) Es gibt verschiedene von diesen Listenern. Alle beginnen mit ** player.on, ** oder mit ** blocks.on **. (player.on_chat, player.on_item_interacted, blocks.on_block_broken, blocks,on_blocks_placed,) ==== 2.2 Während sich der Spieler bewegt eine Funktion aufrufen ==== Ein sehr praktischer "Listener" ist ''player.on_travelled(WALK,)''. Die angegebene wird bei jeder Bewegung des Spielers aufgerufen. Dadurch kann man beliebige Interaktionen auslösen. Beispielsweise kann man den Spieler töten, wenn er bei einer bestimmten Position in die Falle getreten ist etc. Hierfür fragt man in der Funktion die Position des Spielers ab und kann dann in einem if-Befehl entsprechend dieser Position eine Aktion programmieren. Das folgende Programm wird bei jeder Bewegung des Spielers ausgeführt und platziert 4 Felder neben dem Spieler einen Glasblock, wenn sich dieser in einem bestimmten Bereich aufhält: def on_travelled_walk(): x = player.position().get_value(Axis.X) y = player.position().get_value(Axis.Y) z = player.position().get_value(Axis.Z) player.say("x:"+str(x)+" y:"+str(y)+" z:"+str(z)) if (10 Statt WALK geht auch: swim water, fall, climb, swim lava, fly, riding, sneak, sprint. ==== 2.3 Weitere Ereignis-Listeners ==== Es gibt weitere solche "Listener", die auf ein bestimmtes Ereignis reagieren. Alle beginnen mit ** player.on, ** oder mit ** blocks.on **. * player.on_chat * playe.on * player.on_item_interacted * player.on_died * player.on_teleported * blocks.on_block_broken * blocks.on_blocks_placed ===== 3. Mit player.execute() Spielkommandos ausführen ===== Mit dem Befehl ''player.execute'' kann man die Spielkommandos in Python ausführen, die man sonst in den Chat schreibt. Beispielsweise ''kill @s'' (um den Spieler zu töten, Achtung, hierfür muss man im Survival- oder im Adventure-Modus sein) ''setworldspawn x y z'' (um den Weltspawnpunkt zu setzen), ''spawnpoint x y z'' um den Spawnpunkt des Spielers zu setzen. Hierfür gibt man das Kommando in Anführungszeichen ein, ohne den Schrägstrich. Das folgende Programm lässt den Spieler sterben, wenn er das goldene Schwert verwendet (um dem Spieler ein goldenes Schwert zu geben: "/give @s GOLDEN_SWORD" in den Chat schreiben). BEVOR er gestorben ist, kann man noch seinen neuen Spawnpunkt setzen (so kann man ihn bei verschiedenen Aufgaben immer wieder am Anfang der neuen Aufgabe erscheinen lassen). def on_goldensword_interacted(): player.say("Sorry, du bist leider gestorben") player.execute("spawnpoint @s 20 10 30") player.execute("kill @s") player.on_item_interacted(GOLDEN_SWORD, on_goldensword_interacted) Falls ein Spieler nicht durch das Programm durch ''player.execute("kill @s")'' stirbt, sondern z.B. im Kampf mit Monstern, funktioniert der Trick von oben natürlich nicht so. Dann muss man den neuen Spawnpoint des Spielers einfach setzen, wenn er eine bestimmte Leistung erreicht hat (genügend Punkte erzielt, bis zu einem bestimmten Block gekommen etc.). Dafür kann man auch Command-Blocks verwenden (siehe Punkt 4 unten), doch es ist meist viel einfacher, dies direkt im Python-Code zu tun. **Achtung:** in der Funktion ''player.on_died()'' kann man ''player.execute'' nicht ausführen (da der Spieler tot ist und nichts mehr ausführen kann). ===== 4. Code durch Command-Blocks ausführen lassen ===== Man kann z.B. eine Pressure-Plate mit Redstone mit einem Command-Block verbinden. Im Commandblock verwendet man den Befehl ''/tell @p letsgo'' Im Codebuilder kann man nun eine Funktion ''on_tell_command()'' machen: def on_tell_command(): blocks.place(ACACIA_FENCE,pos(4,3,0)) player.on_tell_command("letsgo", on_tell_command) Dasselbe funktioniert auch mit Schaltern, Hebeln, Redstone-Truhen etc. def on_tell_command_maches(): blocks.fill(GOLD_BLOCK,world(12,4,13),world(15,12,13)) player.on_tell_command("mach_es", on_tell_command_maches) def on_tell_command_abbauen(): blocks.fill(AIR,world(12,4,13),world(15,12,13)) player.on_tell_command("abbauen", on_tell_command_abbauen) ===== 5. Testen, welche Items sich in einer Kiste befinden ===== Hierzu kann man einen Trick verwenden: - Die Kiste an einen fernen Ort kopieren - Den Agenten auch dorthin teleportieren - Die Kiste zerstören - Agent sammelt die Items ein - Testen, welche Items der Agent im Inventar hat - Diesen Vorgang könnte man in eine ''loops.forever''-Schleife packen (siehe Beispiel unten) Beispielcode # Die folgende Funktion testet, ob ein Diamant in der Truhe ist. # Sie gibt true oder false als Rückgabewert, sodass man sie weiterverwenden kann. def isDiamondInChest(): diamondFound = False # Agent weit weg teleportieren und alles wegschmeissen agent.teleport(world(20,-60,12),NORTH) agent.drop_all(FORWARD) # Kiste kopieren (sie steht bei (-7,-60,3)) blocks.clone(world(2, -60, 12), world(2,-60,12), world(10,-60,12), CloneMask.REPLACE, CloneMode.NORMAL) # Agenten zur Kiste teleportieren agent.teleport(world(10, -60, 13), NORTH) # Kiste zerstören und Objekte aufsammeln agent.destroy(FORWARD) agent.collect_all() for slotNumber in range(1,10): itemID = agent.get_item_detail(slotNumber) if (itemID == 264): diamondFound = True return diamondFound # Nun können wir z.B. ein Mal pro Sekunde testen, ob ein Diamand in der Truhe ist def on_forever(): if (isDiamondInChest()==True): player.say("Ein Diamant in der Truhe") else: player.say("Nope, kein Diamand in der Truhe") loops.pause(1000) loops.forever(on_forever)