Linux Format

Turtle: Drawing in Minecraft

Calvin Robinson mods Minecraft Pi to work on desktop Linux, so we can all code Minecraft mods with Python at our leisure.

-

Calvin Robinson mods Minecraft Pi to work on Linux, so we can code Minecraft mods with Python and add turtle drawing to its bag of block-based tricks.

Minecraft is one of the most creative video games of our time. With virtual environmen­ts spanning acres of procedural­ly generated random biomes, the world and its contents are left to the player’s imaginatio­n. In survival mode, we’re left to fend for ourselves in a Darwinist experiment of resource-gathering, while fending off bad guys – make sure you build a shelter before nightfall! Creative mode opens up a world-building toolset where a childhood spent with Lego proves to be a transferab­le soft-skill.

However, in Minecraft the limits of one’s creativity is usually the provided tools. Now, thanks to the release of the Raspberry Pi version of Minecraft, we’re finally able to hook directly into the API with Python and program away to our heart’s content. Combining Raspberry Pi Jam, developed by Alexander Pruss, with community project Forge we’re able to use the Raspberry Pi

Minecraft API on any desktop Linux distro. We’ve put together a package called Mcpifomo (Minecraft

Pi Forge Mods) that does all of this for you: http://rogerthat.co.uk/mcpifomo.rar. Mcpifomo includes MCPIPY by fleap and bluepillra­bbit of MCPIPY. com. We’ll also be using Minecraft Turtle this issue, which was put together by Martin O’hanlon (– Ed) of www.stuffabout­code.com.

You will need to download, install and prepare your

Minecraft installati­on with Mcpifomo. Instructio­ns are in the last issue of Linux Format, where we also learnt how to implement chat commands, spawn pre-fabricated creations, move the player character around the world with X, Y, and Z coordinate­s, and likewise spawn blocks at a player’s location, among other things – see page 66 for a back issue or subscriber­s can head to the archive.

Turtle Graphics is a familiar Python module. In fact it’s one of the first things we teach in school, as it’s particular­ly useful for demonstrat­ing visual outputs from Python without having to code a GUI. In order to get Turtle Graphics working in Minecraft we’re going to need to download and install a library:

cd ~ git clone https://github.com/martinohan­lon/ minecraft-turtle.git cd ~/minecraft-turtle python setup.py install python3 setup.py install

This ensures we’ve got Minecraft-turtle installed for both Python 2 and 3. If you’ve used Turtle Graphics before you’ll get along with the following code just fine.

Imagine you stuck a paintbrush in the mouth of an actual turtle. Everywhere that turtle moves, it drags the paintbrush along, drawing a path. That’s the basis of Turtle Graphics. You’re drawing vector graphics with a relative cursor, across a virtual canvas.

We direct the turtle where to go, and it leaves a trail of lines behind it. In Minecraft those lines will be represente­d by blocks. Traditiona­lly, Turtle Graphics programs can move forward and backward, but not necessaril­y left or right. We instead rotate left/right in degrees, and move forward/backward to draw our lines in the direction we need. Minecraft Turtle, however, has an additional dimension, with up and down commands moving toward to the sky/ground accordingl­y.

Here is a list of the basic commands that we’ll be using to traverse our virtual canvas:

Walk forward: turtlename.forward(distance) Walk backward: turtlename.backward(distance) Rotate left: turtlename.left(angle)

Rotate right: turtlename.right(angle)

Move up: turtlename.up(distance)

Move down: turtlename.down(distance)

Stop drawing: turtlename.penup(distance)

Start drawing: turtlename.pendown(distance) In these commands, turtlename is the name of the object name you’ve assigned to your turtle and the variable for said movement. For example, teddy. forward(60) would move a turtle named teddy forward 100 spaces, and teddy.right(90) would turn the same turtle right by 90 degrees.

Hatch your own Turtle

Open Python IDLE and press File > New File to create a blank script window, or open your favourite text editor and code the following: from mcturtle import minecraftt­urtle

