:: BASIC_03_circle_moving

BamgasiJM·2025년 9월 10일

Nannou <BASIC>

목록 보기
16/41
post-thumbnail

📝 Rust Code

use nannou::prelude::*;

fn main() {
    nannou::app(model).update(update).run();
}

struct Model {
    position: Point2,
    velocity: Vec2, // 속도도 벡터로 관리 가능
}

fn model(app: &App) -> Model {
    app.new_window()
        .size(400, 400)
        .view(view)
        .build()
        .unwrap();

    Model {
        position: pt2(0.0, 0.0),
        velocity: vec2(2.0, 0.0), // 오른쪽으로 이동
    }
}

fn update(app: &App, model: &mut Model, _update: Update) {
    model.position += model.velocity;

    let win = app.window_rect();
    let radius = 40.0;

    // 화면 밖으로 나가면 반대편으로 이동
    if model.position.x > win.right() + radius {
        model.position.x = win.left() - radius;
    }
}

fn view(app: &App, model: &Model, frame: Frame) {
    let draw = app.draw();

    draw.background().color(BLACK);
    draw.ellipse()
        .xy(model.position)
        .radius(40.0)
        .color(STEELBLUE);

    draw.to_frame(app, &frame).unwrap();
}

🔎 main 함수 안의 코드 다시 보기

fn main() {
    nannou::app(model).update(update).run();
}
  • 이 코드의 main 함수는 사실상 애플리케이션의 진입점일 뿐.
  • 앱 실행 순서 (모델업데이트실행) 를 체이닝으로 깔끔하게 정리하는 역할.
  • 실제 로직은 전부 nannouApp 객체 안에서 수행됨.

nannou::app(model)

  • 여기서 model 함수는 프로그램이 시작할 때 한 번 실행돼서 Model 구조체를 초기화.
  • 동시에 윈도우를 만들고, 그 안에 view 함수가 등록됨.
  • view 함수의 경우는 model 함수 안에서 app.new_window().view(view).build()로 연결해놨기 때문에, main에서는 따로 적어줄 필요가 없음.
    👉 그래서 view를 main에 쓰지 않는다.

.update(update)

  • 매 프레임마다 update 함수가 실행되도록 연결함.
  • 이 함수에서 Model 값을 바꾸거나 애니메이션 상태를 계산함.

.run()

  • 이벤트 루프를 시작 → 윈도우가 뜨고, 매 프레임마다 updateview 순서로 돌아감.
  • 사실상 "시작 버튼" 같은 역할.

⚡ 메서드 체이닝?

  • Rust에서 흔히 쓰는 builder 패턴 방식
  • nannou::app(model)AppBuilder 같은 객체를 반환.
  • .update(update)가 그 객체를 다시 반환.
  • 마지막 .run()이 실제 실행.
let mut app = nannou::app(model);
app = app.update(update);
app.run();

이거를 한 줄로 체이닝한 것뿐임.

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0개의 댓글