Hi all,
This is my first non obfuscated post, and whilst this is not amazingly useful, i think it fits under the cool (well in my sad world anyway!) category.

Following on from this (which shows just how bad i am at ascii art!), i've made a set of packages to do a similar thing.
Basically there are three packages: Firework.pm Firework::Rockets and Firework::Catherine, and a small demonstration script. Their code is here:

Firework.pm A set of Object Classes for drawing an xterm firework display:
test.pl
#!/usr/bin/perl use Firework; # add_rocket(initial_x, initial_y, v_x, v_y, start_time, color); my $display=new Firework; $display->add_rocket(0,25,18,18); $display->add_rocket(25,25,18,18,7); $display->add_wheel(19,22,3); $display->add_wheel(60,22,8); $display->start_display;

Firework.pm
package Firework; use Firework::Rockets; use Firework::Catherine; ### used for what the rockets look like: use constant Point=>"."; #use constant Point=>"*"; use strict; sub new { my($self,$point)=@_; my $display={fireworks=>[],Time=>0,Point=>$point||Point}; bless$display; return$display; } sub add_rocket { my ($display,@args)=@_; my $firework=Firework::Rockets->new(@_); push@{$display->{fireworks}},$firework; } sub add_wheel { my($display,@args)=@_; my $wheel=Firework::Catherine->new(@_); push@{$display->{fireworks}},$wheel; } sub start_display { my $display=shift; my $live_fireworks=1; $|=1; while($live_fireworks){ $live_fireworks=0; print "\ec"; $display->{Time}+=1; foreach my $firework (@{$display->{fireworks}}){ if(!$firework->{dead}){ $live_fireworks++; if($firework->{exploded}){ $firework->post_explode; } else { if($firework->should_explode ){ $firework->explode; } else { if($display->{Time}>$firework->{start}){ $firework->draw; $firework->{timer}+=.1; } } } } } select undef,undef,undef,0.1 } } # and some defaults; sub draw { my $firework=shift; if($firework->y_t > 0 && $firework->y_t < 25 && $firework->x_t > 0 & +& $firework->x_t < 80){ printf"\e[%d;%dH\e[1;%dm%s\e[m\e[H",$firework->y_t, $firework->x_t, $firework->{colour}, $firework->{display}->{Point}; } } sub x_t { my $firework=shift; return $firework->{i_x}+$firework->{v_x}*$firework->{timer}; } sub y_t { my $firework=shift; # s=ut+1/2*a*t^2 return $firework->{i_y} - $firework->{timer}* ($firework->{v_y}-5*$firework->{timer}); } sub v_y_t { my $firework=shift; return $firework->{v_y}-10*$firework->{timer} } sub explode { my $firework=shift; $firework->{dead}=1; } sub should_explode { return 0; } 1;
Firework/Rockets.pm
package Firework::Rockets; use Firework; our @ISA=qw{ Firework }; sub new { my($self,$display,$i_x,$i_y,$v_x,$v_y,$start,$colour)=@_; my $firework={ i_x=>$i_x, i_y=>$i_y, v_x=>$v_x, v_y=>$v_y, start=>$start, display=>$display, colour=>$colour||31+rand(6) }; bless $firework,$self; return $firework; } sub explode { my $firework=shift; $firework->{exploded}=1; for my $z (1..4){ $firework->{parts}{$z}=bless{ i_x=>$firework->x_t, i_y=>$firework->y_t, v_x=>$z%2?5:-5, v_y=>$z>2?5:-5, colour=>$firework->{colour}, display=>$firework->{display} }; } } sub should_explode { my $self=shift; return ($self->v_y_t < 0); } sub post_explode { my $firework=shift; foreach my $part_count (keys %{$firework->{parts}}){ my $part=$firework->{parts}{$part_count}; if($part->y_t > 22 || $part->x_t > 75 || $part->x_t < 0){ delete $firework->{parts}{$part_count} } else { $part->draw; $part->{timer}+=.1; } } $firework->{dead}=1 if(!scalar keys %{$firework->{parts}}); } 1;
Firework/Catherine.pm
A lot less tidy than others!
package Firework::Catherine; use Firework; our @ISA=qw{ Firework }; sub new { my($self,$display,$x,$y,$start)=@_; my $firework={ pos=>[[-1,-1],[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1]], x=>$x, y=>$y, start=>$start, display=>$display }; bless $firework,$self; return $firework; } sub draw { my $wheel=shift; if($wheel->{x}<40){ push@{$wheel->{pos}},shift@{$wheel->{pos}}; } else { unshift@{$wheel->{pos}},pop@{$wheel->{pos}}; } for(0..2){ printf"\e[%d;%dH\e[1;%dm.\e[m\e[H",$wheel->{y}+$wheel->{pos}[$_][0], $wheel->{x}+$wheel->{pos}[$_][1],31+rand(6); if($wheel->{pos}[$_][1]==-1 && $wheel->{pos}[$_][0]==1 && $wheel->{tim +er}%2){ $wheel->{display}->add_rocket( $wheel->{x}, $wheel->{y}, $wheel->{x}>40?-18:18,15+rand(6) ); } } } sub should_explode { my $wheel=shift; $wheel->{dead}=1 if($wheel->{timer}>6); return 0; } 1;
It still needs some work - notably grabbing the size of the x window and some clipping.
As with most of my posts this requires vt100 - apologies as ever to windows users - i shall try and write a version for them.
I hope you enjoy this.
Alex
ps. standard apologies if this has been done before.
Update: added constant for setting shape of rocket part.
Update 2: fixing broken newlines.

In reply to Fireworks! by teamster_jr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.