unit uMain;

interface

uses zglHeader,
     uVar,
     uSnake,
     LightEngine2D,
     math,
     uzglMyPart,
     uAdd;

procedure GameInit;
procedure GameRender;
procedure GameProcess;
procedure GameFree;

implementation

{$REGION 'add func'}

function vCircle( p : leVect; r, a : Single) : leVect;
begin
  result.x := p.x + Round( Cos( a ) * r );
  result.y := p.y + Round( Sin( a ) * r );
end;

function r(x, y, w, h : single) : zglTRect;
begin
  result.X := x;
  result.Y := y;
  result.W := w;
  result.H := h;
end;

{$ENDREGION}

procedure GameInit;
begin
  // фокусы со светом
  //
  // инициируем свет
  le_InitLightEngine(le_ColorRGB(0.1),'data/tex/Penumbra.png',32,32); 
  // добавляем лампочки
  l1 := le_CreateLightSource(le_v(100, 100), 300, le_ColorRGB(0,1,0));
  l2 := le_CreateLightSource(le_v(450, 100), 300, le_ColorRGB(0.3,0.3,1));
  l3 := le_CreateLightSource(le_v(100, 450), 300, le_ColorRGB(1,1,0));
  l4 := le_CreateLightSource(le_v(450, 450), 300, le_ColorRGB(1,0,0));
  l5 := le_CreateLightSource(le_v(0,     0),  40, le_ColorRGB(1,1,1));
  l6 := le_CreateLightSource(le_v(0,     0),  50, le_ColorRGB(1,0,0));
  le_CreateLightSource(le_v(250, 250), 250, le_ColorRGB(1,1,1));

  // ставим столбики
  le_CreateShadowShape(16, le_v(32*4 + 16,  32*4 + 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*4 + 16,  32*8 + 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*4 + 16,  32*12+ 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*8 + 16,  32*4 + 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*8 + 16,  32*12+ 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*12+ 16,  32*4 + 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*12+ 16,  32*8 + 16), le_GetNewGroup);
  le_CreateShadowShape(16, le_v(32*12+ 16,  32*12+ 16), le_GetNewGroup);
  // выставляем позиции лампочек
  a1 := 0; a2 := 1.57; a3 := 3.14; a4 := -1.57;


  snd_Init();
  audio := snd_PlayFile('data/snd/lambada.ogg', true);
  snd_SetVolume( zglPSound( audio ), SND_STREAM, 0.35 );

  sndOn    := snd_LoadFromFile('data/snd/click.wav', 3 );
  sndClk   := snd_LoadFromFile('data/snd/back.ogg', 2);
  sndTake  := snd_LoadFromFile('data/snd/15.ogg', 3);
  sndMem   := snd_LoadFromFile('data/snd/coin.wav', 3);
  sndLost  := snd_LoadFromFile('data/snd/lose.wav', 3);
  sndSced  := snd_LoadFromFile('data/snd/win.wav', 1);

  fnt := font_loadfromfile('data/gui/Comic Sans MS-Bold-10pt.zfi');

  memTex[0] := tex_LoadFromFile('data/tex/1.png');
  tex_SetFrameSize(memTex[0], 24, 32);

  memTex[1] := tex_LoadFromFile('data/tex/2.png');
  tex_SetFrameSize(memTex[1], 24, 32);

  memTex[2] := tex_LoadFromFile('data/tex/3.png');
  tex_SetFrameSize(memTex[2], 24, 32);

  memTex[3] := tex_LoadFromFile('data/tex/4.png');
  tex_SetFrameSize(memTex[3], 24, 32);

  memTex[4] := tex_LoadFromFile('data/tex/5.png');
  tex_SetFrameSize(memTex[4], 24, 32);

  flrTex := tex_LoadFromFile('data/tex/floor.png');

  bonTex[0] := tex_LoadFromFile('data/tex/b1.png');
  bonTex[1] := tex_LoadFromFile('data/tex/b2.png');
  bonTex[2] := tex_LoadFromFile('data/tex/b3.png');

  texFire := tex_LoadFromFile('data/tex/fireball.png' );
  texBrf  := tex_LoadFromFile('data/tex/brief.png');
  texDlg  := tex_LoadFromFile('data/tex/dialog.png');
  texSpdbr  := tex_LoadFromFile('data/tex/speedbar.png');
  texFunbr  := tex_LoadFromFile('data/tex/funbar.png');
  texFunICO  := tex_LoadFromFile('data/tex/SPEED.png');
  texScOrE  := tex_LoadFromFile('data/tex/score.png');
  texSpEEd  := tex_LoadFromFile('data/tex/speed.png');  

  // создаём образец партикла
  fr_samp.tex := texFire;
  fr_samp.s_w := 32;
  fr_samp.s_h := 32;
  fr_samp.sc_type := PM_RANDOM;
  fr_samp.s_scale := 2;
  fr_samp.move_type := PM_RANDOM;
  fr_samp.m_speed := 5;
  fr_samp.dir_type:= PM_Random;
  fr_samp.m_angle := 360;
  fr_samp.spin_type := PM_RANDOM;
  fr_samp.s_ang := 0.5;
  fr_samp.live_type := PM_FIXED;
  fr_samp.L_Time := 200;
  fr_samp.spin_type := PM_RANDOM;
  fr_samp.s_ang := 3;
  // создаём эмиттер
  em_fire := TEmitter.Create(1024, 400, 120);
  em_fire.SetPosition( 400, 300);
  em_fire.SetPartSample(fr_samp);

  level := 0;
