-
Notifications
You must be signed in to change notification settings - Fork 5
adi_screen tutorial 3: Sprites
Ok. We've done the boring stuff. But, if you want to draw something interesting you need a sprite.
Before we make sprites, we need to make a context. Our context will be a data structure that represents the program. Here's what it'll look like:
struct Context {
window: Window,
sprite: Sprite,
}
The struct
keyword in Rust, defines a type that is made up of other variable types. This struct is made up of a Window
and a Sprite
. Elements in the struct are separated by commas. The last comma is optional.
Here's what the full code looks like, that uses a context and a sprite:
extern crate adi_screen;
use adi_screen::{ Window, Input, Sprite, Style };
struct Context {
window: Window,
sprite: Sprite,
}
fn redraw(context: &mut Context) {
let disp2 = context.window.pulse_full_linear(2.0);
context.window.background(disp2, disp2, disp2);
}
fn main() {
let mut window = Window::create("project_name",
include_bytes!("res/logo.ppm"), &[]);
let sprite = Sprite::create(&mut window, &include!("res/sprite.data"),
Style::create().gradient(), 1);
let mut context = Context {
sprite: sprite,
window: window,
};
loop {
match context.window.update() {
Input::Back => break,
Input::Redraw => redraw(&mut context),
_ => {},
}
}
}
Copy the above code into a file. I will explain.
use adi_screen::{ Window, Input, Sprite, Style };
We've added Sprite and Style. A Sprite is an object that gets drawn on the screen. A Style is how that object is drawn.
struct Context {
window: Window,
sprite: Sprite,
}
fn redraw(context: &mut Context) {
let disp2 = context.window.pulse_full_linear(2.0);
context.window.background(disp2, disp2, disp2);
}
In order to access a variable within a struct, one must use a .
. Example: context.window
is accessing variable window
within the struct context
.
let sprite = Sprite::create(&mut window, &include!("res/sprite.data"),
Style::create().gradient(), 1);
Woah! There's a lot going on here. Like Window
, Sprite
and Style
also implement a create()
function. Sprite::create()
has 4 parameters.
-
&mut Window
- The window. -
&[f32]
- A reference to an array of vertices. O.K., but how do we do this?&include("res/sprite.data")
- We're including an array from a file. -
Style
- The Style to use to draw the Sprite.Style::create().gradient()
makes a gradient style. This is the most simple style. - The fourth parameter is the number of instances of the sprite to create.
Well, let's create that res/sprite.data
file:
[
-1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
-1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
-1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
]
It's broken up into 8 columns: X, Y, Z, W ( which should always be 1.0 ), R, G, B, A
The rows are split into groups of 3. Each group of 3 rows is a triangle. 2 triangles make a rectangle.
let mut context = Context {
sprite: sprite,
window: window,
};
loop {
match context.window.update() {
Input::Back => break,
Input::Redraw => redraw(&mut context),
_ => {},
}
}
Finally, the context is created. Since we're not using references to define the context, the variables sprite and window move inside the context. That means you can't just say window
anymore - you now have to say context.window
. You can see this inside the loop.
Try cargo run
, and see what happens.
These tutorial pages are very much WIP.
These 7 tutorials contain all you need to know to use the screen module!