Densyakunのブログ

高校生プログラマの雑なブログです。ゲームを開発しています。

マイクラ離れと、マイクラでやりたかったこと

こんにちは、電車君です。

今までマイクラ関係でやろうとして上手くいかなくてやめたことや、

やりたかったけど一人じゃ出来なかった事が沢山あるので、それをあげていきます。

 

イクラ離れ

約6年ぐらい前からマイクラをやっていたのですが、「マイクラばっかりやっていてもしょうがない」と思い、高校生になってからは、自称「マイクラ離れ」をして、自分のやっているサーバーなどをやめて、他の事をすると決めました。

次は具体的な内容について。

 

電車君サーバーを辞めた

電車君サーバー(電鯖)は私が約5年ほどやっていた、サバイバルで街を作るサーバーです。

開業は2013年3月29日で、開業当初はプレイヤーがサバイバルで生活し、管理者などがクリエイティブで建築する形を取っていました。

 

開業当初よりリアリティ(現実の街づくりや日本の近代建築などを再現していくという意味で)を目指していたので行政などがありました。(と言っても具体的な内容は土地の管理以外ありませんが)

電鯖には私が都知事の中央都(開業当初は「福田県」。名前かと言われるが決して名前では無く思いつきで付けた名前)を中心に、一都二県がありました。

そう言った理由から一見難しそうなサーバーに思われていたような気もします。

実際、駅や都市開発によって案内を担う看板が増えたのですが、看板を無視する人が多かったので、看板を強調したり同じ看板を増やしたりしましたが、逆に引かれるようだったので、結果的に看板を控えめにしたところ見た目的にも安定しました。

 

途中からやりがいを追求するようになったので、クリエイティブの建築物をサバイバルで作り直す「サバイバル化」を行い、不要な建築物は撤去することになりましたが、結局サーバーが終わるまで完了しませんでした。

また、建築物の減少により全体的に過疎化し、常時プレイヤー数が増えることはありませんでした。

 

理想としては、建築勢が集るサーバーで、アパートやマンションに多くのプレイヤーが住んだり、お城などを作るのも待っていたのですが、実際に建築勢が来たのは一人だけでした。またその建築勢が建築した建築物は一つだけでした。

そういった理由から、納得がいかないまま、電鯖は2017年9月20日に終了しました。

やめた理由は、忙しくなると感じたからです。

鯖民には申し訳ないですが、以前からサーバーの人気度などに納得がいかなかったことがあり、何度もサーバーをやめようと思ったことがあり、何度も諦めずにいたのですが、今回このような結果となりました。

 

翌日の21日から副鯖主の環状線が南北28条サーバーとして引き継ぎました。

と言ってもサーバー自体の運営と鯖主は違う者で、いろいろな要因がありあまり運営できていないように思えます。

 

実は電車君サーバーが始まる前にやっていた生活サーバーがありまして、そちらが初代電車君サーバーのようなものでした。

初代の方で遊んでた人たちは、電鯖で発生した「King達荒らし事件」の奴らです。(和解済みです)

 

懐かしき電車君サーバーについては今後別の記事で詳しく紹介しようと思っています。

 

 

Bukkitプラグイン開発

私の作ったプラグインなどを公開するサイトがありますが、すべてホームページに移行しているところです。

eclipseのプロジェクトは100を超えており、今まで作ってきたたくさんのプラグインがあるのですが、そのほとんどが開発中のプラグインだったりします。

今年中にそのプラグインを完成させたり、ちょっとしたコードなどをgistなんかにあげたりする予定です。

 

今後プラグイン開発をする予定はありません。その代わり今までの技術を公開したり、Bukkitプラグインの作り方講座を行っています。

 

ちなみにプログラミングをやり始めたのはこれがきっかけで、電鯖をやり始めて半年後ぐらいにはじめました。

ちなみにJavaに関しては1年ぐらいでほぼ覚えましたので、今のプラグイン開発の技術は当時とあまり変わりません。

もっと早くプラグインの作り方を教えれば良かったと思います。

 

プラグイン開発の要望を受けてた時期もありましたが、やはり放棄していました。すみませんでした。

 

 

余談ですがサーバーを辞めてからふと思いついたプラグインで「サーバー宣伝プラグイン」てのがあります。

人の少ないサーバーを人の多いサーバーで自動的に宣伝できるものです。

 

 

MOD開発

実はMODも作れます。

1つだけ作ったMODがあり、「PockyMOD」と言います。

その名の通り某有名お菓子を作ったり食べたり出来るものです。

ですが、残念ながら公開されているMODでは動作しません。

こちらもちゃんと動作する完成品を公開したいと思っています。

 

他にも一番作りたいと思っている日本文化を導入するMOD「JapanPack」(略してJP。ドヤッ)と言うのがあります。

こちらは一緒に開発してくれる方を募集しています。(それまでは休止予定です)

 

 

やりたかったサーバー1「電車君RPGサーバー」

前半期の電鯖の副管理人、「和紀」(sorayamakazuki)やそのほか電鯖管理者達でやっていたRPGサーバーです。

2014年5月29日から同年7月17日まで開発を行っていました。

自作プラグインでスキルを追加したりモンスターを追加したりしていました。

お城やストーリー的要素も考えていました。お城は「カズキ城」などと言った電鯖管理者の名前を取ったもので、それぞれの管理者が自分の城を作っていました。

このサーバーの正式開業は無く開発段階で中止になりました。

 

今となっては懐かしいサーバーです。

 

 

やりたかったサーバー2「どうぶつの森サーバー」

どうぶつの森がマイクラでできると言うものです。

村を作成したり、村に遊びに行ったりできる機能はできていました。

個人的には完成させられると思っていたのですが、

考案者の友達が、村機能もできてないうちにやる気がなくなったのか他のゲームをやるようになり、

結局遊ぶ人がいないということでやめました。

 

 

やりたかったサーバー3「SAOサーバー」

