Exrayでゲームを作ろう…明日の為にその１　マウスイベントの取得

# 1. OverView

どもども、今回はマウスイベントの取得を書いてみたいと思います。

やるタスクは二つ
- どう情報を表示しようか？
- イベントはどうやろうか？

…うん、Cursesで表示は今回はやめとくか…

# 2. 本文
## 2.1 まずは本体

さて、Your first Exray applicationを参考に、プログラムの構造を決めましょう。
うん、コピペなんだけどね。まずはプログラムの構造が決まってないと、書けないんだよ、おっさんだから。

https://hexdocs.pm/exray/opening-a-window.html

ソースコードにコメントしていきますが、3つのプライベート関数（main_loop()、update()、draw()）と、
実際にこのモジュールに入るためのパブリック関数（run()）を作成する様です。

main_loopから、update(), draw()を呼び出す構造ですね。

drawは、画面描画をそこに入れるのが慣例の様ですが、updateはゲーム自体のupdateですかね？



```
  defp main_loop() do

    # Stay out of update and draw unless our window is ready to update and draw.
    unless window_is_ready?(), do: main_loop()

    # If at any point we press Raylib's default "Quit Application" key, (ESCAPE), stop looping and exit.
    unless window_should_close?() do
      update()
      draw()
      main_loop()
    end
  end
```

Stage 2; adding Raylib stuff


https://hexdocs.pm/exray/opening-a-window.html#stage-2-adding-raylib-stuff

では、こいつをベースに、やっていきます。

```
defmodule SuperCoolGame do

  # Exray.Core.Windowのimport
  import Exray.Core.Window

  # window_should_close?()イベントをポーリングするため、Exray.Core.Drawingもインポートします。
  # end_draw()がないと、入力がまったくポーリングされないそうです。
  import Exray.Core.Drawing

  # FPSをセットするために、Exray.Core.Timingをimportします。 This is VERY important.だそうな。
  import Exray.Core.Timing
  
  # マウスを使うために、importします。
  import Exray.Core.Input.Mouse
  # テキストを描画する為に、importします。
  import Exray.Text.Drawing
  
  # Runを定義します。
  # これは、publicな関数で、外部から呼び出される本体です。
  def run(width \\ 200, height \\ 200, title \\ "Hello World!") do
    # ウィンドウを初期化します。
    init_window(width, height, title)
    # init_windowを下すぐ後に、FPSを設定します。"SUPER important! Call"だそうで、やらんとsegvしまくります。
    set_target_fps(60)

    # main_loopの呼び出し
    main_loop()

    # WindowsがCloseしなかった場合、ここで再度 window_should_close?()でチェックし、close_window()します。
    if window_should_close?() do
      close_window()
    end

    :ok # :ok, because we're :ok :)
  end

  # mail loopです。
  defp main_loop() do

    # ウィンドウが更新および描画の準備が出来るまで、ここで再帰呼び出しして、これより下のupdateおよびdrawを実行しません。
    unless window_is_ready?(), do: main_loop()

    # Raylib's default "Quit Application" key, (ESCAPE)が押されるまで、実行を続けます。
    unless window_should_close?() do
      update()
      draw()
      main_loop()
    end
  end

  # ゲームをupdateします。
  defp update() do
    # Nothing yet!
  end

  defp draw() do
    # 描画する前に、Exray.Utils.Colors.black関数の結果で背景をクリアします
    clear_background(Exray.Utils.Colors.black())
    begin_drawing()

    # Nothing yet!

    end_drawing()
  end

end
```

## 2.2 どう情報を表示しようか？

Exray.Text.Drawingを調べると、draw_text/5がありましてこいつを使いましょう。
https://hexdocs.pm/exray/Exray.Text.Drawing.html#draw_text/5

こいつの説明は簡単なので省くとして、以下の様にdraw/0をdraw/1へと書き直しております。


マップ。display_itemsで受け取った以下の様なmapを、受け取って、表示されましょう。

%{display_string: 画面のx, x: マウスのｘ座標, y: マウスのｘ座標}

コードはこちら、　
begin_drawing()とend_drawing()の間でdraw_text/5を実行していることに注意してください。

```
  defp draw(display_items) do
    # Before drawing, we'll clear the background with the Exray.Utils.Colors.black function result- Which is %Exray.Structs.Color{r: 0, g: 0, b: 0, a: 255}.
    clear_background(Colors.white)

    begin_drawing()
    draw_text( ~s/#{display_items.display_string} X: #{display_items.x} Y:#{display_items.y}/ , 20, 20, 12,  Colors.red)

    # Basic.draw_circle(100, 100, 50.0, Colors.red)
    end_drawing()
  end
```

## 2.3 マウスの情報はどう取ろう？

import Exray.Core.Input.Mouseを使うんです。
どーせ、ボタンとか押すのはあるはずだがら、今回はシンプルにx, yだけ採取しましょう

|関数名|機能|
|:------|:----------------------------|
|get_mouse_x()|マウスのX軸の座標を取得する|
|get_mouse_y()|マウスのy軸の座標を取得する|

さて、update()に書き込んでみましょう。

```
  defp update() do
    %{display_string: "test", x: get_mouse_x(), y: get_mouse_y()}
  end
```

合わせて、mail_loopもちょっと弄ります。
```
    unless window_should_close?() do
      display_items = update()
      draw(display_items)
      :timer.sleep(100)
      main_loop()
    end
```

## 2.4 、まとめ

本日のソースは、こうなりました。
みなさん、動いたでしょうか？

次回は、もう少し派手に張ろうぜ、派手に。　

```
defmodule Mouseexample do
  # We import Exray.Core.Window, like we did in IEX.
  import Exray.Core.Window
  # But, we also import Exray.Core.Drawing, to have access to begin_draw() and end_draw() calls.
  # This is to poll for window_should_close?() events, as without end_draw() no inputs will be polled at all.
  import Exray.Core.Drawing
  # We also need to import Exray.Core.Timing in order to set our FPS. This is VERY important.
  import Exray.Core.Timing

  import Exray.Core.Input.Mouse
  import Exray.Text.Drawing

  alias Exray.Utils.Colors

  alias Exray.Shapes.Basic

  def run do
    width = 200
    height = 200
    title = "Hello World!"
    init_window(width, height, title)
    set_target_fps(60) # <-- SUPER important! Call this just after you init_window, or segfaults are gonna happen a lot.

    main_loop()
  end

  defp main_loop do
    # Stay out of update and draw unless our window is ready to update and draw.
    unless window_is_ready?(), do: main_loop()

    # If at any point we press Raylib's default "Quit Application" key, (ESCAPE), stop looping and exit.
    unless window_should_close?() do
      display_items = update()
      draw(display_items)
      :timer.sleep(100)
      main_loop()
    end
  end

  defp update() do
    %{display_string: "test", x: get_mouse_x(), y: get_mouse_y()}
  end

  defp draw(display_items) do
    # 描画する前に、Exray.Utils.Colors.black関数の結果で背景をクリアします
    clear_background(Colors.white)

    begin_drawing()
    draw_text( ~s/#{display_items.display_string} X: #{display_items.x} Y:#{display_items.y}/ , 20, 20, 12,  Colors.red)

    end_drawing()
  end
end

Mouseexample.run()
```