LazyBrush Plays Minecraft on Raspberry Pi
So Where do we start? Perhaps at the re-spawn point. Minecraft is an amazingly addictive game. In Minecraft you mine for blocks and you can use these blocks to craft various shapes and buildings. And Kids love it!
The Raspberry Pi is a small cheap computer which is aimed to get kids into computing. The idea is to not just let them learn how to use a spreadsheet, but how to actually program! The combination of Minecraft and Raspberry Pi should be a winner! The creators of Minecraft did something else, they added a Python interface to Minecraft so you can craft outside the game and make various shapes and blocks via programming.
When I saw there was a Python interface I thought it could be quite neat to create a image from blocks automagically. As in, pass in a image file and some magic script makes blocks to represent the image. Here is a sample video of the end result.
In order to do this, you need to program some python. Here is a very simple python script which lets you add a block above the player:
import minecraft.minecraft as minecraft import minecraft.block as block import time mc = minecraft.Minecraft.create() playerPos = mc.player.getPos() xval = int(playerPos.x) yval = int(playerPos.y) + 2 zval = int(playerPos.z) mc.setBlock( xval + 0 , yval + 0, zval, 35 , 15 )
Here, we import various minecraft routines and find the current location of the player. We then change the block at this position (+2 on y axis) to being a ’35’ which is wool. In fact there are 16 different types of wool with the final column of the setBlock being the wool number of interest.
Cool, we have wool. Next, lets thing about getting pixel info from an image. ImageMagick lets you do lots of clever things with images. One thing it can do is convert an image into text like this:
$ convert mona.gif text:- # ImageMagick pixel enumeration: 91,100,255,srgb 0,0: (162,155,104) #A29B68 srgb(162,155,104) 1,0: (151,141, 86) #978D56 srgb(151,141,86) 2,0: (158,148, 95) #9E945F srgb(158,148,95) 3,0: (158,148, 95) #9E945F srgb(158,148,95) ...
The three first 2 numbers are co-ordinates in the image so 0,0 is top left. The next three numbers are the colour, Red, Green and Blue. These numbers range from 0 to 255, so a (0,255,0) would be The Purest Green. In the wool image there is the RGB split for each colour. So ALL we need to do is pick a good wool colour for each image colour we find. We could be clever and convert RGB into a different colour space, but we try not to be too clever most of the time. So lets just compare our image RGB with the wool RGB.
Ok, I said we weren’t going to be too clever, that’s a little white lie. My mate Pythagoras really really liked triangles. We could use his neat idea to find the shortest distance between a colour in our image and one of the wool colours.
So now we almost have everything. Raspberry Pi, Minecraft, Python, Pythagoras anything else? Well, one way to solve this would be to use shell, awk and sed. With all this, mixed with some idle time you might make these scripts.
wool.txt – The same as the above wool image but in a computer readable format.
0 221 221 221 White #DDDDDD 1 219 125 62 Orange #DB7D3E 2 179 80 188 Pink #8350BC 3 107 138 201 Blue #6B8AC9 4 177 166 39 Yellow #B1A627 5 65 174 56 Green #41AE38 6 208 132 153 Salmon #D08499 7 64 64 64 Grey #404040 8 154 161 161 LtGrey #9AA1A1 9 46 110 137 Navy #2E6E89 10 126 61 181 Purple #7E3DB5 11 46 56 141 DrkBlue #2E388D 12 79 50 31 Brown #4F321F 13 53 70 27 Kacki #35461B 14 150 52 48 Red #963430 15 25 22 22 Black #191616
woolbest.sh – A Shell script to pick a nice wool given a colour RGB value
R=$1 G=$2 B=$3 X=$4 Y=$5 T=$6 cat wool.txt | awk -v Red=$R -v Green=$G -v Blue=$B -v Xco=$X -v Yco=$Y -v Type=$T ' BEGIN { near=100000 val=0 } { if ($2 < Red) tRed=Red-$2 else tRed=$2-Red if ($3 < Green) tGreen=Green-$3 else tGreen=$3-Green if ($4 < Blue) tBlue=Blue-$2 else tBlue=$2-Blue distance = tRed*tRed + tGreen*tGreen + tBlue*tBlue if (near > distance) { near=distance val=$1 cols=$2 ", " $3 ", " $4 hash=$6 } } END { #print val #minecraft block if (Type == "Img") print Xco "," Yco ": ( " cols ",255) " hash " srgba(" cols ",1)" else print "mc.setBlock( xval + " Xco " , yval + " Yco ", zval, 35 , " val " )" }'
mkblock.sh – A shell script to take an image in and output a python script.
img=$1 type=$2 img_new=new_$1 img_mc=new_$1.py img_txt=tmp_$1.txt img_txt_head=tmp_head_$1.txt img_txt_tail=tmp_tail_$1.txt img_sh=tmp_$1.sh img_new_txt=tmp_new_$1.txt echo Proceessing Block $img if [ "$type" = "MC" ] then flip=" -flip " else flip="" fi echo Convert to Text convert -resize 64x64 $flip $img text:- > $img_txt echo Get the Head head -1 $img_txt > $img_txt_head echo Get the Tail len=`wc -l $img_txt | awk '{print $1}'` len=`expr $len - 1` tail -$len $img_txt > $img_txt_tail echo Build up Pixel Changing Script cat $img_txt_tail | awk 'BEGIN{FS=","} { print $1 " " $2 " " $3 " " $4 }' | sed 's/://g' | sed 's/(//g' | sed 's/)//g' | awk -v T=$type '{print "./woolbest.sh " $3 " " $4 " " $5 " " $1 " " $2 " " T }' > $img_sh chmod +x $img_sh if [ "$type" = Img ] then echo Type Img Change Pixels cat $img_txt_head > $img_new_txt ./$img_sh >> $img_new_txt echo Convert back from Text to Img convert text:$img_new_txt $img_new fi if [ "$type" = MC ] then cat << DONE > $img_mc import minecraft.minecraft as minecraft import minecraft.block as block import time mc = minecraft.Minecraft.create() playerPos = mc.player.getPos() xval = int(playerPos.x) yval = int(playerPos.y) + 2 zval = int(playerPos.z) DONE ./$img_sh >> $img_mc fi echo Tidy Up rm -f $img_txt $img_txt_head $img_txt_tail $img_sh $img_new_txt
I also decided it might be useful to see what the image could look like before we load it into minecraft with python. With ImageMagick it not only coverts to text format it converts from it too. So a little tweak to the mkblock.sh script means we can do the following:
Andys-iMac:mine andy$ ./mkblock.sh mona.gif Img Proceessing Block mona.gif Convert to Text Get the Head Get the Tail Build up Pixel Changing Script Type Img Change Pixels Convert back from Text to Img Tidy Up Andys-iMac:mine andy$
Which makes an image with the wool colours and at the resolution that we see in minecraft.
You can download these scripts and convert your images into python scripts by doing the following:
Andys-iMac:mine andy$ ./mkblock.sh mona.gif MC Proceessing Block mona.gif Convert to Text Get the Head Get the Tail Build up Pixel Changing Script Tidy Up Andys-iMac:mine andy$
Note the ‘MC’ at the end which then makes a script called ‘new_mona.gif.py’ which you can run with python on a raspberry pi.
If you are unsure what images to try, why not see what Mona Lisa likes to do in her spare time.
Thanks for reading!
Why mix shell, awk, sed and Python, rather than doing the whole lot just in Python?
If you used Python Imaging Library (PIL) you could get rid of the use of ImageMagick too 😉
P.S. One of the neat things about the Pythagoras formula is that the inputs always get squared, i.e. it doesn’t matter if they’re initially negative, i.e. you don’t need to check “if ($2 < Red)" etc.
Hello AndrewS! All good comments. The fun of Unix is that there are many ways to solve a problem. I’d say for quick prototyping pick any tools you like and then you can refine your solution later.
“for quick prototyping pick any tools you like and then you can refine your solution later”
Yeah, that’s what I usually do too 🙂
But in your article you specifically mentioned “get kids into computing”, and I reckon they’d be put off by such a mix of languages all at once.
Whoa it is realy performing first class gaming, i’ve got to talk about that may this can be a perfect gaming in fact, together with our loved one along with my spouse and i finaly observed this excellent write-up that means it is more excellent using this type of free stuff appreciate it!
Good appreciate it greatly for this good stuff my spouse and i minecraft liked that write-up and also this video game device for you to is incredibly beneficial.