大人気アニメ「ソードアートオンライン」をマイクラでできると言ったサーバーです。

昔僕が入っていたマイクラ系Youtuber(?)「俺たちのマインクラフト」(俺クラ)のメンバーらがやっていました。SAO鯖の発案をしたのは俺クラのリーダー「ナイト」(自称「中二病」)です。

そして、何故だかナイトが「マップはオリジナルにしよう」と、SAO鯖の欠片もない要素をぶち込み始めたので嫌な予感がしましたが、

結局メンバーが仲間割れしたりして荒らしに発展したため開発が中止になりました。

その後知ったのが、外国にSAOサーバーがあったと言う衝撃的事実でした。と言ってもアニメ内とマップは異なるようです。

 

プラグインはもちろん自作(やはり僕一人だけで作っていた)です。

と言っても、出来るのはログイン時に「リンクスタート!」と表示されるくらいでした。

(この時初めて1.8からできる画面中央に文字を表示するプラグインの技術を習得しました)

ワールドを管理してSAOにおけるフィールドを擬似的に再現してアインクラッドを作るのも考えていました。

 

完成していれば大人気だったと思いますが、やはり回線の問題もありできても難しかったと思います。

私のサーバーは回線の問題が一番の問題なのでしょうか。

 

 

やりたかったサーバー4「電車君ゲームサーバー」

MCSG、Mineplexなどのようなミニゲームを集めたサーバーです。

2014年あたりからやりたいと思っており、

2017年3月29日の4周年記念としてオープンβテストを開始し、合わせて午後8時から逃走中イベントを開催しましたが、

メイン鯖同様回線が悪く、ゲームサーバーの動作環境(ラズパイ)の通信が遅いこと、ミニゲームプラグインに問題があったこと、対応に時間がかかったこと、以上の理由からミニゲームが遊べないこと、管理者が少ない・いないこと、サーバーにはゲーム以外の要素がないことなど問題が多く、

また、プレイヤーが全ていなくなってしまったためイベントが中止となりました。

イベントには生放送も行っていましたがイベント中止とともに放送も中止となりました。

回線等の問題によりイベントの開催ができなかったことをお詫び申し上げます。 次回安定したイベントの開催ができる状態になりましたら再度イベントを開催する予定です。 今回のイベントにご参加いただきありがとうございました。

 

公式サイトも管理者に頼みましたが誰もやってくれず完成しないままでした。

 

現在はサーバーを運営していないため、ゲーム鯖を建てたい方がいない限りはゲーム鯖再開の予定はなく、再開する可能性は低いです。

 

 

ほかにも多くの主流MODを導入したMOD鯖や、

マインクラフトに現実的な線路や鉄道設備、車両などを導入して、運転したりすることが出来るRealTrainMod(RTM)を使用した街づくりサーバー(もうすでにあるそうです)、

現実世界の都市を再現する専用のサーバーなど考えていましたが、いずれも実現することはありませんでした。

また友達のサーバーなどを多く運営したりもしていました。

現在ではサーバーを運営する予定はありません。

 

また、プラグインについても要望は受け付けていませんが、

プラグインの作り方についてはやりたい人に教えていこうと思っており、

当ブログにおいて「Bukkitプラグインの作り方講座」というものをやっていますので、興味があったら是非ご覧下さい。

 

densyakun.hateblo.jp

 

【Spigot】Bukkitプラグインの作り方講座 第3回 – エンティティ、瞬間移動、ダメージ、ベクトル操作

こんにちは、電車君です。

前回はコマンドの追加や、Bukkitプラグインの基本であるイベントシステムと、その活用例について解説しました。

 

前回のコメントにて今回の話題を募集したところ、

エンティティに関するものが多かったため、

今回はEventシステムを使って、エンティティを制御します。

 

今回やること

  • エンティティの種類について
  • エンティティが受けるダメージを制御する
  • エンティティを瞬間移動させる
  • エンティティにダメージを与える
  • エンティティをスポーンさせる
  • エンティティを乗り物に乗らせる
  • エンティティのベクトルを操作して、移動させる

などなど...

 

 

 

 

エンティティの種類について

 

エンティティには種類があり、用途やバージョンによって使い方が異なる場合があるため、注意が必要です。

エンティティは全て、Entityインターフェース(org.bukkit.entity.Entity)とそれを継承したインターフェースです。

 

また、Entityインターフェースを継承したLivingEntityインターフェースと言うものがあります。

これは、エンティティのうち、生き物が持っているインターフェースです。

つまり、LivingEntityにはダメージを与えることが出来ます

俗に言う「モブ」などはLivingEntityに当たります。

弓矢の矢や、爆発中のTNT、落下中のブロック(砂、砂利、金床等)はLivingEntityではありません。

 

また、LivingEntityインターフェースを継承したHumanEntityインターフェースと言うものがあります。

つまり、人の形をしているエンティティということですが、

実はHumanEntityインターフェースを継承しているのはPlayerインターフェースのみです。(MC1.12時点)

 

他にもコマンドを送信するプレイヤーが継承し、サーバーコンソール用でもあるCommandSenderや、

インベントリを持っているエンティティやブロック(チェスト等)が継承しているInventoryHolder、

弓矢の矢や卵、雪玉などの投げるものが継承しているProjectileなど色々なものがありますが、

これらについては今後別の回で解説していきます。

 

Entityについて詳しくはspigot公式によるjavadocがありますので、ご覧下さい:https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/Entity.html

 

 

 

エンティティのダメージを制御する

 

@EventHandler
public void onEntityDamage(EntityDamageEvent e) {
	double damage = e.getDamage();
	e.setDamage(damage * 2);
}

いきなりコードです。

 

 

上のコードではEntityDamageEventを使用しています。

EntityDamageEventはエンティティがダメージを受けた時に発動するイベントです。

上のコードではエンティティが受けるダメージを二倍にしています。

 

ダメージを受けるエンティティを取得するには、e.getEntity()Entityインターフェースを返します。

