home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / core / camera.cpp next >
Encoding:
C/C++ Source or Header  |  2008-07-01  |  8.5 KB  |  425 lines

  1. /***************************************************************************
  2.  * camera.cpp  -  class for handling screen camera movement
  3.  *
  4.  * copyright (C) 2006 - 2008 by Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../core/camera.h"
  17. #include "../core/game_core.h"
  18. #include "../player/player.h"
  19. #include "../core/framerate.h"
  20. #include "../input/mouse.h"
  21. #include "../core/obj_manager.h"
  22. #include "../overworld/world_manager.h"
  23. #include "../level/level.h"
  24. #include "../overworld/overworld.h"
  25. #include "../core/sprite_manager.h"
  26.  
  27. /* *** *** *** *** *** *** *** cCamera *** *** *** *** *** *** *** *** *** *** */
  28.  
  29. cCamera :: cCamera( void )
  30. {
  31.     x = 0;
  32.     y = 0;
  33.  
  34.     x_offset = 0;
  35.     y_offset = 0;
  36.     hor_offset_speed = 0.3f;
  37.     ver_offset_speed = 0.2f;
  38.  
  39.     fixed_hor_vel = 0;
  40.  
  41.     // default camera limit
  42.     Reset_Limits();
  43. }
  44.  
  45. cCamera :: ~cCamera( void )
  46. {
  47.  
  48. }
  49.  
  50. void cCamera :: Set_Pos( float nx, float ny )
  51. {
  52.     // level mode
  53.     if( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD )
  54.     {
  55.         if( !editor_enabled )
  56.         {
  57.             // camera offset
  58.             nx += x_offset;
  59.             ny += y_offset;
  60.             
  61.             // camera limits
  62.             Update_Limit( nx, ny );
  63.         }
  64.     }
  65.  
  66.     x = nx;
  67.     y = ny;
  68.  
  69.     Update_Position();
  70. }
  71.  
  72. void cCamera :: Set_Pos_X( float nx )
  73. {
  74.     // level mode
  75.     if( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD )
  76.     {
  77.         if( !editor_enabled )
  78.         {
  79.             // camera offset
  80.             nx += x_offset;
  81.             
  82.             // camera limits
  83.             Update_Limit_X( nx );
  84.         }
  85.     }
  86.  
  87.     x = nx;
  88.  
  89.     Update_Position();
  90. }
  91.  
  92. void cCamera :: Set_Pos_Y( float ny )
  93. {
  94.     // level mode
  95.     if( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD )
  96.     {
  97.         if( !editor_enabled )
  98.         {
  99.             // camera offset
  100.             ny += y_offset;
  101.  
  102.             // camera limits
  103.             Update_Limit_Y( ny );
  104.         }
  105.     }
  106.  
  107.     y = ny;
  108.  
  109.     Update_Position();
  110. }
  111.  
  112. void cCamera :: Move( float move_x, float move_y )
  113. {
  114.     if( ( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD ) && !editor_enabled )
  115.     {
  116.         Set_Pos( x + move_x - x_offset, y + move_y - y_offset );
  117.     }
  118.     else
  119.     {
  120.         Set_Pos( x + move_x, y + move_y );
  121.     }
  122. }
  123.  
  124. bool cCamera :: Move_to_Position_Gradually( float px, float py )
  125. {
  126.     // limit to nearest possible position
  127.     float px_final = px + pActive_Camera->x_offset;
  128.     float py_final = py + pActive_Camera->y_offset;
  129.     Update_Limit( px_final, py_final );
  130.  
  131.     // check distance to new position
  132.     float distance_x = px_final - pActive_Camera->x;
  133.     float distance_y = py_final - pActive_Camera->y;
  134.     // velocity
  135.     float vel_x = ( distance_x * 0.04f ) * pFramerate->speedfactor;
  136.     float vel_y = ( distance_y * 0.04f ) * pFramerate->speedfactor;
  137.     // true if reached position
  138.     bool reached_y = 0, reached_x = 0;
  139.  
  140.     if( distance_x > 1 )
  141.     {
  142.         if( vel_x < 1 )
  143.         {
  144.             vel_x = 1;
  145.         }
  146.  
  147.         pActive_Camera->Move( vel_x, 0 );
  148.     }
  149.     else if( distance_x < -1 )
  150.     {
  151.         if( vel_x > -1 )
  152.         {
  153.             vel_x = -1;
  154.         }
  155.  
  156.         pActive_Camera->Move( vel_x, 0 );
  157.     }
  158.     // reached destination position x
  159.     else
  160.     {
  161.         reached_x = 1;
  162.     }
  163.  
  164.     if( distance_y > 1 )
  165.     {
  166.         if( vel_y < 1 )
  167.         {
  168.             vel_y = 1;
  169.         }
  170.  
  171.         pActive_Camera->Move( 0, vel_y );
  172.     }
  173.     else if( distance_y < -1 )
  174.     {
  175.         if( vel_y > -1 )
  176.         {
  177.             vel_y = -1;
  178.         }
  179.  
  180.         pActive_Camera->Move( 0, vel_y );
  181.     }
  182.     // reached destination position y
  183.     else
  184.     {
  185.         reached_y = 1;
  186.     }
  187.  
  188.     // reached position
  189.     if( reached_x && reached_y )
  190.     {
  191.         return 0;
  192.     }
  193.  
  194.     // position not reached
  195.     return 1;
  196. }
  197.  
  198. void cCamera :: Center( ObjectDirection direction /* = DIR_ALL */ )
  199. {
  200.     // Center camera on a not changing player position
  201.     if( direction == DIR_VERTICAL )
  202.     {
  203.         Set_Pos_X( Get_Center_Pos_X() );
  204.     }
  205.     else if( direction == DIR_HORIZONTAL )
  206.     {
  207.         Set_Pos_Y( Get_Center_Pos_Y() );
  208.     }
  209.     else if( direction == DIR_ALL )
  210.     {
  211.         Set_Pos( Get_Center_Pos_X(), Get_Center_Pos_Y() );
  212.     }
  213. }
  214.  
  215. float cCamera :: Get_Center_Pos_X( void )
  216. {
  217.     return pActive_Player->col_rect.x + 5 - ( game_res_w / 2 );
  218. }
  219.  
  220. float cCamera :: Get_Center_Pos_Y( void )
  221. {
  222.     return pActive_Player->col_rect.y + pActive_Player->col_rect.h - 5 - ( game_res_h / 2 );
  223. }
  224.  
  225. void cCamera :: Reset_Limits( void )
  226. {
  227.     limit_rect = GL_rect( 0, 0, 20000, -4000 );
  228. }
  229.  
  230. void cCamera :: Set_Limits( GL_rect rect )
  231. {
  232.     limit_rect = rect;
  233. }
  234.  
  235. void cCamera :: Set_Limit_X( float val )
  236. {
  237.     limit_rect.x = val;
  238. }
  239.  
  240. void cCamera :: Set_Limit_Y( float val )
  241. {
  242.     limit_rect.y = val;
  243. }
  244.  
  245. void cCamera :: Set_Limit_W( float val )
  246. {
  247.     limit_rect.w = val;
  248. }
  249.  
  250. void cCamera :: Set_Limit_H( float val )
  251. {
  252.     limit_rect.h = val;
  253. }
  254.  
  255. void cCamera :: Update_Limit( float &nx, float &ny )
  256. {
  257.     Update_Limit_X( nx );
  258.     Update_Limit_Y( ny );
  259. }
  260.  
  261. void cCamera :: Update_Limit_X( float &nx )
  262. {
  263.     // left
  264.     if( nx < limit_rect.x )
  265.     {
  266.         nx = limit_rect.x;
  267.     }
  268.     // right
  269.     else if( nx + game_res_w > limit_rect.x + limit_rect.w )
  270.     {
  271.         nx = limit_rect.x + limit_rect.w - game_res_w;
  272.     }
  273. }
  274.  
  275. void cCamera :: Update_Limit_Y( float &ny )
  276. {
  277.     // down
  278.     if( ny > limit_rect.y )
  279.     {
  280.         ny = limit_rect.x;
  281.     }
  282.     // up
  283.     else if( ny < limit_rect.y + limit_rect.h )
  284.     {
  285.         ny = limit_rect.y + limit_rect.h;
  286.     }
  287. }
  288.  
  289. void cCamera :: Update( void ) 
  290. {
  291.     // level
  292.     if( Game_Mode == MODE_LEVEL )
  293.     {
  294.         // no leveleditor mode
  295.         if( !editor_enabled )
  296.         {
  297.             // player is moving vertical
  298.             if( pPlayer->vely != 0 && ver_offset_speed > 0 )
  299.             {
  300.                 pPlayer->no_vely_counter = 0;
  301.  
  302.                 if( ( y_offset < 100 && pPlayer->vely > 0 ) || ( y_offset > -100 && pPlayer->vely < 0 ) )
  303.                 {
  304.                     y_offset += ( pPlayer->vely * ver_offset_speed ) * pFramerate->speedfactor;
  305.                 }
  306.             }
  307.             // slowly remove offset
  308.             else 
  309.             {
  310.                 pPlayer->no_vely_counter += pFramerate->speedfactor;
  311.  
  312.                 if( pPlayer->no_vely_counter > 10 && ( y_offset > 20 || y_offset < -20 ) )
  313.                 {
  314.                     y_offset += -( y_offset / 30 ) * pFramerate->speedfactor;
  315.                 }
  316.             }
  317.  
  318.             if( fixed_hor_vel )
  319.             {
  320.                 // todo : remove hackiness
  321.                 x += fixed_hor_vel * pFramerate->speedfactor;
  322.                 // check limit
  323.                 Update_Limit_X( x );
  324.                 // center one side
  325.                 Center( DIR_HORIZONTAL );
  326.  
  327.                 // scrolls to the right
  328.                 if( fixed_hor_vel > 0 )
  329.                 {
  330.                     // out of camera on the left side
  331.                     if( pPlayer->col_rect.x + pPlayer->col_rect.w < x )
  332.                     {
  333.                         pPlayer->DownGrade( 1, 1 );
  334.                     }
  335.  
  336.                 }
  337.                 // scrolls to the left
  338.                 else
  339.                 {
  340.                     // out of camera on the right side
  341.                     if( pPlayer->col_rect.x - game_res_w > x )
  342.                     {
  343.                         pPlayer->DownGrade( 1, 1 );
  344.                     }
  345.                 }
  346.             }
  347.             else
  348.             {
  349.                 // player is moving horizontal
  350.                 if( pPlayer->velx != 0 && hor_offset_speed > 0 )
  351.                 {
  352.                     pPlayer->no_velx_counter = 0;
  353.  
  354.                     if( ( x_offset < 200 && pPlayer->velx > 0 ) || ( x_offset > -200 && pPlayer->velx < 0 ) )
  355.                     {
  356.                         x_offset += ( pPlayer->velx * hor_offset_speed ) * pFramerate->speedfactor;
  357.                     }
  358.                 }
  359.                 // slowly remove offset
  360.                 else
  361.                 {
  362.                     pPlayer->no_velx_counter += pFramerate->speedfactor;
  363.  
  364.                     if( pPlayer->no_velx_counter > 10 && ( x_offset > 40 || x_offset < -40 ) )
  365.                     {
  366.                         x_offset += -( x_offset / 50 ) * pFramerate->speedfactor;
  367.                     }
  368.                 }
  369.  
  370.                 // set position
  371.                 Center();
  372.             }
  373.         }
  374.     }
  375.     // world
  376.     else if( Game_Mode == MODE_OVERWORLD )
  377.     {
  378.         // Left
  379.         if( pActive_Player->posx - x < game_res_w * 0.4f )
  380.         {
  381.             Set_Pos_X( pActive_Player->posx - game_res_w * 0.4f );
  382.         }
  383.         // Right
  384.         else if( pActive_Player->posx - x > game_res_w * 0.6f )
  385.         {
  386.             Set_Pos_X( pActive_Player->posx - game_res_w * 0.6f );
  387.         }
  388.         
  389.         // Up
  390.         if( pActive_Player->posy - y < game_res_h * 0.4f )
  391.         {
  392.             Set_Pos_Y( pActive_Player->posy - game_res_h * 0.4f );
  393.         }
  394.         // Down
  395.         else if( pActive_Player->posy - y > game_res_h * 0.6f )
  396.         {
  397.             Set_Pos_Y( pActive_Player->posy - game_res_h * 0.6f );
  398.         }
  399.     }
  400. }
  401.  
  402. void cCamera :: Update_Position( void )
  403. {
  404.     // mouse
  405.     pMouseCursor->Update_Position();
  406.  
  407.     // update player
  408.     pActive_Player->Update_Valid_Draw();
  409.     // update sprite manager
  410.     pActive_Sprite_Manager->Update_Items_Valid_Draw();
  411.  
  412.     // editor
  413.     if( editor_enabled )
  414.     {
  415.         // update settings activated object position
  416.         if( pMouseCursor->active_object )
  417.         {
  418.             pMouseCursor->active_object->Editor_Position_Update();
  419.         }
  420.     }
  421. }
  422.  
  423. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  424.  
  425.