Hiển thị sự bùng nổ của một ngôi sao trong nghệ thuật ASCII


12

Mục đích là để làm sống động một ngôi sao bùng nổ trong nghệ thuật ASCII, bắt đầu từ một nhân vật ngôi sao duy nhất *đến siêu tân tinh và cuối cùng đến khoảng trống không gian.

Quy tắc :

  • Bạn phải chỉ hiển thị 80 ký tự trên mỗi dòng trên 24 dòng (đây là kích thước thiết bị đầu cuối mặc định trên Linux)
  • Chỉ cho phép 95 ký tự có thể in từ ASCII này
  • Các bước:
    1. Ngôi sao ban đầu phải *ở giữa và theo chiều ngang và chiều dọc
    2. Ngôi sao phải phát triển để chứng tỏ rằng nó phát nổ
    3. Cuối cùng, màn hình phải trống (ngôi sao đã biến mất)
  • Độ dài của mã hoặc ngôn ngữ không liên quan
  • Phiếu bầu sẽ quyết định kết quả sáng tạo và đẹp nhất. Bạn đã bao giờ nhìn thấy một ngôi sao nổ tung? Hãy xem bạn tưởng tượng điều này như thế nào.

Tôi đã thêm một câu trả lời bằng Python làm ví dụ, nhưng bạn được khuyến khích tạo ra thứ gì đó khác biệt hoặc tốt hơn.

Bạn có một tuần để tham gia, người chiến thắng sẽ được chọn vào ngày 2014-04-01.

Các mẫu đầu ra (chỉ với một số khung):

# start





                                        *





# during explosion

                                    ****#****
                                 ***#@##*#@#****
                               *@**@@@*##**#*#**#*
                              **@@*#**#@*#@****#***
                              ****@*@***#****@**@@*
                             *******@***@@***#****#*
                              *#***#*##@****##@@@**
                              **#@###****@*********
                               *****@**@*@*****@**
                                 ************@**
                                    ****#****


# star is expanding

                                        *                                       
                               ********* **@******
                           ****   **#**@ #**#*#   ****
                         ***  **  **##** *@@*@*  **  ***
                       **  *  @@   *@*#* ***@*   *#  *  **
                     *** #  *  *#  *@#** ***@*  **  @  * *@*
                    ** *  * ** *@  ****@ @****  ** #* *  * **
                   ** * @* * ** *@  #### *#**  ** ** * @* * **
                  *# * # ** * #* *  **** ****  @ ** * ** * * #*
                 ** * *# * @ * #  @  @*@ *#*  *  @ # # * @* * **
                 *# * * * * # * @* * **# *#* * ** * * * * * # **
                 ** # * * @ * * # * # ** @* * * * * * # @ @ * **
                *# * * * * * * * * # * * * * * * @ @ * * * * * **
                 *# * @ * @ * @ * * * ** *@ * * # * * * * * @ @*
                 *# # @ * * # * *@ * *** @#@ @ ** * @ @ * * # **
                 *# * ** * * * @  @  **@ ***  *  @ * * * @* * #*
                  ** * * ** * #@ *  #*** **##  * #* * #@ * * @*
                   *# * *@ * @@ *#  **** @***  ** ** * #* * #*
                    *# *  * *@ **  @**@* *@#**  ** ** *  * @*
                     *#* @  *  @@  **##* ****@  **  #  * @**
                       **  @  #*   @*@#* @*@*#   @#  *  **
                         *#*  @*  @#*@*# **#*@#  **  ***
                           ****   *##**# #***@*   @***
                               ****@**@* *****@***