ダメージが関係していますが、返すのはLivingEntityインターフェースではないので注意して下さい。

 

エンティティの種類を取得するには、

Entity entity = e.getEntity();
EntityType type = entity.getType();

又は、e.getEntityType()EntityType型を返します。

 

 

当然ですがこのイベントでダメージを受けるエンティティはプレイヤーも含まれます。

先程のコードではプレイヤーも二倍のダメージを受けてしまいます。

プレイヤーを除外するには以下のようなコードになります。

@EventHandler
public void onEntityDamage(EntityDamageEvent e) {
	double damage = e.getDamage();
	EntityType type = e.getEntityType();
	if (type != EntityType.PLAYER) {
		e.setDamage(damage * 2);
	}
}

 

また前回同様、多くのイベントでイベントのキャンセルをすることが出来ます。

これを使用してプレイヤーが攻撃を受けないようにする事もできます。

if (type == EntityType.PLAYER) {
	e.setCancelled(true);
}

 

このイベントは攻撃する側がどんなものであっても発動します。

攻撃する側をエンティティに限定したい場合は、EntityDamageByEntityEventを使うと良いです。

逆にエンティティ以外に限定したい場合は、EntityDamageByBlockEventを使います。

 

EntityDamageEventで、攻撃するものが何なのか調べたい場合は、e.getCause()を使用します。

 

EntityDamageByEntityEventの場合は、e.getDamager()を使って攻撃したエンティティを取得できます。

 

EntityDamageByBlockEntityではサボテンに刺された時や、奈落に落ちた時などに発生します。

サボテンの場合など、e.getDamager()でブロックを取得できますが、

奈落などの場合は対象のブロックがない場合があるので注意が必要です。

 

 

 

エンティティにダメージを与える

 

Entity entity = e.getEntity();
if (entity instanceof LivingEntity) {
	double damage = 1.0;
((LivingEntity) entity).damage(damage); }

エンティティにダメージを与えるには、LivingEntityにキャストする必要があります。

LivingEntity.damage(double damage)でダメージを与えることが出来ます。

LivingEntity.damage(double damage, Entity damager)でダメージを与えるエンティティを指定することも出来ます。

 

 

 

エンティティを瞬間移動させる

 

エンティティを瞬間移動させるには、

entity.teleport(entity)
entity.teleport(location)

を使います。

引数にEntity型を入れる場合は、そのエンティティの場所に、

Location型(org.bukkit.Location)を入れる場合は、その場所に瞬間移動します。

 

エンティティの座標を取得するには、entity.getLocation()を使います。

 

@EventHandler
public void onEntityDamage(EntityDamageEvent e) {
	Entity entity = e.getEntity();
	Location loc = entity.getLocation();
	loc.setY(loc.getY() + 3);
	entity.teleport(loc);
}

上の例では、getY()で取得したY座標に3を足して、loc.setY(y)でY座標を設定しています。

つまり、エンティティがダメージを受けると、3ブロック上に瞬間移動します。

f:id:Densyakun:20180212202115g:plain

瞬間移動なので、木に埋まったりしてしまいます。 

 

 

 

ベクトルを操作して、移動させる

 

最後に、ベクトルを操作して、移動させます。

ベクトルは、数学では「大きさと向きを持った量」とされています。

 

 

平面で例えると、

原点から点[vx,vy]まで矢印が伸びているとします。

この矢印をベクトルと言います。

この時、原点から点までのvx量とvy量がベクトルの持つ大きさです。

そしてこの量によって向きが決まるわけです。

 

ベクトルは3Dでも使われており、 x,y,z で構成されています。

xは横方向、yは縦方向、zは前後方向の量です。

ベクトルがよくわからない人はこちら: ベクトル解析 - [物理のかぎしっぽ]

 

@EventHandler
public void onEntityDamage(EntityDamageEvent e) {
	Entity entity = e.getEntity();Entity entity = e.getEntity();
entity.setVelocity(new Vector(0f, 2f, 0f)); }

上の例ではダメージを受けたエンティティがトンでいきます。

ベクトル量の調整がちょっと難しかったりします。(1だとなかなか飛びません。10だと果てしなくトンでいきます)

f:id:Densyakun:20180213011025p:plain

f:id:Densyakun:20180213011030p:plain

 

 

 


今回はここまでとなります。

他にも出来ることは山ほどあるので、色々試してみて下さい。

何か質問があればコメントでどうぞ。

次回については未定ということで、次回の話題をコメントで募集します。

 

お楽しみに!

【Spigot】Bukkitプラグインの作り方講座 第2回 - コマンドの追加とEventシステムの活用

こんにちは、電車君です。

前回プラグインの基本的な作り方について説明しました。

今回は第2回ということで、コマンドの追加とEventシステムを活用していきます。

 

  • 追記(2018/03/13): SpigotMCによる公式の解説を追加しました。

 

今回やること

コマンドを使いプラグインに指示を送る
Eventシステムを使うことで「サーバーにプレイヤーがログインした」、「プレイヤーがブロックを破壊した」などのイベントを、プラグインに連動させる事ができる。

 

 

 

 

コマンドの追加

コマンドを追加する方法は二種類あります。

plugin.ymlを編集する方法と、プログラムで動的にコマンドを追加する方法があります。

SpigotMCによる公式の解説はこちら(英語)

 

今回はplugin.ymlを編集してコマンドを追加します。

まず、plugin.ymlを編集します。

plugin.ymlの詳しい書き方についてはこちら: https://bukkit.gamepedia.com/Plugin_YAML

 

name、mainなどの下にcommandsを設定します。

 

書き方:

name: プラグイン名
main: パッケージ.メインクラス
version: バージョン
description: プラグインの説明
# 作者が複数いる場合はauthorsを使用し、一人の場合はauthorを使用して下さい。
author: 作者名
authors: [作者1, 作者2, 作者3]
website: サイトのURL

