When I was looking around for an environment to teach programming, I thought wouldn't it be great if I could teach with raylib, however as much as I like C for all sorts of reasons, it can be a little daunting at first, especially if for example you've only coded with scratch before. Enter python which I kind of think as the modern successor to BASIC, add in a comprehensive wrapper for raylib and you have a powerful environment. Installing the wrapper is often easiest accomplished with pip. When looking at the code with this post I recommend using Thonny which is a great IDE for developing with python....
You are quite likely to have python3 and even pip installed already if not check your package manager. Open a terminal and type
pip install raylib
grab a text editor and you're ready to go!
Not surprisingly setup on windows is a little more complex, first grab python 3 I used the executable installer, do ensure the option add python to path is selected... (why it doesn't do this be default who knows!)
Once installed open a command prompt, first you need to upgrade pip
pip install --upgrade pip
once upgraded we can install the raylib module
pip install raylib
From there you can load scripts into the python IDLE editor and run them by pressing the F5 key. You might want to look for a more comfortable editor once you're all set up and working.
Phew! after all the setup its about time we looked at some code! here's my take on showing a window with some text on it, lets take a look so we can get a handle on how we need to use raylib.
from raylib.static import rl, ffi from raylib.colors import * # Initialization rl.SetConfigFlags(rl.FLAG_MSAA_4X_HINT) # Enable Multi Sampling Anti Aliasing 4x (if available) rl.SetTargetFPS(60) rl.InitWindow(800, 450, b"A window") # Main game loop while not rl.WindowShouldClose(): # Detect window close button or ESC key # Update # TODO: Update your variables here # Draw rl.BeginDrawing() rl.ClearBackground(BLACK) rl.DrawText(b'A window!', 20, 20, 42, WHITE) rl.EndDrawing()
The first thing to remember about python is that it is strict about indenting, it uses the indent (what column the text starts) in order to determine where a block of code begins and ends. For example the main loop is a while loop, notice that all the code in the loop is indented. The fact that python is strict about using indenting, has a interesting effect on your coding, it forces you to be tidy and makes the code easier to follow, add in a good habit of adding comments where you can and your code should be easy to follow, even if you haven't looked at it for some time.
from raylib.static import rl, ffi from raylib.colors import *
The first two lines of the above example, tells python to include the raylib wrapper into our project. Accessing the library is via the namespace rl, we also import ffi which allows low level access to C structures (don't worry about this for now - we'll see more later) The second line simply imports all of the raylib colour values.
# Initialization rl.SetConfigFlags(rl.FLAG_MSAA_4X_HINT) # Enable Multi Sampling Anti Aliasing 4x (if available) rl.SetTargetFPS(60) rl.InitWindow(800, 450, b"A window")
next we have some simple initialisation, we can set hints for raylib to tell it the sort of window we want available flags are
typedef enum { FLAG_RESERVED = 1, // Reserved FLAG_FULLSCREEN_MODE = 2, // Set to run program in fullscreen FLAG_WINDOW_RESIZABLE = 4, // Set to allow resizable window FLAG_WINDOW_UNDECORATED = 8, // Set to disable window decoration (frame and buttons) FLAG_WINDOW_TRANSPARENT = 16, // Set to allow transparent window FLAG_WINDOW_HIDDEN = 128, // Set to create the window initially hidden FLAG_WINDOW_ALWAYS_RUN = 256, // Set to allow windows running while minimized FLAG_MSAA_4X_HINT = 32, // Set to try enabling MSAA 4X FLAG_VSYNC_HINT = 64 // Set to try enabling V-Sync on GPU } ConfigFlag;
Note that this is taken directly from raylib.h probably your best reference to the functions available in raylib next to the cheat sheet. Yes that's a LOT of functions! but don't worry, you don't need to know them all...
So now we have our new window its time for the main loop
# Main game loop while not rl.WindowShouldClose(): # Detect window close button or ESC key # Update # TODO: Update your variables here # Draw rl.BeginDrawing() rl.ClearBackground(BLACK) rl.DrawText(b'A window!', 20, 20, 42, WHITE) rl.EndDrawing()
raylib kindly does a whole bunch of housekeeping for us in the background and looks after our window for us, in return we need to keep an eye on if the window is closing. while the window isn't (not) closing we need our game loop to be running. The first task in your game loop should be to update your variables, for example check key presses and move a character appropriately. Next is the fun bit drawing, all drawing with raylib need to be done in between these two function calls
BeginDrawing() EndDrawing()
BeginDrawing() set everything ready to draw, where as EndDrawing() finalises the render instructions you've supplied and sends them off to the GPU (Graphics Processing Unit - the video card)
So in the case of our very simple example we are just left with two command one to clear the back buffer we're about to draw to and another command to draw the text
rl.ClearBackground(BLACK) rl.DrawText(b'A window!', 20, 20, 42, WHITE)
Here's the C protoype from raylib.h so we can see what the parameters are called.
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
So the DrawText function unsurprisingly needs some text as its first parameter, notice the little b before the string, that's just needed because we want to send a C string to the wrapper, so don't forget it. next two parameters are x & y position to render the text, followed by the font size and colour.
Okay running a simple window is just a handful of lines of code, but there have been some technicalities to bare in mind. That said we have a start!
Printing variables is probably the first thing you'll want to play with, there is a slight complication here and that's the aforementioned binary strings. If we want to take advantage of pythons new "f" strings we'll need to convert it after the string is built, take a look at this...
rl.DrawText(f"Frame: {int(frame)}".encode('UTF-8') , 10, 28, 20, MAROON)
and a more "raylib" version
rl.DrawText(rl.TextFormat(b"level: %i",ffi.cast("int", level)), 10, 216, 20, WHITE)
Take a look at the format string on its own (first example)
f"Frame: {int(frame)}".encode('UTF-8')
we can embed the variable in the string, after this is done, the strings encode method allows us to present it to raylib as a binary string.
So to take stock we have opened a simple window and presented some text, we can also display variable values. On the face of it not much but it hasn't taken very many lines of code, and this gives a template for our forthcoming experiments. Check back for the next episode soon where we'll display some actual graphics....