Python coding for Minecraft (13 / 17 steg)
Steg 13: Avancerad anteckningar 3: knop
På nätet kan du hitta parametriska ekvationen för knop. Den här gången, kommer vi att göra saker lite annorlunda från innan. Innan hade vi loopar körning samtal till mc.setBlock() direkt. Men i vår yta tomter, som Klein flaskan, ofta i samma kvarter skulle få flera gånger, som är långsam och ineffektiv. Ett bättre sätt är att hålla reda på uppsättningen exakta block som drogs redan för att undvika göra om samma sak.
Låt mig gå igenom ett exempel som det (i knot.py) rita en knut. Börja med en vanlig rubrik som:
från mc import *
Nu måste vi skapa vår knut. Jag använde FINGERÖRT formlerna från här. Detta kräver looping en parameter t från 0 till 2 * pi, med små tillräckligt åtgärder för att säkerställa att vi inte har luckor. Jag använde 10000 steg. Eftersom detta görs i minnet, och datorer är snabb och överlappande block är bara skickas en gång till Minecraft, är det lättare att lättare att göra fler steg än att tänka hur många räcker. Det är viktigt att koordinaterna som går i ordlistan vara heltal så att vi kan säga att i samma kvarter som ritning (ett block på (1.1,1.2,1.4) och ett block på (1,1,1) är samma sak i Minecraft).
Vi först initiera och ange positionen för Knut i förhållande till spelaren. Observera att spelare position inte behöver vara ett heltal (du inte kan stå exakt linje med ett block) och bör omvandlas till ett heltal.
MC = Minecraft()
playerPos = mc.player.getPos()
skala = 12
x0 = int(playerPos.x)
y0 = int (playerPos.y + 5 * skala)
Z0 = int(playerPos.z)
Nu gör vi en tom mängd heter gjort att lagra de koordinater som vi redan har ritat:
klart = set()
Och vi dra uppsättningen:
t = 0
även om t < 2 * pi:
x = x 0 + int (skala * cos(2*t) * (3 + cos(5*t)))
y = y0 + int (skala * sin(2*t) * (3 + cos(5*t)))
z = z0 + int (skala * sin(5*t))
om (x, y, z) inte gjort:
mc.setBlock(x,y,z,GOLD_BLOCK)
Done.Add((x,y,z))
t + = 2 * pi / 10000
Detta drar endast data som inte är redan dragna. Observera att vi behöver att runda av x, y och z koordinater med funktionen int(). Det är magin bakom överlappning avlägsnande: när de runda koordinaterna är samma, bara ett kvarter dras. (Obs: den dubbla parentesen i done.add((x,y,z)) linjen är på grund av att vi lägger till uppsättningen är koordinaten trippel (x, y, z).)
Ovanstående kod är i knot.py.
Knut skulle se bättre om repet var tjockare. Det finns många sätt man kan göra som. Ett ineffektivt sätt, men lätt eftersom datorer är snabbt dessa dagar, är bara att dra en liten boll inte en punkt på varje pixel. För att göra det, först göra jag lite nytta funktion för att rita en boll medan checkar in den gjort så finns det inga dubbletter block:
def ball(x0,y0,z0,r,block,done):
x i range(-r,r):
för y i range(-r,r):
för z i range(-r,r):
om (x ** 2 + y ** 2 + z ** 2 < = r ** 2):
om inte (x 0 + x, y0 + y, z0 + z) i gjort:
mc.setBlock (x 0 + x, y0 + y, z0 + z, block)
Done.Add((x0+x,y0+y,Z0+z))
Detta används metoden ojämlikheten för att fylla i en boll på (x0, y0, z0), av radien r.
Sedan bara ändra vår Knut-making medan loop för att göra en boll istället för bara en punkt:
skala = 10
x0 = int(playerPos.x)
y0 = int (playerPos.y + 5 * skala)
Z0 = int(playerPos.z)
klart = set()
t = 0
även om t < 2 * pi:
x = x 0 + int (skala * cos(2*t) * (3 + cos(5*t)))
y = y0 + int (skala * sin(2*t) * (3 + cos(5*t)))
z = z0 + int (skala * sin(5*t))
Ball(x,y,z,4,GOLD_BLOCK,Done)
t + = 2 * pi / 10000
Resultatet är i knot2.py i exempelskripten.
Andra provet knop är i trefoil.py, trefoil2.py och borromean.py. Om du ritar med flera material, kan du använda en ordlista i stället för en uppsättning, eller bara gå sekventiellt genom olika material och klart uppsättningen före (det är vad jag gör i trefoil2.py och borromean.py).