/// <summary>
 /// Adds a GameObject to the object list.
 /// </summary>
 /// <param name="obj">GameObject to add</param>
 public void AddObject(GameObject obj)
 {
     for (int i=0;i<ObjectList.Length;i++)
         if (ObjectList[i]==null) {
             ObjectList[i]=obj;
             break;
         }
 }
 public Animation(GameObject parent,int width,int height,bool useTimer)
 {
     _texture=parent._texture;
     _textureRect=new Rectangle(0,0,_texture.Width,_texture.Height);
     _displayRect=new Rectangle(0,0,width,height);
     _cols=_texture.Width/width;
     _rows=_texture.Height/height;
     _totalFrames=_cols*_rows;
     _parent=parent;
     _currentStage=new AnimationStage(0,_totalFrames-1,true,0,false);
     _parent._srcRect=_displayRect;
     _currentStageIndex=0;
     _useTimer=useTimer;
     if (_useTimer){
         _timer=new Timer(DEFAULT_FRAME_DELAY,0,Animate,this);
         _timerIndex=Timers.Add(_timer);
     }
 }
 public Animation(GameObject parent,int width,int height)
     : this(parent,width,height,true)
 {
 }
 public void Remove()
 {
     Timers.Remove(_timerIndex);
     _parent=null;
 }
 /// <summary>
 /// Do the collide action
 /// </summary>
 /// <param name="go">GameObject that is being collided with</param>
 /// <returns>Returns true if should remove, false if not</returns>
 public virtual bool DoCollide(GameObject go)
 {
     return false;
 }
 /// <summary>
 /// Is the GameObject allowed to collide
 /// </summary>
 /// <param name="o">Query object to check</param>
 /// <returns>Returns if the objects can collide or not</returns>
 public virtual bool CanCollide(GameObject o)
 {
     return false;
 }
 private bool PixelPerfect(GameObject o1,GameObject o2)
 {
     if (o1.Rotation==0&&o2.Rotation==0)
         return PixelPerfectSimple(o1.Rect,o1.TextureData,o2.Rect,o2.TextureData);
     Matrix a2b=Matrix.CreateTranslation(-o1.Origin.X,-o1.Origin.Y,0)*
         Matrix.CreateRotationZ(o1.Rotation)*
         Matrix.CreateTranslation(o1.Position.X,o1.Position.Y,0)*
         Matrix.Invert(
             Matrix.CreateTranslation(-o2.Origin.X,-o2.Origin.Y,0)*
             Matrix.CreateRotationZ(o2.Rotation)*
             Matrix.CreateTranslation(o2.Position.X,o2.Position.Y,0)
         );
     Vector2 stepX=Vector2.TransformNormal(Vector2.UnitX,a2b);
     Vector2 stepY=Vector2.TransformNormal(Vector2.UnitY,a2b);
     Vector2 o2y=Vector2.Transform(Vector2.Zero,a2b);
     for (int y1=0;y1<o1.Rect.Height;y1++) {
         Vector2 o2pos=o2y;
         for (int x1=0;x1<o1.Rect.Width;x1++) {
             int x2=(int)Math.Round(o2pos.X);
             int y2=(int)Math.Round(o2pos.Y);
             if (x2>0&&x2<o2.Rect.Width&&y2>0&&y2<o2.Rect.Height)
                 if (o1.TextureData[x1+y1*o1.Rect.Width].A>0&&o2.TextureData[x2+y2*o2.Rect.Width].A>0)
                     return true;
             o2pos+=stepX;
         }
         o2y+=stepY;
     }
     return false;
 }