Hello Terminal
You can get to hello terminal pretty quickly:
Create a New Project
Find the directory in which you want to start developing, and type cargo init my_project to create a new project.
Link Bracket-Lib
Open Cargo.toml in the newly created project, and expand the [dependencies] section as follows:
[dependencies]
bracket-lib = "0.8"
Hello Minimal Terminal
The following code prints "Hello Bracket World" in a new simple console:
use bracket_lib::prelude::*; struct State {} impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { ctx.print(1, 1, "Hello Bracket World"); } } fn main() -> BError { let context = BTermBuilder::simple80x50() .with_title("Hello Minimal Bracket World") .build()?; let gs: State = State {}; main_loop(context, gs) }
This provides what you need for a minimal start:
- Importing the
preludefrombracket_libmakes the various types and functions available. - You have to create a
Stateobject. This is where your ongoing game state is stored. - Implementing
GameStateprovidesbracket-libwith atickfunction to call on every frame. - Your
mainfunction constructs a terminal---in this case an 80x50 text console. - You create a
Stateobject, even though it doesn't have much state to store. - Launching
main_loophands control over tobracket-lib, and runs thetickfunction on every rendered frame.
Bouncy Hello World
Another example (hello_terminal in the bracket-lib source) provides a bouncing "Hello World". Let's use it to explore some of the features available in the library:
use bracket_lib::prelude::*; struct State { y: i32, going_down: bool, } impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { let col1 = RGB::named(CYAN); let col2 = RGB::named(YELLOW); let percent: f32 = self.y as f32 / 50.0; let fg = col1.lerp(col2, percent); ctx.cls(); ctx.printer( 40, 49, "#[blue]Hello #[pink]Bracket#[] world.", TextAlign::Center, Some(RGBA::from_u8(200, 200, 200, 255)), ); ctx.print_color( 1, self.y, fg, RGB::named(BLACK), "♫ ♪ Hello Bracket World ☺", ); if self.going_down { self.y += 1; if self.y > 48 { self.going_down = false; } } else { self.y -= 1; if self.y < 2 { self.going_down = true; } } ctx.draw_box(39, 0, 20, 3, RGB::named(WHITE), RGB::named(BLACK)); ctx.printer( 58, 1, &format!("#[pink]FPS: #[]{}", ctx.fps), TextAlign::Right, None, ); ctx.printer( 58, 2, &format!("#[pink]Frame Time: #[]{} ms", ctx.frame_time_ms), TextAlign::Right, None, ); } } fn main() -> BError { let context = BTermBuilder::simple80x50() .with_title("Hello Bracket World") .build()?; let gs: State = State { y: 1, going_down: true, }; register_palette_color("blue", RGB::named(BLUE)); register_palette_color("pink", RGB::named(MAGENTA)); main_loop(context, gs) }
There's quite a lot to unwrap here, so let's go through a quick tour of using bracket-lib.
The State Structure
Everything your program needs to retain during execution lives in your state structure (well, you could use globals and lazy-statics). In this case, we're storing two variables in State:
ystores the current vertical location of the bouncing "Hello Bracket World".going_downstores whether the words are going up or down at the moment. It changes direction at the top and bottom of the screen.
Setup
In the main function, we start by initializing bracket-terminal. We ask for a simple 80x50 console, and title the window. The build() function actually creates the window; the other chained functions return an object describing what you want. There's a lot of options you can choose, documented elsewhere in this guide.
We initialize State with some starting values for the bouncing text. Then we call register_palette_color---more on that in "pretty printing", below. Finally, we call main_loop to begin running the program---and calling tick every frame.
Printing to the Console
- The
tickfunction starts by defining some colors. TheRGB::named(xxx)functions return a color object. The library defines all of the W3C named colors; you can also usefrom_rgbto specify one yourself. These colors are then used in various printing functions. - Then it does a little dance to figure out where to draw the bouncing hello world.
ctx.cls()clears the console.ctx.printeris then used to "pretty print" the words "Hello Bracket World".- The decorators
#[blue],#[pink]specify that text following that marker should be in the color that was registered wih theregister_palette_colorlabel. - The two numbers (40, 49) are screen coordinates.
TextAlign::centerwill center the text horizontally around the specified coordinates.Some(RGBA::from_u8(200, 200, 200, 255))describes a background color for the text.
- The decorators
- Then we use the
print_colorcommands, which is a simpler way to put single-color text on the console. - Some more
printercalls, demonstrating different alignments and color settings.
Notice that in the text, we use unicode. ♫ ♪ Hello Bracket World ☺ is valid, because the characters are part of the codepage-437 set---and bracket-terminal automatically translates them.
You'll find more detailed usage instructions throughout this document.