commands:
  コマンド名:
    description: コマンドの説明
    aliases: [他のコマンド名1, 他のコマンド名2]
    permission: コマンドの権限
    usage: コマンドの使い方
  コマンド名:
    description: コマンドの説明
    aliases: [他のコマンド名1, 他のコマンド名2]
    permission: コマンドの権限
    usage: |
      コマンドの使い方1行目
      2行目
      3行目...
permissions:
  権限名1.*:
    description: 権限の説明
    children:
      権限名1.権限名2: true
      権限名1.権限名3: true
      権限名1.権限名3.権限名4: true
  権限名1.権限名2:
    description: 権限の説明
    default: true
  権限名1.権限名3:
    description: 権限の説明
    default: true
  権限名1.権限名3.権限名4:
    description: 権限の説明
    default: op
    children:
      権限名1.権限名3: true

青色の文字が新しく記入した文です。name、main、versionの他に色々追加していますが、好きなものを追加して下さい。

 

 

記載例:

name: TestPlugin
main: io.github.densyakun.bukkit.test.Main
version: 0.2
description: This plugin is test plugin.
author: Densyakun
website: https://github.com/Densyakun

commands:
  flagrate:
    description: Set yourself on fire.
    aliases: [combust_me, combustMe]
    permission: inferno.flagrate
    usage: Syntax error! Simply type /command to ignite yourself.
  burningdeaths:
    description: List how many times you have died by fire.
    aliases: [burning_deaths, burningDeaths]
    permission: inferno.burningdeaths
    usage: |
      /command [player]
      Example: /command - see how many times you have burned to death
      Example: /command CaptainIce - see how many times CaptainIce has burned to death
permissions:
  inferno.*:
    description: Gives access to all Inferno commands
    children:
      inferno.flagrate: true
      inferno.burningdeaths: true
      inferno.burningdeaths.others: true
  inferno.flagrate:
    description: Allows you to ignite yourself
    default: true
  inferno.burningdeaths:
    description: Allows you to see how many times you have burned to death
    default: true
  inferno.burningdeaths.others:
    description: Allows you to see how many times others have burned to death
    default: op
    children:
      inferno.burningdeaths: true

インデントは空白二個ですが、三個でも出来ます。間違えると動きません。(インデントは揃えて下さい)

今回はversionを0.2に書き換えました。

 

 

まず、commandsを書き、その中にコマンド名を書きます。

name: TestPlugin
main: io.github.densyakun.bukkit.test.Main
version: 0.2
author: Densyakun
commands:
  test:

これで /test コマンドを追加できます。

commands:コマンド名だけでも動きますので、書くのがめんどくさい方はこれで大丈夫です。

 

 

他にも、コマンドの説明を書きたい場合はdescriptionを書いて下さい。

aliasesを使って他のコマンド名を使えます。

例えば、/flagrateコマンドを/combust_meや/combustMeでも出来るようにした場合は、

/flagrateコマンドの中にaliases: [combust_me, combustMe]と書きます。

 

使い方の説明は二種類あり、一行だけで書く場合は

usage: コマンドの使い方

で出来ます。

 

複数行で表示したい場合は

usage: |
  コマンドの使い方1行目
  2行目
  3行目...

で出来ます。(「...」は消して下さい)

 

 

 

プラグインの権限

コマンドのpermissionを書くと権限を持っていない場合はコマンドが実行できなくなります。

権限を付与するにはOP権限を与えるか、PermissionExなどを使って権限を付与します。

細かく権限を設定するには、permissions:を追加します。

permissions:
  権限名1.*:
    description: 権限の説明
    children:
      権限名1.権限名2: true
      権限名1.権限名3: true
      権限名1.権限名3.権限名4: true
  権限名1.権限名2:
    description: 権限の説明
    default: true
  権限名1.権限名3:
    description: 権限の説明
    default: true
  権限名1.権限名3.権限名4:
    description: 権限の説明
    default: op
    children:
      権限名1.権限名3: true

permissions:の中に権限の名前を書きます。

通常、権限の名前はプラグイン名.権限名という風に書きます。

コマンド用にプラグイン名.command.コマンド名と書く場合などもありますので、お好みの書き方をして構いません。

 

権限の名前を書いたら、その中にdescriptionで権限の説明を書きます。

defaultは、誰がこの権限を持っているか設定します。trueにすると誰でも使えます。opにするとOP権限を持っていればPermissionExなどで付与していなくても使えます。falseにするとOP権限を持っていてもPermissionExなどで設定しないと権限が付与できません。

 

権限にchildrenを記入すると、権限の子権限を設定でき、権限の親子関係を定義できます。

例えば権限test.command.testと、その親権限のtest.command、更にその親のtest.*があります。

その場合はtest.*の子権限にtest.command

test.commandの子権限にtest.command.testを追加します。

子権限の名前の後にtrueと書いてありますが、これはtrueだと通常の親子関係を定義し、falseだと親子関係が逆になるように定義できます。

 

 

 

コードを書く

次に前回作成したメインクラスを編集します。

メインクラスはplugin.ymlに書かれているmainと同じです。

以下のコードを追加します。

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
	if (label.equalsIgnoreCase("test")) {
		sender.sendMessage("コマンドが実行されました");
	}
	
	return true;
}

 

onCommandは自分のプラグインのコマンドが打たれると実行されるメソッドです。

引数のlabelはコマンド名、argsはコマンドの引数です。

例えば「/tp Densyakun Steve」の場合、labelは"tp"、argsには["Densyakun", "Steve"]と言う配列が入ります。

 

 

senderのCommandSenderクラスは、プレイヤーやコンソールなどの「コマンドを実行できる者」のクラスです。

例えばプレイヤーはPlayerクラスですが、CommandSenderインターフェースを継承していますし、プレイヤーでない場合もコマンドブロック、サーバーコンソールなどからコマンドが実行できるためこれもCommandSenderになります。

 

senderについての詳しい使い方はあとで説明します。

 

