Thursday, 27 June 2013

Raspberry Pi - Minecraft - Sounds Effects

I got bored with Minecraft on the Raspberry Pi not having any sound so I decided to make my own!

I grabbed some sound effects off http://soundbible.com and set about making a program which would monitor what Minecraft Steve was doing and play an appropriate sound effect, e.g if Steve's walking I would play the sound of footsteps, if he jumped I would play a 'boing' and my favourite if he fell off a cliff you would hear him scream before hitting the ground.


The program does 3 things:


  • It monitors Steve position using mc.player.getPos() and works out if he's stopped, walking, jumping or falling
  • Based on what Steve has just done it decides what sound effect to play or stop playing
  • Then for added 'effect', the program also checks to see if any blocks have been hit and also plays a sound

Download and run

You can download the code direct from githubhttps://github.com/martinohanlon/minecraft-sound, 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-sound.git
cd minecraft-sound
python minecraft-sound.py

All the sound effect wav files are included in the github repository.

Code
I've included the code for reference but if you want to have a go or modify it I would recommend you download the repository from github as you will need other files (e.g. wav's) to get it working.

#www.stuffaboutcode.com
#Raspberry Pi, Minecraft Sound - Add some sound effects to minecraft

#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
#import pygame to use the mixer to play wav file
import pygame

# constants
STOPPED = 1
WALKING = 2
FALLING = 3

if __name__ == "__main__":

    #Connect to minecraft by creating the minecraft object
    # - minecraft needs to be running and in a game
    mc = minecraft.Minecraft.create()

    #Initialise pygame and the mixer
    pygame.init()
    pygame.mixer.init()

    #load WAVS files
    soundWalking = pygame.mixer.Sound("sounds/walking.wav")
    soundJump = pygame.mixer.Sound("sounds/jump.wav")
    soundFalling = pygame.mixer.Sound("sounds/falling.wav")
    soundBang = pygame.mixer.Sound("sounds/bang.wav")
    soundSword = pygame.mixer.Sound("sounds/sword.wav")

    # setup variables
    lastPlayersState = STOPPED
    playersState = STOPPED
    playerJumped = False
    playerFalling = False
    playerFallDistance = 0

    #get players position
    lastPlayerPos = mc.player.getPos()
    
    mc.postToChat("Minecraft Sound Effects - www.stuffaboutcode.com")
    
    # loop until CTRL C
    try:
        while(True):
            
            # get players position
            currentPlayerPos = mc.player.getPos()

            # has the player moved in either X or Z (are they WALKING?)
            if lastPlayerPos.x != currentPlayerPos.x or lastPlayerPos.z != currentPlayerPos.z:
                # if player is FALLING they cant be WALKING
                if playersState != FALLING:
                    playersState = WALKING

            # has the player moved in positive Y (have they jumped?)
            if int(lastPlayerPos.y) < int(currentPlayerPos.y):
                playerJumped = True

            # has the player moved in negative Y (are they FALLING?)
            if int(lastPlayerPos.y) > int(currentPlayerPos.y):
                playersState = FALLING

            # is the player still falling?
            if playersState == FALLING and lastPlayersState == FALLING:
                # increase the distance they have fallen
                playerFallDistance = playerFallDistance + (lastPlayerPos.y - currentPlayerPos.y)

            # if the player is FALLING but has stopped moving down
            # (have they STOPPED FALLING?)
            if playersState == FALLING and int(lastPlayerPos.y) == int(currentPlayerPos.y):
                playersState = STOPPED

            # has the player STOPPED
            if lastPlayerPos.x == currentPlayerPos.x and lastPlayerPos.z == currentPlayerPos.z:
                playersState = STOPPED

            # if last players state != walking and players state = walking
            # player has started WALKING
            if lastPlayersState != WALKING and playersState == WALKING:
                soundWalking.play(-1)

            # if last players state = walking and players state != walking
            # player has stopped WALKING
            if lastPlayersState == WALKING and playersState != WALKING:
                soundWalking.stop()

            # if the players state = falling and the distance they have fell is greater than 3
            # player has started FALLING
            if playersState == FALLING and playerFallDistance > 3:
                if playerFalling == False:
                    soundFalling.play()
                    playerFalling = True

            # if last players state = falling and the players state != falling
            # player has stopped falling
            if lastPlayersState == FALLING and playersState != FALLING and playerFalling == True:
                soundFalling.stop()
                soundBang.play()
                playerFallDistance = 0
                playerFalling = False
            
            # if player has jumped and the jump sound is not playing
            if playerJumped == True:
                soundJump.play()
                playerJumped = False

            lastPlayerPos = currentPlayerPos
            lastPlayersState = playersState

            #Get the block hit events
            blockHits = mc.events.pollBlockHits()
            # if a block has been hit play sword sound
            if blockHits:
                soundSword.play()
            
            # sleep for a bit
            time.sleep(0.05)

    except KeyboardInterrupt:
        print("stopped")


13 comments:

  1. Great! I especially like the falling "screaming" effect. Really funny! I've been developing my own "Parkour Pack", and I might use these sounds.

    ReplyDelete
  2. I followed all the steps outlined on this page and the code runs fine without any error message and the text pops up on the screen but there is still no sound. Does this have to do with the fact that I am using an HDMI cable?

    ReplyDelete
    Replies
    1. Maybe, the first thing I would check is if you are getting sound through the audio jack on the Pi - plug in a set of headphones and have a listen.

      If you are, it sounds like a hdmi audio selection problem thingy! Search the forums your bound to find some support.

      Delete
    2. still no luck through the headphone jack! my pi plays other audio fine but for some reason is having trouble with minecraft.

      Delete
    3. If you downloaded all the files and have all the wavs, I dont know what to suggest, all the program does is uses the standard pygame module to play the sounds.

      Delete
    4. Chuck, try making a small edit to minecraft-sound/minecraft-sound.py to ensure that the sound files are being found -- it could be that you've installed Martin's files in an unexpected directory.

      Change lines 29-33 from this
      soundWalking = pygame.mixer.Sound("sounds/walking.wav")
      to this
      soundWalking = pygame.mixer.Sound("/home/pi/PATH-TO-FILES/sounds/walking.wav")
      In my case (raspi B+) I set this
      soundWalking = pygame.mixer.Sound("/home/pi/minecraft-mods/minecraft-sound/sounds/walking.wav")

      Hope that helps.

      Delete
  3. Hey , thanks for this its great!, also not sure if your aware but theres a website "http://media.io/" that has an online sound converter that will convert the original minecraft .ogg files into a .wav file so that you can set the original sounds into MCPI if you would like. hope that helps!

    ReplyDelete
  4. Thank you Martin, You made my son happy and made me look like a hero/genius

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

    ReplyDelete
  6. Its giving me the error 10061, connection refused. Should I change this line to something else?

    return Minecraft(Connection(address, port))

    ReplyDelete
    Replies
    1. Minecraft needs to be running and in a game before you run the program.

      Delete
  7. I ran the program on python 3 and got this:
    Traceback (most recent call last):
    File "/home/pi/minecraft-sound/minecraft-sound.py", line 5, in
    import minecraft.minecraft as minecraft
    File "/home/pi/minecraft-sound/minecraft/minecraft.py", line 1, in
    from connection import Connection
    ImportError: No module named 'connection'

    What am I missing?

    ReplyDelete
  8. I haven't tried this yet, but earlier I noticed that the audio output source for the Pi defaulted to my monitor, which has no speakers. Just right click on the speaker icon in the top right of the Pi desktop and select he correct source.

    ReplyDelete

Note: only a member of this blog may post a comment.