aboutsummaryrefslogblamecommitdiffstats
path: root/Game/Code/Classes/UGraphicClasses.pas
blob: 34a964b2f1ce2968ec314ff89d93691f714cf059 (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                      





                                                      

                                                                   
 
                                                                                                                                  
















                                                
                                                                                                           
                                                  
                                                                     


                       
                                                                                                                                         



                                                                     
                                                   
                                                                         



                                
               

                                                                                                   



                               
            
                                                                                                                                         





                  

                              







                          
                    
 


                   
                                                





                                          
                                                



                                        






                                       

       
                                     
                           
                                                     
                      














                                                                    
                 

                            





                               

























                                                                  
 





















                                      
                                                                                                                                                   


                                     
                                                                                              

















                                                                                                                                                                           
                                                                                          






                                           




















                                                                                                                                      
                 





                                    




                             

     
                                                                                     
                                      
                                                      

                                 
                         
      










                                                                               
              

                                            







                                                                                  
           

     



                                                                                 
                         
      








                                                                                                  
 
                                                               







                                                                            
       








                                                               
                         
      








                                                                                                            
 
                                                               




                                               







                                                                                                     
     
     
 
unit UGraphicClasses;

interface

type
 TParticle = Class
   X, Y     : Real;     //Position
   Frame    : Byte;     //act. Frame
   Tex      : Cardinal; //Tex num from Textur Manager
   Live     : Byte;     //How many Cycles before Kill
   RecIndex : Integer;  //To which rectangle this particle belongs
   StarType : Integer;  // 1: GoldenNote | 2: PerfectNote

   Constructor Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : Integer);
   procedure Draw;
 end;

 RectanglePositions   = Record
   xTop, yTop, xBottom, yBottom : Real;
   TotalStarCount   : Integer;
   CurrentStarCount : Integer;
 end;

 PerfectNotePositions = Record
   xPos, yPos : Real;
 end;

 TEffectManager = Class
   Particle      : array of TParticle;
   LastTime      : Cardinal;
   RecArray      : Array of RectanglePositions;
   TwinkleArray  : Array[0..5] of PerfectNotePositions; // store position of last twinkle for every player
   PerfNoteArray : Array of PerfectNotePositions;
   KillallTime   : Cardinal; // Timestamp set when Killall is called

   constructor Create;
   procedure Draw;
   function  Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer;  RecArrayIndex : Integer; StarType : Integer): Cardinal;
   procedure SpawnRec();
   procedure Kill(index: Cardinal);
   procedure KillAll();
   procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
   procedure SavePerfectNotePos(Xtop, Ytop: Real);
   procedure GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
 end;

var GoldenRec : TEffectManager;

implementation
uses sysutils, Windows,OpenGl12, UThemes, USkins, UGraphic, UDrawTexture, UTexture, math, dialogs;

const
  KillallDelay: Integer = 100;


//TParticle
Constructor TParticle.Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : Integer);
begin
  X := cX;
  Y := cY;
  Tex := cTex;
  Live := cLive;
  Frame:= cFrame;
  RecIndex := cRecArrayIndex;
  StarType := cStarType;
end;


procedure TParticle.Draw;
var
  W, H:   real;
  Alpha : real;
begin
    //Fade Eyecandy

  Case StarType of
      1:
        begin
          Alpha := (-cos((Frame+1)*2*pi/16)+1);
          W := 20;
          H := 20;
          glColor4f(0.99, 1, 0.6, Alpha);
        end;
      2:
        begin
          Alpha := (-cos((Frame+1)*2*pi/16)+1);
          W := 30;
          H := 30;
          glColor4f(1, 1, 0.95, Alpha);
        end;
      3:
        begin
          Alpha := (Live/3);
          W := 15;
          H := 15;
          glColor4f(1, 1, 0.9, Alpha);
        end;
  end;

  glBindTexture(GL_TEXTURE_2D, Tex);
  glEnable(GL_TEXTURE_2D);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);

  begin
    glBegin(GL_QUADS);
    glTexCoord2f((1/16) * Frame, 0);          glVertex2f(X-W, Y-H);
    glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W, Y+H);
    glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W, Y+H);
    glTexCoord2f((1/16) * Frame, 1);          glVertex2f(X+W, Y-H);
    glEnd;
  end;
  glcolor4f(1,1,1,1);
end;



constructor TEffectManager.Create;
var c: Cardinal;
begin
  LastTime := GetTickCount;
  KillallTime := LastTime;
  for c:=0 to 5 do
  begin
    TwinkleArray[c].xPos := 0;
    TwinkleArray[c].yPos := 0;
  end;
end;


procedure TEffectManager.Draw;
var
  I: Integer;
  CurrentTime: Cardinal;
const
  DelayBetweenFrames : Integer = 100;
begin

  CurrentTime := GetTickCount;
  //Manage particle life
  if (CurrentTime > (LastTime + DelayBetweenFrames)) then
    begin
      LastTime := CurrentTime;
        for I := 0 to high(Particle) do
          begin
            Particle[I].Frame := (Particle[I].Frame + 1 ) mod 16;
              //Live = 0 => Live forever
              if (Particle[I].Live > 0) then
                begin
                  Dec(Particle[I].Live);
                end;
          end;
    end;

  I := 0;
  //Kill dead particles
  while (I <= High(Particle)) do
    begin
      if (Particle[I].Live <= 0) then
        begin
          kill(I);
        end
      else
        begin
          inc(I);
        end;
    end;

 //Draw
 for I := 0 to high(Particle) do
   begin
     Particle[I].Draw;
   end;
end;


