3 điểm bởi GN⁺ 2024-05-21 | 1 bình luận | Chia sẻ qua WhatsApp

City In A Bottle – hệ thống raycasting 256 byte

  • Giới thiệu

    • Hôm nay giới thiệu một engine raycasting nhỏ và trình tạo thành phố được gói trong một tệp HTML 256 byte.
    • Có thể hiểu chương trình này như giải một câu đố, nơi nhiều khái niệm được nén vào một không gian cực nhỏ.
    • Các thành phần chính gồm mã HTML, vòng lặp cập nhật khung hình, hệ thống render, engine raycasting và bản thân thành phố.
  • Toàn bộ mã

    • Đây không chỉ là một snippet JavaScript đơn giản mà là một chương trình HTML hoàn chỉnh.
    • <canvas style=width:99% id=c onclick=setInterval('for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a',t=9)>
      

Mã HTML

  • Mã HTML
    • Phần HTML gồm một phần tử canvas đơn giản và sự kiện onclick.
    • <canvas style=width:99% id=c onclick=setInterval('',t=9)>
      
    • Phần tử canvas có id là 'c' để có thể được truy cập từ JavaScript.
    • Sự kiện onclick khởi động chương trình và tạo vòng lặp cập nhật thông qua lời gọi setInterval.

Mã JavaScript

  • Mã JavaScript

    • Đoạn mã JavaScript dài 199 byte được thực thi khi canvas được nhấp.
    • for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a
      
  • Phân tích mã

    • Mã được tách ra để dễ đọc hơn.
    • c.width = w = 99
      ++t
      for (i = 6e3; i--;){
        a = i%w/50 - 1
        s = b = 1 - i/4e3
        X = t
        Y = Z = d = 1
        for(; ++Z<w &  (Y < 6 - (32<Z & 27<X%w && X/9^Z/8)*8%46 ||  d | (s = (X&Y&Z)%3/Z, a = b = 1, d = Z/w));) {
          X += a
          Y -= b
        }
        c.getContext`2d`.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1)
      }
      
  • Giải thích mã theo từng bước

    • c.width = w = 99: khởi tạo canvas và đặt chiều rộng thành 99 pixel.
    • ++t: tăng biến thời gian để tạo hoạt ảnh.
    • for (i = 6e3; i--;){}: dùng vòng lặp để quyết định độ sáng của từng pixel.
    • a = i % w / 50 - 1: tính thành phần ngang của vector camera.
    • b = s = 1 - i / 4e3: tính thành phần dọc của vector camera.
    • X = t: dùng giá trị thời gian làm vị trí X ban đầu.
    • Y = Z = d = 1: khởi tạo các giá trị Y, Z và d.
    • for(; ++Z<w & ...;): hệ thống raycasting lặp cho đến khi phát hiện va chạm.
    • c.getContext2d.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1): vẽ từng pixel để tạo ra hình ảnh cuối cùng.

Học thêm

  • Học thêm
    • Bản demo này đã được gửi tới demoparty Revision 2022 và có thể xem trên Pouet.
    • Có thể xem phiên bản mở rộng thành shader 256 byte trên Shadertoy.
    • Công cụ tương tác do Daniel Darabos tạo ra cho phép thao tác nhiều khía cạnh khác nhau của chương trình theo thời gian thực.

Ý kiến của GN⁺

  • Điểm thú vị

    • Chương trình này cho thấy cách tạo ra đồ họa phức tạp bằng lượng mã cực nhỏ.
    • Chỉ sử dụng những phép toán cơ bản nên ngay cả kỹ sư phần mềm mới vào nghề cũng dễ hiểu.
    • Đây là ví dụ tốt về tối ưu hóa mã và chủ nghĩa tối giản, hữu ích trong các cuộc thi như code golf.
  • Góc nhìn phê bình

    • Mã được nén rất mạnh nên có thể khó đọc.
    • Phù hợp hơn cho mục đích nghệ thuật và thử nghiệm hơn là ứng dụng thực tế.
  • Công nghệ liên quan

    • Với các dự án tương tự, có thể xem nhiều ví dụ shader khác nhau trên Shadertoy.
    • Cũng có thể khám phá các ví dụ mã nhỏ khác trên những nền tảng như Dwitter.
  • Các điểm cần cân nhắc khi áp dụng công nghệ

    • Khi áp dụng kỹ thuật này, cần cân nhắc khả năng đọc và bảo trì của mã.
    • Cần nhận thức được những khó khăn về tối ưu hiệu năng và debug khi hiện thực chức năng phức tạp bằng lượng mã nhỏ.

1 bình luận

 
GN⁺ 2024-05-21
Ý kiến trên Hacker News

Tóm tắt các bình luận trên Hacker News

  • Trò chơi pinball 1K bằng JavaScript:

    • "Thật đáng kinh ngạc khi có thể chứa được nhiều thông tin đến vậy với chừng này mã."
    • "Cái này thực sự rất ngầu, nhưng trong lúc tôi đọc bài thì vòng lặp cứ chạy liên tục khiến laptop bị quá nhiệt."
    • "Tài liệu liên quan: cách xây dựng thế giới của [Atari 2600] Pitfall, sinh thủ tục, lazy evaluation, v.v."
  • Sinh thủ tục và lazy evaluation:

    • "Cung cấp nhiều liên kết tài liệu khác nhau về sinh thủ tục."
    • "Nhận xét về sự tương đồng giữa lazy evaluation và thuật toán ray tracing."
  • Ý kiến khác:

    • "Thật sự rất ngầu! Làm tốt lắm."
    • "Cả tác phẩm lẫn bài viết đều đáng kinh ngạc."
    • "Remnants by Alcatraz tương tự demo MS-DOS 256 byte - kèm liên kết YouTube."
    • "Việc nó được viết bằng JavaScript còn ấn tượng hơn."
    • "Thật sự đáng kinh ngạc."
    • "Đọc rất thú vị."
    • "Nếu thích thứ này thì bạn cũng sẽ thích #tweetcart trên Twitter. Đó là các chương trình có kích thước bằng một tweet dành cho máy chơi game ảo Pico-8."