理解图形学之一入门

use std::io::{stdout, Write};
use std::thread::sleep;
use std::time::Duration;

// 颜色
struct Color(u8, u8, u8);

// 虚拟窗口
struct Window {
    width: usize,
    height: usize,
    buffer: Vec<u32>, // 每个像素的颜色值
}

impl Window {
    fn new(width: usize, height: usize) -> Self {
        Window {
            width,
            height,
            buffer: vec![0x000000; width * height], // 黑色
        }
    }

    fn set_pixel(&mut self, x: usize, y: usize, color: Color) {
        if x < self.width && y < self.height {
            let c = ((color.0 as u32) << 16) | ((color.1 as u32) << 8) | (color.2 as u32);
            self.buffer[y * self.width + x] = c;
        }
    }

    fn clear(&mut self, color: Color) {
        let c = ((color.0 as u32) << 16) | ((color.1 as u32) << 8) | (color.2 as u32);
        self.buffer.fill(c);
    }

    // 将缓冲区内容显示到终端(用 ANSI 背景色)
    fn present(&self) {
        let mut out = String::new();
        out.push_str("\x1b[1;1H"); // 移动光标到左上角
        for y in 0..self.height {
            for x in 0..self.width {
                let pixel = self.buffer[y * self.width + x];
                let r = ((pixel >> 16) & 0xFF) as u8;
                let g = ((pixel >> 8) & 0xFF) as u8;
                let b = (pixel & 0xFF) as u8;
                // 用背景色填充两个空格,模拟一个正方形“像素”
                out.push_str(&format!("\x1b[48;2;{r};{g};{b}m  "));
            }
            out.push_str("\x1b[0m\n"); // 行尾重置颜色
        }
        print!("{out}");
        stdout().flush().unwrap();
    }
}

fn main() {
    let mut win = Window::new(40, 20); // 40×20 的“像素”网格
    let mut x = 20.0_f32;
    let mut y = 10.0_f32;
    let mut vx = 0.5;
    let mut vy = 0.3;

    print!("\x1b[2J"); // 初始清屏
    loop {
        win.clear(Color(20, 20, 40)); // 深蓝紫色背景

        // 画一个金色小球(以及它的十字光晕)
        let px = x as usize;
        let py = y as usize;
        win.set_pixel(px, py, Color(255, 200, 0));
        if px > 0 { win.set_pixel(px - 1, py, Color(255, 200, 0)); }
        if px < win.width - 1 { win.set_pixel(px + 1, py, Color(255, 200, 0)); }
        if py > 0 { win.set_pixel(px, py - 1, Color(255, 200, 0)); }
        if py < win.height - 1 { win.set_pixel(px, py + 1, Color(255, 200, 0)); }

        win.present(); // 把画好的帧显示出来

        // 移动小球,碰到边界反弹
        x += vx;
        y += vy;
        if x <= 0.0 || x >= win.width as f32 - 1.0 { vx = -vx; }
        if y <= 0.0 || y >= win.height as f32 - 1.0 { vy = -vy; }

        sleep(Duration::from_millis(50));
    }
}

  

posted @ 2026-08-10 12:36  华腾智算  阅读(4)  评论(0)    收藏  举报
https://damo.alibaba.com/ https://tianchi.aliyun.com/course?spm=5176.21206777.J_3941670930.5.87dc17c9BZNvLL