Zeigen Sie die Explosion eines Sterns in ASCII-Kunst an


12

Das Ziel ist es, einen Stern zu animieren, der in der ASCII-Kunst explodiert, angefangen von einem einzelnen Sterncharakter *über eine Supernova bis hin zur Leere.

Regeln:

  • Sie müssen nur 80 Zeichen pro Zeile in 24 Zeilen anzeigen (dies ist die Standard-Terminalgröße unter Linux).
  • Nur diese 95 druckbaren Zeichen aus ASCII sind zulässig
  • Schritte:
    1. Der Anfangsstern muss *horizontal und vertikal zentriert sein
    2. Der Stern muss wachsen, um zu zeigen, dass er explodiert
    3. Am Ende muss der Bildschirm leer sein (der Stern ist verschwunden)
  • Die Länge des Codes oder der Sprachen spielt keine Rolle
  • Die Stimmen entscheiden über die kreativsten und schönsten Ergebnisse. Hast du jemals einen explodierenden Stern gesehen? Mal sehen, wie du dir das vorstellst.

Ich habe eine Antwort mit Python als Beispiel hinzugefügt, aber Sie werden aufgefordert, etwas anderes oder besseres zu erstellen.

Sie haben eine Woche Zeit, um teilzunehmen. Der Gewinner wird am 01.04.2014 ermittelt.

Ausgabebeispiele (nur bei einigen Frames):

# start





                                        *





# during explosion

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


# star is expanding

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

# star is disappearing

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

# the star is gone
















(there is nothing)

Animiertes Ausgabebeispiel:

Explodierender Stern

Wenn Sie sich inspirieren lassen möchten, können Sie sich eine Explosion von Captain Blood ansehen , einem Spiel aus dem Jahr 1988.


1
Es gibt hier nicht wirklich eine Spezifikation, um festzustellen, ob eine Antwort " richtig " ist oder nicht.
Peter Taylor

Ich entferne das richtige Wort aus der Frage. Die beliebteste Antwort wird zum Gewinner erklärt.
AL

1
Unabhängig davon, ob sich das Wort in der Frage befindet oder nicht, sollten alle Fragen eine eindeutige Spezifikation haben, anhand derer die Antworten gemessen werden können.
Peter Taylor

1
Ist "etwas anzeigen, das wie die Ausgabebeispiele aussieht, sich aber frei fühlt, kreativ und künstlerisch zu sein" genug? Ich kann mehr Regeln hinzufügen (Zeit, Anzahl der Frames, Größen usw.), aber ich bin mir ziemlich sicher, dass es dadurch weniger interessant wird.
AL

Bitte erläutern Sie, ob die Regeln nicht klar genug sind und wie ich sie verbessern kann.
AL

Antworten:


27

C + Flüche

ASCII-Explosion

Ich habe mich nicht sehr bemüht, den Quellcode aufzuräumen. Grundsätzlich wird eine sich ausdehnende Stoßwelle berechnet, wobei den ersten Bildern ein fester Hintergrund hinzugefügt wird, um eine Art Blitzlichteffekt zu erzielen. [[BEARBEITEN: Die Explosion sah von einem einzelnen Sternchen aus etwas seltsam aus, daher habe ich zu Beginn der Animation einige Frames der Erweiterung hinzugefügt.]]

Darüber werden zufällige Partikel eingeblendet, deren Positionen anhand einer grundlegenden perspektivischen Berechnung ermittelt werden, um ein leichtes 3D-Gefühl zu erzeugen. (Nun, das war sowieso die Idee.)

#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
Das ist schön! Können Sie bitte erklären, wie Sie die Terminalbilder aufgenommen haben? Ich denke, Sie sollten den Teil reduzieren, wenn Sie tippen, wenn Sie ihn nicht hinzugefügt haben, um den Betrachter zu ärgern.
AL

1
@ n.1 Du hast recht - es zog sich ein bisschen hin. Ich verwende IShowU , um den Bildschirm zu erfassen, und exportiere die Bilder von QuickTime nach ImageMagick, um ein animiertes GIF zu erstellen. Anschließend optimiere ich die GIF-Animation mit Gifsicle. Es ist wirklich ein bisschen palaver. Lassen Sie mich wissen, ob Sie eine bessere Methode gefunden haben.
r3mainer

7

Javascript

Ich dachte, es ist einen Versuch wert in JS. Schlagen Sie das Speichern und Ausführen vor. sehr sehr langsam, wenn Sie in der Konsole einfügen.

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="";
        }
    }
}());

Bearbeitungen in JSBin: http://jsbin.com/worofeqi/5/watch?js,output

Seltsamerweise läuft es viel reibungsloser, wenn es über das lokale Dateisystem ausgeführt wird, als in JSBin. Ehrlich gesagt nicht sicher warum; darf sich das heute abend anschauen.


Können Sie es bitte auf jsfiddle, jsbin oder einer anderen Website platzieren, auf der wir es leicht sehen können? Beim Hinzufügen der Frage habe ich nur darüber nachgedacht, das Ergebnis in einem Terminal anzuzeigen, aber ich werde die Regeln jetzt nicht aktualisieren, da Sie Ihre Antwort hinzugefügt haben. Ich hätte diese Regel vorher hinzufügen sollen.
AL

Antwort aktualisiert (beachten Sie die (sehr seltsame) Einschränkung)
Dave Forber

1

Python

#!/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))

Beispielausgabe (mit weniger Schritten und ohne Löschen des Bildschirms).

In der Frage werden auch Auszüge der Ausgabe angezeigt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.