added guide to raylib
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 28 Nov 2023 00:57:58 +0000 (18:57 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 28 Nov 2023 00:57:58 +0000 (18:57 -0600)
src/app.onyx
www/static/images/guide_raylib_1.png [new file with mode: 0644]
www/static/images/guide_raylib_2.png [new file with mode: 0644]
www/static/vendor/highlight.min.js
www/templates/pages/docs/guide_http_server.html
www/templates/pages/docs/guide_raylib.html [new file with mode: 0644]
www/templates/partials/navbar.html

index fad9de75f4c071cd62b7599a91c0c956d3cbec43..e50ff2e11c0b23541c90e1a69f9db8adb0ae099d 100644 (file)
@@ -56,6 +56,9 @@ reg: otmp.TemplateRegistry;
 @route.{.GET, "/docs/guides/http-server"}
 (req: &Req, res: &Res) => res->render("pages/docs/guide_http_server", null);
 
+@route.{.GET, "/docs/guides/raylib"}
+(req: &Req, res: &Res) => res->render("pages/docs/guide_raylib", null);
+
 @route.{.GET, "/docs/packages"}
 (req: &Req, res: &Res) => res->render("pages/docs/package", null);
 
diff --git a/www/static/images/guide_raylib_1.png b/www/static/images/guide_raylib_1.png
new file mode 100644 (file)
index 0000000..60406a2
Binary files /dev/null and b/www/static/images/guide_raylib_1.png differ
diff --git a/www/static/images/guide_raylib_2.png b/www/static/images/guide_raylib_2.png
new file mode 100644 (file)
index 0000000..474546b
Binary files /dev/null and b/www/static/images/guide_raylib_2.png differ
index 4e0c75334ac33b0e395a67f4c095221459b558f5..a169db4b647904fcb06fbde95f3574a4f3f82198 100644 (file)
@@ -2582,7 +2582,7 @@ var hljs = (function () {
                     "cast", "sizeof", "alignof", "typeof"
                 ],
                 literal: "true false null null_proc null_str it",
-                type: "i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 rawptr str cstr dyn_str i8x16 i16x8 i32x4 i64x2 f32x4 f64x2 v128 type_expr any",
+                type: "i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 rawptr str cstr dyn_str bool i8x16 i16x8 i32x4 i64x2 f32x4 f64x2 v128 type_expr any",
                 built_in: "math map set array random iter list conv type_info",
             },
 
index 8d8cca2727bb77f549b9a900a64e3243551b8001..e5bc6433b131d4d7afe73e8d88ffc1c7f4dc6d48 100644 (file)
@@ -6,7 +6,7 @@
 
 <div class="container header">
     <h1>Guide - HTTP Server</h1>
-    <div>⇦ <a href="/docs">Back to the docs</a></div>
+    <div>⇦ <a href="/docs/guides">Back to the guides</a></div>
 
     <p>
         This guide walks you through all steps of setting up an HTTP server Onyx,
diff --git a/www/templates/pages/docs/guide_raylib.html b/www/templates/pages/docs/guide_raylib.html
new file mode 100644 (file)
index 0000000..c67abb3
--- /dev/null
@@ -0,0 +1,315 @@
+{{block "title"}}Guide - Using Raylib{{endblock}}
+
+{{ let navbar_page = "docs" }}
+
+{{ block "page_content" }}
+
+<div class="container header">
+    <h1>Guide - Using Raylib</h1>
+    <div>⇦ <a href="/docs/guides">Back to the guides</a></div>
+
+    <p>
+        This guide will get you set up to use <a href="https://raylib.com">Raylib</a> in your next Onyx project.
+    </p>
+</div>
+
+<div class="container">
+    <div class="title">
+        <h2>Setting up the Project</h2>
+    </div>
+
+    <p>
+        To get started, create a new directory for the project. In that directory, run the following commands.
+    </p>
+
+    <pre class="hljs"><code class="language-sh">$ onyx package init
+Creating new project manifest in ./onyx-pkg.kdl.
+
+Package name: raylib-example
+Package description: An example project using the Raylib bindings
+Package url:    
+Package author: Brendan Hansen
+Package version (0.0.1):
+
+$ onyx package add
+       Added  'raylib' version 0.0.3
+
+$ onyx package sync
+       Fetch  http://github.com/onyx-lang/pkg-raylib  0.0.3
+     Install  Running installation of 'lib/github.com/onyx-lang/pkg-raylib'</code></pre>
+
+    <p>
+        This will initialize the prompt you for the project information, which you can leave blank because
+        you probably won't be publishing this project as a package.
+    </p>
+    <p>
+        It will also add the <code>raylib</code> dependency and synchronize all packages to install it.
+        When it installs, it compiles a native binding library to be used by Onyx to interoperate with Raylib.
+        This process should on any MacOS or Linux system. If it does not, consider making an issue on the
+        <a href="https://github.com/onyx-lang/pkg-raylib/issues">raylib package</a> repository.
+    </p>
+</div>
+
+<div class="container">
+    <div class="title">
+        <h2>Writing some code</h2>
+    </div>
+
+    <p>
+        Now that the project is set up and Raylib is installed, you can start writing some code.
+        Lets start by testing our environment by creating a simple window with a gray background.
+        Write the following code in a file called <code>game.onyx</code>.
+    </p>
+
+    <pre class="hljs"><code class="language-onyx">#load "./lib/packages"
+
+use core {*}
+use raylib
+
+main :: () {
+    // Create a new window
+    raylib.InitWindow(1200, 900, "Raylib Example");
+
+    while !raylib.WindowShouldClose() {
+        // Start drawing
+        raylib.BeginDrawing();
+        
+        // Clear the screen to a gray screen
+        raylib.ClearBackground(.{20, 20, 20, 255});
+
+        // Finish drawing
+        raylib.EndDrawing();
+    }
+
+    // Close window when done
+    raylib.CloseWindow();
+}</code></pre>
+
+    <p>
+        To test your code, you can run it using <code>onyx run</code>.
+    </p>
+
+    <pre class="hljs"><code class="language-sh">$ onyx run game.onyx</code></pre>    
+
+    <p>
+        Assuming everything is working, you should see a window that looks like this.
+    </p>
+
+    <div style="text-align: center;">
+        <img src="/static/images/guide_raylib_1.png" alt="Raylib is working" width="600">
+    </div>
+</div>
+
+<div class="container">
+    <div class="title">
+        <h2>Making a "Game"</h2>
+    </div>
+
+    <p>
+        Let's expand your simple window testing program by making a (very simple) game.
+        In this game, you will control a character, and your job is to run to a checkpoint,
+        but in your way will be random mines that you need to avoid.
+    </p>
+
+    <p>
+        It's a silly game idea, but it will demonstrate some Onyx and Raylib features.
+    </p>
+
+    <p>
+        To start making this game, let's define some structures and global variables
+        to store the state of the game.
+    </p>
+
+    <pre class="hljs"><code class="language-onyx">Player :: struct {
+    x, y: f32;
+    size: f32;
+}
+
+Checkpoint :: struct {
+    x, y: f32;
+    size: f32;
+}
+
+Mine :: struct {
+    x, y: f32;
+    size: f32;
+}
+
+//
+// Game state
+player: Player;
+checkpoint: Checkpoint;
+mines: [..] Mine;
+score: i32;</code></pre>
+
+    <p>
+        Next, you can add some code to reset the game state in <code>resetGame</code>, generate new mines
+        and move the checkpoint in <code>moveCheckpointAndSpawnMines</code>.
+    </p>
+
+    <pre class="hljs"><code class="language-onyx">resetGame :: () {
+    // Reset the score.
+    score = 0;
+
+    // Put our player in the middle of the screen.
+    player = .{
+        x = 600,
+        y = 450,
+        size = 20
+    };
+
+    // Remove all existing mines
+    array.clear(&mines);
+
+    moveCheckpointAndSpawnMines();
+}
+
+moveCheckpointAndSpawnMines :: () {
+    checkpoint = .{
+        x = random.float(0, 1180),
+        y = random.float(0, 880),
+        size = 20,
+    };
+
+    // Spawn 5 mines at a time.
+    for 5 {
+        mine := mineGenerator()
+            |> iter.skip_while(m => collidesWithCheckpointOrPlayer(m))
+            |> iter.next();
+
+        array.push(&mines, mine);
+    }
+}</code></pre>
+
+    <p>
+        The above uses a couple of utility functions that you need to write.
+        The first one checks if a mine that is going to be place collides with
+        the checkpoint or the player.
+    </p>
+
+    <p>
+        The other one is a little weirder.
+        It procudes an <em>Iterator</em> over random <code>Mine</code>s.
+        This iterator never ends, and will infinitely produce random mines.
+        When combined with <code>iter.skip_while</code>, you can easily
+        find the first mine that meets a constraint.
+        In this case, the first mine thatis infinite does not collide with the checkpoint
+        or the player.
+    </p>
+
+    <pre class="hljs"><code class="language-onyx">#doc "Returns if a mine collides with the checkpoint or the player."
+collidesWithCheckpointOrPlayer :: (m: Mine) -> bool {
+    return
+        raylib.CheckCollisionCircleRec(
+            .{ m.x, m.y }, m.size,
+            .{ checkpoint.x, checkpoint.y, checkpoint.size, checkpoint.size }
+        )
+        ||
+        raylib.CheckCollisionCircleRec(
+            .{ m.x, m.y }, m.size,
+            .{ player.x, player.y, player.size, player.size }
+        );
+}
+
+#doc "Produces an interator of random mines."
+mineGenerator :: () -> Iterator(Mine) {
+    return iter.generator(&.{}, _ => {
+        return Mine.{
+            x = random.float(0, 1180),
+            y = random.float(0, 880),
+            size = random.float(10, 30),
+        }, true;
+    });
+}</code></pre>
+
+    <p>
+        Finally, you need to update your <code>main</code> procedure to use the new procedures
+        and make the game, well, a game.
+    </p>
+
+    <pre class="hljs"><code class="language-onyx">main :: () {
+    random.set_seed(os.time());
+
+    resetGame();
+
+    // Create a new window
+    raylib.InitWindow(1200, 900, "Raylib Example");
+
+    while !raylib.WindowShouldClose() {
+        // Update player based on keys pressed
+        dt := raylib.GetFrameTime();
+
+        player_speed :: 160.0f;
+        if raylib.IsKeyDown(.UP)    do player.y -= player_speed * dt;
+        if raylib.IsKeyDown(.DOWN)  do player.y += player_speed * dt;
+        if raylib.IsKeyDown(.LEFT)  do player.x -= player_speed * dt;
+        if raylib.IsKeyDown(.RIGHT) do player.x += player_speed * dt;
+
+        // Check for collision with the checkpoint
+        if raylib.CheckCollisionCircleRec(
+            .{ player.x, player.y }, player.size,
+            .{ checkpoint.x, checkpoint.y, checkpoint.size, checkpoint.size }
+        ) {
+            score += 10;
+            moveCheckpointAndSpawnMines();
+        }
+
+        // Check collision with mines
+        for mine: mines {
+            if raylib.CheckCollisionCircles(
+                .{ player.x, player.y }, player.size,
+                .{ mine.x, mine.y }, mine.size,
+            ) {
+                resetGame();
+            }
+        }
+
+        // Start drawing
+        raylib.BeginDrawing();
+        
+        // Clear the screen to a gray screen
+        raylib.ClearBackground(.{20, 20, 20, 255});
+
+        // Draw mines
+        for mine: mines {
+            raylib.DrawCircle(~~mine.x, ~~mine.y, mine.size, .{100, 0, 0, 255});
+        }
+
+        // Draw the checkpoint
+        raylib.DrawRectangle(~~checkpoint.x, ~~checkpoint.y, ~~checkpoint.size, ~~checkpoint.size, .{50, 200, 0, 255});
+
+        // Draw the player
+        raylib.DrawCircle(~~player.x, ~~player.y, player.size, .{0, 0, 200, 255});
+
+        // Draw the score
+        raylib.DrawText(tprintf("Score: {}\0", score).data, 0, 0, 24, .{255, 255, 255, 255});
+
+        // Finish drawing
+        raylib.EndDrawing();
+    }
+
+    // Close window when done
+    raylib.CloseWindow();
+}</code></pre>
+
+    <p>
+        With all of the above code in <code>game.onyx</code>, you can run your game in the same way
+        as before. 
+    </p>
+
+    <pre class="hljs"><code class="language-sh">$ onyx run game.onyx</code></pre>    
+
+    <div style="text-align: center;">
+        <img src="/static/images/guide_raylib_2.png" alt="Raylib is working" width="600">
+    </div>
+
+    <p>
+        Now, you can take this simple game and make something even better! 
+        See the <a href="https://raylib.com">Raylib</a> documentation for more details on
+        how to use Raylib.
+    </p>
+</div>
+    
+{{ endblock }}
+
+{{ extends "pages/normal_page" }}
index 2bc6b4839e528ad41d1af7ed4fbe7914cf808015..60a8f42590127a75223acce08bd5846cfa7ce0ab 100644 (file)
@@ -21,8 +21,7 @@
         </span>
 
         <div>
-            <a href="/"><span {{ if navbar_page == "home" }} class="active" {{ endif }}>Home</span></a>
-            <a target="_blank" href="https://try.onyxlang.io"><span>Try Online</span></a>
+            <a target="_blank" href="https://try.onyxlang.io"><span>Try Onyx</span></a>
             <a href="/docs"><span {{ if navbar_page == "docs" }} class="active" {{ endif }}>Docs</span></a>
             <a href="/news"><span {{ if navbar_page == "news" }} class="active" {{ endif }}>News</span></a>
             <a href="https://github.com/onyx-lang/onyx" target="_blank"><span>GitHub</span></a>