Bunnymark
Mix.install([
{:zexray, github: "jn-jairo/zexray", depth: 1}
])
Code example
Example complexity rating: [★★★☆] 3/4
defmodule Bunny do
require Record
require Zexray.Enum.Color
require Zexray.Type.Vector2
Record.defrecord(:bunny,
position: Zexray.Type.Vector2.t(x: 0, y: 0),
speed: Zexray.Type.Vector2.t(x: 0, y: 0),
color: Zexray.Enum.Color.enum(:black)
)
@type bunny ::
record(:bunny,
position: Zexray.Type.Vector2.t(),
speed: Zexray.Type.Vector2.t(),
color: Zexray.Type.Color.t()
)
end
defmodule ExampleState do
require Record
Record.defrecord(:example_state,
tex_bunny: nil,
tex_bunny_info: nil,
bunnies_count: 0,
bunnies: []
)
@type example_state ::
record(:example_state,
tex_bunny: Zexray.Type.Texture2D.t_resource(),
tex_bunny_info: Zexray.Type.Texture2D.t(),
bunnies_count: non_neg_integer,
bunnies: [Bunny.bunny()]
)
end
defmodule Example do
@resources_dir System.tmp_dir!() <> "/zexray/resources"
@resources_url "https://github.com/raysan5/raylib/raw/3e336e4470f7975af67f716d4d809441883d7eef"
use Zexray.Enum
use Zexray.Type
import Zexray.Util, only: [random_number: 2]
import Bunny
import ExampleState
def download_resources do
File.mkdir_p!(@resources_dir)
resources = %{
"#{@resources_dir}/wabbit_alpha.png" =>
"#{@resources_url}/examples/textures/resources/wabbit_alpha.png"
}
: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 [textures] example - bunnymark"
# bunnies limit
@max_bunnies 500
def init do
# Initialize window
Zexray.Window.with_window(@screen_width, @screen_height, @title, 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 bunny texture
tex_bunny = Zexray.Texture.load("#{@resources_dir}/wabbit_alpha.png", :resource)
tex_bunny_info = Zexray.Resource.content!(tex_bunny)
example_state(
tex_bunny: tex_bunny,
tex_bunny_info: tex_bunny_info
)
end,
&loop/1
)
end)
end
defp loop(state) do
# Detect window close button or ESC key
if Zexray.Window.should_close?() do
:ok
else
# Update
example_state(
tex_bunny: tex_bunny,
tex_bunny_info: tex_bunny_info,
bunnies_count: bunnies_count,
bunnies: bunnies
) = state
type_texture_2d(width: tex_bunny_width, height: tex_bunny_height) = tex_bunny_info
{bunnies_count, bunnies} =
if Zexray.Mouse.down?(enum_mouse_button(:left)) do
position = Zexray.Mouse.get_position()
# Create more bunnies
1..10
|> Enum.reduce({bunnies_count, bunnies}, fn _, {bunnies_count, bunnies} ->
if bunnies_count < @max_bunnies do
bunny =
bunny(
position: position,
speed:
type_vector2(
x: random_number(-250, 250) / 60,
y: random_number(-250, 250) / 60
),
color:
type_color(
r: random_number(50, 240),
g: random_number(80, 240),
b: random_number(100, 240),
a: 255
)
)
{bunnies_count + 1, [bunny | bunnies]}
else
{bunnies_count, bunnies}
end
end)
else
{bunnies_count, bunnies}
end
# Update bunnies
bunnies =
bunnies
|> Enum.map(fn bunny ->
bunny(position: position, speed: speed) = bunny
type_vector2(x: position_x, y: position_y) = position
type_vector2(x: speed_x, y: speed_y) = speed
position_x = position_x + speed_x
position_y = position_y + speed_y
speed_x =
if position_x + tex_bunny_width / 2 > @screen_width or
position_x + tex_bunny_width / 2 < 0 do
speed_x * -1
else
speed_x
end
speed_y =
if position_y + tex_bunny_height / 2 > @screen_height or
position_y + tex_bunny_height / 2 - 40 < 0 do
speed_y * -1
else
speed_y
end
bunny(
bunny,
position: type_vector2(x: position_x, y: position_y),
speed: type_vector2(x: speed_x, y: speed_y)
)
end)
# Draw
Zexray.Drawing.with_drawing(fn ->
Zexray.Drawing.clear_background(enum_color(:raywhite))
Enum.each(bunnies, fn bunny ->
bunny(position: position, color: color) = bunny
type_vector2(x: position_x, y: position_y) = position
Zexray.Texture.draw(tex_bunny, position_x, position_y, color)
end)
Zexray.Shape.draw_rectangle(0, 0, @screen_width, 40, enum_color(:black))
Zexray.Text.draw("bunnies: #{bunnies_count}", 120, 10, 20, enum_color(:green))
Zexray.Text.draw_fps(10, 10)
end)
state
|> example_state(
bunnies_count: bunnies_count,
bunnies: bunnies
)
|> loop()
end
end
end
Example.download_resources()
Example.init()