Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Playing sound multiple times

examples/audio/sound_multi.livemd

Playing sound multiple times

Mix.install([
  {:zexray, github: "jn-jairo/zexray", depth: 1}
])

Code example

Example complexity rating: [★★☆☆] 2/4

defmodule Example do
  @resources_dir System.tmp_dir!() <> "/zexray/resources"
  @resources_url "https://github.com/raysan5/raylib/raw/3e336e4470f7975af67f716d4d809441883d7eef"

  use Zexray.Enum

  def download_resources do
    File.mkdir_p!(@resources_dir)

    resources = %{
      "#{@resources_dir}/sound.wav" => "#{@resources_url}/examples/audio/resources/sound.wav"
    }

    :inets.start()
    :ssl.start()

    Enum.each(resources, fn {file, url} ->
      if not File.exists?(file) do
        {:ok, :saved_to_file} =
          :httpc.request(:get, {~c"#{url}", []}, [], stream: ~c"#{file}")
      end
    end)
  end

  @screen_width 800
  @screen_height 450
  @title "zexray [audio] example - playing sound multiple times"

  @max_sounds 10

  def init do
    # Initialize window
    Zexray.Window.with_window(@screen_width, @screen_height, @title, fn ->
      # Initialize audio device
      Zexray.Audio.with_audio(fn ->
        # Set our game to run at 60 frames-per-second
        Zexray.Timing.set_target_fps(60)

        # Manage resources loading/unloading
        Zexray.Resource.with_resource(
          fn ->
            # load the sound list

            # Load WAV audio file into the first slot as the 'source' sound
            # this sound owns the sample data
            sound = Zexray.Audio.load_sound("#{@resources_dir}/sound.wav", :resource)

            # Load an alias of the sound into slots 1-9
            # These do not own the sound data, but can be played
            sound_aliases =
              1..(@max_sounds - 1)
              |> Enum.map(fn _ ->
                Zexray.Audio.load_sound_alias(sound, :resource)
              end)

            sounds = [sound | sound_aliases]

            {sounds}
          end,
          &amp;loop/1
        )
      end)
    end)
  end

  defp loop({sounds} = state) do
    # Detect window close button or ESC key
    if Zexray.Window.should_close?() do
      :ok
    else
      # Update

      if Zexray.Keyboard.pressed?(enum_keyboard_key(:space)) do
        # Look at the list for the first sound that is not playing and use that slot
        sound =
          Enum.find(sounds, fn sound ->
            not Zexray.Audio.playing?(sound)
          end)

        if not is_nil(sound) do
          Zexray.Audio.play(sound)
        end
      end

      # Draw

      Zexray.Drawing.with_drawing(fn ->
        Zexray.Drawing.clear_background(enum_color(:raywhite))

        Zexray.Text.draw(
          "Press SPACE to PLAY the WAV sound!",
          200,
          180,
          20,
          enum_color(:lightgray)
        )
      end)

      loop(state)
    end
  end
end
Example.download_resources()
Example.init()