このコードではsender.sendMessage(str)を使ってコマンド送信元にメッセージを送り返しています。

 

 

if(label.equalsIgnoreCase("test"))を使って、testコマンドが実行されたかどうかを判別しています。

JavaではequalsIgnoreCase(str)を使って文字列と文字列を大文字小文字を気にせず判定することが出来ます。

 

booleanを返さなくてはいけないため、return trueと書いています。コマンドを間違えた場合にfalseを返すとplugin.ymlにて設定したコマンドの使い方が表示されます。trueを返すと何も起きません。

 

 

実際はこんな感じになります。

package io.github.densyakun.bukkit.test;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin {
	
	@Override
	public void onEnable() {
		System.out.println("プラグインが有効になりました");
	}
	
	@Override
	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
		if (label.equalsIgnoreCase("test")) {
			sender.sendMessage("コマンドが実行されました");
		}
		
		return true;
	}
	
	@Override
	public void onDisable() {
		System.out.println("プラグインが無効になりました");
	}
}

 

実際に使ってみましょう。前回と同じようにエクスポートして下さい。

サーバーにプラグインを入れて、サーバーを起動したら、

plコマンドを実行してプラグインが正しく導入されているか確認して下さい。

入れてもプラグインが読み込まれていない場合はplugin.ymlが間違っている可能性があります。

 

 

f:id:Densyakun:20180211191238p:plain

/ver TestPluginと入れると、バージョンが変わっているはずです。

 

 

f:id:Densyakun:20180211191259p:plain

/help TestPluginを実行すると追加されたプラグインが載っています。

 

 

f:id:Densyakun:20180211191335p:plain

/help testと入力するとtestコマンドについての説明や使い方が表示されますが、今回は書いていないので出ていません。

 

 

f:id:Densyakun:20180211191404p:plain

コマンドを実行してみましょう。

実行すると「コマンドが実行されました」と言うメッセージが表示されます。

 

 

f:id:Densyakun:20180211191431p:plain

/tとだけ入力してTABキーを押すと追加したtestコマンドがリストに載っています。

 

 

コマンド以外の権限について

plugin.ymlで設定した権限はコマンド以外にも使用できます。

権限を所有しているかどうか判定するには以下のコードを使用して下さい。

if (sender.hasPermission("権限名"))

 

 

 

Eventシステムを使う

次は、Eventシステムを活用していきます。

 

 

まず、org.bukkit.event.Listenerインターフェースを継承したクラスを作成して下さい。

(メインクラスに継承しても構いません)

 

そしたら、onEnable()内に以下のコードを書いて下さい。

getServer().getPluginManager().registerEvents(this, this);

第一引数はListener、第二引数はJavaPlugin(メインクラス)です。

これでプラグインにEventシステムが使えるようになりました。

 

 

次に、「Listenerを継承したクラス」にイベントを追加します。

新しくメソッドを追加します。この時のメソッド名はなんでも良いです。

新しく追加したメソッドの引数にはイベントのクラスを書きます。

イベントの一覧はこちら http://www.jias.jp/blog/?85

 

最後にメソッドに@EventHandlerアノテーションを追加して下さい。

 

今回はPlayerJoinEventを使用してプレイヤーのログインメッセージを変更します。

@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
	e.setJoinMessage("プレイヤーがログインしました: " + e.getPlayer().getName());
}

e.getPlayer()でプレイヤーを取得し、getName()でプレイヤー名を取得しています。

getName()はプレイヤーの本来の名前です。プレイヤーの表示名はgetDisplayName()で取得できます。

プレイヤーの表示名を設定するにはsetDisplayName(String)を使用します。

 

PlayerJoinEvent.setJoinMessage(String)でログインメッセージを変更しています。

 

 

メインクラスに書いた場合の例:

package io.github.densyakun.bukkit.test;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin implements Listener {
	
	@Override
	public void onEnable() {
		getServer().getPluginManager().registerEvents(this, this);
		
		System.out.println("プラグインが有効になりました");
	}
	
	@Override
	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
		if (label.equalsIgnoreCase("test")) {
			sender.sendMessage("コマンドが実行されました");
		}
		
		return true;
	}
	
	@Override
	public void onDisable() {
		System.out.println("プラグインが無効になりました");
	}
	
	@EventHandler
	public void onPlayerJoin(PlayerJoinEvent e) {
		e.setJoinMessage("プレイヤーがログインしました: " + e.getPlayer().getName());
	}
}

 

 

これでイベントを追加することが出来ました。

 

 

エクスポートして、プラグインをサーバーに入れます。

f:id:Densyakun:20180211191510p:plain

このように表示されていればOKです。

 

 

 

Eventシステムの活用

最後に、Eventシステムを活用します。

 

このようなイベントを追加して下さい。

@EventHandler
public void onPlayerJoin(BlockBreakEvent e) {
	Block b = e.getBlock();
	if (b.getType() == Material.GRASS) {
		e.setCancelled(true);
		b.setType(Material.SAND);
	}
}

 

BlockBreakEventはプレイヤーがブロックを破壊した時に実行されるイベントです。

これを使って草ブロックを破壊すると砂に変わります。

 

ブロックに関係するイベントはBlockEventを継承しています。

BlockEvent.getBlock()でブロックを取得できます。

Block.getType()はブロックの素材をMaterial型で返します。

 

if (b.getType() == Material.GRASS)

Material.GRASSと判定して草ブロックであるかどうかを判別しています。

 

e.setCancelled(true);

イベントをキャンセルすることで砂に変える時にブロックを破壊されないようになります。

 

b.setType(material);

これを使ってブロックの素材を砂に設定します。

 

マテリアルの一覧はこちら(バージョンにより異なる可能性があります)

 

 

 

実際にやってみます。

 

 

f:id:Densyakun:20180211191535p:plain

※暗い。

 

 

f:id:Densyakun:20180211191609g:plain

 

 

 

おわりに

今回はコマンドの追加とEventシステムの活用について解説しました。

