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

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:
1 2 3 4 5 6 | import mcpi.minecraft as minecraft # import modułu minecraft
import mcpi.block as block # import modułu block
import os
os.environ["USERNAME"] = "Steve" # wpisz dowolną nazwę użytkownika
os.environ["COMPUTERNAME"] = "mykomp" # wpisz dowolną nazwę komputera
mc = 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:

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:

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

Ć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
:
38 39 40 41 42 43 44 45 46 | def drukujPoz():
"""Drukuje pozycję gracza.
Wymaga globalnego obiektu połączenia mc.
"""
pos = mc.player.getPos()
print pos
pos_str = map(str, (pos.x, pos.y, pos.z))
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:

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

9.1.3.4. Po czym chodzę?¶
Teraz spróbujemy dowiedzieć się, po jakich blokach chodzimy. Definiujemy jeszcze jedną funkcję:
86 87 88 | def jakiBlok():
x, y, z = mc.player.getPos()
return mc.getBlock(x, y - 1, z)
|
Dopisujemy jej wywołanie: print "Typ bloku: ", jakiBlok()
– w funkcji głównej i testujemy.

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
:
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 43 44 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import local.minecraft as minecraft # import modułu minecraft
import local.block as block # import modułu block
os.environ["USERNAME"] = "Steve" # nazwa użytkownika
os.environ["COMPUTERNAME"] = "mykomp" # nazwa komputera
# utworzenie połaczenia z symulatorem
mc = minecraft.Minecraft.create("")
def plac(x, y, z, roz=10, gracz=False):
"""Funkcja wypełnia sześcienny obszar od podanej pozycji
powietrzem i opcjonalnie umieszcza gracza w środku.
Parametry: x, y, z - współrzędne pozycji początkowej,
roz - rozmiar wypełnianej przestrzeni,
gracz - czy umieścić gracza w środku
Wymaga: globalnych obiektów mc i block.
"""
kamien = block.STONE
powietrze = block.AIR
# kamienna podłoże
mc.setBlocks(x, y - 1, z, x + roz, y - 1, z + roz, kamien)
# czyszczenie
mc.setBlocks(x, y, z, x + roz, y + roz, z + roz, powietrze)
# umieść gracza w środku
if gracz:
mc.player.setPos(x + roz / 2, y + roz / 2, z + roz / 2)
def main(args):
mc.postToChat("Cześć! Tak działa MC chat!") # wysłanie komunikatu do mc
plac(0, 0, 0, 18)
return 0
if __name__ == '__main__':
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:

9.1.5. Umieszczanie bloków¶
W pliku mcsim.py
przed funkcją główną (main()
) umieszczamy funkcję buduj()
:
37 38 39 40 41 42 | def buduj():
"""
Funkcja do testowania umieszczania bloków.
Wymaga: globalnych obiektów mc i block.
"""
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:
37 38 39 40 41 42 43 44 45 46 47 48 49 50 | def buduj():
"""
Funkcja do testowania umieszczania bloków.
Wymaga: globalnych obiektów mc i block.
"""
for i in range(19):
mc.setBlock(0 + i, 0, 0, block.WOOD)
mc.setBlock(0 + i, 1, 0, block.LEAVES)
mc.setBlock(0 + i, 0, 18, block.WOOD)
mc.setBlock(0 + i, 1, 18, block.LEAVES)
for i in range(19):
mc.setBlock(9, 0, 18 - i, block.BRICK_BLOCK)
mc.setBlock(9, 1, 18 - i, block.BRICK_BLOCK)
|
Teraz plac powinien wyglądać, jak poniżej:

Ć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¶
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | def jakiBlok():
while True:
x, y, z = mc.player.getPos()
blok_pod = mc.getBlock(x, y - 1, z)
print(blok_pod)
sleep(1)
def slad(blok=38):
while True:
x, y, z = mc.player.getPos()
mc.setBlock(x, y, z, blok)
sleep(0.1)
def slad_jezeli(pod=2, blok=38):
while True:
x, y, z = mc.player.getPos()
blok_pod = mc.getBlock(x, y - 1, z) # blok pod graczem
if blok_pod == pod:
mc.setBlock(x, y, z, blok)
sleep(0.1)
|
9.1.6.2. Buduję pomnik¶
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | def pomnik():
"""
Funkcja ustawia blok lawy, nad nim blok wody, a później powietrza.
"""
x, y, z = mc.player.getPos()
lawa = 10
woda = 8
powietrze = 0
mc.setBlock(x + 5, y + 3, z, lawa)
sleep(10)
mc.setBlock(x + 5, y + 5, z, woda)
sleep(4)
mc.setBlock(x + 5, y + 5, z, powietrze)
|
9.1.6.3. Piramida¶
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | def kwadrat(bok, x, y, z):
"""
Fukcja buduje kwadrat, którego środek to punkt x, y, z
"""
pol = bok // 2
piaskowiec = block.SANDSTONE
mc.setBlocks(x - pol, y, z - pol, x + pol, y, z + pol, piaskowiec, 2)
def piramida(podstawa, x, y, z):
"""
Buduje piramidę z piasku, której środek wypada w punkcie x, y, z
"""
bok = podstawa
wysokosc = y
while bok >= 1:
kwadrat(bok, x, wysokosc, z)
bok -= 2
wysokosc += 1
|
Źródła:
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: | 2022-05-22 o 19:52 w Sphinx 1.5.3 |
---|---|
Autorzy: | Patrz plik “Autorzy” |