src/map/water.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Refresh de l'eau pouvant apparaitre en bas du terrain.
00020  *****************************************************************************/
00021 
00022 #include "water.h"
00023 #include <SDL.h>
00024 #include "camera.h"
00025 #include "map.h"
00026 #include "maps_list.h"
00027 #include "../game/time.h"
00028 #include "../include/app.h"
00029 #include "../interface/interface.h"
00030 #include "../tool/resource_manager.h"
00031 
00032 const uint WAVE_TIME=10;
00033 const uint WAVE_STEP=1;
00034 const uint WAVE_HEIGHT = 5;
00035 
00036 const uint GO_UP_TIME = 1; // min
00037 const uint GO_UP_STEP = 15; // pixels
00038 const uint GO_UP_OSCILLATION_TIME = 30; // seconds
00039 const uint GO_UP_OSCILLATION_NBR = 30; // amplitude
00040 const float t = (GO_UP_OSCILLATION_TIME*1000.0);
00041 const float a = GO_UP_STEP/t;
00042 const float b = 1.0;
00043 
00044 void Water::Init(){
00045    Profile *res = resource_manager.LoadXMLProfile( "graphism.xml", false);
00046    surface = resource_manager.LoadImage(res, "gfx/water");
00047    surface.SetAlpha(0, 0);
00048    pattern.NewSurface( Point2i(180, surface.GetHeight() + 40), SDL_SWSURFACE|SDL_SRCALPHA, true);
00049    shift1 = 0;
00050    resource_manager.UnLoadXMLProfile(res);
00051 }
00052 
00053 void Water::Reset(){
00054   actif = ActiveMap().UseWater();
00055   if(!actif) return;
00056   Init();
00057   hauteur_eau = WATER_INITIAL_HEIGHT;
00058   vague = 0;
00059   temps_eau = 0;
00060   temps_montee = GO_UP_TIME * 60 * 1000;
00061   height.clear();
00062   height.assign(180, 0);
00063   Refresh(); // Calculate first height position
00064 }
00065 
00066 void Water::Free(){
00067   if(!actif)
00068     return;
00069   surface.Free();
00070   pattern.Free();
00071   height.clear();
00072 }
00073 
00074 void Water::Refresh(){
00075   if (!actif)
00076     return;
00077 
00078   height_mvt = 0;
00079 
00081   Time * global_time = Time::GetInstance();
00082   if (temps_montee < global_time->Read())
00083   {
00084     if(temps_montee + GO_UP_OSCILLATION_TIME * 1000 > global_time->Read()){
00085       uint dt=global_time->Read()- temps_montee;
00086       height_mvt = GO_UP_STEP + (uint)(((float)GO_UP_STEP * sin(((float)(dt*(GO_UP_OSCILLATION_NBR-0.25))/GO_UP_OSCILLATION_TIME/1000.0)*2*M_PI))/(a*dt+b));
00087     }
00088     else{
00089       temps_montee += GO_UP_TIME * 60 * 1000;
00090       hauteur_eau += GO_UP_STEP;
00091     }
00092   }
00093 
00095   // on rempli le sol avec de l'eau
00096   if (WAVE_TIME < (global_time->Read() - temps_eau))
00097   {
00098     temps_eau = global_time->Read();
00099     vague += WAVE_STEP;
00100     if (surface.GetWidth() <= vague)
00101                 vague=0;
00102   }
00103 
00104   int x = -surface.GetWidth() + vague;
00105   int y = world.GetHeight()-(hauteur_eau + height_mvt);
00106 
00107   double decree = (double) 2*M_PI/360;
00108 
00109   double angle1 = 0;
00110   double angle2 = shift1;
00111   do
00112   {
00113     int offset=0;
00114     double y_pos = y + sin(angle1)*10 + sin(angle2)*10;
00115 
00116     if (0<=x+offset)
00117          height.at(x+offset) = (int)y_pos;
00118 
00119     angle1 += 2*decree;
00120     angle2 += 4*decree;
00121     x++;
00122   } while ((uint)x < 180);
00123 
00124   shift1 += 4*decree;
00125 }
00126 
00127 void Water::Draw(){
00128   if (!actif)
00129     return;
00130 
00131   // Compute 1 pattern:
00132   pattern.SetAlpha( 0, 0);
00133   pattern.Fill(0x00000000);
00134 
00135   int y0 = world.GetHeight()-(hauteur_eau + height_mvt)-20;
00136 
00137   for(uint x=0; x<180; x++){
00138     Point2i dst(x, height.at(x) - y0);
00139     pattern.Blit(surface, dst);
00140   }
00141   pattern.SetAlpha(SDL_SRCALPHA, 0);
00142 
00143   int x0 = camera.GetPosition().x;
00144   while(x0<0)
00145     x0+=180;
00146   while(x0>180)
00147     x0-=180;
00148 
00149   for(int x=camera.GetPosition().x-x0; x<camera.GetPosition().x+camera.GetSize().x; x+=180)
00150     for(int y=y0; y<(int)camera.GetPosition().y+(int)camera.GetSize().y; y+=surface.GetSize().y)
00151       AbsoluteDraw(pattern, Point2i(x, y));
00152 }
00153 
00154 int Water::GetHeight(int x){
00155   if (IsActive()){
00156     while(x<0)
00157       x += 180;
00158     while(x>=180)
00159       x -= 180;
00160     return height.at(x);
00161   }
00162   else
00163     return world.GetHeight();
00164 }
00165 
00166 bool Water::IsActive(){
00167   return actif;
00168 }
00169 

Generated on Mon Jan 1 13:10:58 2007 for Wormux by  doxygen 1.4.7