次回については未定ですので、コメント欄にて次回の話題を募集します!

 

お楽しみに!

f:id:Densyakun:20180211191630p:plain

 

次回:

 

前回:

densyakun.hateblo.jp

【Spigot】Bukkitプラグインの作り方講座 第1回 – 簡単なプラグインを作る

f:id:Densyakun:20180211184737p:plain

こんにちは、電車君です。

今回からBukkitプラグインの作り方講座をやっていきます。

今回は第1回ということでBukkitプラグイン開発環境の構築から、プラグインの作成までやっていきます。

 

 

Bukkitプラグインとは…

  • Bukkitとは、ゲーム「Minecraft」のサーバーMODの一つである。
  • Bukkitには、プラグインを入れることで通常のバニラサーバーでは出来ない機能を追加できる。
  • プラグインはMODのようにブロックやアイテムを追加することは出来ない。
  • 2017年現在多くのサーバーがBukkitにて稼働しており、プラグインによって経済や要素が追加されている。
  • Bukkitは現在更新及び公開が停止しているが、その派生版としてSpigotが存在しBukkitと同様に使用でき、加えて多くの機能が追加されている。ただし、プラグイン開発ではBukkitとSpigotに一部違いがあるため注意が必要。今回はSpigotを使用する

 

 

プラグイン開発に必要なもの

  • プログラミングの基礎知識
  • Minecraftの基礎知識

 

 

 

 

開発環境を構築する

まずはじめに、Bukkitプラグインの開発環境を構築します。

Bukkitプラグインプログラミング言語Java」で出来ています。

今回は、Javaのプログラミング開発環境で有名な「eclipse」を使用します。

 

 

Eclipseのダウンロード・インストール

公式のeclipseは日本語に対応していないため、

こちらのサイトから日本語版をダウンロードします。

eclipse日本語版http://mergedoc.osdn.jp/

 

お好みのバージョンを選択して、JavaのFull Editionをダウンロードしてください。

 

ダウンロードが終わったらzipを展開して下さい。

中にある「pleiades-…」フォルダの中にあるeclipseのフォルダを開くと、

中にeclipse.exeがあるのでそれを開くとeclipseを起動します。

 

eclipseを起動するとスプラッシュ画面が表示されます。

初回起動時のみしばらく時間がかかります。

f:id:Densyakun:20180211183750p:plain

eclipse4.6(日本語版)のスプラッシュ画面

 

 

f:id:Densyakun:20180211183800p:plain

しばらくすると「Eclipse ランチャー」画面が表示され、

プロジェクトを管理するフォルダ「ワークスペース」を設定します。

「OK」を押すと、eclipseの起動が完了し画面が表示されます。

 

これで、eclipseが導入できました。

 

 

 

Spigotサーバーを立てる

次は、Spigotサーバーを立てます。

Spigotとは、更新及び公開が停止しているBukkitの派生版で、Bukkitと同様に使用でき、さらに多くの機能が追加されているものです。

 

プラグイン開発ではBukkitとSpigotに一部違いがあるため注意が必要です。

 

Spigotサーバーをダウンロード

次に、プラグインを実行するためのサーバーであるSpigotをダウンロードします。今回は1.9.4のサーバー及びプラグインを作りますが、1.9.4じゃなくても構いません。

 

Spigotダウンロードサイト(非公式): https://getbukkit.org/download/spigot

 

非公式サイトですが、公式サイトだとビルドツールとかgitとかなんだかんだでめんどくさいので、こちらの方が簡単にサーバーが立てられます。

ダウンロードしたいバージョンの右にあるDownloadボタンを押します。(横のCreate a Serverは押さないで下さい)

すると次のページに行き、少し下にスクロールすると広告に囲まれたリンクがあるのでそれを開いてダウンロードします。


ダウンロードしたら、好きなところにサーバーのフォルダを作り、その中にダウンロードしたjarファイルを入れます。(この時、間違えて開かないで下さい)

 

 

batファイルを作成する

次に、サーバーのフォルダの中にbatファイルを作成します。(Windowsの場合)

ファイル名に拡張子が表示されない場合は、エクスプローラーの設定を変更して下さい。

フォルダを右クリックして、 新規作成>テキストドキュメント を選択して、ファイル名を「start.bat」にします。

この時警告が出るはずですが、問題ないので続行して下さい。

ファイル名のstartはお好みの文字にしても構いません。”.txt”は消して下さい。

 

作成したbatファイルを右クリックして「編集」を押して下さい。(お好みのテキストエディタがあればそれを使って開いて下さい)

するとメモ帳が出てくるので以下の文章を入力します。

#.bat file example to run spigot by densyakun.
@ECHO OFF
java -Xms128M -Xmx1024M -jar spigot-xxx.jar
PAUSE

(spigot-xxx.jarにはダウンロードしたjarファイルのファイル名を入力)

 

javaはjarファイルを実行します。つまりサーバーを実行する処理が書かれています。

 

-Xmsは最小メモリ使用量、-Xmxは最大メモリ使用量です。1024Mは1GBと同じです。

-Xms と -Xmx は省略しても構いませんし、-Xmxだけ書いてもいいです。

省略した場合はデフォルトで最大1GBを使用します。大したワールドデータや50個を超えるほどの大量のプラグインを使用しなければ1GBで十分です。

・注意: MBやGBなどの単位は-Xms-Xmxの単位を揃えて下さい。

 

PAUSEは処理を停止して、キーボードを押したときに処理を再開するものです。

PAUSE の上にjavaがあるのでサーバーが実行されます。

サーバーが停止すると PAUSE により処理を停止してキーボードを押すとコンソールが消えます。

PAUSE が無いとサーバーが停止したときにすぐにコンソールが消えます。

 

@ECHO OFFは気にしなくていいです。

(詳しく説明すると、@ECHO はbatが実行するコマンド【今回の場合はjavaPAUSEなど】をコンソールに表示するかどうかを設定するものです)

 