# star is disappearing

               *  -  -  --  --   ------- -------   --  --  -  -  *
             ** -  -  -  --  --   ------ ------   --  --  -  -  - **
            * -- - -- -- --  --   ------ ------   --  -- -- -- - -- *
          ** - -  - -- -- --  --  ------ ------  --  -- -- -- -  - - **
         *  - - -- - -- -  -  --   ----- -----   --  -  - -- - -- - -  *
        ** - - - -- - -- -  -  --  ----- -----  --  -  - -- - -- - - - **
        * - - - -  - - -  - -- --  ----- -----  -- -- -  - - -  - - - - *
       * - - - -  - - - -- - -- --  ---- ----  -- -- - -- - - -  - - - - *
      * -- - - - - - - - -- - -- -  ---- ----  - -- - -- - - - - - - - -- *
      * - - - - - - - -- - - - -  -  --- ---  -  - - - - -- - - - - - - - *
      * - - - - - - - - - - - - -- - --- --- - -- - - - - - - - - - - - - *
      * - - - - - - - - - - - - - - - -- -- - - - - - - - - - - - - - - - *
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
      * - - - - - - - - - - - - - - - -- -- - - - - - - - - - - - - - - - *
      * - - - - - - - - - - - - -- - --- --- - -- - - - - - - - - - - - - *
      * - - - - - - - -- - - - -  -  --- ---  -  - - - - -- - - - - - - - *
      * -- - - - - - - - -- - -- -  ---- ----  - -- - -- - - - - - - - -- *
       * - - - -  - - - -- - -- --  ---- ----  -- -- - -- - - -  - - - - *
        * - - - -  - - -  - -- --  ----- -----  -- -- -  - - -  - - - - *
        ** - - - -- - -- -  -  --  ----- -----  --  -  - -- - -- - - - **
         *  - - -- - -- -  -  --   ----- -----   --  -  - -- - -- - -  *
          ** - -  - -- -- --  --  ------ ------  --  -- -- -- -  - - **
            * -- - -- -- --  --   ------ ------   --  -- -- -- - -- *
             ** -  -  -  --  --   ------ ------   --  --  -  -  - **

# the star is gone
















(there is nothing)

Ví dụ hoạt hình của đầu ra:

Ngôi sao nổ

Nếu bạn muốn có một chút cảm hứng, bạn có thể nhìn vào một vụ nổ từ Captain Blood , một trò chơi từ năm 1988.


1
Thực sự không có thông số kỹ thuật nào ở đây để xác định xem câu trả lời có " đúng " hay không.
Peter Taylor

Tôi đang xóa từ đúng trong câu hỏi. Câu trả lời phổ biến nhất sẽ được tuyên bố là người chiến thắng.
AL

1
Cho dù từ đó có trong câu hỏi hay không, tất cả các câu hỏi nên có một thông số rõ ràng dựa trên câu trả lời nào có thể được đo.
Peter Taylor

1
"Hiển thị một cái gì đó trông giống như các ví dụ đầu ra, nhưng hãy thoải mái sáng tạo và nghệ thuật"? Tôi có thể thêm nhiều quy tắc (thời gian, số khung hình, kích thước, v.v.) nhưng tôi khá chắc chắn rằng nó sẽ làm cho nó ít thú vị hơn.
AL

Vui lòng giải thích nếu các quy tắc không đủ rõ ràng và làm thế nào tôi có thể cải thiện chúng.
AL

Câu trả lời:


27

C + nguyền rủa

Vụ nổ ASCII

Tôi đã không nỗ lực nhiều để dọn dẹp mã nguồn. Về cơ bản, nó tính toán một sóng xung kích mở rộng, với một nền tảng vững chắc được thêm vào một vài khung hình đầu tiên để tạo ra một hiệu ứng flash. [[EDIT: Vụ nổ trông hơi kỳ lạ xuất hiện từ một dấu sao, vì vậy tôi đã thêm một vài khung mở rộng ở đầu hoạt hình.]]

Các hạt ngẫu nhiên được đặt chồng lên trên, với các vị trí được xác định theo tính toán phối cảnh cơ bản để mang lại cảm giác 3D nhẹ. (Dù sao đó cũng là ý tưởng.)

#include <curses.h>
#include <stdlib.h>
#include <math.h>

#define NUM_FRAMES 150
#define NUM_BLOBS 800
#define PERSPECTIVE 50.0

typedef struct {
  double x,y,z;
} spaceblob;

double prng() {
  static long long s=1;
  s = s * 1488248101 + 981577151;
  return ((s % 65536) - 32768) / 32768.0;
}

