純規の暇人趣味ブログ

首を突っ込んで足を洗う

[Bukkitプラグイン制作講座-其之十]音を鳴らす、爆発を起こす

      2016/12/13    HimaJyun

Bukkitプラグインから音を鳴らしたり、爆発を起こしたい状況は多々あることでしょう。(個人的には無意味に音を鳴らしたりするプラグインは嫌いなのですが……)

と言う訳で「音を鳴らす」「爆発を起こす」「パーティクルを発生させる」「エフェクトを再生する」「雷を落とす」の5つの操作を行ってみましょう。

前回の記事は「[Bukkitプラグイン制作講座-其之九]チェストの中身(インベントリ)を操作する」です。

音!!爆発!!パーティクル!!

音や爆発、パーティクルなんかはユーザに対しても目に見える効果が発生するため「なんか凄そう」と言う印象を与えます(例え中身がゴミクソでも)

無意味なカッコつけのためにやっているのであればうっとおしいだけなのですが、場合によっては適切な視聴覚効果を与える事も出来るでしょう。

音を鳴らす

「World#playSound()」で可能です。

実際はWorldをLocationからgetWorld()で取得する事が多いでしょうし、以下の様な形になるかと思われます。

Location loc;
loc.getWorld().playSound(Location,Sound,float,float)

こうやって書くと普通に見えるのですが、playSoundの引数にはLocationを与える必要があるので、上の例で言うと「loc(Location型)」の変数が同じ行に2回出て来ることになり違和感を覚えます。(今分からなくてもきっとその内言ってる意味が分かるはず)

なんと言うか、「メンドクセーナー」と思っています。

具体的な使い方

これは比較的簡単、以下の様に使います。(locにはLocationが入っています)

loc.getWorld().playSound(
		loc, // 鳴らす場所
		Sound.ENTITY_PLAYER_LEVELUP, // 鳴らす音
		1, // 音量
		1 // 音程
);

上の例ではレベルアップ時の音を普通に鳴らしています。

音量は文字通りで、上げれば上げる程意味もなく音がデカくなります。(1で標準)

音程は上げれば(数字を大きくすれば)上げる程音が高くなり、再生が早くなります、下げれば音が低くなり、再生がゆっくりに(1で標準)

これとは別に、JavaDocの添付されていない「SoundCategory」なるEnumを引数に取るplaySoundがありますが、これが何かは良く分からない。

爆発を起こす

「World#createExplosion()」で可能です。

基本的な部分はplaySoundと同じですが、細かい指定が出来たりします。

基本形

最小限の形であれば座標と火力を指定すればOK

loc.getWorld().createExplosion(
		loc, // 爆発させる場所
		1 // 火力
);

火力は1でガストの火球、3でクリーパーの爆発、4でTNTの爆発と同等。

バカでかい数字にすると当然ながら広範囲で吹き飛ぶ、当たり前だがその分だけ処理が重くなる。

爆発の際、火力が高いとなぜか地形が歯抜けのように吹き飛ぶ、それはそれで面白いので試してみてね。

起爆と同時に火をつける

先程の基本形に加えて、第三引数にtrueを渡すと爆発した場所に火が付くようになる。

loc.getWorld().createExplosion(
		loc, // 爆発させる場所
		1, // 火力
		true // 火をつける
);

これをダークオーク森林だのジャングルだので火力数百にして使用すると……

PCが暖房になる。

座標を細かく指定する

先程のcreateExplosionから座標指定がdoubleになった物。

座標が数値で指定出来る様になっただけで他は変わらない。

loc.getWorld().createExplosion(0, 60, 0, 50);
loc.getWorld().createExplosion(0, 60, 0, 30, true);

例えば上の例であればX=0、Y=60、Z=0の座標に爆発を起こしている。

ブロックを壊さない

何故かLocationでの座標指定には存在しないのですが、数値での座標指定であれば「ブロックを壊さない」爆発を起こす事が可能です。

loc.getWorld().createExplosion(
		loc.getX(),
		loc.getY(),
		loc.getZ(),
		10,
		true, // 火をつける
		false // でもブロックは壊さない
);