コピペで入力しても構いませんので、入力が完了したら保存して下さい。

 

 

サーバーを起動する

次に、start.batを実行してサーバーを起動します。

すると黒い画面に白い文字が表示されたコンソール画面が出てきます。

f:id:Densyakun:20180211183922p:plain

すると、「Stopping server」と表示されサーバーが停止しました。

初回起動時には利用規約に同意する必要があります

 

サーバーを開くとサーバーフォルダにサーバーのファイルが生成されているので、

利用規約に同意するにはサーバーフォルダに生成されたeula.txtを編集し

eula=falseeula=trueに書き換えて下さい。

そしてもう一度start.batを起動するとサーバーが起動できます。

 

コンソールではコマンドを入力することが出来ます。

「stop」と入力するとサーバーを停止できます。

その他コマンドについてはhttps://www.spigotmc.org/wiki/spigot-commands/をご覧下さい。

・ここではポート開放のやり方などは説明しません。

 

 

 

Bukkitプラグインを作る

次に、今回の課題である「Bukkitプラグイン」を作っていきます。

 

 

 

プロジェクトの作成

まず、eclipseでプロジェクトを作成します。

 

上のメニューから ファイル>新規>Java プロジェクト を押すか、又は下の画像のようにアイコンの▼を選択して下さい。

f:id:Densyakun:20180211183836p:plain

アイコンを選択したら「Java プロジェクト」を選択して下さい。

f:id:Densyakun:20180211183946p:plain

 

「新規 Java プロジェクト」画面が出てくるので、お好みでプロジェクト名を入力して下さい。

 

プログラミングをしているとついプロジェクトが増えてしまうので、

他のプロジェクトを判別できる名前にしておくと便利です。

f:id:Densyakun:20180211183956p:plain

 

プロジェクト名を入力したら完了を押し、プロジェクトを作成します。

 

f:id:Densyakun:20180211184106p:plain

作成したプロジェクトは左側の「パッケージ・エクスプローラー」に表示されています。

プロジェクトの中には「src」(ソースフォルダ)と「JRE システム・ライブラリー」があります。

ソースフォルダには自分の作成した「ソース」を入れておくフォルダです。

JRE システム・ライブラリー」は簡単に言うとJavaです。特に気にしなくて大丈夫です。

 

 

 

ビルドパスの設定

このままではプロジェクトはただのJava プロジェクトでしか無いので、

Bukkit(Spigot)を読み込む必要があります。

プロジェクトを右クリックして下の方にある「Windows エクスプローラ」を選択すると、プロジェクトのフォルダがWindows標準のエクスプローラーで開かれます。

 

プロジェクトのフォルダの中には「bin」や「src」フォルダがあります。

プロジェクトのフォルダの中に「lib」と言うフォルダを作成して下さい。

そしたらその「lib」フォルダの中に先程ダウンロードしたサーバーjarをコピーします。

eclipseで見てみると、サーバーjarが反映されず表示されていないため、F5キーを押して反映させます。(その際にプロジェクトを選択して下さい)

そしたらeclipseからlibフォルダの中のサーバーjarを右クリックして、 ビルドパス>ビルドパスに追加 を押します。

これでプロジェクトでBukkit(Spigot)が使えるようになりました。

 

 

パッケージの作成

ここからが本番です。次にパッケージを作成します。

 

パッケージにはクラスファイルなどのプログラムを入れておくフォルダのことです。
Javaのパッケージについてはこちらをご覧ください:
https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8_(Java)

 

srcフォルダを右クリックして、 新規>パッケージ を選択します。

