00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00056 Sfxp a=((spr2->Pos())-(spr1->Pos())).Trajectory();
00057
00058
00059 Sfxp v1=spr1->Vel().Magnitude();
00060
00061 Sfxp v2=spr2->Vel().Magnitude()-v1;
00062
00063
00064 Sfxp v1f_=v1_final(m1,m2,v1,v2);
00065 Sfxp v2f_=v2_final(m1,m2,v1,v2);
00066
00067
00068 v1f.Vector(v1f_,a);
00069 v2f.Vector(v2f_,a);
00070
00071
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