模拟爆炸的最紧凑代码


13

您是否可以编写一个程序来渲染一组爆炸的像素(如在简单的粒子引擎中),并且可以用很少数量的字符(按键)完成此操作?(回想一下游戏中的旅鼠,那时候这些小家伙会爆炸并且他们的小像素碎片飞散开来。)

有人在这里将一个简单的粒子系统编程为“ 处理”草图,与我认为其他人应该尝试完成的工作相比,它相当庞大。但是如果有人可以在c ++和sdl甚至Java或c#中做同样的事情,我会印象深刻。


2
“代码行数”是一个引起很多歧义的度量,当然不是[code-golf],它是“字符数”或有时是“字节数”。关于meta的相关讨论。
dmckee ---前主持人小猫,

4
顺便说一句-我在上面提出的问题以及相对不完整的规范,可以通过在Puzzle Lab聊天室meta上Sandbox中事先进行讨论来有效地解决。但是,无论如何,欢迎来到CodeGolf.SE。
dmckee ---前主持人小猫,

更新了问题,用字符数替换了LOC。
托德·霍普金森

1
是的,如果您编写C / C ++ / Java / Any C衍生物,则可以用1行代码编写整个OS
Nate Koppenhaver

Answers:


13

Python,245个字符

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)

这不是猛烈的爆炸,但为简洁起见绝对是+1!
托德·霍普金森

10

C#,WPF – 1523

不十分严重;这主要是尝试是否真正起作用。

我在这里所做的是在WPF中使用ItemsControl(菜单,因为它更短),以通过数据绑定和模板显示粒子。数据模板控制粒子的外观(在这种情况下为简单的圆形),数据绑定控制粒子的颜色和位置。

每个粒子都有一个位置,颜色和方向,这些位置会通过计时器更新。最初,一堆粒子是在窗口的中心以(正态分布)随机方向生成的。该集合将数据绑定到ItemsControl,然后每当属性更新时,ItemsControl就会自动处理显示粒子。粒子由于重力而向下拖动。

诚然,它有点冗长。但至少看起来不错:

在此处输入图片说明

可以通过省略来缩短它:

  • 重力,使颗粒均匀地向所有侧面膨胀;
  • 初始向量的正态分布,导致粒子在稀疏的“盒子”中扩展;
  • 亮度变化,使颗粒变黑。

我选择不这样做是为了美观。该解决方案比几乎其他任何方法都长。数据绑定和模板化方法可能很优雅,但与仅更新位图相比,它也很冗长。(注意:我忽略了以上所有内容,将其降低到1356,但那时看起来太可怕了。)

该代码分布在三个文件中,为便于阅读,此处以格式化的形式给出:

应用程式

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" StartupUri="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>

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

1
+1好看的例子!就像过去的那些经典爆炸式旅鼠一样。而且我认为这胜过最初的Question中的Processing代码。
托德·霍普金森

@icnivad:我必须承认,Processing草图(我只查看最终结果,而不是代码)是外观的灵感。
乔伊(Joey)

加!我现在停止打高尔夫球了。到目前为止,它具有一些不错的技巧(例如,针对所有属性的PropertyChanged,并且仅针对最后设置的属性)。考虑到我开始使用2000个字符以上,我认为减少500个字符并不算太糟糕。到现在,它也变得相当慢。DispatcherTimer的工作原理比Timer好得多,但时间更长。不过,我可能会想将其移植到Silverlight并在手机上运行它。
乔伊(Joey)

我认为这是将代码大小和爆炸的美学质量相结合的最佳选择。
托德·霍普金森,

icnivad:稍后,我将重写整个内容以直接在位图上进行绘制;然后,它应该短得多。45%的代码是XAML;很大一部分代码用于将UI元素绑定到粒子属性。加上C#的一般冗长性,它比需要的更加冗长。
乔伊,

7

后记-287244个字符

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

gs -dNOPAUSE asplode.ps

您甚至可以将其打印出来并制作为活动簿


精彩!很美丽!
用户未知

5

Javascript-268个字符

这是一维2粒子爆炸:

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)

要运行它,请在良好的Web浏览器中打开about:blank页面,粘贴到网址栏中,然后按Enter。您可以通过在末尾编辑值来修改爆炸s(10,5,1,0)。第一个值是爆炸的粒子的大小。第二个值是从中爆炸出来的粒子的大小。第三个值是粒子从其中爆炸的速度。保持“ 0”不变。


