3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

1. OverView

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

やるタスクは二つ

  • どう情報を表示しようか?
  • イベントはどうやろうか?

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

2. 本文

2.1 まずは本体

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

ソースコードにコメントしていきますが、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

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

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: マウスのx座標, y: マウスのx座標}

コードはこちら、 
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()
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?