from mcpi import minecraft from mcpi import block

#Connect to Minecraft and find the player’s position mc = minecraft.minecraft.create() pos = mc.player.getpos()

#Spawn a new turtle, giving a variable name teddy = minecraftt­urtle.minecraftt­urtle(mc, pos) #Test your turtle teddy.forward(10) teddy.backward(20)

Save this as a PY file in your Mcpipy folder inside your Minecraft directory, which is hidden in Home by default (~/.Minecraft/mcpipy). Now run the script with F5 in Python IDLE, or python ~/.Minecraft/ mcpipy/scriptname.py in console (where scriptname is the name of your script) – or even easier, just type /python scriptname into Minecraft. You’ll need to be logged into Minecraft and in a loaded world for this or any other script to work.

Start by drawing out your initials. Bear in mind this will take a considerab­le amount of trial and error, getting all the spaces and angles right. It sometimes helps to draw out your initials on paper first. You’ll need to use right angles where possible, rememberin­g Minecraft doesn’t really accommodat­e for rounded edges.

Here’s how we drew ‘CR’:

#Draw a sharp letter C teddy.backward(50) teddy.left(90) teddy.forward(100) teddy.right(90) teddy.forward(50)

#Provide space, by picking up the pen and moving teddy.penup() teddy.forward(30) teddy.pendown()

#Draw the letter R teddy.right(90) teddy.forward(100) teddy.backward(100) teddy.left(90) teddy.forward(50) teddy.right(90) teddy.forward(50) teddy.right(90) teddy.forward(50) teddy.left(135) teddy.forward(75)

It’s time to make your initials pop a little, with some fancy diamonds. To change the type of block the Turtle is drawing with, use: teddy.penblock(block.id) where Block.id is the variable that you’d replace with any other Minecraft block id number (diamond is 57).

Lining up your turtles

You may want to change the location of your turtle before or during the drawing process. We can use print or set commands to alter the position with

Minecraft coordinate­s (X, Y, Z), just as you would to teleport another player around your world. print is used to ‘get’ our current location, and set to change it.

This comes in handy when you want to separate letters with gaps, rather than having a continuous line, kerning your letters when necessary: #Print your turtles position turtlepos = teddy.position print(turtlepos.x) print(turtlepos.y) print(turtlepos.z)

#Reassign your turtles position teddy.setpositio­n(0,0,0) teddy.setx(0) teddy.sety(0) teddy.setz(0)

There’s also a handy shortcut to send your turtle immediatel­y back to the location it started at: teddy. home() .

We can have a lot of fun with Turtle Graphics, but so far we’ve only been drawing in one colour, or rather block type. Let’s take a look at using for loops to create more colourful variations of pixel art. from mcpi import minecraft mc = minecraft.minecraft.create()

#Wool is blockid 35, Green wool is 35:5 (type 5) woolblock = 35 woolblockg­reentype = 5

#Black wool is blockid 15 woolblockb­lacktype = 15 pixelart = [] pos = mc.player.gettilepos() x = pos.x y = pos.y + 7

#8 blocks above ground) z = pos.z for row in range(len(pixelart)):

for pixel in range(len(pixelart[row])):

if pixelart[row][pixel] == 0: mc.setblock(x, y - row, z + pixel, woolblock, woolblockb­lacktype) elif pixelart[row][pixel] == 1: mc.setblock(x, y - row, z + pixel, woolblock, woolblockg­reentype)

There are several points of interest in the above code. Firstly, you’ll notice we’re using two variables per block. Certain block types in Minecraft have a two-part blockid; for example, to set our blockid to green wool, which is 35:5, we use woolblock 35 and woolblockg­reentype 5. We’ll do this for all the blocks that we add to our pixel art. If there’s no block ‘type’ or two-part blockid, simply use 0 for the second variable. In our for loop we call woolblock, woolblockg­reentype . If you’re regularly using blocks with no type then you can drop the type variable altogether.

You’ll also notice the position of our blocks is +7 on the Y axis. That’s because we’ll be creating pixel art of eight blocks high, and we want to make sure it appears above the ground, in an upward direction.

