9.1. Podstawy mcpi

9.1.1. Połączenie z serwerem

Za pomocą wybranego edytora utwórz pusty plik, umieść w nim podany niżej kod i zapisz w katalogu mcpi-sim pod nazwą mcpi-podst.py:

Kod nr
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4import sys
 5import os
 6import mcpi.minecraft as minecraft  # import modułu minecraft
 7import mcpi.block as block  # import modułu block
 8
 9os.environ["USERNAME"] = "Steve"  # nazwa użytkownika
10os.environ["COMPUTERNAME"] = "mykomp"  # nazwa komputera
11
12# utworzenie połączenia z minecraftem
13mc = minecraft.Minecraft.create("192.168.1.10")  # podaj adres IP Rpi
14
15
16def main(args):
17    mc.postToChat("Czesc! Tak dziala MC chat!")  # wysłanie komunikatu do mc
18    return 0
19
20
21if __name__ == '__main__':
22    sys.exit(main(sys.argv))

Na początku importujemy moduły do obsługi Minecrafta i za pomocą instrukcji os.environ["ZMIENNA"] ustawiamy wymagane przez mcpi zmienne środowiskowe z nazwami użytkownika i komputera:

Informacja

Udany import wymaga, aby w katalogu ze skryptem znajdował się katalog mcpi, z którego importujemy wymagane moduły. Jeżeli katalog ten byłby w innym folderze, np. biblioteki, przed instrukcjami importu musielibyśmy wskazać ścieżkę do niego, np: sys.path.append("/home/user/biblioteki").

Po wykonaniu czynności wstępnych tworzymy podstawowy obiekt reprezentujący grę Minecraft: mc = minecraft.Minecraft.create("192.168.1.8").

Wskazówka

Adres IP serwera Minecrafta, czyli minikomputera Raspberry Pi, odczytamy po najechaniu myszą na ikonę połączenia sieciowego w prawym górnym rogu pulpitu (zob. zrzut poniżej). Możemy też wydać w terminalu polecenie ip addr i odczytać adres poprzedzony przedrostkiem inet dla interfejsu eth0 (łącze kablowe) lub wlan0 (łącze radiowe).

../../_images/rasplan-ip.jpg

Na końcu w funkcji main(), czyli głównej, wywołujemy metodę postToChat(), która pozwala wysłać i wyświetlić podaną wiadomość na czacie Minecrafta.

Skrypt uruchamiamy z poziomu edytora, jeśli to możliwe, lub wykonując w terminalu polecenie:

~/mcpi-sim$ python mcpi-podst.py

Informacja

Omówiony kod (linie 4-14) stanowi niezbędne minimum, które musi znaleźć się w każdym skrypcie lub w sesji interpretera (konsoli), jeżeli chcemy widzieć efekty naszych działań na serwerze. Dla wygody kopiowania podajemy go w skondensowanej formie:

Kod nr
1import mcpi.minecraft as minecraft  # import modułu minecraft
2import mcpi.block as block  # import modułu block
3import os
4os.environ["USERNAME"] = "Steve"  # wpisz dowolną nazwę użytkownika
5os.environ["COMPUTERNAME"] = "mykomp"  # wpisz dowolną nazwę komputera
6mc = minecraft.Minecraft.create("192.168.1.8")

9.1.2. Świat Minecrafta Pi

Świat Minecrafta Pi opisujemy za pomocą trójwymiarowego układu współrzędnych:

../../_images/minecraft-system.png

Obserwując położenie bohatera gry Steve’a zauważymy, że zmiany współrzędnej x (klawisze A i D) i z (klawisze W i S) przesuwają postać w lewo/prawo, do przodu/tyłu, czyli horyzontalnie, natomiast zmiany współrzędnej y do góry/w dół - wertykalnie.

Informacja

W Pi Edition wartości x i y ograniczono do przedziału [-128, 127].

Ćwiczenie 1

Uruchamiamy rozszerzoną konsolę Pythona i wchodzimy do katalogu mcpi-sim:

    ~$ ipython qtconsole
In [1]: cd /root/mcpi-sim

Wskazówka

Podane polecenie można wpisać również w okienko „Uruchom” wywoływane w środowiskach linuksowych zazwyczaj przez skrót ALT+F2.

Zamiast rozszerzonej konsoli qt możemy użyć zwykłej konsoli ipython lub podstawowego interpretera python uruchamianych w terminalu. Uwaga: jeżeli skorzystamy z interpretera podstawowego kod kopiujemy i wklejamy linia po linii.

Kopiujemy do okna konsoli, uruchamiamy omówiony powyżej „Kod 2”, służący nawiązaniu połączenia z serwerem, i wysyłamy wiadomość na czat:

../../_images/ipython01.png

Poznamy teraz kilka podstawowych metod pozwalających na manipulowanie światem Minecrafta.

9.1.3. Orientuj się Steve!

Wpisz w konsoli poniższy kod:

>>> mc.player.getPos()
>>> x, y, z = mc.player.getPos()
>>> print x, y, z
>>> x, y, z = mc.player.getTilePos()
>>> print x, y, z

Metoda getPos() obiektu player zwraca nam obiekt zawierający współrzędne określające pozycję bohatera. Metoda getTitlePos() zwraca z kolei współrzędne bloku, na którym stoi bohater. Instrukcje typu x, y, z = mc.player.getPos() rozpakowują kolejne współrzędne do zmiennych x, y i z. Możemy wykorzystać je do zmiany położenia bohatera:

>>> mc.player.setPos(x+10, y+20, z)

Powyższy kod przesunie bohatera w bok o 10 bloków i do góry na wysokość 20 bloków. Podobnie zadziała kod mc.player.setTilePos(x+10, y+20, z), który przeniesie postać na blok, którego pozycję podamy.

9.1.3.1. Idź i przesuń się

Zadania takie możemy realizować za pomocą funkcji, które dodatkowo zwrócą nam nową pozycję. W pliku mcpi-podst.py umieszczamy kod:

Kod nr
16def idzDo(x=0, y=0, z=0):
17    """Funkcja przenosi gracza w podane miejsce.
18    Parametry: x, y, z - współrzędne miejsca
19    """
20    y = mc.getHeight(x, z)  # ustalenie wysokości podłoża
21    mc.player.setPos(x, y, z)
22    return mc.player.getPos()
23
24
25def przesunSie(x1=0, y1=0, z1=0):
26    """Funkcja przesuwa gracza o podaną liczbę bloków
27    i zwraca nową pozycję.
28    Parametry: x1, y1, z1 - ilość bloków, o którą powiększamy
29    lub pomniejszamy współrzędne pozycji gracza.
30    """
31
32    x, y, z = mc.player.getPos()  # aktualna pozycja
33    y = mc.getHeight(x + x1, z + z1)  # ustalenie wysokości podłoża
34    mc.player.setPos(x + x1, y + y1, z + z1)
35    return mc.player.getPos()

W pierwszej funkcji idzDo() warto zwrócić uwagę na metodę getHeight(), która pozwala ustalić wysokość świata w punkcie x, z, czyli współrzędną y najwyższego bloku nie będącego powietrzem. Dzięki temu umieścimy bohatera zawsze na jakiejś powierzchni, a nie np. pod ziemią ;-). Druga funkcja przesunSie() nie tyle umieszcza, co przesuwa postać, stąd dodatkowe instrukcje.

Dopisz wywołanie print idzDo(50, 0, 50) w funkcji main() przed instrukcją return i przetestuj kod uruchamiając skrypt mcpi-podst.py lub w konsoli. Później dopisz również drugą funkcję print przesunSie(20) i sprawdź jej działanie.

../../_images/ipython02.png

Ćwiczenie 2

Sprawdź, co się stanie, kiedy podasz współrzędne większe niż świat Minecrafta. Zmień kod obydwu funkcji na „bezpieczny dla życia” ;-)

9.1.3.2. Gdzie jestem?

Aby odczytywać i drukować pozycję bohatera dodamy kolejną funkcję do pliku mcpi-podst.py:

Kod nr
38def drukujPoz():
39    """Drukuje pozycję gracza.
40    Wymaga globalnego obiektu połączenia mc.
41    """
42
43    pos = mc.player.getPos()
44    print pos
45    pos_str = map(str, (pos.x, pos.y, pos.z))
46    mc.postToChat("Pozycja: " + ", ".join(pos_str))

Funkcja nie tylko drukuje koordynaty w konsoli (print x, y, z), ale również – po przekształceniu ich na listę wartości typu string pos_str = map(str, pos_list) – wysyła jako komunikat na czat Minecrafta. Wywołanie funkcji dopisujemy do funkcji głównej i testujemy kod:

../../_images/ipython03.png

9.1.3.3. Więcej ruchu

Teraz możemy trochę pochodzić, ale będziemy obserwować to z lotu ptaka. Dopiszmy kod poniższej funkcji do pliku mcpi-podst.py:

Kod nr
49def ruszajSie():
50    from time import sleep
51
52    krok = 10
53    # ustawienie pozycji gracza w środku świata na odpowiedniej wysokości
54    przesunSie(0, 0, 0)
55
56    mc.postToChat("Latam...")
57    przesunSie(0, krok, 0)  # idź krok bloków do góry - latamy :-)
58    sleep(2)
59
60    mc.camera.setFollow()  # ustawienie kamery z góry
61
62    mc.postToChat("Ide w bok...")
63    for i in range(krok):
64        przesunSie(1)  # idź krok bloków w bok
65    sleep(2)
66
67    mc.postToChat("Ide w drugi bok...")
68    for i in range(krok):
69        przesunSie(-1)  # idź krok bloków w drugi bok
70    sleep(2)
71
72    mc.postToChat("Ide do przodu...")
73    for i in range(krok):
74        przesunSie(0, 0, 1)  # idź krok bloków do przodu
75    sleep(2)
76
77    mc.postToChat("Ide do tylu...")
78    for i in range(krok):
79        przesunSie(0, 0, -1)  # idź krok bloków do tyłu
80    sleep(2)
81
82    drukujPoz()
83    mc.camera.setNormal()  # ustawienie kamery normalnie

Warto zauważyć, jak pętla for i in range(krok) umożliwia symulowanie ruchu postaci. Wywołanie funkcji dodajemy do funkcji głównej. Kod testujemy uruchamiając skrypt lub w konsoli.

../../_images/ipython04.png

9.1.3.4. Po czym chodzę?

Teraz spróbujemy dowiedzieć się, po jakich blokach chodzimy. Definiujemy jeszcze jedną funkcję:

Kod nr
86def jakiBlok():
87    x, y, z = mc.player.getPos()
88    return mc.getBlock(x, y - 1, z)

Dopisujemy jej wywołanie: print "Typ bloku: ", jakiBlok() – w funkcji głównej i testujemy.

../../_images/ipython05.png

9.1.4. Plac budowy

Skoro orientujemy się już w przestrzeni, możemy zacząć budować. Na początku wykorzystamy symulator. Rozpoczniemy od przygotowania placu budowy. Posłuży nam do tego odpowiednia funkcja, którą umieścimy w pliku mcsim.py:

Kod nr
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4import sys
 5import os
 6import local.minecraft as minecraft  # import modułu minecraft
 7import local.block as block  # import modułu block
 8
 9os.environ["USERNAME"] = "Steve"  # nazwa użytkownika
10os.environ["COMPUTERNAME"] = "mykomp"  # nazwa komputera
11
12# utworzenie połaczenia z symulatorem
13mc = minecraft.Minecraft.create("")
14
15
16def plac(x, y, z, roz=10, gracz=False):
17    """Funkcja wypełnia sześcienny obszar od podanej pozycji
18    powietrzem i opcjonalnie umieszcza gracza w środku.
19    Parametry: x, y, z - współrzędne pozycji początkowej,
20    roz - rozmiar wypełnianej przestrzeni,
21    gracz - czy umieścić gracza w środku
22    Wymaga: globalnych obiektów mc i block.
23    """
24
25    kamien = block.STONE
26    powietrze = block.AIR
27
28    # kamienna podłoże
29    mc.setBlocks(x, y - 1, z, x + roz, y - 1, z + roz, kamien)
30    # czyszczenie
31    mc.setBlocks(x, y, z, x + roz, y + roz, z + roz, powietrze)
32    # umieść gracza w środku
33    if gracz:
34        mc.player.setPos(x + roz / 2, y + roz / 2, z + roz / 2)
35
36
37def main(args):
38    mc.postToChat("Cześć! Tak działa MC chat!")  # wysłanie komunikatu do mc
39    plac(0, 0, 0, 18)
40    return 0
41
42
43if __name__ == '__main__':
44    sys.exit(main(sys.argv))

Funkcja plac() korzysta z metody setBlocks(x0,y0,z0,x1,y1,z1,blockType, blockData), która wypełnia obszar w przedziałach [x0-x1], [y0-y1], [z0-z1] blokiem podanego typu o opcjonalnych właściwościach. Na początku tworzymy „podłogę” z kamienia, później wypełniamy sześcian o podanym rozmiarze powietrzem. W symulatorze nie jest to przydatne, ale bardzo przydaje się do „wyczyszczenia” miejsca w świecie Minecrafta. Opcjonalnie możemy umieścić gracza w środku utworzonego obszaru.

Kod testujemy uruchamiając skrypt mcsim.py:

~/mcpi-sim$ python mcsim.py

Ostrzeżenie

Skrypt mcsim.py musi znajdować się w katalogu mcpi-sim ze źródłami symulatora, który wykorzystuje specjalne wersje bibliotek minecraft i block z podkatalogu local.

Klawisze sterujące podglądem symulacji widoczne są w terminalu:

../../_images/mc01.png

9.1.5. Umieszczanie bloków

W pliku mcsim.py przed funkcją główną (main()) umieszczamy funkcję buduj():

Kod nr
37def buduj():
38    """
39    Funkcja do testowania umieszczania bloków.
40    Wymaga: globalnych obiektów mc i block.
41    """
42    mc.setBlock(0, 0, 18, block.CACTUS)

Używamy podstawowej metody setBlock(x, y, z, blockType), która w podanych koordynatach umieszcza określony blok. Wywołanie funkcji buduj() dodajemy do main() po funkcji plac() i testujemy. Ponad „podłogą” powinien znaleźć się zielony blok.

Do rysowania bloków można użyć pętli. Zmieniamy funkcję buduj() następująco:

Kod nr
37def buduj():
38    """
39    Funkcja do testowania umieszczania bloków.
40    Wymaga: globalnych obiektów mc i block.
41    """
42    for i in range(19):
43        mc.setBlock(0 + i, 0, 0, block.WOOD)
44        mc.setBlock(0 + i, 1, 0, block.LEAVES)
45        mc.setBlock(0 + i, 0, 18, block.WOOD)
46        mc.setBlock(0 + i, 1, 18, block.LEAVES)
47
48    for i in range(19):
49        mc.setBlock(9, 0, 18 - i, block.BRICK_BLOCK)
50        mc.setBlock(9, 1, 18 - i, block.BRICK_BLOCK)

Teraz plac powinien wyglądać, jak poniżej:

../../_images/mcsim.png

Ćwiczenie 3

Odpowiednio modyfikując funkcję buduj() skonstruuj:

  • kwadrat 2D

  • prostokąt 2D

  • słup

  • bramę, czyli prostokąt 3D

  • sześcian

9.1.6. Przykłady

Zapisz skrypt mcsim.py pod nazwą mcpi-test.py i dostosuj go do uruchomienia na serwerze MC Pi. W tym celu zamień ciąg „local” w importach na „mcpi” oraz podaj adres IP serwera MC Pi w poleceniu tworzącym połączenie. Następnie umieść w pliku kody poniższych funkcji i po kolei je przetestuj dodając ich wywołania w funkcji głównej.

9.1.6.1. Zostawiam ślady

Kod nr
17def jakiBlok():
18    while True:
19        x, y, z = mc.player.getPos()
20        blok_pod = mc.getBlock(x, y - 1, z)
21        print(blok_pod)
22        sleep(1)
23
24
25def slad(blok=38):
26    while True:
27        x, y, z = mc.player.getPos()
28        mc.setBlock(x, y, z, blok)
29        sleep(0.1)
30
31
32def slad_jezeli(pod=2, blok=38):
33    while True:
34        x, y, z = mc.player.getPos()
35        blok_pod = mc.getBlock(x, y - 1, z)  # blok pod graczem
36
37        if blok_pod == pod:
38            mc.setBlock(x, y, z, blok)
39        sleep(0.1)

9.1.6.2. Buduję pomnik

Kod nr
38def pomnik():
39    """
40    Funkcja ustawia blok lawy, nad nim blok wody, a później powietrza.
41    """
42    x, y, z = mc.player.getPos()
43
44    lawa = 10
45    woda = 8
46    powietrze = 0
47
48    mc.setBlock(x + 5, y + 3, z, lawa)
49    sleep(10)
50    mc.setBlock(x + 5, y + 5, z, woda)
51    sleep(4)
52    mc.setBlock(x + 5, y + 5, z, powietrze)

9.1.6.3. Piramida

Kod nr
37def kwadrat(bok, x, y, z):
38    """
39    Fukcja buduje kwadrat, którego środek to punkt x, y, z
40    """
41    pol = bok // 2
42    piaskowiec = block.SANDSTONE
43    mc.setBlocks(x - pol, y, z - pol, x + pol, y, z + pol, piaskowiec, 2)
44
45
46def piramida(podstawa, x, y, z):
47    """
48    Buduje piramidę z piasku, której środek wypada w punkcie x, y, z
49    """
50    bok = podstawa
51    wysokosc = y
52    while bok >= 1:
53        kwadrat(bok, x, wysokosc, z)
54        bok -= 2
55        wysokosc += 1

Źródła:


Licencja Creative Commons Materiały Python 101 udostępniane przez Centrum Edukacji Obywatelskiej na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowa.

Utworzony:

2025-04-12 o 10:21 w Sphinx 7.3.7

Autorzy:

Patrz plik „Autorzy”