Kompaktester Code für eine simulierte Explosion

13

Können Sie ein Programm schreiben, mit dem eine Gruppe von Pixeln, die auseinander explodieren (wie in einer einfachen Partikelmaschine), gerendert werden kann, und können Sie dies in einer bemerkenswert geringen Anzahl von Zeichen (Tastenanschlägen) tun? (Erinnern Sie sich an die Spielelemminge, als diese kleinen Kerle explodierten und ihre kleinen Pixelstücke auseinander flogen.)

Jemand hat hier ein einfaches Partikelsystem als Verarbeitungsskizze programmiert und es ist ziemlich umfangreich im Vergleich zu dem, was meiner Meinung nach andere können sollten, wenn sie es versuchen. Aber ich wäre viel beeindruckter, wenn jemand dasselbe in c ++ und sdl oder sogar in Java oder c # machen könnte.

Todd Hopkinson
quelle
2
"Codezeilen" ist eine Metrik, die viel Unklarheit hervorruft, und es handelt sich sicherlich nicht um [Code-Golf], bei dem es sich um "Anzahl der Zeichen" oder manchmal um "Anzahl der Bytes" handelt. Verwandte Diskussion über Meta.
dmckee --- Ex-Moderator Kätzchen
4
Übrigens - Das Problem, das ich oben angesprochen habe, und die ziemlich unvollständige Spezifikation sind Dinge, die nützlich herausgearbeitet werden könnten, indem dies im Puzzle Lab-Chat oder in der Sandbox auf Meta im Voraus besprochen wird . Aber auf jeden Fall herzlich willkommen bei CodeGolf.SE.
dmckee --- Ex-Moderator Kätzchen
Aktualisierte Frage, LOC wurde durch die Anzahl der Zeichen ersetzt.
Todd Hopkinson
1
Ja, wenn Sie C / C ++ / Java / ein beliebiges C-Derivat schreiben, können Sie ein ganzes Betriebssystem in einer Codezeile schreiben
Nate Koppenhaver
Siehe auch
gnibbler

Antworten:

13

Python, 245 Zeichen

import random,time
R=lambda:random.randrange(-999,999)/1e3
P=[(40+20j,R()+1j*R())for i in' '*20]
for i in' '*20:
 C=([' ']*80+['\n'])*40
 for p,v in P:C[int(p.real)+81*int(p.imag)]='*'
 print''.join(C);P=[(p+v,v*.95)for p,v in P];time.sleep(.1)
Keith Randall
quelle
Es ist keine Lemming-Explosion, aber definitiv eine +1 für die Kürze!
Todd Hopkinson
10

C #, WPF - 1523

Nicht sehr ernst; Dies war hauptsächlich ein Versuch, ob es tatsächlich funktionierte.

Ich verwende hier ein ItemsControl (Menü, da es kürzer ist) in WPF, um Partikel über Datenbindung und Vorlagen anzuzeigen. Eine Datenvorlage steuert, wie die Partikel aussehen (in diesem Fall ein einfacher Kreis), und die Datenbindung steuert Farbe und Position der Partikel.

Jedes Partikel hat eine Position, eine Farbe und eine Richtung, die von einem Timer aktualisiert werden. Zunächst wird in der Mitte des Fensters ein Partikelbündel mit (normalverteilten) Zufallsrichtungen erzeugt. Diese Auflistung wird datengebunden an ItemsControl, das die Partikel dann automatisch anzeigt, wenn die Eigenschaften aktualisiert werden. Partikel werden aufgrund der Schwerkraft etwas nach unten gezogen.

Zugegeben, es wurde etwas langwierig. Aber zumindest sieht es gut aus:

Bildbeschreibung hier eingeben

Es kann sicherlich kürzer gemacht werden, indem weggelassen wird:

  • Schwerkraft, wodurch sich Partikel gleichmäßig nach allen Seiten ausdehnen;
  • die Normalverteilung für die Anfangsvektoren, wodurch sich die Partikel in einer spärlichen »Kiste« ausdehnen;
  • die Helligkeitsschwankung, die Partikel bleiben schwarz.

