Advertisement
Looong

Firework

Jun 15th, 2014
535
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 10.75 KB | None | 0 0
  1. program Happy_New_Year;
  2. uses    WinCrt, Windows, Graph;
  3. const   MaxX= 640;
  4.         MaxY= 475;
  5.         BackFire_Cycle= 500;
  6.         Explosion_Cycle= 1000;
  7.         Max_BackFire= 10;
  8.         Max_BackFire_Particle= 25;
  9.         Max_BackFire_Vel_X= 50;
  10.         BackFire_Vel_Y= -250;
  11.         BackFire_Arc= Pi/3;
  12.         BackFire_Particle_Size= 3;
  13.         Particle_AirResist= 0.8;
  14.         Max_Regular_Explosion= 20;
  15.         Max_Explosion_Particle= 20;
  16.         Chain_Explosion_Cycle= 500;
  17.         Max_Regular_Speed= 400;
  18.         Min_Regular_Speed= 300;
  19.         Cycle= 5000;
  20. type    Unit_Vector= record
  21.                 x, y: Real;
  22.         end;
  23.         Type_Position= Unit_Vector;
  24.         Type_Velocity= Unit_Vector;
  25.         Effect_BackFire= record
  26.                 PrePos, Pos: Type_Position;
  27.                 Vel: Type_Velocity;
  28.                 Use: Boolean;
  29.         end;
  30.         Type_Firework_BackFire= record
  31.                 Pos: Type_Position;
  32.                 Vel: Type_Velocity;
  33.                 Use: Boolean;
  34.                 Par: array[1..Max_BackFire_Particle]of Effect_BackFire;
  35.                 CurTime: LongInt;
  36.                 Color: Byte;
  37.         end;
  38.         Effect_Particle= record
  39.                 PrePos, Pos: Type_Position;
  40.                 Vel: Type_Velocity;
  41.                 Color: Byte;
  42.                 Size: Byte;
  43.         end;
  44.         Type_Regular_Explosion= record
  45.                 Use: Boolean;
  46.                 Angle, Arc: Real;
  47.                 StartTime: LongInt;
  48.                 Vel: Real;
  49.                 Chain: Byte;
  50.                 Par: array[1..Max_Explosion_Particle]of Effect_Particle;
  51.         end;
  52. var     GraphDriver, GraphMode: Integer;
  53.         Time_Cycle, Explosion_Time_Cycle, BackFire_Time_Cycle, Time: LongInt;
  54.         i: Byte;
  55.         BackFire: array[1..Max_BackFire]of Type_Firework_BackFire;
  56.         Number_BackFire: Byte;
  57.         Regular_Explosion: array[1..Max_Regular_Explosion]of Type_Regular_Explosion;
  58.         Number_Regular_Explosion: Byte;
  59.  
  60. function Position(Ox, Oy: Real): Type_Position;
  61. begin
  62.         Position.x:= Ox;
  63.         Position.y:= Oy;
  64. end;
  65.  
  66. operator +(V1, V2: Unit_Vector)V3: Unit_Vector;
  67. begin
  68.         V3.x:= V1.x + V2.x;
  69.         V3.y:= V1.y + V2.y;
  70. end;
  71.  
  72. operator *(V1: Unit_Vector; Con: Real)V2: Unit_Vector;
  73. begin
  74.         V2.x:= V1.x*Con;
  75.         V2.y:= V1.y*Con;
  76. end;
  77.  
  78. operator /(V1: Unit_Vector; Con: Real)V2: Unit_Vector;
  79. begin
  80.         V2.x:= V1.x/Con;
  81.         V2.y:= V1.y/Con;
  82. end;
  83.  
  84. function Distance(Pos1, Pos2: Type_Position): Real;
  85. begin
  86.         Distance:= Sqrt(Sqr(Pos1.x - Pos2.x) + Sqr(Pos1.y - Pos2.y));
  87. end;
  88.  
  89. function VectorLength(Vec: Unit_Vector): Real;
  90. var     BaseO: Type_Position;
  91. begin
  92.         BaseO.x:= 0;
  93.         BaseO.y:= 0;
  94.         VectorLength:= Distance(BaseO,Vec);
  95. end;
  96.  
  97. function VectorRotate(V1: Unit_Vector; Alpha: Real): Unit_Vector;
  98. begin
  99.         VectorRotate.x:= V1.x*Cos(Alpha) - V1.y*Sin(Alpha);
  100.         VectorRotate.y:= V1.x*Sin(Alpha) + V1.y*Cos(Alpha);
  101. end;
  102.  
  103. procedure Draw_Particle(P: Type_Position; Size, Color: Byte);
  104. begin
  105.         SetColor(Color);
  106.         SetFillStyle(SolidFill,Color);
  107.         Bar(Round(P.x)-Size div 2,Round(P.y)-Size div 2,Round(P.x)+Size div 2,Round(P.y)+Size div 2);
  108. end;
  109.  
  110. function BackFire_OffScreen(Pos: Type_Position): Boolean;
  111. begin
  112.         if (Pos.x < MaxX/8) or (Pos.x > MaxX*10/8) or (Pos.y < -MaxY) or (Pos.y > MaxY + 1) then
  113.                 BackFire_OffScreen:= True
  114.         else    BackFire_OffScreen:= False;
  115. end;
  116.  
  117. procedure New_BackFire;
  118. var     u: Byte;
  119. begin
  120.         Number_BackFire:= Number_BackFire + 1;
  121.         u:= 0;
  122.         while u < Number_BackFire do
  123.         begin   u:= u + 1;
  124.                 if not BackFire[u].Use then
  125.                         Break;
  126.         end;
  127.         with BackFire[u] do
  128.         begin   Pos.x:= Random(MaxX);
  129.                 Pos.y:= MaxY;
  130.                 Vel.x:= Max_BackFire_Vel_X - Random(Max_BackFire_Vel_X*2);
  131.                 Vel.y:= BackFire_Vel_Y;
  132.                 Use:= True;
  133.                 CurTime:= GetTickCount;
  134.                 Color:= Random(20);
  135.         end;
  136. end;
  137.  
  138. procedure Process_BackFire(u: Byte);
  139. var     v: Byte;
  140. begin
  141.         with BackFire[u] do
  142.                 if BackFire_OffScreen(Pos) then
  143.                 begin   for v:= 1 to Max_BackFire_Particle do
  144.                         begin   Draw_Particle(Par[v].Pos,4*BackFire_Particle_Size,Black);
  145.                                 Par[v].Use:= False;
  146.                         end;
  147.                         Use:= False;
  148.                         Number_BackFire:= Number_BackFire - 1;
  149.                 end
  150.                 else
  151.                 begin   Pos:= Pos + Vel*(GetTickCount - Time)/1000;
  152.                         if (GetTickCount - CurTime) >= 20000/VectorLength(Vel) then
  153.                         begin   v:= 0;
  154.                                 while v < Max_BackFire_Particle do
  155.                                 begin   v:= v + 1;
  156.                                         if not Par[v].Use then
  157.                                                 Break;
  158.                                 end;
  159.                                 Par[v].Pos:= Pos;
  160.                                 Par[v].PrePos:= Pos;
  161.                                 Par[v].Vel:= VectorRotate(Vel,Pi - BackFire_Arc/2 + Random(Round(BackFire_Arc*1E9))/1E9);
  162.                                 Par[v].Use:= True;
  163.                                 CurTime:= GetTickCount;
  164.                         end;
  165.                         for v:= 1 to Max_BackFire_Particle do
  166.                                 if Par[v].Use then
  167.                                         with Par[v] do
  168.                                         begin   Draw_Particle(PrePos,4*BackFire_Particle_Size,Black);
  169.                                                 PrePos:= Pos;
  170.                                                 Vel:= Vel*(1 - (GetTickCount-Time)*Particle_AirResist/1000);
  171.                                                 if VectorLength(Vel) < VectorLength(BackFire[u].Vel)/2 then
  172.                                                         Use:= False
  173.                                                 else
  174.                                                 begin   Pos:= Pos + Vel*(GetTickCount - Time)/1000;
  175.                                                         Draw_Particle(Pos,BackFire_Particle_Size,Color);
  176.                                                 end;
  177.                                         end;
  178.                 end;
  179. end;
  180.  
  181. procedure New_Regular_Explosion(P: Type_Position; Speed: Real; Ang, Ar: Real; Ch: Byte; Col: Byte; Si: Byte);
  182. var     u, v: Byte;
  183. begin
  184.         for u:= 1 to Max_Regular_Explosion do
  185.                 if not Regular_Explosion[u].Use then
  186.                 begin   Number_Regular_Explosion:= Number_Regular_Explosion + 1;
  187.                         Break;
  188.                 end;
  189.         with Regular_Explosion[u] do
  190.         begin   Use:= True;
  191.                 Angle:= Ang;
  192.                 Arc:= Ar;
  193.                 Chain:= Ch;
  194.                 Vel:= Speed;
  195.                 StartTime:= GetTickCount;
  196.                 for v:= 1 to Max_Explosion_Particle do
  197.                         with Par[v] do
  198.                         begin   Pos:= P;
  199.                                 PrePos:= P;
  200.                                 Vel:= VectorRotate(Position(Speed,0),Angle - Arc/2 + Arc*v/(Max_Explosion_Particle - 1));
  201.                                 Color:= Col;
  202.                                 Size:= Si;
  203.                         end;
  204.         end;
  205. end;
  206.  
  207. procedure New_Chain_Explosion(P: Type_Position; Re: Byte; Max_Size, Min_Size: Byte);
  208. var     v: Byte;
  209. begin
  210.         for v:= 1 to Re do
  211.                 New_Regular_Explosion(P,Min_Regular_Speed + Random(Max_Regular_Speed - Min_Regular_Speed),0,Pi*2,Re - 1,Random(20),Min_Size + (Max_Size - Min_Size)*Round((Re - v + 1)/Re));
  212. end;
  213.  
  214. procedure Process_Regular_Explosion(u: Byte);
  215. var     v: Byte;
  216. begin
  217.         with Regular_Explosion[u] do
  218.         begin   if GetTickCount - StartTime > Chain*Chain_Explosion_Cycle then
  219.                         for v:= 1 to Max_Regular_Explosion do
  220.                                 with Par[v] do
  221.                                 begin   Draw_Particle(PrePos,2*Size,Black);
  222.                                         PrePos:= Pos;
  223.                                         Vel:= Vel*(1 - (GetTickCount - Time)*Particle_AirResist/1000);
  224.                                         if (VectorLength(Vel) < Regular_Explosion[u].Vel/2) then
  225.                                                 Use:= False
  226.                                         else
  227.                                         begin   Pos:= Pos + Vel*(GetTickCount - Time)/1000;
  228.                                                 Draw_Particle(Pos,Size,Color);
  229.                                         end;
  230.                                 end;
  231.                 if not Use then
  232.                 begin   Number_Regular_Explosion:= Number_Regular_Explosion - 1;
  233.                         for v:= 1 to Max_Regular_Explosion do
  234.                                 with Par[v] do
  235.                                         Draw_Particle(Pos,2*Size,Black);
  236.                 end;
  237.         end;
  238.  
  239. end;
  240.  
  241. begin
  242.         ShowWindow(GetActiveWindow,0);
  243.         GraphDriver:= VGA;
  244.         GraphMode:= 2;  // Use 2 for 640x475x16 resolution
  245.         //GraphMode:= VGAHi; // Use VGAHi for maximum available resolution
  246.         InitGraph(GraphDriver,GraphMode,'');
  247.  
  248.         SetBkColor(Black);
  249.         ClearViewPort;
  250.  
  251.         SetColor(13);
  252.         SetTextStyle(SansSerifFont,HorizDir,3);
  253.         OutTextXY(75,440,'<3 Happy New Year <3');
  254.         Randomize;
  255.         BackFire_Time_Cycle:= GetTickCount;
  256.         Explosion_Time_Cycle:= GetTickCount;
  257.         Time:= GetTickCount;
  258.         Time_Cycle:= GetTickCount;
  259.         repeat  SetColor(13);
  260.                 SetTextStyle(SansSerifFont,HorizDir,3);
  261.                 OutTextXY(75,440,'<3 Happy New Year <3');
  262.                 if (GetTickCount - BackFire_Time_Cycle >= BackFire_Cycle) and (Number_BackFire < Max_BackFire) then
  263.                 begin   New_BackFire;
  264.                         BackFire_Time_Cycle:= GettickCount;
  265.                 end;
  266.                 if (GetTickCount - Explosion_Time_Cycle >= Explosion_Cycle) and (Number_Regular_Explosion < Max_Regular_Explosion) then
  267.                 begin   New_Chain_Explosion(Position(Random(MaxX),Random(MaxY)),Random(8) + 1,3,3);
  268.                         Explosion_Time_Cycle:= GetTickCount;
  269.                 end;
  270.                 for i:= 1 to Max_BackFire do
  271.                         if BackFire[i].Use then
  272.                                 Process_BackFire(i);
  273.                 for i:= 1 to Max_Regular_Explosion do
  274.                         if Regular_Explosion[i].Use then
  275.                                 Process_Regular_Explosion(i);
  276.                 Time:= GetTickCount;
  277.         until keypressed;
  278.  
  279.         CloseGraph;
  280. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement