Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

bouncy.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                           bouncy.h  -  description
00003                              -------------------
00004     begin                : Tue Jun 10 2003
00005     copyright            : (C) 2003 by Tyler Montbriand
00006     email                : tsm@accesscomm.ca
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 #ifndef __BOUNCY_H__
00018 #define __BOUNCY_H__
00019 
00020 #include <spritelib/sprite.h>
00021 #include "screen.h"
00028 
00035 #define BOUNCY_VELOCITY 300
00036 
00038 inline Sfxp v1_final(int m1, int m2, Sfxp v1, Sfxp v2)
00039 {
00040   return(((v1*(m1-m2))+(v2*2*m2))/(m1+m2));
00041 }
00042 
00044 inline Sfxp v2_final(int m1, int m2, Sfxp v1, Sfxp v2)
00045 {
00046   return(((v1*2*m1)+ (v2*(m2-m1)))/(m1+m2));
00047 }
00048 
00050 inline void ElasticCollide2(Sprite *spr1, Sprite *spr2)
00051 {
00052   int m1=1, m2=1;
00053   SfxpCoord v1f,v2f;
00054 
00055   /* Calculate angle between objects  */
00056   Sfxp a=((spr2->Pos())-(spr1->Pos())).Trajectory();
00057 
00058   /* Calculate initial velocities of objects */
00059   Sfxp v1=spr1->Vel().Magnitude();
00060   /* Velocity is relative */
00061   Sfxp v2=spr2->Vel().Magnitude()-v1;
00062 
00063   /* Calculate final velocities */
00064   Sfxp v1f_=v1_final(m1,m2,v1,v2);
00065   Sfxp v2f_=v2_final(m1,m2,v1,v2);
00066 
00067   /* Put the velocities back in terms of X and Y */
00068   v1f.Vector(v1f_,a);
00069   v2f.Vector(v2f_,a);
00070   
00071   /* Set the new velocities */
00072   spr1->SetVel(v1f);
00073   spr2->SetVel(v2f);      
00074 }
00075 
00077 inline void MoveApart(Sprite *spr1, Sprite *spr2)
00078 {
00079   if(spr1->CanCollide(spr2))
00080   {  
00081     bitmask *b1=spr1->GetBitmask();
00082     Sfxp x1=spr1->Xfxp();
00083     Sfxp y1=spr1->Yfxp();
00084 
00085     bitmask *b2=spr2->GetBitmask();
00086     Sfxp x2=spr2->Xfxp();
00087     Sfxp y2=spr2->Yfxp();
00088 
00089     Sfxp dx=x2-x1;
00090     Sfxp dy=y2-y1;
00091 
00092     while(bitmask_overlap(b1,b2,FROM_SFXP(dx),FROM_SFXP(dy)))
00093     {
00094       x1-=(dx/20);
00095       y1-=(dy/20);
00096 
00097       x2+=(dx/20);
00098       y2+=(dy/20);
00099 
00100       dx=x2-x1;
00101       dy=y2-y1;                  
00102     }
00103     spr1->MoveTo(x1,y1);
00104     spr2->MoveTo(x2,y2);
00105   }   
00106 }
00107 
00108 
00118 class Bouncy:public Sprite
00119 {
00120 public:
00122   virtual void OnCollide(const Sprite *spr, ColType index)
00123   {
00124     MoveApart(this,(Sprite *)spr);
00125     ElasticCollide2(this,(Sprite *)spr);
00126     AdvanceFrame();
00127   }
00128 
00130   Bouncy():Sprite()
00131   {
00132     SetFlags(SPRITE_DELETEABLE);
00133     MoveTo(TO_SFXP(rand()%SCREEN_W),TO_SFXP(rand()%SCREEN_H));
00134     vel.Vector(BOUNCY_VELOCITY,DEG_TO_AFXP(rand()%360));
00135   }
00136 
00138   virtual void Update(Sint32 dtick)
00139   {
00140     if(Xfxp()<XMin())
00141     {
00142       pos.SetFxp(XMin(),Yfxp());
00143       ReverseXVelocity();
00144       AdvanceFrame();
00145     }
00146     else if(Xfxp()>=XMax())
00147     {
00148       pos.SetFxp(XMax(),Yfxp());      
00149       ReverseXVelocity();
00150       AdvanceFrame();      
00151     }
00152 
00153     if(Yfxp()<YMin())
00154     {
00155       pos.SetFxp(Xfxp(),YMin());
00156       ReverseYVelocity();
00157       AdvanceFrame();      
00158     }
00159     else if(Yfxp()>YMax())
00160     {
00161       pos.SetFxp(Xfxp(),YMax());
00162       ReverseYVelocity();
00163       AdvanceFrame();      
00164     }
00165 
00166     Sprite::Update(dtick);    
00167   }
00168   
00169 protected:
00171   inline Sfxp XMin()  const { return(0);  }
00173   inline Sfxp YMin()  const { return(0);  }
00175   inline Sfxp XMax()  const { return(TO_SFXP(SCREEN_W)-TO_SFXP(frames.w));  }
00177   inline Sfxp YMax()  const { return(TO_SFXP(SCREEN_H)-TO_SFXP(frames.h));  }
00178 
00180   inline void AdvanceFrame()
00181   {
00182     frame+=TO_SFXP(1);
00183     frame%=TO_SFXP(frames.x*frames.y);
00184     CalcFrame();
00185   }
00186 };
00187 
00189 
00190 #endif/*__BOUNCY_H__*/

Generated on Sat Oct 11 13:19:25 2003 for Spritelib by doxygen 1.3.4