Wednesday, 17 April 2013

Raspberry Pi - Minecraft Cannon

I had this idea about using Minecraft: Pi Edition and its API to show how trigonometry, mechanics and mathematics can actually be useful and given that everyone likes to blow stuff up....  I thought I would make a cannon. 
A cannon which could point in any direction (0-360 degrees), angle upwards (0-90 degrees) and when fired would send a cannon ball upwards, falling in-line with the laws of gravity and then explode when it hit the ground.

http://youtu.be/6NHorP5VuYQ

I liked the idea of a command line interface, its a cannon after all they are not meant to be hi-tech devices, to control the cannon you use the following commands:
  • start - create [start-up] the cannon
  • rotate [0-360 degress] - rotate the cannon
  • tilt [0-90 degress] - tilt the cannon upwards
  • fire - FIRE!
  • exit - exit and clear the cannon

The code contains 4 classes written in Python:
  1. CannonCommands - used to control the command line interface, based on python's cmd module
  2. MinecraftDrawing - a generic class I'm building up which supports many generic drawing functions (drawLine, drawFace, drawSphere, etc)
  3. MinecraftCannon - a class which controls the building and changing of the cannon base and its gun, this contains all the code required to 'point' the gun to a specific point on the a sphere based on the direction and tilt angles
  4. MinecraftBullet - a class which controls the flight of the bullet through the air and its eventual explosion, including the maths to manage general mechanics of velocity and gravity

Download and run
You can download the code direct from github, https://github.com/martinohanlon/minecraft-cannon, 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-cannon.git
cd minecraft-cannon
python minecraft-cannon.py


22 comments:

  1. Hey, how do you make it so the TNT blows up?

    ReplyDelete
    Replies
    1. Its not tnt! Its actually a block of glowing obsidian, but it could be any block, the code i wrote calculates the next position of the cannon ball and if its not air it creates an explosion by creating a sphere of air! Its all coded basically even the explosion. Download it and have a look at the bullet class in the program.

      Delete
  2. Martin,
    Really great achievement!! You are an inspiration to me an my son (the resident minecrafter :-))

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hi Martin. My daughter and I enjoy following your tutorials. She is wanting to code an elevator for her very enormous house. Any ideas on where to start??

    ReplyDelete
    Replies
    1. Elevators are so yesterday, what about a transporter?

      Delete
    2. to do an elevator, you'd need to move the player up, draw the new platform over the old one, and then clear the old platform, rinse and repeat.

      A transporter is much easier. Give me a few days for my exams to be over, and i'll write one to show you. (star ship enterprise anyone?)

      Actually, youve just given my an idea for a coooooool project :) will be even cooler if survival mode ever makes it to minecraft (might have to see if thats code-able too)

      Delete
    3. Code for a teleporter (including download) with a GUI rather than command line interface. http://pi-projects.blogspot.co.uk/2013/06/minepi-beam-me-up-scotty.html

      Hope you like it

      If anyone wants to rip it appart and make it better, please do. Just drop me a message on my blog to let me know your results :D

      Delete
  5. you are so epic Martin, hey do you know if there is a way to make a pi server that is.not connected by lan?

    ReplyDelete
    Replies
    1. What do you mean? Do you mean a minecraft server running on a Pi?

      Delete
  6. Should I use a command line terminal or a python code editor to type in the cannon's code?

    ReplyDelete
    Replies
    1. Either. If you run the program from the command line e.g. by using python minecraft-cannon.py, just type the commands into the command line. If you are running the code from Idle, type it into the Python run window.

      Delete
  7. Hi Martin. Nice Cannon.
    I found I had to modify the code slightly in order to fire/adjust the weapon though. Problem was the call to self.mc.setBlock on line 38, which doesn't work if blockData is None, i.e. if the preceding call to drawPoint3d is made without a blockData argument. Here is a diff against my working version which may or may not clarify things:

    def drawPoint3d(self, x, y, z, blockType, blockData=None):
    - self.mc.setBlock(x,y,z,blockType,blockData)
    + if blockData == None:
    + self.mc.setBlock(x,y,z,blockType)
    + else:
    + self.mc.setBlock(x,y,z,blockType,blockData)

    Do you have any insight as to why I need to do this? Am thinking maybe something changed in mcpi 0.1.1. Anyways, thanks for your tutorials!

    ReplyDelete
    Replies
    1. I have no idea why you need to do this! I use the same MinecraftDrawing class in loads of my projects and I have never seen this issue. Its using the minecraft.py and block.py api libraries which came with 0.1.1. What version are you using? Also what version of python were you using?

      Delete
    2. This is with Python 2.7.3 on up-to-date Raspbian, mcpi 0.1.1 and the code from your github. It's very odd, and I would like to understand it better, but handling of None vs actual nothing is hard. With your code, if I start the cannon and then issue the fire command, then the bullet draw() function triggers the error, which ultimately is thrown by math.floor being called with an empty list, which is clearly wrong.

      Delete
    3. I have just retried the code, got it fresh out of github and no problems. Sorry dont know what to suggest.

      Delete
    4. Finally figured this out -- in your github the file minecraft/minecraft.py is from v0.1.0. Check line 5: Minecraft PI low level api v0.1_0
      Where as I am using 0.1.1 which amongst other things has a fussier setTilePos()

      Delete
    5. I see. Ill have to update the code when I get 2 mins.

      Delete
    6. Ok. At some point I must have come across the same issue, because I have modded by minecraft-stuff class to take care of the issue, so change:

      def drawPoint3d(self, x, y, z, blockType, blockData=None):

      to

      def drawPoint3d(x, y, z, blockType, blockData=0):

      Delete
  8. This comment has been removed by the author.

    ReplyDelete