src/graphic/effects.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  *  Graphic effects on sprite
00020  *****************************************************************************/
00021 
00022 #include <SDL.h>
00023 #include <SDL_video.h>
00024 #include <SDL_image.h>
00025 #include <math.h>
00026 #include "sprite.h"
00027 #include "video.h"
00028 #include "../game/time.h"
00029 
00030 //Make the sdl_surface 'a', do a wave of 'nbr_frames', and last 'duration' milliseconds.
00031 //wave_amp is the amplitude of the wave on the left and the right side of the sprite
00032 //wave_per is the number of periode of the wave when it is waved at the maximum
00033 //used on the skin during teleportation
00034 Sprite* WaveSurface(Surface &a, unsigned int nbr_frames, unsigned int duration, float wave_amp, float wave_per){
00035         Sprite* sprite = new Sprite;
00036         Point2i newSize = a.GetSize() + Point2i(2 * (int)wave_amp, 0);
00037         
00038     sprite->SetSize(newSize);
00039         for(unsigned int f=0; f < nbr_frames; f++){
00040                 Surface b(newSize, SDL_SWSURFACE|SDL_SRCALPHA );
00041                 b.Fill(0x00000000);
00042                 b.SetAlpha(SDL_SRCALPHA, 0);
00043                 a.Lock();
00044                 b.Lock();
00045                 for(int x = 0; x < a.GetWidth(); x++){
00046                         for(int y = 0; y < a.GetHeight(); y++){
00047                                 Uint32 col = a.GetPixel(x, y);
00048                                 Uint8 r, g, bl, al;
00049                                 a.GetRGBA(col, r, g, bl, al);
00050                                 col = b.MapRGBA(r, g, bl, al);
00051 
00052                                 float t = (float)nbr_frames * sin(M_PI*(float)f/(float)nbr_frames);
00053                                 unsigned int wave_x = (unsigned int)(x+(wave_amp*(1+sin(((float)t*wave_per*2.0*M_PI/(float)nbr_frames)*(float)y*2.0*M_PI/(float)a.GetHeight()))));
00054                                 b.PutPixel(wave_x, y, col);
00055                         }
00056                 }
00057                 a.Unlock();
00058                 b.Unlock();     
00059 
00060                 sprite->AddFrame(b, duration / nbr_frames);
00061         }
00062         return sprite;
00063 }
00064 
00065 // Modify the scale of 'spr' to make it deform as if it was rebounding
00066 // dy return the offset that should be used to display the sprite at the good position
00067 // t0 time when we began to rebound
00068 // per time to do one full rebound
00069 // dy_max offset max of the rebound ( 0 <= dy <= dy_max )
00070 void Rebound(Sprite* spr, int &dy, uint t0, uint per, int dy_max)
00071 {
00072   float scale_x, scale_y;
00073   int spr_w, spr_h;
00074   uint dt = (Time::GetInstance()->Read() - t0) % per;
00075 
00076   spr->Scale(1.0,1.0);
00077   spr_w = spr->GetWidth();
00078   spr_h = spr->GetHeight();
00079   dy = 0;
00080 
00081   //sprite at bottom:
00082   if( dt < per / 4 )
00083   {
00084     float dt2 = ((per / 4) - dt) / ((float)per / 4.0);    
00085     scale_y =        2.0*dt2*dt2 - 2.0*dt2 + 1.0;
00086     scale_x = 2.0 - (2.0*dt2*dt2 - 2.0*dt2 + 1.0);
00087     dy = 0;
00088     spr->Scale(scale_x,scale_y);
00089     return;
00090   }
00091 
00092   dt -= per/4;
00093   float dt2 = ((3*per/4)-dt)/(3.0*per/4.0);
00094   dy += (int)((-4.0*dt2*dt2 + 4.0*dt2) * dy_max);
00095 }
00096 
00097 //Returns value of y_stretch and y, to be used on an object, to make him do
00098 // a gelatine like shaking.
00099 // stretch_y: number of pixel to stretch the img
00100 // t0 : time of begining of the effect in milliseconds
00101 // amp: amplitude of the oscillation in pixel
00102 // dur: duration of the oscillation in milliseconds
00103 // per: number of oscillations
00104 void Gelatine (int &y, int &stretch_y, uint t0, uint amp, uint dur, uint per)
00105 {
00106   uint dt = Time::GetInstance()->Read() - t0;
00107   if(dt >= dur)
00108   {
00109     y = 0;
00110     stretch_y = 0;
00111     return;
00112   }
00113 
00114   //Amplitude decrease linearly with time
00115   amp = amp * (dur - dt) / dur;
00116 
00117   //Scale
00118   stretch_y = (int)(sin((float)per * (float)dt * 2.0 * M_PI / (float)dur) * (float)amp);
00119 
00120   //Offset
00121   if(stretch_y < 0.0)
00122   {
00123     y = stretch_y;
00124     stretch_y = -stretch_y;
00125   }
00126   else
00127   {
00128     y = 0;
00129   }
00130 }
00131 

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