The code is relatively simple, the program continually monitors the position of the player and by understanding where the player is and where they were, you can predict where they are going to be, if the block they are going to be standing on is empty (or AIR), fill it in!
This is based on the version 0.1.1 of Minecraft: Pi edition, see this post for info on how to install.
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-bridge.git
cd minecraft-bridge
python minecraft-bridge.py
cd ~
git clone https://github.com/martinohanlon/minecraft-bridge.git
cd minecraft-bridge
python minecraft-bridge.py
The Code
If you want to have a go yourself, here's the code.
Create a directory for the program
mkdir ~/minecraft-bridge
Copy the python api class library from minecraft to the programs directory
cp -r ~/mcpi/api/python/mcpi ~/minecraft-bridge/minecraft
Create minecraft-bridge.py python program
nano ~/minecraft-bridge/minecraft-bridge.py
or open Idle and save minecraft-bridge.py to the minecraft-bridge directory
Code
Be careful cutting and pasting direct from the web browser, its really easy to get odd characters in the code which will give you syntax errors.
#www.stuffaboutcode.com
#Raspberry Pi, Minecraft - auto bridge
#import the minecraft.py module from the minecraft directory
import minecraft.minecraft as minecraft
#import minecraft block module
import minecraft.block as block
#import time, so delays can be used
import time
#function to round players float position to integer position
def roundVec3(vec3):
return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))
if __name__ == "__main__":
time.sleep(2)
#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 - Auto Bridge Active")
mc.postToChat("www.stuffaboutcode.com")
#Get the players position
lastPlayerPos = mc.player.getPos()
while (True):
#Get the players position
playerPos = mc.player.getPos()
#Find the difference between the player's position and the last position
movementX = lastPlayerPos.x - playerPos.x
movementZ = lastPlayerPos.z - playerPos.z
#Has the player moved more than 0.2 in any horizontal (x,z) direction
if ((movementX < -0.2) or (movementX > 0.2) or (movementZ < -0.2) or (movementZ > 0.2)):
nextPlayerPos = minecraft.Vec3(nextPlayerPos.x - movementX, nextPlayerPos.y, nextPlayerPos.z - movementZ)
#to resolve issues with negative positions
if blockBelowPos.z < 0: blockBelowPos.z = blockBelowPos.z - 1
if blockBelowPos.x < 0: blockBelowPos.x = blockBelowPos.x - 1
blockBelowPos.y = blockBelowPos.y - 1
if mc.getBlock(blockBelowPos) == block.AIR:
mc.setBlock(blockBelowPos.x, blockBelowPos.y, blockBelowPos.z, block.DIAMOND_BLOCK)
#Raspberry Pi, Minecraft - auto bridge
#import the minecraft.py module from the minecraft directory
import minecraft.minecraft as minecraft
#import minecraft block module
import minecraft.block as block
#import time, so delays can be used
import time
#function to round players float position to integer position
def roundVec3(vec3):
return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))
if __name__ == "__main__":
time.sleep(2)
#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 - Auto Bridge Active")
mc.postToChat("www.stuffaboutcode.com")
#Get the players position
lastPlayerPos = mc.player.getPos()
while (True):
#Get the players position
playerPos = mc.player.getPos()
#Find the difference between the player's position and the last position
movementX = lastPlayerPos.x - playerPos.x
movementZ = lastPlayerPos.z - playerPos.z
#Has the player moved more than 0.2 in any horizontal (x,z) direction
if ((movementX < -0.2) or (movementX > 0.2) or (movementZ < -0.2) or (movementZ > 0.2)):
#Project players direction forward to the next square
nextPlayerPos = playerPos
# keep adding the movement to the players location till the next block is found
while ((int(playerPos.x) == int(nextPlayerPos.x)) and (int(playerPos.z) == int(nextPlayerPos.z))):nextPlayerPos = minecraft.Vec3(nextPlayerPos.x - movementX, nextPlayerPos.y, nextPlayerPos.z - movementZ)
#Is the block below the next player pos air, if so fill it in with DIAMOND
blockBelowPos = roundVec3(nextPlayerPos)#to resolve issues with negative positions
if blockBelowPos.z < 0: blockBelowPos.z = blockBelowPos.z - 1
if blockBelowPos.x < 0: blockBelowPos.x = blockBelowPos.x - 1
blockBelowPos.y = blockBelowPos.y - 1
if mc.getBlock(blockBelowPos) == block.AIR:
mc.setBlock(blockBelowPos.x, blockBelowPos.y, blockBelowPos.z, block.DIAMOND_BLOCK)
#Store players last position
lastPlayerPos = playerPos
#Delay
time.sleep(0.01)The complete code repository is also on github, https://github.com/martinohanlon/minecraft-bridge.git
Run
Note - minecraft must be running and you must be in a game
python ~/minecraft-bridge/minecraft-bridge.py
or if using Idle, click Run Module
Hi Martin,
ReplyDeleteI think your Minecraft Pi tutorials are super. I was wondering if I could use one for my video tutorials to get girls coding (youtube.com/geekGurlDiaries)?
It would be an honour! Obviously a mention and link, would also be appreciated...
DeleteIf you need any help, just give me a shout.
Ive just realised this had a bug, so when dealing with negative positions it would do odd things like creating blocks to the right of the players position. It turns out I'm not perfect after all! Although the code has now been fixed, so perhaps I've redeemed myself.
ReplyDeleteThis comment has been removed by the author.
DeleteHi, I just commented on your other post but anyway, do you know how to spawn pigs? I don't know if you can use the setBlock or what.
ReplyDeleteNo idea, they might not be supported, i havent seen them wandering about in the game. Hopefully they will appear in an update.
DeleteQuestion.
ReplyDeleteWhen I do this it is giving me a syntax error. I have tried this and the clock and it does the same on both. I am trying to get these working for my son and I am a little lost. Thanks
Hi,
DeleteWhat's the syntax error? Is there anything specific?
Are you by any chance cutting and pasting the code directly from the browser into Idle? I suspect you might be getting some odd characters from the browser, they have a habit of doing that.
I've modified the post to give some instructions about how to download the code directly from github. This way you can be sure you have the right code.
Let me know ho you get on.
Mart
Doing it from github worked perfectly. There is a very happy 5 year old.
ReplyDeleteThanks so much
Super
Deletehi martin, can I change the Ice block to TNT block ?
ReplyDeleteThanks. :)
Do you mean the block I use to create the Bridge? Its actually Diamond block, not ice.
DeleteIf so absolutely you can use any block you want, other than ones affected by gravity I suppose like sand.
Change the DIAMOND_BLOCK in the code to TNT.
Brilliant. This should get a lot of kids hooked in to programming. MC is all about algorithms! I'm hoping to use something like this at our Bring Your Kids to Work Day.
ReplyDeleteThe biggest problem I'm having in playing MC is knowing what direction I'm facing (and getting disoriented all the time). Do you know of a way to show that in the chat window using the API, like you do for distance in the Hide & Seek?
I'm also wondering about using the API to create a world map and showing it in a separate screen using PyGame.
At any rate, thanks for blazing the way on this. Great stuff!
When i try to run the program in run it comes up with this; Failed to execute child process "minecraft-bridge/minecraft-bridge.py" (Permission Denied)
ReplyDeleteI've gotten it to run in Terminal but the message pops up in the game and does nothing.
I have never experienced a permission denied error before, have you tried the simple stuff like running it with sudo, perhaps you have got some odd permissions.
DeleteWhen you say you have got it to run in terminal, do you mean that the program is running successfully and you get the "Minecraft Autobridge Active" message in Minecraft? When you say it doesnt do anything, Im guessing you mean when you walk it doesnt automatically create a bridge? Do the program give an error in the terminal window?
I've got run to run it but it doesn't say anything or do anything.
DeleteYeah, it runs in the Terminal and i get the ingame message but the Auto-Bridge doesn't form when i walk off a cliff etc. It doesn't give any error whatsoever.
Then I am at a loss Im afraid. Just re-downloaded the code and run it with no problems. Sorry.
DeleteJust to confirm any error would appear in the terminal window not as a message in the game tho.
I am not able to successfully complete the "git clone" command (this or any other git clone attempt). When I try, I get:
ReplyDeletegit: 'clone https://github.com/martinohanlon/minecraft-bridge.git' is not a git command. See 'git --help'
Any ideas?
Er no. I haven't experienced that before or had anyone else mention it.
Delete1 thought are you cutting and pasting the command from the browser sometimes you get odd characters. Try typing it if you are.
Yes, you solved it. I cut-and-paste, and there was not a real "space" between "clone" and "https". Seems obvious in retrospect. Thank you for taking the time to clue me in!
Deletehi there!
ReplyDeleteI have made a program similar to this and i thought that you could help. My program does almost the same thing but disassembls the bridge when you walk on grass, but it crashes when it removes the bridge. can you help me? here is the program:
import mcpi.minecraft as minecraft
import time
mc = minecraft.Minecraft.create()
list = ['e',]
bridge = 20
water = (8, 9)
air = 0
grass = 2
i = 1
listlen = 0
while True:
pos = mc.player.getTilePos()
blockbelow = mc.getBlock(pos.x, pos.y - 1, pos.z)
if blockbelow == air:
mc.setBlock(pos.x, pos.y - 1, pos.z, bridge)
list.append((pos.x, pos.y - 1, pos.z))
print len(list)
listlen = len(list)
elif blockbelow == grass and listlen > 3:
mc.setBlock(list[i], air)
del(list[i])
time.sleep(0.01)
time.sleep(0.001)
the tabs don't work on blogger, but there there
DeleteCrashes? Is there an error message?
Deletethis is the error message (tabs don't work so i'll add an '~' to replace them):
DeleteTraceback (most recent call last):
~File 'bridge.py', line 25, in
~~mc.setBlock(list[i], air)
IndexError: list index out of range
I think I need a way to stop it before it deletes the last block
DeleteThe error is easy to explain, you are trying to find an item in your list which doesnt exist, in this case i, which always seems to be 1, why this is happening is more difficult as i cant understand what trying to do.
DeleteThe code to me says, if im standing on grass and i have more than 3 blocks in my list, set block 1 in that list to air and move on. If the block below me is air, create a bridge block and add it to the list.
If your walking through the air you are going to put LOADS of blocks in your list, say 100, if you start standing on grass you are going to remove blocks from that list until you are no longer standing on grass and which point you stop taking blocks off the list, unless you reach a point where there are only 3 blocks list on the list? Is that right? Comments are always very helpful!
The first thing i would check is that mc.setBlock is ok with you passing a list as the x,y,z parameters e.g. setBlock(list[i], air) i would expect to see setBlock(x,y,z, air). I dont think this is the route of you issue but it might be hiding the real error.
Best of luck
hi
ReplyDeleteslight problem here. after i typed python minecraft-bridge.py it said python: cant open file 'minecraft-bridge.py' : [errno 2] no such file or directory.
im new to programming and not very good at it. also no luck with copy paste too.
-Tyler
Did the code download properly from github? Does the ~/minecraft-bridge/minecraft-bridge.py file exist?
Delete