
// 다른 외부 crate를 불러올 때 use를 이용합니다.
// nannou의 prelude(가장 자주 사용되는 기능들의 모음)를 가져옵니다.
use ::nannou::prelude::*;
// ======================================================================
// ==== 1. 전역 상수 설정 (Global Constants)
// ======================================================================
// 아트워크의 특성을 결정하는 주요 파라미터들을 상수로 정의합니다.
// `const`는 컴파일 타임에 값이 결정되는 불변 상수입니다.
const EXAMPLE_NUM: usize = 500;
const EXAMPLE_SCALE: f64 = 0.005;
// ======================================================================
// ==== 2. 메인 함수 (Main Function)
// ======================================================================
// Rust 프로그램의 진입점(entry point)입니다.
fn main() {
// nannou 앱을 설정하고 실행합니다. 빌더(builder) 패턴을 사용합니다.
// app(model): `model` 함수를 사용해 앱의 초기 상태를 설정합니다.
// .update(update): 매 프레임마다 상태를 변경할 `update` 함수를 지정합니다.
// .run(): 모든 설정을 마치고 앱의 메인 루프를 시작합니다.
nannou::app(model).update(update).run();
}
// ======================================================================
// ==== 3. Sub 구조체 정의 (Sub Struct)
// ======================================================================
// Model 속에서 사용되는 커스텀 데이터 타입(구조체)입니다.
struct Sub {
pos: Vec2,
vel: Vec2,
}
// ======================================================================
// ==== 4. Sub 메서드 구현 (Implementation)
// ======================================================================
// `impl` 키워드는 특정 구조체에 대한 메서드(함수)를 구현하는 블록입니다.
impl Sub {
}
// ======================================================================
// ==== 5. 모델(상태) 구조체 정의 (Model Struct)
// ======================================================================
// nannou 앱의 전체 상태(state)를 담는 구조체입니다.
// 이 `Model`의 인스턴스가 `update`와 `view` 함수 사이에서 계속 전달되며 앱의 생명주기를 관리합니다.
struct Model {
}
// ======================================================================
// ==== 6. 모델 초기화 함수 (Model Initialization)
// ======================================================================
// 앱이 시작될 때 단 한 번 호출되어 `Model`의 초기 상태를 설정합니다.
fn model(app: &App) -> Model {
// 창(window)을 생성하고, 크기/제목 등을 설정한 뒤, `view` 함수를 이 창의 렌더링 루프로 지정합니다.
app.new_window()
.size(800, 800)
.title("Nannou Generative Artwork")
.view(view)
.build()
.unwrap();
// 변수 설정
// 다양한 기능 명시
// 완성된 초기 상태를 담은 `Model` 인스턴스를 반환합니다.
Model {}
}
// ======================================================================
// ==== 7. 상태 업데이트 함수 (State Update Function)
// ======================================================================
// 매 프레임마다 `view` 함수가 호출되기 직전에 실행됩니다.
// 앱의 논리적인 상태(위치, 속도 등)를 계산하고 변경하는 역할을 합니다.
fn update(app: &App, model: &mut Model, update: Update) {
// 프레임마다 실행되는 로직
}
// ======================================================================
// ==== 8. 드로잉 함수 (View / Drawing Function)
// ======================================================================
// 매 프레임마다 `update` 함수가 실행된 후에 호출됩니다.
// 현재 `Model`의 상태를 바탕으로 화면에 그림을 그리는 역할을 합니다.
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw(); // `Draw` 인스턴스를 가져옵니다. 모든 그리기 명령은 이 `draw` 객체를 통해 이루어집니다.
// 첫 프레임에만 배경을 완전히 검은색으로 칠합니다.
if app.elapsed_frames() == 1 {
draw.background().color(BLACK);
}
// 매 프레임, 이전에 그려진 그림 위에 반투명한 검은 사각형을 덮어 그립니다.
// 이 과정이 반복되면서 파티클의 움직임에 자연스러운 잔상(trail) 효과가 생깁니다.
draw.rect()
.wh(app.window_rect().wh()) // 창 전체 크기의 사각형
.color(srgba(0.0, 0.0, 0.0, 0.1));
// 컬러 세팅, 애니메이션 세팅 등
// 여기에 도형을 그립니다!
// draw.ellipse().x_y(0.0, 0.0).radius(100.0).color(rgba(0.1, 0.8, 0.7, 1.0));
draw.rect().x_y(0.0, 0.0).w_h(200.0, 10.0).z_degrees(45.0).color(rgba(0.1, 0.8, 0.7, 1.0));
draw.tri().points(pt2(0.0, 50.0),pt2(-50.0, -50.0),pt2(50.0, -50.0),).color(GREEN);
draw.polygon().points(vec![pt2(0.0, 50.0), pt2(-43.3, -25.0), pt2(43.3, -25.0)]).color(rgba(0.1, 0.8, 0.7, 1.0));
draw.line().start(pt2(-100.0, 0.0)).end(pt2(100.0, 0.0)).weight(3.0).color(WHITE);
// 지금까지 버퍼에 쌓인 모든 그리기 명령들을 실제 프레임에 렌더링합니다.
draw.to_frame(app, &frame).unwrap();
}