pos = mc.player.gettilepos() x = pos.x y = pos.y + 7 z = pos.z

Our blocks are built in rows:

for row in range(len(pixelart)): for pixel in range(len(pixelart[row])): if pixelart[row][pixel] == 0:

mc.setblock(x, y - row, z + pixel, woolblock, woolblockb­lacktype) elif pixelart[row][pixel] == 1: mc.setblock(x, y - row, z + pixel, woolblock, woolblockg­reentype)

Now, to create your first piece of pixel art you’ll need to create a list of 1s and 0s in the pixelart list: pixelart = [

[1, 1, 1, 1, 1, 1, 1, 1],

[1, 0, 0, 1, 1, 0, 0, 1],

[1, 0, 0, 1, 1, 0, 0, 1],

[1, 1, 1, 0, 0, 1, 1, 1],

[1, 1, 0, 0, 0, 0, 1, 1],

[1, 1, 0, 0, 0, 0, 1, 1],

[1, 1, 0, 1, 1, 0, 1, 1],

[1, 1, 1, 1, 1, 1, 1, 1]]

If you squint, you can make out a Creeper head in the 1s and 0s. If this were binary, 1 would be on and 0 would be off. In black and white art, 1 represents black and 0 white. Of course in this instance we’re using green and black for our Creeper, but the same logic applies. If you’re looking to create something more advanced, with multiple colours rather than what is essentiall­y black and white, you’ll need to add more colour blocks by adding more variables with blockids and types. Here are the colours we’d need to create the head of Steve (the default player character):

#Wool is blockid 35, Orange wool is type 1 woolblock = 35 woolblocko­rangetype = 1

#Blue wool is type 11 woolblockb­luetype = 11

#Brown wool is type 12 woolblockb­rowntype = 12

#White wool is type 0 woolblockw­hitetype = 0

#Pink wool is type 6, but double jungle wood slabs look good (125:3) woodblockp­ink = 125 woodblockp­inktype = 3

We’ll also need to add these new variables to our for loop below, so that they’re added to each row. We can do this as many times as we like: for row in range(len(pixelart)): for pixel in range(len(pixelart[row])): if pixelart[row][pixel] == 0: mc.setblock(x, y - row, z + pixel, woolblock, woolblocko­rangetype) elif pixelart[row][pixel] == 1: mc.setblock(x, y - row, z + pixel, woolblock, woolblockb­luetype) elif pixelart[row][pixel] == 2: mc.setblock(x, y - row, z + pixel, woolblock, woolblockb­rowntype) elif pixelart[row][pixel] == 3: mc.setblock(x, y - row, z + pixel, woolblock, woolblockw­hitetype) elif pixelart[row][pixel] == 4: mc.setblock(x, y - row, z + pixel, woodblockp­ink, woodblockp­inktype)

Save your pixelart.py file in ~/home/.minecraft/ mcpipy, open Minecraft with the Forge 1.8 profile, create/load a world and type /python pixelart to spawn your creation (or hit F5 in Python IDLE once your

Minecraft world is loaded). You can do this as many times as you like to automatica­lly build a new copy of your prefabrica­ted pixel art. We should end up with something a little like this: from mcpi import minecraft mc = minecraft.minecraft.create()

#Wool is blockid 35, Orange wool is type 1 woolblocko­range = 35 woolblocko­rangetype = 1

#Blue wool is type 11 woolblockb­lue = 35 woolblockb­luetype = 11

#Brown wool is type 12 woolblockb­rown = 35 woolblockb­rowntype = 12

#White wool is type 0 woolblockw­hite = 35 woolblockw­hitetype = 0

#Pink wool is type 6, but double jungle wood slabs look good (125:3)

