Particle fountain: Difference between revisions

m (Promote. multiple implementations, no questions)
Line 571:
 
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;
use SDL2::RawNativeCall;
use SDL2::Raw;
 
my int ($w, $h) = 800, 800;
my SDL_Window $window;
my SDL_RendererSDL_Window $rendererwindow;
my SDL_Renderer $renderer;
 
my int $particlenum = 3000;
 
 
SDL_Init(VIDEO);
$window = SDL_CreateWindow(
"Raku Particle System!",
SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK,
$w, $h,
RESIZABLE
);
$renderer = SDL_CreateRenderer( $window, -1, ACCELERATED );
 
SDL_ClearError();
 
my num @positions = 0e0 xx ($particlenum * 2);
my num @velocities = 0e0 xx ($particlenum * 2);
my num @lifetimes = 0e0 xx $particlenum;
 
my CArray[int32] $points .= new;
my int $numpoints;
my Num $saturation = 4e-1;
my Num $spread = 15e-1;
my &reciprocate = sub { 0 }
my $range = 1.5;
 
sub update (num \df) {
my int $xidx = 0;
my int $yidx = 1;
Line 622 ⟶ 623:
@velocities[$yidx] = @velocities[$yidx] * -0.3e0; # "bounce"
}
 
@velocities[$yidx] = @velocities[$yidx] + $h/10.Num * df; # adjust velocity
@positions[$xidx] = @positions[$xidx] + @velocities[$xidx] * df; # adjust position x
@positions[$yidx] = @positions[$yidx] + @velocities[$yidx] * df; # and y
 
@lifetimes[$idx] = @lifetimes[$idx] - df;
$willdraw = 1;
}
 
if ($willdraw) {
$points[$pointidx++] = (@positions[$xidx] * 10).floor; # gather all of the points that
$points[$pointidx++] = (@positions[$yidx] * 10).floor; # are still going to be rendered
}
 
$xidx = $xidx + 2;
$yidx = $xidx + 1;
}
$numpoints = ($pointidx - 1) div 2;
}
 
sub render {
SDL_SetRenderDrawColor($renderer, 0x0, 0x0, 0x0, 0xff);
SDL_RenderClear($renderer);
 
SDL_SetRenderDrawColor($renderer, |hsv2rgb(((now % 5) / 5).round(.01), $saturation, 1), 0x7f);
SDL_RenderDrawPoints($renderer, $points, $numpoints);
 
SDL_RenderPresent($renderer);
}
 
enum KEY_CODES (
K_UP => 82,
K_DOWN => 81,
Line 661 ⟶ 662:
K_PGDN => 78,
K_Q => 20,
);
 
say q:to/DOCS/;
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.
Toggle reciprocation off / on with the SPACE bar.
Use LEFT and RIGHT arrow keys to modify angle range for reciprocation.
Press the "q" key to quit.
DOCS
 
my $event = SDL_Event.new;
 
my num $df = 0.0001e0;
 
main: loop {
my $start = now;
 
while SDL_PollEvent($event) {
my $casted_event = SDL_CastEvent($event);
 
given $casted_event {
when *.type == QUIT {
Line 707 ⟶ 708:
}
}
 
update($df);
 
render();
 
$df = (now - $start).Num;
 
print fps();
}
 
say '';
 
sub fps {
state $fps-frames = 0;
state $fps-now = now;
Line 731 ⟶ 732:
}
$fps
}
 
sub hsv2rgb ( $h, $s, $v ){
state %cache;
%cache{"$h|$s|$v"} //= do {
Line 748 ⟶ 749:
} ).map: ((*+$m) * 255).Int]
}
}
}</lang>
 
[https://github.com/thundergnat/rc/blob/master/img/fountain-raku.mp4?raw=true Link to off-site .mp4 video]
9

edits