end;

procedure GameRender;
var i, j: integer;
    w : Single;
begin


case gs of
   gsMenu : begin
                // рисуем всплохи огня
                fx_SetBlendMode( FX_BLEND_ADD );
                em_fire.Draw;
                fx_SetBlendMode( FX_BLEND_Normal );
                // название
                fx2d_SetVCA( $00ff00, $ffFF00, $00FFff, $0000ff, 255 , 255, 255, 255 );
                text_DrawEx(fnt, 120, 150, 5, 2, 'Lambada-game', 255, $0000ff, TEXT_FX_VCA);

                case ms  of
                   msMain: begin
{$REGION 'Rects'}
                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 290, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 290, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 290, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 320, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 320, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 320, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 350, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 350, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 350, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 380, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 380, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 380, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 410, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 410, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 410, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;
{$ENDREGION}
                              text_Draw(fnt, 350, 300, 'Начать игру');
                              text_Draw(fnt, 350, 330, 'Рекорды');
                              text_Draw(fnt, 350, 360, 'Настройки');
                              text_Draw(fnt, 350, 390, 'Автор');
                              text_Draw(fnt, 350, 420, 'Покинуть игру');
                           end;
                   msLogin:begin
                             text_Draw(fnt, 350, 300, 'Введите своё имя');

                             text_Draw( fnt, 400, 330, profile, TEXT_HALIGN_CENTER );
                             w := text_GetWidth( fnt, profile );
                             pr2d_Rect( 400 + w / 2, 325, 10, 20, $FFFFFF, linealpha, PR2D_FILL );

                             text_Draw(fnt, 200, 400, 'Нажмите "Enter" для продолжения');
                             text_Draw(fnt, 200, 430, 'Нажмите "Esc" для возвращения');
                           end;
                end;

            end;
   gsGame : begin
              for I := 1 to 15 do
                for j := 1 to 15 do
                  SSprite2d_draw(flrTex, i*32, j*32, 32, 32, 0);

              if igs = igsGame then
                begin
                   Snake_Render;

                   asprite2d_draw(memTex[dot_t - 1], dot.x*32 + 4, dot.y*32, 24, 32, 0, 3 + fr + 1);
                   if bon_t <> 0 then
                      SSprite2d_draw(BonTex[bon_t - 1], bon.x * 32, bon.y * 32, 32, 32, 0);
                end;

              pr2d_circle(32*4 + 16,  32*4 + 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*4 + 16,  32*8 + 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*4 + 16,  32*12+ 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*8 + 16,  32*4 + 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*8 + 16,  32*12+ 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*12+ 16,  32*4 + 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*12+ 16,  32*8 + 16, 16, $ffffff, 255, 32, PR2D_FILL);
              pr2d_circle(32*12+ 16,  32*12+ 16, 16, $ffffff, 255, 32, PR2D_FILL);

              // рисуем свет и тени
              le_EachShadowShape( @le_DrawShadowShape );
              le_EachLightSource(@le_RenderLight);
              le_RenderShadows;

              case igs of
                 igsGame : begin
                              SSprite2d_draw(texSpeed, 630, 120, 32, 32, 0);
                              SSprite2d_draw(texFunIco , 580, 120, 32, 32, 0);

                              SSprite2d_draw(texScore, 550, 50, 150, 60, 0);

                              text_drawEx(fnt, 620, 70, 1, 1, u_IntToStr(score), 255, $ffffff);

                              SSprite2d_draw(texFunBr, 581, 151 + 198 - interest/1000*198, 30, interest/1000*198, 0);
                              SSprite2d_draw(texSpdBr, 631, 151 + 198 - speed /120*198, 30, speed/120*198, 0);

                              text_draw(fnt, 580, 400, 'Длина : ' + u_IntToStr(snake.length));
                              text_draw(fnt, 580, 430, 'Человек : ' + u_IntToStr(snake.length));
                              text_draw(fnt, 580, 460, 'Время : ' + u_IntToStr(time div 60) + '.' + u_IntToStr(time - (time div 60)*60));

                              pr2d_rect(580, 150, 32, 200, $00aa00, 255);
                              pr2d_rect(630, 150, 32, 200, $ff0000, 255);
                           end;
                 igsBriefing : begin
                                 SSprite2d_Draw(texDlg, 50,  460, 600, 150, 0);
                                 SSprite2d_Draw(texBrf, 560, 400, 100, 200, 0);
                                 pr2d_Rect(70, 510, 500, 70, $00ff00);
                                 text_DrawInRectEx(fnt, r(70, 510, 500, 70), 1, 1, briefings[level], 255, $000000);
                               end;
                 igsSucceed : begin
                                  fx2d_SetVCA( $ffff00, $ffFF00, $ff00ff, $0000ff, 255 , 255, 255, 255 );
                                  text_DrawEx(fnt, 180, 150, 3,  2, 'Уровень ' + u_IntToStr(level + 1) + ' пройден', 255, $0000ff, TEXT_FX_VCA);

                                  fx2d_SetVCA( $00ff00, $55FF55, $ffff00, $00ffff, 255 , 255, 255, 255 );
                                  if t_counter > 50 then text_DrawEx(fnt, 220, 200,1.5, 1, 'Длина     : ' + u_IntToStr(snake.length) + ' x 10 = ' + u_IntToStr(snake.length * 10) , 255, $000000, TEXT_FX_VCA);
                                  if t_counter >100 then text_DrawEx(fnt, 220, 230,1.5, 1, 'Скорость  : ' + u_IntToStr(speed div 7 ) + ' x 7 = ' + u_IntToStr(speed), 255, $000000, TEXT_FX_VCA);
                                  if t_counter >150 then text_DrawEx(fnt, 220, 260,1.5, 1, 'Веселье   : ' + u_IntToStr(interest ) + ' x 3 = ' + u_IntToStr(interest * 3), 255, $000000, TEXT_FX_VCA);
                                  if t_counter >200 then text_DrawEx(fnt, 220, 290,1.5, 1, 'Время     : ' + u_IntToStr(time ) + ' x 2 = ' + u_IntToStr(time * 2), 255, $000000, TEXT_FX_VCA);
                                  if t_counter >250 then text_DrawEx(fnt, 220, 320,1.5, 1, 'Итог      : ' + u_IntToStr(snake.length * 10 + time *2 + speed + interest * 3), 255, $000000, TEXT_FX_VCA);
                                  if t_counter >300 then text_DrawEx(fnt, 180, 370,  2, 1, 'Нажмите "пробел" для продолжения', 255, $000000, TEXT_FX_VCA);
                              end;
              end;

            end;