int main() {
  char *frames[NUM_FRAMES], *p;
  int i,j,x,y,z,v,rows,cols,ith,i0;
  int maxx,minx,maxy,miny,delay=1E6;
  double bx,by,bz,br,r,th,t;
  spaceblob *blobs;

  /* Initialize ncurses and get window dimensions */
  initscr();
  getmaxyx(stdscr,rows,cols);
  minx = -cols / 2;
  maxx = cols+minx-1;
  miny = -rows / 2;
  maxy = rows+miny-1;

  /* Generate random blob coordinates */
  blobs = malloc(NUM_BLOBS * sizeof(spaceblob));
  for (i=0; i<NUM_BLOBS; i++) {
    bx = prng();
    by = prng();
    bz = prng();
    br = sqrt(bx*bx + by*by + bz*bz);
    blobs[i].x = (bx / br) * (1.3 + 0.2 * prng());
    blobs[i].y = (0.5 * by / br) * (1.3 + 0.2 * prng());;
    blobs[i].z = (bz / br) * (1.3 + 0.2 * prng());;
  }

  /* Generate animation frames */
  for (i=0; i<NUM_FRAMES; i++) {
    t = (1. * i) / NUM_FRAMES;
    p = frames[i] = malloc(cols * rows + 1);
    for (y=miny; y<=maxy; y++) {
      for (x=minx; x<=maxx; x++) {

        /* Show a single '*' in first frame */
        if (i==0) {
          *p++ = (x==0 && y==0) ? '*' : ' ';
          continue;
        }

        /* Show expanding star in next 7 frames */
        if (i<8) {
          r = sqrt(x*x + 4*y*y);
          *p++ = (r < i*2) ? '@' : ' ';
          continue;
        }

        /* Otherwise show blast wave */
        r = sqrt(x*x + 4*y*y) * (0.5 + (prng()/3.0)*cos(16.*atan2(y*2.+0.01,x+0.01))*.3);
        ith = 32 + th * 32. * M_1_PI;
        v = i - r - 7;
        if (v<0) *p++ = (i<19)?"%@W#H=+~-:."[i-8]:' '; /* initial flash */
        else if (v<20) *p++ = " .:!HIOMW#%$&@08O=+-"[v];
        else *p++=' ';
      }
    }

    /* Add blobs with perspective effect */
    if (i>6) {
      i0 = i-6;
      for (j=0; j<NUM_BLOBS; j++) {
        bx = blobs[j].x * i0;
        by = blobs[j].y * i0;
        bz = blobs[j].z * i0;
        if (bz<5-PERSPECTIVE || bz>PERSPECTIVE) continue;
        x = cols / 2 + bx * PERSPECTIVE / (bz+PERSPECTIVE);
        y = rows / 2 + by * PERSPECTIVE / (bz+PERSPECTIVE);
        if (x>=0 && x<cols && y>=0 && y<rows)
          frames[i][x+y*cols] = (bz>40) ? '.' : (bz>-20) ? 'o' : '@';
      }
    }

    /* Terminate the text string for this frame */
    *p = '\0';
  }

  /* Now play back the frames in sequence */
  curs_set(0); /* hide text cursor (supposedly) */
  for (i=0; i<NUM_FRAMES; i++) {
    erase();
    mvaddstr(0,0,frames[i]);
    refresh();
    usleep(delay);
    delay=33333; /* Change to 30fps after first frame */
  }
  curs_set(1); /* unhide cursor */
  endwin(); /* Exit ncurses */
  return 0;
}

1
Thật tuyệt! Bạn có thể giải thích làm thế nào bạn chụp được hình ảnh thiết bị đầu cuối? Tôi nghĩ bạn nên giảm phần khi bạn gõ, nếu bạn chưa thêm phần đó để trêu chọc người xem.
AL

1
@ n.1 Bạn nói đúng - nó đã kéo theo một chút. Tôi sử dụng IShowU để chụp màn hình và xuất các khung hình từ QuickTime sang ImageMagick để tạo một GIF hoạt hình, sau đó sử dụng Gifsicle để tối ưu hóa hoạt hình GIF. Đó là một chút của một palaver, thực sự. Hãy cho tôi biết nếu bạn đã tìm thấy một phương pháp tốt hơn.
r3mainer

7

Javascript

Nghĩ rằng nó đáng để bắn trong JS. Đề nghị tiết kiệm và chạy; rất rất chậm nếu bạn dán trong bàn điều khiển.