Ich habe mich aus ästhetischen Gründen dagegen entschieden. Diese Lösung ist ungeachtet dessen viel länger als fast alles andere. Der Ansatz für die Datenbindung und das Templating ist zwar elegant, aber im Vergleich zum einfachen Aktualisieren einer Bitmap auch ziemlich ausführlich. (Anmerkung: Ich habe es auf 1356 gebracht, indem ich alle oben genannten Punkte weggelassen habe, aber es sieht dann schrecklich aus.)

Der Code wird in drei Dateien verteilt, die hier aus Gründen der Lesbarkeit in formatierter Form angegeben sind:

App.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" StartupUri="W.xaml"/>

W.xaml

<Window x:Class="W" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Menu Name="i">
        <Menu.ItemTemplate>
            <DataTemplate>
                <Ellipse Width="2" Height="2" Fill="#000" Opacity="{Binding O}">
                    <Ellipse.RenderTransform>
                        <TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
                    </Ellipse.RenderTransform>
                </Ellipse>
            </DataTemplate>
        </Menu.ItemTemplate>
        <Menu.Template>
            <ControlTemplate>
                <ItemsPresenter/>
            </ControlTemplate>
        </Menu.Template>
        <Menu.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </Menu.ItemsPanel>
    </Menu>
</Window>

W.xaml.cs

using M = System.Math;
using T = System.Timers.Timer;
using System;
using System.ComponentModel;

partial class W
{
    int a;
    T t = new T(99);

    public W()
    {
        InitializeComponent();
        Height = Width = 500;
        var r = new Random();
        Func<double> n = () => 2 * (M.Sqrt(-2 * M.Log(r.NextDouble())) * M.Sin(6 * r.NextDouble()));
        var l = new System.Collections.Generic.List<P>();
        for (; a++ < 300; )
            l.Add(new P { X = 250, Y = 250, f = n(), g = n() });
        i.ItemsSource = l;
        t.Elapsed += delegate
        {
            foreach (P x in l)
            {
                x.X += x.f;
                x.Y += x.g += .2;
                x.O = M.Max(1 - M.Sqrt(M.Pow(250 - x.X, 2) + M.Pow(250 - x.Y, 2)) / 250, 0);
            }
        };
        t.Start();
    }
}