1
在Safari 5.0.5(显示有点像棒球棍的东西)或Chrome 11.0.696.68(显示两个球,一个球比另一个球稍大,移动缓慢)中,此功能不起作用。
marinus

1
@marinus Chrome中正在发生的事情应该是正在发生的事情。
david4dev 2011年

无法在FF4,IE8上运行。:(
st0le 2011年

好吧,我在Firefox 4.0.1和Chromium 11.0.696.65上进行了测试。提起诉讼,您复制了整个脚本-我发现复制时很容易错过结尾括号。
david4dev 2011年

@ st0le IE8不支持画布标记,除非你执行一些肮脏的把戏:stackoverflow.com/questions/1332501/...
克里斯蒂安Lupascu

4

APL(120 118)

它具有与Python条目相同的输出(即,它仅在字符网格上输出状态)。仅栅格为30x15,粒子原点为15x7。

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

2

JavaScript的502 500 496

这是Joeydavid4dev答案的结合(这是使用Javascript / canvas☺实现的Joey算法的无耻复制):

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预览:http : //jsfiddle.net/GVqFr/60/(您可以按TidyUp按钮以很好地格式化代码)


@Qqwy感谢您的编辑!
克里斯蒂安·卢帕斯库

我不是javascript专家,但是您经常使用常量500。如果你能定义一个全局变量a=500,您可以通过更换所有保存一些字符500a
拉玛先生先生2013年

@GigaWatt你是对的;该工作了250为好。
克里斯蒂安·卢帕斯库

1

重击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
}

像爆炸一样叫e。

更新:彩色

t =文字,c = cls,g =果胶,f =果蝇,C =颜色


1

带SDL的C,423个字符

由于最初的问题描述明确提到了SDL,所以我觉得提交SDL解决方案已经过去了。不幸的是,SDL函数和结构的名称并不是特别简洁,因此该程序有点长。实际上,我什至不能忽略#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);}}

(由于代码已经非常庞大,因此我留下了一些额外的位,以便可以在没有警告的情况下进行编译。有时会错过没有警告的编译。删除它们会节省大约30个字符。)

动画无限循环运行。关闭窗口以退出程序。每次爆炸都使用一组新的随机粒子。

我还要指出67372036代码中的数字。它出现在第二个调用中的最后一个参数的表达式中SDL_FillRect()。如代码所示,爆炸完全以灰色呈现。稍微更改此数字将为爆炸添加非常微妙但令人愉悦的色彩效果。数字67372032在爆炸开始时为粒子67372034着色,而数字在粒子逐渐消失时提供色彩效果。其他数字可能会产生较微妙的色彩循环效果。我鼓励您尝试一下。


1

看完这里的其他一些出色示例之后,我决定尝试一下,并制作一个适合140byt.es的粒子函数。

Javascript,282个字符

138个字符的粒子功能和150个基本的画布绘图样板)

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示例在这里

通过使代码完全具有过程性,我不再需要任何数组或对象分配代码,从而大大减少了代码大小。产生程序效果还具有其他一些不错的副作用。

通过省略重力,种子,粒子数等可以使代码更小,但是我认为这些功能太好了,无法删除;)。

特征

  • 可配置的X,Y爆炸中心。
  • 可配置的粒子数
  • 垂直方向的重力:让您的粒子掉落或飞起来!
  • 可播种的每种种子都有自己的爆炸,每次在计算机上都会准确显示该爆炸。
  • 由于创建效果的程序方式,慢动作,快进和向后播放爆炸都是可能的。
  • 大小:138字节

还可以在GitHub上检出带注释的版本。


0

带有PyGame的Python,240个字符

我意识到python中已经存在一种解决方案,但是由于该解决方案仅打印字符,所以我认为制作一个可以绘制精美动画的解决方案是值得的。

脱胎换骨,我从什么开始:

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()

经过很多黑客攻击。全屏保存一些字符。不使用声音或字体,因此我认为这init()是不必要的(对我有用)。

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)

0

Python-327个字符

有趣的事情:

  • 使用复数作为2D向量
  • (v * cos(a), v * sin(a)) 实施为 v*e**(1j*a)
  • 看起来像是3D爆炸。
  • 重力。

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)

0

糖水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)})

通过将代码复制/粘贴到dwitter.net进行尝试


语言在挑战发布日期之后,您应该将其标记为非竞争。
fəˈnɛtɪk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.