今回は、前回の記事で読み込んだ音源を鳴らすよ!

SPONSERD LINK

楽器の音のクラス

音を管理するパッケージを作る。

com.watermelonheadman.gopichandmod.audio

先ほど作ったパッケージの中に楽器の音のクラスを作る。

package com.watermelonheadman.gopichandmod.audio;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.audio.PositionedSound;
import net.minecraft.util.ResourceLocation;

@SideOnly( Side.CLIENT )
public class InstrumentSound extends PositionedSound
{
	public int entityid;

	public InstrumentSound(
			ResourceLocation resourcelocation,
			int id,
			float x,
			float y,
			float z,
			float vol,
			boolean loop )
	{
		super( resourcelocation );

		this.entityid = id;
		this.volume = vol;
		//protected float field_147663_c = 1.0F;
		this.xPosF = x;
		this.yPosF = y;
		this.zPosF = z;
		this.repeat = loop;
	}
}

このクラスは、場所の情報を持っているクラス PositionedSound を継承する。

メンバー変数の entityid は、音を鳴らしたプレイヤーの ID を記録する。
ゴピチャンドはモノフォニーな楽器なので音が既に鳴っている状態で鳴らした場合、前に鳴らしてた音は止める必要がある。

コンストラクタの引数はそれぞれ下記のとおり。

ResourceLocation resourcelocation → 鳴らす音
int id → 音を鳴らすプレイヤーの ID
float x → 音を鳴らす x 座標
float y → 音を鳴らす y 座標
float z → 音を鳴らす z 座標
float vol → 鳴らす音の音量
boolean loop → 鳴らす音を繰り返すか

楽器の音を管理するクラス

楽器の音を管理するクラスを作る。
このクラスでは、先ほど作ったクラス InstrumentSound を作ったり、プレイヤーがどの音を鳴らしたかの情報を管理する。

package com.watermelonheadman.gopichandmod.audio;

import java.util.HashMap;
import java.util.Map;

import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.ISound;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class InstrumentManager
{
	private static final String header = "instruments.";

	public static final int GOPICHAND_PICK = 0;
	public static final int GOPICHAND_UP = 1;
	public static final int GOPICHAND_TREMOLO = 2;

	public static final int MAX = 256;

	private static String[] name;

	private static Map< Integer, ISound > playermap;

	public static void registry() {
		InstrumentManager.name = new String[ InstrumentManager.MAX ];

		InstrumentManager.name[ 0 ] = "gopichand_pick";
		InstrumentManager.name[ 1 ] = "gopichand_up";
		InstrumentManager.name[ 2 ] = "gopichand_tremolo";

		playermap = new HashMap< Integer, ISound >( 256 );

		return;
	}

	public static String getName( int n )
	{
		return InstrumentManager.header + InstrumentManager.name[ n ];
	}

	@SideOnly( Side.CLIENT )
	public static void play(
		int soundid,
		int entityid,
		float x,
		float y,
		float z,
		float vol,
		boolean loop )
	{
		Minecraft mc = FMLClientHandler.instance().getClient();

		ISound isound = playermap.get( entityid );

		if ( isound != null ) {
			if ( mc.getSoundHandler().isSoundPlaying( isound ) ) {
				mc.getSoundHandler().stopSound( isound );
			}
		}

		InstrumentSound sound = new InstrumentSound(
			new ResourceLocation (
				"gopichandmod",
				InstrumentManager.getName( soundid ) ),
			entityid,
			x,
			y,
			z,
			vol,
			loop );
		mc.getSoundHandler().playSound( sound );

		playermap.put( entityid, sound );
	}
}

とりあえず鳴らしてみる

ゴピチャンドのクラスに音を鳴らす処理を追加する。
この処理はシングルプレイでのみ有効です。
このままでは、他のプレイヤーが鳴らした音は聞こえない。鳴らした本人のみに音が聞こえる。
マルチプレイ対応版は、次回の記事で書きます。

package com.watermelonheadman.gopichandmod.items;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import cpw.mods.fml.common.registry.GameRegistry;
import com.watermelonheadman.gopichandmod.audio.InstrumentManager;

public class ItemGopichand extends Item
{
	public ItemGopichand()
	{
		String name = "gopichand";

		this.setCreativeTab( CreativeTabs.tabMisc );
		this.setUnlocalizedName( name );
		this.setTextureName( "gopichandmod:gopichand" );
		maxStackSize = 1;

		GameRegistry.registerItem( this, name );

		return;
	}

	@Override
	public ItemStack onItemRightClick(
		ItemStack item,
		World world,
		EntityPlayer player )
	{
		player.setItemInUse( item, this.getMaxItemUseDuration( item ) );

		if ( !world.isRemote ) {
			if ( player.onGround == false ) {
				InstrumentManager.play(
						InstrumentManager.GOPICHAND_TREMOLO,
						player.getEntityId(),
						(float)player.posX,
						(float)player.posY,
						(float)player.posZ,
						1.0f,
						false );
			} else if ( player.isSneaking() ) {
				InstrumentManager.play(
						InstrumentManager.GOPICHAND_UP,
						player.getEntityId(),
						(float)player.posX,
						(float)player.posY,
						(float)player.posZ,
						1.0f,
						false );
			} else {
				InstrumentManager.play(
						InstrumentManager.GOPICHAND_PICK,
						player.getEntityId(),
						(float)player.posX,
						(float)player.posY,
						(float)player.posZ,
						1.0f,
						false );
			}
		}

		return item;
	}

	public int getMaxItemUseDuration( ItemStack par1ItemStack )
	{
		return 72000;
	}

	public EnumAction getItemUseAction( ItemStack par1ItemStack )
	{
		return EnumAction.block;
	}
}

プロジェクトの構成は、下記のようになった。

java
	com.watermelonheadman.gopichandmod
		GopichandMod.java
		Recipes.java
	com.watermelonheadman.gopichandmod.audio
		InstrumentManager.java
		InstrumentSound.java
	com.watermelonheadman.gopichandmod.items
		GopichandItems.java
		ItemGopichand.java
		ItemGopichandBody.java
		ItemGopichandHead.java
		ItemIronString.java
resource
	assets.gopichandmod
		sounds.json
	assets.gopichandmod.lang
		en_US.lang
		ja_JP.lang
	assets.testmod.sounds.instruments
		gopichand_pick.ogg
		gopichand_up.ogg
		gopichand_tremolo.ogg
	assets.gopichandmod.textures.items
		gopichand.png
		gopichandbody.png
		gopichandhead.png
		ironstring.png

テスト

ゴピチャンドを手に持って、右クリックする。
ジャンプやスニークした状態で音が変わるか確認する。

音がならない場合は、Eclipse のコンソールに何かしら出力されていると思うので確認する。

次回予告

次回は、マルチプレイに対応するよ!