class P : System.Windows.ContentElement, INotifyPropertyChanged
{
    public double y, f, g;
    public double X { get; set; }
    public double O { get; set; }
    public double Y
    {
        get { return y; }
        set
        {
            y = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(""));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
Joey
quelle
1
+1 Toll aussehendes Beispiel! Ähnlich wie die klassischen explodierenden Lemminge vergangener Tage. Und ich denke, das übertrifft den Verarbeitungscode in der ersten Frage.
Todd Hopkinson
@icnivad: Ich muss zugeben, dass die Verarbeitungsskizze (ich habe nur das Endergebnis betrachtet, nicht den Code) meine Inspiration für das Aussehen war.
Joey
Gah! Ich höre jetzt auf, Golf zu spielen. Inzwischen sind einige nette Tricks enthalten (z. B. PropertyChanged für alle Eigenschaften und nur für die letzte, die festgelegt wurde). Angesichts der Tatsache, dass ich mit mehr als 2000 Zeichen angefangen habe, ist eine Reduzierung um 500 Zeichen wohl nicht schlecht. Mittlerweile ist es auch ziemlich langsam geworden. DispatcherTimer funktioniert viel besser als Timer, ist aber viel länger. Ich könnte versucht sein, dies auf Silverlight zu portieren und es auf meinem Telefon auszuführen.
Joey
Ich denke, dies ist derjenige, der für die Kombination von Codegröße und ästhetischer Qualität der Explosion zu schlagen ist.
Todd Hopkinson
icnivad: Ich werde das Ganze neu schreiben, um es später direkt auf eine Bitmap zu malen. es sollte dann viel kürzer sein. 45% des Codes sind XAML; Ein großer Teil des Codes wird in die Lage versetzt, Benutzeroberflächenelemente an die Partikeleigenschaften zu binden. Fügen Sie dem die allgemeine Ausführlichkeit von C # hinzu und es ist viel ausführlicher, als es sein müsste.
Joey
7

Nachschrift - 287 244 Zeichen

currentpagedevice/q{exch def}def/PageSize get/z{dup 3 1 roll add exch 4 2 roll}def{2
div}forall/y/r{rand 2 27 exp div 8 sub}def q/x q[99{[x r y r]}repeat]50{dup{aload/t q
3 index 2 index 4 4 rectfill 1 sub z z t astore pop}forall showpage}repeat

renn mit gs -dNOPAUSE asplode.ps

Sie können es sogar ausdrucken und ein Daumenkino erstellen

Geoff Reedy
quelle
Wunderbar! Es ist wunderschön!
Benutzer unbekannt
5

Javascript - 268 Zeichen

Hier ist eine eindimensionale 2-Teilchen-Explosion:

javascript:d=document;c=d.createElement('canvas');d.body.appendChild(c);g=c.getContext("2d");function e(x,y,m){g.arc(x,y,m,0,2*Math.PI,false);g.fill()}function s(a,b,v,t){c.width=c.width;e(50+t*v,50,b);e(50+t*b*v/(b-a),50,a-b);setTimeout(function(){s(a,b,v,t+1)},100)};s(9,5,1,0)

Um es auszuführen, öffne eine leere Seite in einem guten Webbrowser, füge sie in die URL-Leiste ein und drücke die Eingabetaste. Sie können die Auflösung ändern, indem Sie die Werte am Ende von bearbeiten s(10,5,1,0). Der erste Wert ist die Größe des explodierten Partikels. Der zweite Wert ist die Größe des Partikels, das aus ihm herausgesprengt wird. Der dritte Wert ist die Geschwindigkeit des aus ihm herausgesprengten Partikels. Lass die '0' so wie sie ist.

david4dev
quelle
1
Dies funktioniert nicht in Safari 5.0.5 (zeigt etwas, das einem Baseballschläger ähnelt) oder in Chrome 11.0.696.68 (zeigt zwei Bälle, die etwas größer als die anderen sind und sich langsam auseinander bewegen).
marinus
1
@marinus Was in Chrome passiert, ist das, was eigentlich passieren soll.
david4dev
Ich kann es nicht auf FF4, IE8 zum Laufen bringen. :(
st0le
Nun, ich habe es auf Firefox 4.0.1 und Chromium 11.0.696.65 getestet. Stellen Sie sicher, dass Sie das gesamte Skript kopiert haben. Ich finde es einfach, beim Kopieren die Endklammer auszulassen.
david4dev
@ st0le IE8 unterstützt das Canvas- Tag nur, wenn Sie einige schmutzige Tricks ausführen: stackoverflow.com/questions/1332501/…
Cristian Lupascu
4

APL ( 120 118)

Es hat die gleiche Ausgabe wie der Python-Eintrag (dh es gibt nur die Zustände in einem Zeichenraster aus). Nur das Raster ist 30x15 und der Partikelursprung ist 15x7.

⍎⊃,⌿(9⍴⊂'(⎕DL.1)⊢{{(A+2↑⍵),0.95×A←2↓⍵}¨⍵⊣⎕←'' ⍟''[1+(⍳15 30)∊2↑¨⌊⍵]}'),⊂',⌿⍉10 4⍴⍎''⍬'',420⍴'',(7 15,.01×99-?2⍴199)'''
Marinus
quelle
2

JavaScript 502 500 496

Dies ist eine Kombination der Antworten von Joey und david4dev (es ist eine schamlose Kopie von Joeys Algorithmus, der mit Javascript / canvas implementiert wurde):

W=500;H=250;function r(){return 2*m.sqrt(-2*m.log(m.random()))*m.sin(6*m.random())}function n(){z=[];for(i=W;i;i--){s={};s.x=s.y=H;s.f=r();s.g=r();z.push(s)}}function w(){x.clearRect(0,0,W,W);z.forEach(function(a){a.x+=a.f;a.y+=a.g+=.2;x.fillStyle="rgba(0,0,0,"+m.max(1-m.sqrt(m.pow(H-a.x,2)+m.pow(H-a.y,2))/H,0)+")";x.fillRect(a.x,a.y,2,2)})}z=[];m=Math;d=document;c=d.createElement("canvas");c.width=c.height=W;d.body.appendChild(c);x=c.getContext("2d");n();setInterval(n,2e3);setInterval(w,10)

JSFiddle-Vorschau: http://jsfiddle.net/GVqFr/60/ (Sie können die TidyUp-Taste drücken, um den Code schön zu formatieren)

Cristian Lupascu
quelle
@Qqwy Danke für die Bearbeitung!
Cristian Lupascu
Ich bin kein Javascript-Experte, aber Sie verwenden die Konstante häufig 500. Wenn Sie eine globale Variable definieren können a=500, können Sie ein paar Zeichen speichern , indem Sie alle ersetzen 500mit a.
Mr. Llama
@ Gigawatt du hast recht; das hat auch geklappt 250.
Cristian Lupascu
1

Bash 380

C="4443311177"
t=".-xxXMXxx-."
alias c='echo -e "\e[2J"'
g(){
echo -e "\e[1;$4\e[$2;$1H$3"
}
f(){
x=$1
y=$2
p=$((2-RANDOM%5))
q=$((2-RANDOM%5))
for i in {-5..5}
do
x=$((x+p))
y=$((y+q))
n=$((5+i))
c=$((5+i))
g $x $y ${t:n:1} 3${C:c:1}m 
w=$(printf "%04i\n" $((5*i*i)))
sleep ${w/0/0.}
g $x $y " " 3${C:c:1}m
done
}
e(){
c
for i in {1..10}
do
f $((COLUMNS/2)) $((LINES/2)) &
done
}

Rufen Sie e wie explodieren.

Update: eingefärbt

t = text, c = cls, g = gotoxy, f = fly, C = COLOR

Benutzer unbekannt
quelle
1

C mit SDL, 423 Zeichen

Da in der ursprünglichen Problembeschreibung SDL ausdrücklich erwähnt wurde, war es meines Erachtens an der Zeit, eine SDL-Lösung einzureichen. Leider sind die Namen der SDL-Funktion und der Strukturen nicht besonders knapp, sodass dieses Programm etwas lang ist. Tatsächlich kann ich das nicht mal auslassen #include.

#include<math.h>
#include"SDL.h"
SDL_Surface*s;SDL_Event e;SDL_Rect p;int i,n;double q[256];main(){
SDL_Init(SDL_INIT_VIDEO);s=SDL_SetVideoMode(320,320,32,0);
for(srand(time(0));e.type-SDL_QUIT;n=-~n%64){
for(i=256*!n;i;q[--i]=rand()%65536*9.5874e-5);
for(SDL_FillRect(s,0,i=0);++i<256;SDL_FillRect(s,&p,-n*67372036))
p.x=160+cos(q[i])*q[i-1]*n,p.y=160+sin(q[i])*q[i-1]*n,p.w=p.h=1;
SDL_Flip(s);SDL_Delay(50);SDL_PollEvent(&e);}}

(Da der Code bereits so umfangreich ist, habe ich einige zusätzliche Bits übrig gelassen, damit er ohne Warnungen kompiliert werden kann. Ich vermisse es manchmal, ohne Warnungen zu kompilieren. Durch das Entfernen werden etwa 30 Zeichen gespart.)

Die Animation läuft in einer Endlosschleife. Schließen Sie das Fenster, um das Programm zu beenden. Bei jeder Explosion wird ein neuer Satz zufälliger Partikel verwendet.

Ich möchte auch auf die Nummer 67372036im Code hinweisen . Es erscheint im Ausdruck für das letzte Argument im zweiten Aufruf von SDL_FillRect(). Nach dem derzeitigen Stand des Codes wird die Explosion vollständig in Grautönen wiedergegeben. Eine geringfügige Änderung dieser Zahl fügt der Explosion einen sehr subtilen, aber angenehmen Farbeffekt hinzu. Die Zahl 67372032färbt die Partikel zu Beginn der Explosion, während die Zahl 67372034einen Farbeffekt liefert, wenn sie am Ende ausgeblendet werden. Andere Zahlen können zu weniger subtilen Farbwechseleffekten führen. Ich ermutige Sie, sie auszuprobieren.

Brot-Box
quelle
1

Nachdem ich einige der anderen großartigen Beispiele hier gesehen hatte, entschloss ich mich, es auszuprobieren und eine Partikelfunktion zu erstellen , die in 140 Byte passt

Javascript, 282 Zeichen

( 138 Zeichen Partikelfunktion und 150 Zeichen Basis-Zeichenfläche Boilerplate)

p=function(a,t,x,y,n,g,s,i,d){with(Math)for(i=n;i--;d=cos(i*sin(i*s)),a.globalAlpha=n/t/i,a.fillRect(x+t*sin(i)*d, y+t*cos(i)*d+t*g,2,2));};d=document;a=d.body.appendChild(d.createElement('canvas')).getContext('2d');t=setInterval("a.clearRect(0,0,300,150);p(a,t++, 50,50,1e3,.2,1)")

Live JSFiddle Beispiel hier

Indem ich den Code vollständig prozedural machte, benötigte ich keinen Array- oder Objektzuweisungscode mehr, wodurch sich die Größe erheblich verringerte. Das Erzeugen eines prozeduralen Effekts hat auch einige andere nette Nebenwirkungen.

Der Code könnte kleiner gemacht werden, indem man die Schwerkraft, die Samen, die Anzahl der Partikel usw. weglässt, aber ich denke, diese Merkmale sind zu schön, um sie zu entfernen.

Eigenschaften

  • Konfigurierbares X, Y-Explosionszentrum.
  • Konfigurierbare Partikelanzahl
  • Schwerkraft in vertikaler Richtung: Lassen Sie Ihre Partikel fallen oder fliegen!
  • Seedable, jeder Samen hat seine eigene Explosion und zeigt jedes Mal genau diese Explosion auf allen Computern.
  • Slowmotion, Fast Forward und das Abspielen von Explosionen in Rückwärtsrichtung sind aufgrund der prozeduralen Art und Weise, wie der Effekt erzeugt wird, möglich.
  • Größe: 138 Bytes.

Schauen Sie sich auch GitHub an , um eine kommentierte Version zu erhalten.

Qqwy
quelle
0

Python mit PyGame, 240 Zeichen

Mir ist klar, dass es in Python bereits eine Lösung gibt, aber da hier nur Zeichen gedruckt werden, dachte ich, dass es sich lohnen würde, eine zu erstellen, die eine schöne Animation zeichnet.

Ungolfed, womit ich angefangen habe:

import math
import random
import pygame
pygame.init()

screen = pygame.display.set_mode((800, 800))
particles = [(random.gauss(0,.5), random.uniform(0,6.28318)) for i in range(2000)]

for i in range(399):
    screen.fill((255,255,255))
    for speed, angle in particles:
        distance = i * speed
        x = 400 + distance * math.cos(angle)
        y = 400 + distance * math.sin(angle)
        screen.set_at((int(x), int(y)), (0,0,0))
    pygame.display.flip()

Nach viel hackery. Vollbild, um einige Zeichen zu speichern. Ich benutze weder Sound noch Schriften, deshalb halte ich es für init()unnötig (es funktioniert bei mir).

import math as m,random,pygame
d,x,g=pygame.display,range(999),random.gauss
s,e=d.set_mode(),[(g(0,.2),g(0,9))for i in x]
for i in x:
 d.flip(),s.fill([255]*3)
 for v,a in e:
        y=400+i*v*m.cos(a),400+i*v*m.sin(a)
        s.set_at(map(int,y),[0]*3)
Ahnungslos
quelle
0

Python - 327 Zeichen

Interessante Dinge:

  • Verwenden Sie eine komplexe Zahl als 2D-Vektor
  • (v * cos(a), v * sin(a)) umgesetzt als v*e**(1j*a)
  • Sieht aus wie eine 3D-Explosion.
  • Schwere.

.

import pygame as P,random as R,math
R=R.random
D=P.display
D.init()
W=800
S=D.set_mode((W,W))
T=P.time.Clock()
C=lambda v:map(int,(v.real,v.imag))
X=[(8+R())*math.cos(R()*1.57)*2.7**(1j*R()*6.28) for i in range(999)]
for t in range(250):
 D.flip();T.tick(30);S.fill(2**24-1)
 for v in X:S.set_at(C(v*t+.005j*t*t+W/2*(1+1j)),0)
Strahl
quelle
0

dwitter 112

c.width^=0
t?o.push({X:1e3,Y:500,U:S(99*t),V:C(9*t)}):o=[]
o.map(a=>{a.X+=a.U,a.Y+=a.V,x.fillRect(a.X,a.Y,9,9)})

Probieren Sie es aus, indem Sie den Code auf dwitter.net kopieren / einfügen

nicht hell
quelle
Wenn die Sprache die Herausforderung veröffentlicht, soll sie als nicht konkurrierend markiert werden.
16.