第六引数をfalseにするだけ、簡単。

パーティクルを発生させる

「World#spawnParticle()」で可能、やたらと引数のバリエーションが多い。

あまりにも種類(オーバーロード)が多いので座標の数値指定とかは省略。

基本形

基本形は以下の形。

loc.getWorld().spawnParticle(
		Particle.VILLAGER_HAPPY, // パーティクルの種類
		loc, // 発生させる場所
		10 // 発生させる数
);

上の例では幸福村人(適当に命名、村人と交易した際に出るアレ)を10個発生させる。

座標(locの部分)はx,y,zの数値指定でも可

散開させる

とは言え、上の基本形では10個が同じ場所に発生して無意味。

散開させるメソッドもきちんと用意されている。

loc.getWorld().spawnParticle(
		Particle.VILLAGER_HAPPY,
		loc,
		50,
		10, // 散開させるXの範囲
		10, // 散開させるYの範囲
		10 // 散開させるZの範囲
);

上の例ではx,y,z共に10の範囲に50個の幸福村人を散らしている。

もちろん座標の数値指定版もある。

速度を変える?

散開させる時のメソッドから更にdoubleの引数が追加されたものがある。

loc.getWorld().spawnParticle(
		Particle.CLOUD,
		loc,
		500,
		10, // 散開させるXの範囲
		10, // 散開させるYの範囲
		10, // 散開させるZの範囲
		0.1 // 速度?
);

幸福村人では違いが分からなかったので雲(?)に変えてみた所、パーティクルの速度が変わった

JavaDoc曰く、「使うパーティクルによって効果が変わる(通常は速度が変わる」模様

エフェクトを再生する

パーティクルと似ているがこちらは音なんかも同時に発生する。(と言うか殆どの場合音しか鳴らない)

良く分からないが一応紹介しておく。

基本形

基本的に以下の様に使う、3つめの引数はパーティクルの種類によって効果を発揮する

loc.getWorld().playEffect(
		loc, // 発生させる場所
		Effect.DRAGON_BREATH, // エフェクトの種類
		0 // 大抵の場合は無意味
);

上の場合ではエンドラのブレスが直撃した時にエフェクトが再生される。

範囲を限定する

第四引数に範囲を指定すると、その範囲の中に居る時のみエフェクトが見えるようになる。

loc.getWorld().playEffect(
		loc, // 発生させる場所
		Effect.DRAGON_BREATH, // エフェクトの種類
		0, // 大抵の場合は無意味
		10 // エフェクトの範囲
);

上の例であれば周囲10ブロック内のプレイヤーにのみエフェクトが見える/聞こえる

雷を落とす

最後に簡単な簡単な雷を落とす処理。

普通の雷

良くある普通の雷、ダメージ受けるし火が付くし……

loc.getWorld().strikeLightning(loc);

これだけ、簡単。

痛くない雷

痛くもないし火もつかない雷

loc.getWorld().strikeLightningEffect(loc);

なぜか別のメソッドになる、それなら第二引数にbooleanを指定すれば切り替わる様にすれば良かったのに……

BukkitのAPIってなんか全体的に統一感がない気がする……

最後に

と言う訳でいくつか視聴覚的な効果を発生させる方法を紹介した。

が、多分これらは殆どの場合使う事は無いと思う、何故って?キラキラしたりピコピコ鳴ったりしたって殆どのプラグインではうっとおしいだけで無意味だから。

これらの効果は必要な所でだけ使うようにして欲しい、と、個人的には思う(稀に無駄にパーティクルを発生させたりサウンドを鳴らしたりしやがるプラグインがあるので)

今回の例示で使用したコードはGitHubにあるので、興味があればどうぞ。

……もう少し続くよ。

オマケ:Locationを作る

どうでも良いがLocation型の変数を作成したい場合。

new Location(
		world, // 世界
		0, // X座標
		64, // Y座標
		0, // Z座標
		0, // yaw(ヨー:向き)、省略可能
		1 // pitch(ピッチ:角度)、省略可能
);

無関係だが、唐突として数値指定でLocationが欲しくなることがあるので。

 - プログラミング , ,