Ive been playing around with the pre-release of minecraft on the Raspberry Pi and in particular the API, see this post for some background on the basics, and rather than watching 'Food Inspectors' on the tv, I thought I would see if I could write a game in minecraft (a game in a game I suppose) in an hour. This is what I came up with....
Minecraft - Hide and Seek!
The concept is really simple, a diamond block is hidden, at a random location, in the minecraft world and you have to find it and stand next to it and its quickest time wins. You are helped along the way by the game telling you whether you are getting "warmer" or "colder" and how far you are from the block!
I recorded this video using the the pre-release and you will notice towards the end of the video that it starts to go a bit weird, with a flashing screen and the player being moved about!
Download and run
You can download the code direct from git-hub, so run minecraft, open/create a world and follow the instructions:
sudo apt-get install git-core
cd ~
git clone https://github.com/martinohanlon/minecraft-hs.git
cd minecraft-hs
python minecraft-hs.py
cd ~
git clone https://github.com/martinohanlon/minecraft-hs.git
cd minecraft-hs
python minecraft-hs.py
The code
If you want learn and have a go yourself, here's how:
Create a directory for the program
mkdir ~/minecraft-hs
Create minecraft-hs.py python program
nano ~/minecraft-hs/minecraft-hs.py
or open Idle and save minecraft-hs.py to the minecraft-hs directory
Code
#www.stuffaboutcode.com
#Raspberry Pi, Minecraft - hide and seek
#import the minecraft.py module from the mcpi library
import mcpi.minecraft as minecraft
#import minecraft block module
import mcpi.block as block
#import time, so delays can be used
import time
#import random module to create random number
import random
#import math module to use square root function
import math
#function to round players float position to integer position
def roundVec3(vec3):
return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))
def distanceBetweenPoints(point1, point2):
xd = point2.x - point1.x
yd = point2.y - point1.y
zd = point2.z - point1.z
return math.sqrt((xd*xd) + (yd*yd) + (zd*zd))
if __name__ == "__main__":
#Connect to minecraft by creating the minecraft object
# - minecraft needs to be running and in a game
mc = minecraft.Minecraft.create()
#Post a message to the minecraft chat window
mc.postToChat("Hi, Minecraft Hide & Seek")
time.sleep(2)
#Find the players position
playerPos = mc.player.getPos()
#Create random position within 50 blocks from the player, our hidden block will go there
randomBlockPos = roundVec3(playerPos)
randomBlockPos.x = random.randrange(randomBlockPos.x - 50, randomBlockPos.x + 50)
randomBlockPos.y = random.randrange(randomBlockPos.y - 5, randomBlockPos.y + 5)
randomBlockPos.z = random.randrange(randomBlockPos.z - 50, randomBlockPos.z + 50)
print randomBlockPos
#Create hidden diamond block
mc.setBlock(randomBlockPos.x, randomBlockPos.y, randomBlockPos.z, block.DIAMOND_BLOCK)
mc.postToChat("A diamond has been hidden - go find!")
#Start hide and seek
seeking = True
lastPlayerPos = playerPos
lastDistanceFromBlock = distanceBetweenPoints(randomBlockPos, lastPlayerPos)
timeStarted = time.time()
while (seeking == True):
#Get players position
playerPos = mc.player.getPos()
#Has the player moved
if lastPlayerPos != playerPos:
#print "lastDistanceFromBlock = " + str(lastDistanceFromBlock)
distanceFromBlock = distanceBetweenPoints(randomBlockPos, playerPos)
#print "distanceFromBlock = " + str(distanceFromBlock)
if distanceFromBlock < 2:
#found it!
seeking = False
else:
if distanceFromBlock < lastDistanceFromBlock:
mc.postToChat("Warmer " + str(int(distanceFromBlock)) + " blocks away")
if distanceFromBlock > lastDistanceFromBlock:
mc.postToChat("Colder " + str(int(distanceFromBlock)) + " blocks away")
lastDistanceFromBlock = distanceFromBlock
time.sleep(2)
timeTaken = time.time() - timeStarted
mc.postToChat("Well done - " + str(int(timeTaken)) + " seconds to find the diamond")
time.sleep(5)
mc.postToChat("www.stuffaboutcode.com")
#Raspberry Pi, Minecraft - hide and seek
#import the minecraft.py module from the mcpi library
import mcpi.minecraft as minecraft
#import minecraft block module
import mcpi.block as block
#import time, so delays can be used
import time
#import random module to create random number
import random
#import math module to use square root function
import math
#function to round players float position to integer position
def roundVec3(vec3):
return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))
def distanceBetweenPoints(point1, point2):
xd = point2.x - point1.x
yd = point2.y - point1.y
zd = point2.z - point1.z
return math.sqrt((xd*xd) + (yd*yd) + (zd*zd))
if __name__ == "__main__":
#Connect to minecraft by creating the minecraft object
# - minecraft needs to be running and in a game
mc = minecraft.Minecraft.create()
#Post a message to the minecraft chat window
mc.postToChat("Hi, Minecraft Hide & Seek")
time.sleep(2)
#Find the players position
playerPos = mc.player.getPos()
#Create random position within 50 blocks from the player, our hidden block will go there
randomBlockPos = roundVec3(playerPos)
randomBlockPos.x = random.randrange(randomBlockPos.x - 50, randomBlockPos.x + 50)
randomBlockPos.y = random.randrange(randomBlockPos.y - 5, randomBlockPos.y + 5)
randomBlockPos.z = random.randrange(randomBlockPos.z - 50, randomBlockPos.z + 50)
print randomBlockPos
#Create hidden diamond block
mc.setBlock(randomBlockPos.x, randomBlockPos.y, randomBlockPos.z, block.DIAMOND_BLOCK)
mc.postToChat("A diamond has been hidden - go find!")
#Start hide and seek
seeking = True
lastPlayerPos = playerPos
lastDistanceFromBlock = distanceBetweenPoints(randomBlockPos, lastPlayerPos)
timeStarted = time.time()
while (seeking == True):
#Get players position
playerPos = mc.player.getPos()
#Has the player moved
if lastPlayerPos != playerPos:
#print "lastDistanceFromBlock = " + str(lastDistanceFromBlock)
distanceFromBlock = distanceBetweenPoints(randomBlockPos, playerPos)
#print "distanceFromBlock = " + str(distanceFromBlock)
if distanceFromBlock < 2:
#found it!
seeking = False
else:
if distanceFromBlock < lastDistanceFromBlock:
mc.postToChat("Warmer " + str(int(distanceFromBlock)) + " blocks away")
if distanceFromBlock > lastDistanceFromBlock:
mc.postToChat("Colder " + str(int(distanceFromBlock)) + " blocks away")
lastDistanceFromBlock = distanceFromBlock
time.sleep(2)
timeTaken = time.time() - timeStarted
mc.postToChat("Well done - " + str(int(timeTaken)) + " seconds to find the diamond")
time.sleep(5)
mc.postToChat("www.stuffaboutcode.com")
The complete code repository is also on github, https://github.com/martinohanlon/minecraft-hs.git.
Run
Note - minecraft must be running and you must be in a game
python ~/minecraft-hs/minecraft-hs.py
or if using Idle, click Run Module
Well done! I think you should try integrating a python video game into Minecraft Pi Edition, like snake. That would be a challenge!
ReplyDeleteHi Martin, my 10 year old loves minecraft and his raspberry pi, he is setting up a blog and would like to blog about this and post the code onto github - would that be OK? Of course he would attribute the work to you! Cheers.
ReplyDeleteHi, I would love for you son to blog about this post, anyone is welcome to link to my blog, its always 'nicer' to provide links rather than cut and paste content, that way the original author also gets a hit. Ive put the code on github (ill update the post), see https://github.com/martinohanlon/minecraft-hs.git. Martin
DeleteMartin, Thanks for that, he had created a repo, but instead we will fork yours.
DeleteCheers,
Peter
Hi Martin,
ReplyDeleteI have followed your steps in the above and I don't think I missed anything but got this when I tried to run it:
pi@raspberrypi ~ $ python ~/minecraft-hs/minecraft-hs.py
File "/home/pi/minecraft-hs/minecraft-hs.py", line 17
SyntaxError: Non-ASCII character '\xc2' in file /home/pi/minecraft-hs/minecraft-hs.py on line 17, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
pi@raspberrypi ~ $
I'm very new to all this so please forgive me if I'm being silly and have missed a trick.
many thanks
Tim
Hi Tim,
DeleteIt sounds like you have got some odd characters in your code, web browsers have a habit of doing if you cut and paste. Head over to my github page, https://github.com/martinohanlon/minecraft-hs.git, open the minecraft-hs.py file, click raw and cut and paste the code from there.
Martin
Wow! Thank you. This should help me learn to do some basic programming! Thanks Again.
ReplyDeletehi martin
ReplyDeletenow you may get this or not, but when i type in 'python ~/minecraft-hs/minecraft-hs.py' i get back bash: python ~/minecraft-hs.py: no such file or directory
I'm completely new to programming so if you can help that'd be great.
-Tyler
So, I would say your problems are either down to the code not having downloaded so the file ~/minecraft-hs/minecraft-hs.py doesn't exist or there is a mistake in the command "python ~/minecraft-hs/minecraft-hs.py". My advice would be check to see if the file is there and see if the file exists.
Deletehey martin um i downloaded pretty much all of your programs and their all awesome but now i cant open minecraft and it gives me an error: "failed to add ervice, already in use?" i dont know what it means.pls help
ReplyDeleteby the way sorry for the misuse of grammar
I have never seen the error myself, but I quick google seach led me to here http://www.instantsupportsite.com/self-help/raspberry-pi/raspberry-failed-service/ which suggests the error occurs if you dont have enough memory allocated to the GPU. Have you by any chance setup a minecraft server on your Pi? If you followed my tutorial I change the memory allocation to take the memory away from the GPU so the server has more.
DeleteI have a line saying import minecraft.minecraft as minecraft and it says no module named minecraft what do I do and also did you use python 2 or 3 please help!!??
ReplyDeleteFirst off this is a really old example... I created it before the minecraft pi library was installed on the pi by default. I have updated the code listing to reflect the python minecraft api library is now called mcpi (import mcpi.minecraft).
DeletePython 2 or 3 is fine, providing you are running a recent version of Raspbian.