pub fn draw_line(
x1: f32,
y1: f32,
x2: f32,
y2: f32,
thickness: f32,
color: Color
)
Expand description
Draws a line between points [x1, y1]
and [x2, y2]
with a given thickness
and color
.
Examples found in repository?
examples/camera_transformations.rs (line 16)
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
fn draw_cross(x: f32, y: f32, color: Color) {
let size = 0.1;
let thickness = 0.005;
draw_line(x - size, y, x + size, y, thickness, color);
draw_line(x, y - size, x, y + size, thickness, color);
}
#[macroquad::main("Camera")]
async fn main() {
let mut target = (0., 0.);
let mut zoom = 1.0;
let mut rotation = 0.0;
let mut smooth_rotation: f32 = 0.0;
let mut offset = (0., 0.);
loop {
if is_key_down(KeyCode::W) {
target.1 -= 0.1;
}
if is_key_down(KeyCode::S) {
target.1 += 0.1;
}
if is_key_down(KeyCode::A) {
target.0 += 0.1;
}
if is_key_down(KeyCode::D) {
target.0 -= 0.1;
}
if is_key_down(KeyCode::Left) {
offset.0 -= 0.1;
}
if is_key_down(KeyCode::Right) {
offset.0 += 0.1;
}
if is_key_down(KeyCode::Up) {
offset.1 += 0.1;
}
if is_key_down(KeyCode::Down) {
offset.1 -= 0.1;
}
#[cfg(not(target_arch = "wasm32"))]
if is_key_down(KeyCode::Q) | is_key_down(KeyCode::Escape) {
break;
}
match mouse_wheel() {
(_x, y) if y != 0.0 => {
// Normalize mouse wheel values is browser (chromium: 53, firefox: 3)
#[cfg(target_arch = "wasm32")]
let y = if y < 0.0 {
-1.0
} else if y > 0.0 {
1.0
} else {
0.0
};
if is_key_down(KeyCode::LeftControl) {
zoom *= 1.1f32.powf(y);
} else {
rotation += 10.0 * y;
rotation = match rotation {
angle if angle >= 360.0 => angle - 360.0,
angle if angle < 0.0 => angle + 360.0,
angle => angle,
}
}
}
_ => (),
}
smooth_rotation = angle_lerp(smooth_rotation, rotation, 0.1);
clear_background(LIGHTGRAY);
set_camera(&Camera2D {
target: vec2(target.0, target.1),
..Default::default()
});
draw_cross(0., 0., RED);
set_camera(&Camera2D {
target: vec2(target.0, target.1),
rotation: smooth_rotation,
..Default::default()
});
draw_cross(0., 0., GREEN);
set_camera(&Camera2D {
target: vec2(target.0, target.1),
rotation: smooth_rotation,
zoom: vec2(zoom, zoom * screen_width() / screen_height()),
..Default::default()
});
draw_cross(0., 0., BLUE);
set_camera(&Camera2D {
target: vec2(target.0, target.1),
rotation: smooth_rotation,
zoom: vec2(zoom, zoom * screen_width() / screen_height()),
offset: vec2(offset.0, offset.1),
..Default::default()
});
// Render some primitives in camera space
draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
draw_circle(0., 0., 0.1, YELLOW);
// Back to screen space, render some text
set_default_camera();
draw_text(
format!("target (WASD keys) = ({:+.2}, {:+.2})", target.0, target.1).as_str(),
10.0,
10.0,
15.0,
BLACK,
);
draw_text(
format!("rotation (mouse wheel) = {} degrees", rotation).as_str(),
10.0,
25.0,
15.0,
BLACK,
);
draw_text(
format!("zoom (ctrl + mouse wheel) = {:.2}", zoom).as_str(),
10.0,
40.0,
15.0,
BLACK,
);
draw_text(
format!("offset (arrow keys) = ({:+.2}, {:+.2})", offset.0, offset.1).as_str(),
10.0,
55.0,
15.0,
BLACK,
);
draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
next_frame().await
}
}
More examples
examples/basic_shapes.rs (line 8)
4 5 6 7 8 9 10 11 12 13 14 15 16
async fn main() {
loop {
clear_background(LIGHTGRAY);
draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
draw_text("HELLO", 20.0, 20.0, 30.0, DARKGRAY);
next_frame().await
}
}
examples/camera.rs (line 14)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
async fn main() {
loop {
clear_background(LIGHTGRAY);
// Render some primitives in camera space
set_camera(&Camera2D {
zoom: vec2(1., screen_width() / screen_height()),
..Default::default()
});
draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
draw_circle(0., 0., 0.1, YELLOW);
// Back to screen space, render some text
set_default_camera();
draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
next_frame().await
}
}
examples/post_processing.rs (line 29)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
async fn main() {
let render_target = render_target(320, 150);
render_target.texture.set_filter(FilterMode::Nearest);
let material = load_material(
ShaderSource::Glsl {
vertex: CRT_VERTEX_SHADER,
fragment: CRT_FRAGMENT_SHADER,
},
Default::default(),
)
.unwrap();
loop {
// drawing to the texture
// 0..100, 0..100 camera
set_camera(&Camera2D {
zoom: vec2(0.01, 0.01),
target: vec2(0.0, 0.0),
render_target: Some(render_target.clone()),
..Default::default()
});
clear_background(LIGHTGRAY);
draw_line(-30.0, 45.0, 30.0, 45.0, 3.0, BLUE);
draw_circle(-45.0, -35.0, 20.0, YELLOW);
draw_circle(45.0, -35.0, 20.0, GREEN);
// drawing to the screen
set_default_camera();
clear_background(WHITE);
gl_use_material(&material);
draw_texture_ex(
&render_target.texture,
0.,
0.,
WHITE,
DrawTextureParams {
dest_size: Some(vec2(screen_width(), screen_height())),
..Default::default()
},
);
gl_use_default_material();
next_frame().await;
}
}
examples/raw_miniquad.rs (line 22)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
async fn main() {
let stage = {
let InternalGlContext {
quad_context: ctx, ..
} = unsafe { get_internal_gl() };
raw_miniquad::Stage::new(ctx)
};
loop {
clear_background(LIGHTGRAY);
// Render some primitives in camera space
set_camera(&Camera2D {
zoom: vec2(1., screen_width() / screen_height()),
..Default::default()
});
draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
draw_circle(0., 0., 0.1, YELLOW);
{
let mut gl = unsafe { get_internal_gl() };
// Ensure that macroquad's shapes are not going to be lost
gl.flush();
let t = get_time();
gl.quad_context.apply_pipeline(&stage.pipeline);
gl.quad_context
.begin_default_pass(miniquad::PassAction::Nothing);
gl.quad_context.apply_bindings(&stage.bindings);
for i in 0..10 {
let t = t + i as f64 * 0.3;
gl.quad_context
.apply_uniforms(miniquad::UniformsSource::table(
&raw_miniquad::shader::Uniforms {
offset: (t.sin() as f32 * 0.5, (t * 3.).cos() as f32 * 0.5),
},
));
gl.quad_context.draw(0, 6, 1);
}
gl.quad_context.end_render_pass();
}
// Back to screen space, render some text
set_default_camera();
draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
next_frame().await
}
}
examples/snake.rs (lines 87-94)
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
async fn main() {
let mut snake = Snake {
head: (0, 0),
dir: (1, 0),
body: LinkedList::new(),
};
let mut fruit: Point = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
let mut score = 0;
let mut speed = 0.3;
let mut last_update = get_time();
let mut navigation_lock = false;
let mut game_over = false;
let up = (0, -1);
let down = (0, 1);
let right = (1, 0);
let left = (-1, 0);
loop {
if !game_over {
if is_key_down(KeyCode::Right) && snake.dir != left && !navigation_lock {
snake.dir = right;
navigation_lock = true;
} else if is_key_down(KeyCode::Left) && snake.dir != right && !navigation_lock {
snake.dir = left;
navigation_lock = true;
} else if is_key_down(KeyCode::Up) && snake.dir != down && !navigation_lock {
snake.dir = up;
navigation_lock = true;
} else if is_key_down(KeyCode::Down) && snake.dir != up && !navigation_lock {
snake.dir = down;
navigation_lock = true;
}
if get_time() - last_update > speed {
last_update = get_time();
snake.body.push_front(snake.head);
snake.head = (snake.head.0 + snake.dir.0, snake.head.1 + snake.dir.1);
if snake.head == fruit {
fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
score += 100;
speed *= 0.9;
} else {
snake.body.pop_back();
}
if snake.head.0 < 0
|| snake.head.1 < 0
|| snake.head.0 >= SQUARES
|| snake.head.1 >= SQUARES
{
game_over = true;
}
for (x, y) in &snake.body {
if *x == snake.head.0 && *y == snake.head.1 {
game_over = true;
}
}
navigation_lock = false;
}
}
if !game_over {
clear_background(LIGHTGRAY);
let game_size = screen_width().min(screen_height());
let offset_x = (screen_width() - game_size) / 2. + 10.;
let offset_y = (screen_height() - game_size) / 2. + 10.;
let sq_size = (screen_height() - offset_y * 2.) / SQUARES as f32;
draw_rectangle(offset_x, offset_y, game_size - 20., game_size - 20., WHITE);
for i in 1..SQUARES {
draw_line(
offset_x,
offset_y + sq_size * i as f32,
screen_width() - offset_x,
offset_y + sq_size * i as f32,
2.,
LIGHTGRAY,
);
}
for i in 1..SQUARES {
draw_line(
offset_x + sq_size * i as f32,
offset_y,
offset_x + sq_size * i as f32,
screen_height() - offset_y,
2.,
LIGHTGRAY,
);
}
draw_rectangle(
offset_x + snake.head.0 as f32 * sq_size,
offset_y + snake.head.1 as f32 * sq_size,
sq_size,
sq_size,
DARKGREEN,
);
for (x, y) in &snake.body {
draw_rectangle(
offset_x + *x as f32 * sq_size,
offset_y + *y as f32 * sq_size,
sq_size,
sq_size,
LIME,
);
}
draw_rectangle(
offset_x + fruit.0 as f32 * sq_size,
offset_y + fruit.1 as f32 * sq_size,
sq_size,
sq_size,
GOLD,
);
draw_text(format!("SCORE: {score}").as_str(), 10., 20., 20., DARKGRAY);
} else {
clear_background(WHITE);
let text = "Game Over. Press [enter] to play again.";
let font_size = 30.;
let text_size = measure_text(text, None, font_size as _, 1.0);
draw_text(
text,
screen_width() / 2. - text_size.width / 2.,
screen_height() / 2. + text_size.height / 2.,
font_size,
DARKGRAY,
);
if is_key_down(KeyCode::Enter) {
snake = Snake {
head: (0, 0),
dir: (1, 0),
body: LinkedList::new(),
};
fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
score = 0;
speed = 0.3;
last_update = get_time();
game_over = false;
}
}
next_frame().await;
}
}