var boomboom = (function() {
    //Clear any existing page
    document.getElementsByTagName("body")[0].innerHTML="";

    var space=document.createElement("div");
    var iterator=0;
    var stars = 50;
    var timer=100;

    //Set container
    space.setAttribute("id","space");
    space.setAttribute("style","width:1000px;height:600px;margin:auto;border:solid 1px #000;position:relative;overflow:hidden;background:#000;color:#fff");
    document.getElementsByTagName("body")[0].appendChild(space);

    //Set interval and draw...
    var interval = setInterval(function(){ drawStars(iterator,stars); }, timer);
    drawStars(iterator, stars);

    function drawStars(r,c) {
        clearInterval(interval);

        //a container for this set of stars
        var starContainer=document.createElement("div");

        //don't draw more if there are too many, it's got to go
        if(iterator < 1000) {
            for(var i = 0; i < c; i++) {
                var x,y;

                if(iterator < 100) {
                    x=500 + r * Math.cos(2 * Math.PI * i / c) * 0.7;
                    y=300 + r * Math.sin(2 * Math.PI * i / c) * 0.7;
                }

                //add some randomness for the boom boom
                if(iterator > 100) { 
                    x=500 + r * Math.cos(2 * Math.PI * i / c) * 0.7*Math.random();
                    y=300 + r * Math.sin(2 * Math.PI * i / c) * 0.7*Math.random();
                }

                //Make a star
                var star=document.createElement("div");
                star.setAttribute("class","star");

                //Exploding stars are red, I hope
                var color = iterator < 100 ? "color:#fff" : "color:rgb("+parseInt(255*Math.random())+",0,0)";
                star.setAttribute("style","position:absolute; left:"+ x +"px;top:"+ y +"px;"+color);

                //Change the star character as boom boom gets bigger
                if(iterator <= 200) {
                    star.innerText="*";
                }
                else if(iterator >=200 & iterator <= 400) {
                    star.innerText="O";
                }
                else  {
                    star.innerText="-";
                }
                //Add the star to its container
                starContainer.appendChild(star);
            }
        }
        //draw the container
        space.appendChild(starContainer);

        //increment the iterator.  It's an iterator because we're using intervals and it's late.
        iterator+=5;

        //remove stars when we get too many
        if(iterator > 200) {
            space.removeChild(space.firstChild);
        }
        if(iterator < 1500) { //do it all again
            timer = timer > 10 ? timer-10 : timer;
            interval=setInterval(function(){ drawStars(iterator,stars); }, timer);
        }

        //make sure it's actually empty
        else {
            space.innerHTML="";
        }
    }
}());

Chỉnh sửa trong JSBin: http://jsbin.com/worofeqi/5/watch?js,output

Oddly chạy trơn tru hơn nhiều khi được thực hiện từ hệ thống tệp cục bộ so với trong JSBin. Thành thật không chắc tại sao; có thể nhìn vào tối nay


Bạn có thể vui lòng đặt nó trên jsfiddle, jsbin hoặc một trang web khác mà chúng ta có thể nhìn thấy dễ dàng không? Khi thêm câu hỏi tôi chỉ nghĩ đến việc hiển thị kết quả trong một thiết bị đầu cuối nhưng tôi sẽ không cập nhật các quy tắc ngay bây giờ khi bạn đã thêm câu trả lời của mình, tôi nên thêm quy tắc này trước đây.
AL

Câu trả lời được cập nhật (lưu ý cảnh báo (rất kỳ quặc))
Dave Forber

1

Con trăn

#!/usr/bin/python

import sys, math, time, random

def distance(x, y):
    # ((y - y_center) * 2) -> correct ratio for a true circle
    return math.ceil(math.sqrt(((x - 40) ** 2) + (((y - 12) * 2) ** 2)))

def star(radiuses):
    for r in radiuses:
        #~ clear screen: http://stackoverflow.com/a/2084521/2257664
        print chr(27) + "[2J"

        # width
        for y in range(24):
            # height
            for x in range(80):
                d = distance(x, y)

                #~ border
                if (d == r):
                    sys.stdout.write('*')
                #~ inside the star
                elif (d < r):
                    if (r > 35):
                        sys.stdout.write(' ')
                    elif (r > 25) and ((d % 2) != 0):
                        sys.stdout.write('-')
                    elif (r > 15) and ((d % 2) == 0):
                        sys.stdout.write(' ')
                    else :
                        sys.stdout.write(random.choice('****#@'))
                #~ space outside the star
                else:
                    sys.stdout.write(' ')
            print
        time.sleep(0.1)

star(range(0, 12) + range(10, 0, -1) + range(0, 50))

Ví dụ đầu ra (sử dụng ít bước hơn và không xóa màn hình).

Đoạn trích của đầu ra cũng được hiển thị trong câu hỏi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.