Animated Eyes, my first code in Rust, Yay!

Hi all,

Some code I would like to share you, give a try and it is a fun =)

In toml :

[package]
name = "animated_eyes"
version = "0.1.0"
edition = "2024"

[dependencies]
macroquad = "0.4"

and here is the code :

use macroquad::prelude::*;

//const WIDTH: f32 = 800.0;
//const HEIGHT: f32 = 600.0;


struct Eye {
    x: f32,
    y: f32,
    radius: f32,
    blink: f32,
}


fn draw_eye(eye: &Eye, mx: f32, my: f32) {

    let dx = mx - eye.x;
    let dy = my - eye.y;

    let dist = (dx * dx + dy * dy).sqrt();

    let limit = eye.radius - 12.0;

    let mut px = 0.0;
    let mut py = 0.0;

    if dist > 0.0 {
        px = dx / dist * limit;
        py = dy / dist * limit;
    }


    // Black eye border
    draw_circle(
        eye.x,
        eye.y,
        eye.radius + 3.0,
        BLACK,
    );


    // Blink animation
    if eye.blink > 0.0 {

        // Closed eyelid
        draw_rectangle(
            eye.x - eye.radius,
            eye.y - eye.radius,
            eye.radius * 2.0,
            eye.radius * 2.0,
            Color::from_rgba(255,220,180,255),
        );


        draw_line(
            eye.x - eye.radius,
            eye.y,
            eye.x + eye.radius,
            eye.y,
            2.0,
            Color::from_rgba(80,40,20,255),
        );


    } else {

        // White eye
        draw_circle(
            eye.x,
            eye.y,
            eye.radius,
            WHITE,
        );


        // Iris
        draw_circle(
            eye.x + px,
            eye.y + py,
            18.0,
            Color::from_rgba(70,150,255,255),
        );


        // Pupil
        draw_circle(
            eye.x + px,
            eye.y + py,
            10.0,
            BLACK,
        );


        // Reflection
        draw_circle(
            eye.x + px - 4.0,
            eye.y + py - 4.0,
            3.0,
            WHITE,
        );
    }
}



#[macroquad::main("Animated Eyes")]
async fn main() {


    let mut left_eye = Eye {
        x: 300.0,
        y: 250.0,
        radius: 40.0,
        blink: 0.0,
    };


    let mut right_eye = Eye {
        x: 500.0,
        y: 250.0,
        radius: 40.0,
        blink: 0.0,
    };


    let mut blink_timer: i32 = 0;
    let mut blinking = false;



    loop {


        clear_background(
            Color::from_rgba(220,230,255,255)
        );


        let (mx,my) = mouse_position();



        let dist_left =
            ((mx-left_eye.x).powi(2)
            +(my-left_eye.y).powi(2))
            .sqrt();


        let dist_right =
            ((mx-right_eye.x).powi(2)
            +(my-right_eye.y).powi(2))
            .sqrt();



        // Start blinking when mouse gets close
        if (dist_left < 100.0 || dist_right < 100.0)
            && !blinking
        {
            blink_timer = 60;
            blinking = true;
        }



        if blinking {

            blink_timer -= 1;


            if blink_timer < 20 {

                left_eye.blink = 1.0;
                right_eye.blink = 1.0;

            }


            if blink_timer <= 0 {

                left_eye.blink = 0.0;
                right_eye.blink = 0.0;

                blinking = false;
            }
        }



        // Face
        draw_circle(
            400.0,
            300.0,
            180.0,
            Color::from_rgba(255,220,180,255)
        );


        // Eyebrows
        draw_line(
            250.0,
            190.0,
            350.0,
            205.0,
            3.0,
            Color::from_rgba(70,40,20,255),
        );


        draw_line(
            450.0,
            205.0,
            550.0,
            190.0,
            3.0,
            Color::from_rgba(70,40,20,255),
        );


        // Nose
        draw_line(
            400.0,
            270.0,
            390.0,
            330.0,
            3.0,
            Color::from_rgba(120,80,50,255),
        );


        draw_line(
            390.0,
            330.0,
            410.0,
            330.0,
            3.0,
            Color::from_rgba(120,80,50,255),
        );



        // Mouth
        draw_circle(
            400.0,
            390.0,
            45.0,
            Color::from_rgba(200,50,50,255),
        );

        draw_rectangle(
            355.0,
            390.0,
            90.0,
            50.0,
            Color::from_rgba(220,230,255,255),
        );



        draw_eye(&left_eye,mx,my);
        draw_eye(&right_eye,mx,my);



        // Mouse crosshair
        /*draw_line(
            mx-15.0,
            my,
            mx+15.0,
            my,
            2.0,
            RED
        );


        draw_line(
            mx,
            my-15.0,
            mx,
            my+15.0,
            2.0,
            RED
        );


        draw_circle(
            mx,
            my,
            3.0,
            YELLOW
        );*/



        if is_key_pressed(KeyCode::Escape) {
            break;
        }


        next_frame().await;
    }
}

Enjoy !

Happy coding !

Deeply disturbing :slight_smile: The eyes seem to follow you...

Too much great for a beginner :thinking:

btw! I noticed that you comment WIDTH, and HEIGHT in your code :slightly_smiling_face:,
but you can use them :grin::

// Other parts of your code
// ...

const WIDTH: f32 = 800.;
const HEIGHT: f32 = 600.;

fn conf() -> Conf {
    Conf {
        window_title: String::from("Some title for your game's window"),
        window_width: WIDTH,
        window_height: HEIGHT,
        ..Default::default()
    }
}

#[macroquad::main(conf)]
async fn main() {
    // Your main's function code here
    // ...
}

Also, you can take my project as an example for learning Macroquad :slightly_smiling_face::

Vasya go to home :house_with_garden:

But some parts of the code there may be "dirty" still :grimacing: (and I know it)

Yeah beginner to Rust but not beginner in programming :wink:

Your Vasya is great but not tested yet, nice to see something big project of your game :star_struck:

It's not so much big project :sweat_smile:, and I haven't a plan to make it bigger later :slightly_smiling_face:. I've start to do it just for making some piece of my portfolio for a future :briefcase:. But now I think that fixation on the idea to make a portfolio :briefcase:, and only portfolio - isn't too much worthiness idea in our days :thinking:. When some companies change us, humans :man_curly_hair::woman_red_hair:, on soulsless AIs :grimacing::robot:

But if compare my project, with many other ones, those was be made by other people, and those was be dropped :thinking:... Yeah! :grin: It's big! :smirking_face:

This post got me introduced to miniquad, macroquad's backend. I'm having a funny idea of building a game engine around it. I'm trying to start with the Visual Editor so I could learn the low-level stuff along the way. Though it gets kinda hard with so little documentation that you have to scour the source to read the comments.

What do you want for making in game from style ? Would you want to work something together for game or not ? I am open and share some my thought for you if you want :slight_smile: