0. 初めに
build.gradle
や plugin.yml
の設定は終わらせた前提で進めます。
プロジェクトを作成する を参考にメインクラスを作るまで終わらせておいてください。
1. 処理の流れ
今回の内容はいたって簡単です。
イベントってこんなもんなんです。とても簡単で便利なので色々やってみましょう!
2. イベント登録を理解する
PlayerJoinEvent を使う場合のプログラムを追って理解していきましょう。
object EventListener: Listener {
}
メインクラスとは別に、イベントを受け取るためのクラス(オブジェクト) を作成しておきます。
(※class
と object
の違いは 後の記事で解説します。)
メインクラスの時は JavaPlugin() というものをクラス名の後に書きました。
イベントを受け取るためのクラス(オブジェクト) では Listener というものをクラス名の後に書きます。
後ろに書くことを 継承 といいます。継承の目的は、クラスに対して定義付けをすることです。
「イベントを受け取るためのクラス」や「プラグインのメインクラス」であることを定義しています。
しかし、これだけだとイベントを受け取る器が出来ただけです。実際にイベントを受け取るためには
server.pluginManager.registerEvents(EventListener, this)
これを呼び出す必要があります。onEnable
に書いておけばいいでしょう。
registerEvents
を日本語で言うと「イベントを登録する」です。
class Main: JavaPlugin() {
override fun onEnable() {
server.pluginManager.registerEvents(EventListener, this)
}
}
あとは実際のイベントを書くだけです。
object EventListener: Listener {
@EventHandler
fun on(e: PlayerJoinEvent){
/* イベントが呼び出されたときの処理を書く */
}
}
@EventHandler
をつけるとイベントの関数だと定義できます。
逆に言うと、忘れると何も起きません。
また、関数の引数にイベントの種類を書きます。今回であれば、PlayerJoinEvent
です。
関数の引数については後で解説します。
コメントにある通り、中括弧の中に呼び出されたときの処理を書きます。
3. メッセージを変更する
中括弧の中に「メッセージを変更」の処理を書きましょう。
object EventListener: Listener {
@EventHandler
fun on(e: PlayerJoinEvent){
val p = e.player
e.joinMessage = "${p.displayName} がサーバーに入りました"
}
}
val
というのは変数です。
「変数」は「値を保存するもの」 です。
e.player
で取得できるのはサーバーに入ってきたプレイヤーです。
一時的に変数として保存しておくことで、取得にかかる時間や、入力文字数が減ります。
それだけ?と思うかもしれませんが、前者の方はとても重要なことです。
変数として値を保存しておくことを意識してやってみましょう。
p.displayName
で取得できるのはプレイヤーの名前です。
${変数}
と書くことで文字列の中に変数の値を埋め込めることができます。
e.joinMessage
に文字列を代入することでメッセージが変更できます。
「代入」は「値を置き換える動作」 だと思ってください。
この状態で .jar を生成してサーバーで試してみましょう。
4. メッセージに色を付けてみる
「真っ白な字なんて・・・」って思っている方もいるかもしれません。
色を変えるだけで見栄えがぐっと良くなります。
こんな感じにしてみましょう。
基本は簡単です。§
を使ってカラーコードを書けばいいだけです。
e.joinMessage = "${p.displayName} がサーバーに入りました"
§b
と §f
を書き足します。しかし、これはやらなくていいです。
§
というのは セクション
と入力すると変換できるんですが問題があります。
e.joinMessage = "§b${p.displayName} §fがサーバーに入りました"
セクションには二つの問題があります。
・入力しにくい
・マイクラのチャットで書けない
だから普通は &
をセクションの代わりに使います。
でもただ置き換えるだけでは出来ません。
「&
を §
に置き換える」そういう処理が必要です。
e.joinMessage = ChatColor.translateAlternateColorCodes('&', "&b${p.displayName} &fがサーバーに入りました")
いきなり長くなりました。
「セクションには入力しにくいという問題がある。」とか言っておきながら、もっと面倒くさくなったと思いませんか?
最低でも私は思います。であれば、関数 として定義しておけばいい。そういう発想になります。
関数を作る目的は、「長い処理・面倒な処理をまとめる」といったことが多いです。
積極的に 処理のパーツ分け をしていきましょう。
さて、「文字列を色付き文字列に変換する」関数の処理の流れを考えてみましょう。
この図を元に言い換えると、
「文字列を一つ受け取って、何らかの処理をして、文字列を一つ返す」です。
もっとプログラムっぽくいうと
「文字列を引数とする 関数で 戻り値は文字列」といった感じですかね。
実際にプログラムにしてみましょう。
fun getColored(text: String): String {
return ChatColor.translateAlternateColorCodes('&', text)
}
分解して見ていきましょう。
・fun
function の略で「関数」という意味です。
・getColored
関数の名前です。分かりやすい名前を付けるように心がけましょう。
今回は「色付き文字列を取得する」関数なので get: 取得
Colored: 色付き
としています。
関数名の始まりは get
や is
など動詞から始まると分かりやすいです。
その後に別の英単語を繋げますが、頭文字は大文字にします。
一つ目の単語の頭文字は小文字。それ以降は大文字 という名前の付け方を camelCase
と言います。
・(text: String)
関数の引数です。関数が受け取る値です。
複数受け取ることも可能ですが、今回は文字列(String)一つのみです。
・: String
関数の戻り値です。関数が返す値です。
・return
ここでその関数を終了させる。ということです。
もしも、戻り値があるのであれば、その値をその後ろにつけましょう。
・ChatColor.translateAlternateColorCodes('&', text)
&
を §
に置き換える関数です。text
というのは引数に書いてあるものです。
分解してみると分かりやすいですね。分解できると分かりやすいというメリットだけではないんです。
例えば、受け取る値を一つ増やす。なら 引数の部分に足せばいいんだ。といったように対応がしっかりと出来ます。プログラムを分解できるということはプログラムを理解しているということだと私は思います。
この関数を実際に実装してみましょう。
object EventListener: Listener {
@EventHandler
fun on(e: PlayerJoinEvent){
val p = e.player
e.joinMessage = getColored("&b${p.displayName} &fがサーバーに入りました")
}
fun getColored(text: String): String {
return ChatColor.translateAlternateColorCodes('&', text)
}
}
こんな書き換えになると思います。さぁこの調子で Quit メッセージも変えてみましょう!
object EventListener: Listener {
@EventHandler
fun on(e: PlayerJoinEvent){
val p = e.player
e.joinMessage = getColored("&b${p.displayName} &fがサーバーに入りました")
}
@EventHandler
fun on(e: PlayerQuitEvent){
val p = e.player
e.quitMessage = getColored("&b${p.displayName} &fがサーバーを出ました")
}
fun getColored(text: String): String {
return ChatColor.translateAlternateColorCodes('&', text)
}
}
とても簡単ですね。しかし、まだ終わりではありません。
getColored
という関数。これからも使うことがありそうなくらい便利な関数ですよね。
使いたくなったらそのクラス毎に実装するのも面倒なので、Util
みたいなクラスを定義しましょう!
いつものように新規ファイルで Object
を Util
という名前で作成!
以下のようにしましょう。
getColored
はこちらに移動しましょう。
object Util {
fun getColored(text: String): String {
return ChatColor.translateAlternateColorCodes('&', text)
}
}
EventListener
の方から getColored
を消してしまったので
赤くなっていると思います。これまで同様、importしましょう。
3つのファイルが出来たところで今回は終了です。お疲れ様でした。
退出メッセージは自分では見えないのでテストがしにくいかもしれませんが、
参加メッセージと同じように書いていれば問題ないでしょう。