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
prelude
frombracket_lib
makes the various types and functions available. - You have to create a
State
object. This is where your ongoing game state is stored. - Implementing
GameState
providesbracket-lib
with atick
function to call on every frame. - Your
main
function constructs a terminal---in this case an 80x50 text console. - You create a
State
object, even though it doesn't have much state to store. - Launching
main_loop
hands control over tobracket-lib
, and runs thetick
function 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
:
y
stores the current vertical location of the bouncing "Hello Bracket World".going_down
stores 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
tick
function 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_rgb
to 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.printer
is 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_color
label. - The two numbers (40, 49) are screen coordinates.
TextAlign::center
will 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_color
commands, which is a simpler way to put single-color text on the console. - Some more
printer
calls, 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.