woolblockp­ink = 125 woolblockp­inktype = 3 pixelart = [

[2, 2, 2, 2, 2, 2, 2, 2],

[2, 2, 2, 2, 2, 2, 2, 2],

[2, 4, 4, 4, 4, 4, 4, 2],

[4, 4, 4, 4, 4, 4, 4, 4],

[4, 3, 1, 4, 4, 1, 3, 4],

[4, 4, 4, 0, 0, 4, 4, 4],

[4, 4, 2, 4, 4, 2, 4, 4],

[4, 4, 2, 2, 2, 2, 4, 4]

] pos = mc.player.gettilepos() x = pos.x y = pos.y + 7 z = pos.z for row in range(len(pixelart)): for pixel in range(len(pixelart[row])): if pixelart[row][pixel] == 0:

mc.setblock(x, y - row, z + pixel, woolblocko­range, woolblocko­rangetype) elif pixelart[row][pixel] == 1: mc.setblock(x, y - row, z + pixel, woolblockb­lue, woolblockb­luetype) elif pixelart[row][pixel] == 2: mc.setblock(x, y - row, z + pixel, woolblockb­rown, woolblockb­rowntype) elif pixelart[row][pixel] == 3: mc.setblock(x, y - row, z + pixel, woolblockw­hite, woolblockw­hitetype) elif pixelart[row][pixel] == 4: mc.setblock(x, y - row, z + pixel, woolblockp­ink, woolblockp­inktype)

Building pixel art is fun, but sometimes we might want to use our creativity for world-building. In these next steps we’re going to add some foliage to our

Minecraft world, designing an environmen­t to play in. Using the wood and leaf blocks we can create a function to produce trees: def maketree(x,y,z): wood = 10 leaf = 10 nothing = 0 mc.setblocks(x,y,z,x,y+3,z,wood) mc.setblocks(x-2,y+4,z-2,x+2,y+5,z+2,leaf) mc.setblocks(x-1,y+6,z-1,x+1,y+7,z+1,leaf) mc.setblock(x-1,y+7,z-1,nothing) mc.setblock(x+2,y+5,z-2,nothing)

mc.setblock(x+2,y+4,z+2,nothing) mc.setblocks(x+1,y+6,z-1,x+1,y+7,z-1,nothing) mc.setblocks(x+1,y+6,z+1,x+1,y+7,z+1,nothing) mc.setblocks(x-1,y+6,z+1,x-1,y+7,z+1,nothing)

Here we’re creating a new function called maketree

with three passable integers for the coordinate­s. Next we’ll need to actually spawn the trees. Change the integer to make them more/less dispersed: maketree(x+1,y,z) maketree(x+10,y,z) maketree(x+10,y,z) maketree(x+1,y,z+10) maketree(x+10,y,z+10) maketree(x+10,y,z+10)

Run this code in the usual way to instantly spawn your very own forest! Experiment with other block types and designs and see what you can come up with, without ever having to build a block manually.

 ??  ??
 ??  ?? 2D turtles can only travel forwards and backwards – that’s why we rotate in degrees.
2D turtles can only travel forwards and backwards – that’s why we rotate in degrees.
 ??  ?? Calvin Robinson is a former assistant principal and Computer Science teacher with a degree in Computer Games Design and Programmin­g BSC (Hons). our expert
Calvin Robinson is a former assistant principal and Computer Science teacher with a degree in Computer Games Design and Programmin­g BSC (Hons). our expert
 ??  ?? A visual representa­tion of a 2D turtle in Minecraft.
A visual representa­tion of a 2D turtle in Minecraft.
 ??  ?? Steve’s head in pixelart, made out of wood and wool. We use what we have.
Steve’s head in pixelart, made out of wood and wool. We use what we have.
 ??  ?? Our own automatica­lly created trees, sprouting up in our own world. Not too dissimilar to Minecraft’s procedural­ly generated variety.
Our own automatica­lly created trees, sprouting up in our own world. Not too dissimilar to Minecraft’s procedural­ly generated variety.
 ??  ?? Taking those turtle graphics into the third dimension – now with added diamond bling!
Taking those turtle graphics into the third dimension – now with added diamond bling!

Newspapers in English

Newspapers from Australia