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));
}
}