Particle fountain: Difference between revisions

Content added Content deleted
m (Promote. multiple implementations, no questions)
Line 571: Line 571:


Has options to vary the direction at which the fountain sprays, the "spread" angle and the color of the emitted particles.
Has options to vary the direction at which the fountain sprays, the "spread" angle and the color of the emitted particles.
<lang perl6>use NativeCall;
<lang perl6>
use SDL2::Raw;
use NativeCall;
use SDL2::Raw;

my int ($w, $h) = 800, 800;
my int ($w, $h) = 800, 800;
my SDL_Window $window;
my SDL_Renderer $renderer;
my SDL_Window $window;
my SDL_Renderer $renderer;

my int $particlenum = 3000;
my int $particlenum = 3000;


SDL_Init(VIDEO);
SDL_Init(VIDEO);
$window = SDL_CreateWindow(
$window = SDL_CreateWindow(
"Raku Particle System!",
"Raku Particle System!",
SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK,
SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK,
$w, $h,
$w, $h,
RESIZABLE
RESIZABLE
);
);
$renderer = SDL_CreateRenderer( $window, -1, ACCELERATED );
$renderer = SDL_CreateRenderer( $window, -1, ACCELERATED );

SDL_ClearError();
SDL_ClearError();

my num @positions = 0e0 xx ($particlenum * 2);
my num @positions = 0e0 xx ($particlenum * 2);
my num @velocities = 0e0 xx ($particlenum * 2);
my num @velocities = 0e0 xx ($particlenum * 2);
my num @lifetimes = 0e0 xx $particlenum;
my num @lifetimes = 0e0 xx $particlenum;

my CArray[int32] $points .= new;
my CArray[int32] $points .= new;
my int $numpoints;
my int $numpoints;
my Num $saturation = 4e-1;
my Num $saturation = 4e-1;
my Num $spread = 15e-1;
my Num $spread = 15e-1;
my &reciprocate = sub { 0 }
my &reciprocate = sub { 0 }
my $range = 1.5;
my $range = 1.5;

sub update (num \df) {
sub update (num \df) {
my int $xidx = 0;
my int $xidx = 0;
my int $yidx = 1;
my int $yidx = 1;
Line 622: Line 623:
@velocities[$yidx] = @velocities[$yidx] * -0.3e0; # "bounce"
@velocities[$yidx] = @velocities[$yidx] * -0.3e0; # "bounce"
}
}

@velocities[$yidx] = @velocities[$yidx] + $h/10.Num * df; # adjust velocity
@velocities[$yidx] = @velocities[$yidx] + $h/10.Num * df; # adjust velocity
@positions[$xidx] = @positions[$xidx] + @velocities[$xidx] * df; # adjust position x
@positions[$xidx] = @positions[$xidx] + @velocities[$xidx] * df; # adjust position x
@positions[$yidx] = @positions[$yidx] + @velocities[$yidx] * df; # and y
@positions[$yidx] = @positions[$yidx] + @velocities[$yidx] * df; # and y

@lifetimes[$idx] = @lifetimes[$idx] - df;
@lifetimes[$idx] = @lifetimes[$idx] - df;
$willdraw = 1;
$willdraw = 1;
}
}

if ($willdraw) {
if ($willdraw) {
$points[$pointidx++] = (@positions[$xidx] * 10).floor; # gather all of the points that
$points[$pointidx++] = (@positions[$xidx] * 10).floor; # gather all of the points that
$points[$pointidx++] = (@positions[$yidx] * 10).floor; # are still going to be rendered
$points[$pointidx++] = (@positions[$yidx] * 10).floor; # are still going to be rendered
}
}

$xidx = $xidx + 2;
$xidx = $xidx + 2;
$yidx = $xidx + 1;
$yidx = $xidx + 1;
}
}
$numpoints = ($pointidx - 1) div 2;
$numpoints = ($pointidx - 1) div 2;
}
}

sub render {
sub render {
SDL_SetRenderDrawColor($renderer, 0x0, 0x0, 0x0, 0xff);
SDL_SetRenderDrawColor($renderer, 0x0, 0x0, 0x0, 0xff);
SDL_RenderClear($renderer);
SDL_RenderClear($renderer);

SDL_SetRenderDrawColor($renderer, |hsv2rgb(((now % 5) / 5).round(.01), $saturation, 1), 0x7f);
SDL_SetRenderDrawColor($renderer, |hsv2rgb(((now % 5) / 5).round(.01), $saturation, 1), 0x7f);
SDL_RenderDrawPoints($renderer, $points, $numpoints);
SDL_RenderDrawPoints($renderer, $points, $numpoints);

SDL_RenderPresent($renderer);
SDL_RenderPresent($renderer);
}
}

enum KEY_CODES (
enum KEY_CODES (
K_UP => 82,
K_UP => 82,
K_DOWN => 81,
K_DOWN => 81,
Line 661: Line 662:
K_PGDN => 78,
K_PGDN => 78,
K_Q => 20,
K_Q => 20,
);
);

say q:to/DOCS/;
say q:to/DOCS/;
Use UP and DOWN arrow keys to modify the saturation of the particle colors.
Use UP and DOWN arrow keys to modify the saturation of the particle colors.
Use PAGE UP and PAGE DOWN keys to modify the "spread" of the particles.
Use PAGE UP and PAGE DOWN keys to modify the "spread" of the particles.
Toggle reciprocation off / on with the SPACE bar.
Toggle reciprocation off / on with the SPACE bar.
Use LEFT and RIGHT arrow keys to modify angle range for reciprocation.
Use LEFT and RIGHT arrow keys to modify angle range for reciprocation.
Press the "q" key to quit.
Press the "q" key to quit.
DOCS
DOCS

my $event = SDL_Event.new;
my $event = SDL_Event.new;

my num $df = 0.0001e0;
my num $df = 0.0001e0;

main: loop {
main: loop {
my $start = now;
my $start = now;

while SDL_PollEvent($event) {
while SDL_PollEvent($event) {
my $casted_event = SDL_CastEvent($event);
my $casted_event = SDL_CastEvent($event);

given $casted_event {
given $casted_event {
when *.type == QUIT {
when *.type == QUIT {
Line 707: Line 708:
}
}
}
}

update($df);
update($df);

render();
render();

$df = (now - $start).Num;
$df = (now - $start).Num;

print fps();
print fps();
}
}

say '';
say '';

sub fps {
sub fps {
state $fps-frames = 0;
state $fps-frames = 0;
state $fps-now = now;
state $fps-now = now;
Line 731: Line 732:
}
}
$fps
$fps
}
}

sub hsv2rgb ( $h, $s, $v ){
sub hsv2rgb ( $h, $s, $v ){
state %cache;
state %cache;
%cache{"$h|$s|$v"} //= do {
%cache{"$h|$s|$v"} //= do {
Line 748: Line 749:
} ).map: ((*+$m) * 255).Int]
} ).map: ((*+$m) * 255).Int]
}
}
}
}</lang>
</lang>


[https://github.com/thundergnat/rc/blob/master/img/fountain-raku.mp4?raw=true Link to off-site .mp4 video]
[https://github.com/thundergnat/rc/blob/master/img/fountain-raku.mp4?raw=true Link to off-site .mp4 video]