function TEffectManager.Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : Integer): Cardinal;
begin
  Result := Length(Particle);
  SetLength(Particle, (Result + 1));
  Particle[Result] := TParticle.Create(X, Y, Tex, Live, StartFrame, RecArrayIndex, StarType);
end;


procedure TEffectManager.SpawnRec();
Var
  Xkatze, Ykatze    : Real;
  RandomFrame : Integer;
  P : Integer; // P as seen on TV as Positionman
begin
//Spawn a random amount of stars within the given coordinates
//RandomRange(0,14) <- this one starts at a random  frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame
for P:= 0 to high(RecArray) do
  begin
    while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do
      begin
        Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom));
        Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom));
        RandomFrame := RandomRange(0,14);
        Spawn(Xkatze, Ykatze, Tex_Note_Star.TexNum, 16 - RandomFrame, RandomFrame, P, 1);
        inc(RecArray[P].CurrentStarCount);
      end;
    end;
  draw;
end;


procedure TEffectManager.Kill(Index: Cardinal);
var
  LastParticleIndex : Cardinal;
begin
// We put the last element of the array on the place where our element_to_delete resides and then we shorten the array - cool, hu? :P

LastParticleIndex := high(Particle);
if not(LastParticleIndex = -1) then
  begin
  Try
    Finally
      if not(Particle[Index].RecIndex = -1) then
        dec(RecArray[Particle[Index].RecIndex].CurrentStarCount);
      Particle[Index].Destroy;
      Particle[Index] := Particle[LastParticleIndex];
      SetLength(Particle, LastParticleIndex);
    end;
    end;
end;

procedure TEffectManager.KillAll();
var c: Cardinal;
begin
//It's the kill all kennies rotuine
  while Length(Particle) > 0 do
    Kill(0);
  SetLength(RecArray,0);
  SetLength(PerfNoteArray,0);
  for c:=0 to 5 do
  begin
    TwinkleArray[c].xPos:=0;
    TwinkleArray[c].yPos:=0;
  end;
end;

procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
//Twinkle stars while golden note hit
// this is called from UDraw.pas, SingDrawPlayerCzesc
var
  C, P, XKatze, YKatze: Integer;
  CurrentTime: Cardinal;
begin
  CurrentTime := GetTickCount;
  //delay after Killall
  if (CurrentTime > (KillallTime + KillallDelay)) then
    // make sure we spawn only one time at one position
    if (TwinkleArray[Player].xPos < Right) then
      For P := 0 to high(RecArray) do  // Are we inside a GoldenNoteRectangle?
      begin
        if ((RecArray[P].xBottom >= Right) and
            (RecArray[P].xTop <= Right) and
            (RecArray[P].yTop <= (Top+Bottom)/2) and
            (RecArray[P].yBottom >= (Top+Bottom)/2)) then
        begin
          TwinkleArray[Player].xPos:=Right;
          
          for C := 1 to 8 do
          begin
            Ykatze := RandomRange(ceil(Top) , ceil(Bottom));
            XKatze := RandomRange(-7,3);
            Spawn(Ceil(Right)+XKatze, YKatze, Tex_Note_Star.TexNum, 3, 0, -1, 3);
          end;
          exit; // found a GoldenRec, did spawning stuff... done
        end;
      end;
end;

procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
var
  P : Integer;   // P like used in Positions
  NewIndex : Integer;
  CurrentTime: Cardinal;
begin
  CurrentTime := GetTickCount;
  //delay after Killall
  if (CurrentTime > (KillallTime + KillallDelay)) then
  begin
    For P := 0 to high(RecArray) do  // Do we already have that "new" position?
      begin
        if ((ceil(RecArray[P].xTop) = ceil(Xtop)) and (ceil(RecArray[P].yTop) = ceil(Ytop))) then
          exit; // it's already in the array, so we don't have to create a new one
      end;

  // we got a new position, add the new positions to our array
      NewIndex := Length(RecArray);
      SetLength(RecArray, NewIndex + 1);
      RecArray[NewIndex].xTop    := Xtop;
      RecArray[NewIndex].yTop    := Ytop;
      RecArray[NewIndex].xBottom := Xbottom;
      RecArray[NewIndex].yBottom := Ybottom;
      RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3;
      RecArray[NewIndex].CurrentStarCount := 0;
  end;
end;

procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real);
var
  P : Integer;   // P like used in Positions
  NewIndex : Integer;

  RandomFrame : Integer;
  Xkatze, Ykatze : Integer;
  CurrentTime: Cardinal;
begin
  CurrentTime := GetTickCount;
  //delay after Killall
  if (CurrentTime > (KillallTime + KillallDelay)) then
  begin
    For P := 0 to high(PerfNoteArray) do  // Do we already have that "new" position?
      begin
        if ((ceil(PerfNoteArray[P].xPos) = ceil(Xtop)) and (ceil(PerfNoteArray[P].yPos) = ceil(Ytop))) then
          exit; // it's already in the array, so we don't have to create a new one
      end;

  // we got a new position, add the new positions to our array
      NewIndex := Length(PerfNoteArray);
      SetLength(PerfNoteArray, NewIndex + 1);
      PerfNoteArray[NewIndex].xPos    := Xtop;
      PerfNoteArray[NewIndex].yPos    := Ytop;

      for P:= 0 to 2 do
        begin
          Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10);
          Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10);
          RandomFrame := RandomRange(0,14);
          Spawn(Xkatze, Ykatze, Tex_Note_Perfect_Star.TexNum, 16 - RandomFrame, RandomFrame, -1, 2);
      end;
  end;
end;
end.