end;

end;

procedure GameProcess;
var i: integer;
begin
case gs of
  gsMenu : begin
             em_fire.SetPosition(random(800), random(600));
             em_fire.Update;
             case ms of
               msMain: begin

                         if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 290, 800, 30)) then
                         begin
                            if m_i <> 1 then snd_Play( sndOn, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            m_i := 1;
                            if (mouse_Click(M_BLEFT)) then
                            begin
                              snd_Play( sndClk, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                              ms:=msLogin;
                              key_BeginReadText( profile, 20 );
                            end;
                         end;

                         if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 320, 800, 30)) then
                         begin
                            if m_i <> 2 then snd_Play( sndOn, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            m_i := 2;
                         end;

                         if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 350, 800, 30)) then
                         begin
                            if m_i <> 3 then snd_Play( sndOn, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            m_i := 3;
                         end;

                         if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 380, 800, 30)) then
                         begin
                            if m_i <> 4 then snd_Play( sndOn, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            m_i := 4;
                         end;

                         if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 410, 800, 30)) then
                         begin
                            if m_i <> 5 then snd_Play( sndOn, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            m_i := 5;
                         end;

                       end;

               msLogin:begin
                         DEC( lineAlpha, 10 );
                         profile := key_GetText();

                         if Key_Press(K_ESCAPE) then
                            begin
                              key_EndReadText;
                              ms:=msMain;
                              snd_Play( sndClk, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );
                            end;

                         if Key_Press(K_ENTER) then
                         begin
                           key_EndReadText;
                           ms  := msMain;
                           gs  := gsGame;
                           igs := igsBriefing;

                           zgl_Disable( COLOR_BUFFER_CLEAR );
                           snake_init;
                         end;
                       end;
             end;
           end;
  gsGame : begin
             a1 := a1 + degtorad( 0.2 );
             l1.Position := vCircle( le_v( 265, 265 ), 250, a1);
             a2 := a2 + degtorad( 0.2 );
             l2.Position := vCircle( le_v( 265, 265 ), 250, a2);
             a3 := a3 + degtorad( 0.2 );
             l3.Position := vCircle( le_v( 265, 265 ), 250, a3);
             a4 := a4 + degtorad( 0.2 );
             l4.Position := vCircle( le_v( 265, 265 ), 250, a3);

             if bon_t = 0 then l6.position := le_v(-1000, -1000);

             le_Update;

             case igs of
               igsBriefing :
                         begin
                           if Key_Press(K_SPACE) or Key_Press(K_ENTER) then igs := igsGame;
                         end;
               igsSucceed  :
                         begin
                           inc(t_counter);

                           if t_counter = 1 then snd_Play( sndSced, FALSE, CalcX2D( mouse_X ), CalcY2D( mouse_Y ) );

                           if (t_Counter div 50 = t_counter / 50) and (t_counter < 310) then
                              snd_Play( sndTake, FALSE, CalcX2D( 400 ), CalcY2D( 300 ) );

                           
                           if Key_Press(K_SPACE) or Key_Press(K_ENTER) then
                             begin
                               igs := igsBriefing;
                               score := score + snake.length * 10 + time *2 + speed + interest * 3;
                               Snake_Init;
                               time := 0;
                               speed:= 0;
                               t_counter := 0;
                               inc(level);
                             end;
                         end;
               igsGame : begin
                            snake_update;

                            inc(pause);
                            inc(a_counter);
                            inc(s_counter);
                            inc(tmr);

                            if tmr = 100 then
                            begin
                              tmr := 0;
                              inc(time);
                            end;
                            

                            if a_counter > 15 then
                            begin
                              inc(fr);
                              a_counter := 0;
                              if fr > 2 then fr := 0;
                            end;

                            if s_counter > 30 then
                            begin
                              s_counter := 0;
                              inc(speed);
                              if speed > 120 then speed:= 120;
                              if (level = 6) and (speed > 70) then speed := 70;
                            end;
                            

                            if pause > 30 - speed div 7 then
                            begin
                              pause := 0;
                              i := snake.length - speed div 7 ;
                              if i < snake.length div 2  then i := snake.length div 2;
                              dec(interest, i);
                               if (level = 6) and (interest < 1) then interest := 1;
                              if interest < 1 then Snake_losemember;
                              snake_step;
                            end;

                            case level of
                               0: begin
                                    if snake.length > 6 then igs := igsSucceed;
                                  end;
                               1: begin
                                    if speed div 7 > 15 then igs := igsSucceed;
                                  end;
                               2: begin
                                    if snake.length > 14 then igs := igsSucceed;
                                  end;
                               3: begin
                                    if membs > 25 then igs := igsSucceed;
                                  end;
                               4: begin
                                    if time > 90 then igs := igsSucceed;
                                  end;
                               5: begin

                                  end;
                               6: begin
                                    if snake.length > 40 then igs := igsSucceed;
                                  end;
                            end;
                         end;
             end;


           end;
end;

end;

procedure GameFree;
begin
  em_fire.Free;
  le_EachLightSource( @le_FreeLightSource );
  le_EachShadowShape( @le_FreeShadowShape );
end;

end.