パッケージの名前には自分のサイトなどのアドレスを逆にしたもの(「densyakun.github.io」であればio.github.densyakun)にして下さい。(できればパッケージ名は全て小文字にして下さい。Javaの制約です

プログラミングをしているとパッケージが増えていくと思うので他のとかぶらないようにio.github.author.bukkit.testpluginなどとするといいです。(author=作者)

(私はio.github.densyakun.bukkit.testにしています)

完了を押すとsrcフォルダの中にパッケージが作成されます。

 

 

クラスの作成

次にパッケージの中にクラスを作成します。

先程作ったパッケージを右クリックして、 新規>クラス を選択します。

クラスの名前はお好みで大丈夫です。(ここでは「Main」とします。クラス名の頭文字は大文字にして下さい。Javaの制約です。メインクラスの名前はプラグイン名にするのがおすすめです)

完了を押すとパッケージの中にクラスファイルが作成され、画面中央の内蔵テキストエディタで作成したクラスファイルが編集できます。

 

すでにこのようなプログラムが書かれているはずです。
(プログラミングの基礎知識が必要です。分からない方はJavaを少し勉強して下さい)

package io.github.author.bukkit.testplugin;

public class Main {
	
}

 

これから書く内容の完成形です。めんどくさい方はコピペして下さい。

package io.github.author.bukkit.testplugin;

import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin {
	
	@Override
	public void onEnable() {
		System.out.println("プラグインが有効になりました");
	}
	
	@Override
	public void onDisable() {
		System.out.println("プラグインが無効になりました");
	}
}

 

まずMainクラスにJavaPluginクラスを継承します。

public class Mainpublic class Main extends JavaPluginに書き換えて下さい。

すると、JavaPluginがインポートされていないため "JavaPlugin" に赤い下線が表示されエラーが出ています。

その場合はJavaPluginにカーソルを合わせて「JavaPluginをインポートする」を選択して下さい。eclipseの便利な機能です。

 

 

次はMainの中にカーソルを置き、Ctrl+Spaceを押すとコンテンツ・アシストが表示されます。こちらもeclipseの便利な機能です。

onEnable()を選択してonEnableメソッドを作成して下さい。

そしたらもう一度、コンテンツ・アシストを表示してonDisableメソッドも作成して下さい。

onEnableメソッドとonDisableメソッドの中に自動生成されたもの(super.onEnable()、super.onDisable()含む)は削除して、

onEnableメソッドの中にはSystem.out.println(“プラグインが有効になりました”);

onDisableメソッドの中にはSystem.out.println(“プラグインが無効になりました”);を書いて下さい。

これでクラスは完成です。

 

 

plugin.ymlの作成

次に「plugin.yml」を作成します。


srcフォルダを右クリックして、 新規>ファイル を選択します。

ファイル名を”plugin.yml”にして完了を押します。

すると画面中央の内蔵テキストエディタにplugin.ymlが表示されます。

ちなみにymlはYAMLと言う文法で書きます。

 

plugin.ymlに以下の文章を入力して下さい。

name: プラグイン名
main: パッケージ.メインクラス
version: バージョン
author: 作者名
description: 説明

 

記入例:

name: TestPlugin
main: io.github.author.bukkit.testplugin.Main
version: 0.1
author: Author
description: Test Plugin

 

nameにはプラグイン名、

versionにバージョンとauthorに作者名、

descriptionにプラグインの説明を書いて下さい。

mainにはパッケージ名.メインクラスを書きます。上の記入例はパッケージがio.github.author.bukkit.testpluginでメインクラス(先ほど作成したクラス)が「Main」である場合の例です。

name、main、version以外は省略可能です。

plugin.ymlについてはこちらをご覧ください:https://bukkit.gamepedia.com/Plugin_YAML

 

 

 

Jarファイルの作成

plugin.ymlが完成したら、これでプラグインが動くようになりました。


次はプラグインをビルドしてjarファイルを作成します。

プロジェクトを右クリックして、 エクスポート を選択して下さい。

Jarファイルを押して下さい。こんな画面が出てきます。

f:id:Densyakun:20180211184121p:plain

 

右上の.classpathと.projectがチェックを外してエクスポートから除外して下さい。

左側でプロジェクトを開き、中にあるlibフォルダもチェックを外して除外して下さい。

これは、エクスポートする際には必ず確認して下さい。

 

エクスポート先をサーバーのpluginsフォルダの中にファイルを作成するようにして、

完了を押すとjarファイルが作成されます。

 

 

 

プラグインを動かす

次にサーバーを起動します。

サーバーが空いている場合は /reload コマンドを実行して下さい。

 

f:id:Densyakun:20180211184210p:plain

このようにログに「プラグインが有効になりました」と表示されていれば成功です。

次にサーバーにログインします。

接続元と接続先が同じPCである場合はサーバーアドレスを「localhost」にすることで接続できます。

 

 

/plコマンドを入力して、プラグイン一覧に作成したプラグインが追加されていれば完成です。

f:id:Densyakun:20180211184224p:plain

 

/version [プラグイン名] と入力するとプラグインのバージョンや説明文などが見れます。

 

今度はサーバーを閉じてみましょう。

 

f:id:Densyakun:20180211184320p:plain

このように「プラグインが無効になりました」と表示されていれば完成です。

 

おわりに

これでプラグインを作ることが出来ました。

今回はBukkitプラグイン開発環境の構築から、プラグインの作成までを行いました。

次回からは先程作成したプラグインをいじっていきます。

ありがとうございました。

f:id:Densyakun:20180211184259p:plain

 

次回:

densyakun.hateblo.jp

お久しぶりです。

お久しぶりです、電車君です。

約9ヶ月ぶりの投稿です。

 

9ヶ月前の投稿を見てみると、「『第33回 全国都市緑化よこはまフェア』が凄いことになってました」などというUnityの記事に要らん文章を書いていたことを少し反省しています。

 

最近の状況について(たまに来るコーナー?)

まず、ゲーム開発についてですが、

2015年に開発し、2015年に開発を中止したサンドボックスゲーム「BluePrint」を作り直して、

2016年3月に計画し、2017年2月に開発を開始した街づくり生活ゲーム「Blueprint」を作ることを重視しています。ちなみに開発者はわたくし一人です。(2018年2月7日現在)

 

他には、スマホでサクサクプレイできる一輪車レースゲームや、

Rintechでは、なあさんとBlockCity、るぴおとうさぎのゲームを作っています。(全く進んでないやつです)

 

ゲーム開発に関しては全て開発者募集中です。

 

 

 

次に、マインクラフト関連です。

「電車君サーバー」は2017年9月21日より「南北28条サーバー」に移行しました。

南北鯖はなあさんと環状線が運営します。果たしてちゃんと運営できているのか

 

 

 

次に、Rintechでやっているニュースサイト「Frare」があります。

実は、Frareに「Bukkitプラグイン作り方講座」を出しているのですが、

Frareがなんでもニュース的なことになっているということもあり、

ブログの方に移行しようかと思っています。

 

 

 

f:id:Densyakun:20180207213849j:plain

それと久々にUnturnedを遊びました。

数年前に友達と遊んでいたのが懐かしいです。

その頃とは随分ゲームが進化しているように思います。

 

 

 

最近はやることが決まらないというのもあり、

誰かと一緒に何かやりたいと思っています。いつも言ってる気がする...

 

それではまた今度。

 

フラクタル地形を生成する

 

gyazo.com

こんにちは電車君です。

今回はUnityでフラクタル地形を生成する方法を紹介します。

続きを読む

MonoBehaviourの挙動について

お久しぶりです。電車君です。

港の見える丘公園に行ったらちょうど「第33回 全国都市緑化よこはまフェア」をやっていてものすごいことになっていました。

小さい時は自然が好きだったのを改めて実感しました。

超会議に行ってきたりもしましたが、自分は人が多いところが苦手なので...

 

Unity関連は少し後回ししていました。電鯖もやりますよ。...多分。

 

今年から高校生になったので少し忙しくなりますが、

ブログの投稿頻度は上げていきます。

 

MonoBehaviourの挙動について

本題ですが、MonoBehaviourの基本的なメソッドにはStartとUpdateがあります。

 

Unity - マニュアル: イベント関数の実行順

続きを読む