Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

rect_collider.cxx

Go to the documentation of this file.
00001 //  $Id: rect_collider.cxx,v 1.8 2003/01/11 01:35:11 grumbel Exp $
00002 //
00003 //  Construo - A wire-frame construction gamee
00004 //  Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include <math.h>
00021 #include "colors.hxx"
00022 #include "particle_factory.hxx"
00023 #include "controller.hxx"
00024 #include "rect_collider.hxx"
00025 #include "construo_error.hxx"
00026 
00027 Collider*
00028 RectCollider::duplicate() const
00029 {
00030   return new RectCollider(x1, y1, x2, y2);
00031 }
00032 
00033 RectCollider::RectCollider (lisp_object_t* cursor)
00034 {
00035   Vector2d pos1, pos2;
00036   
00037   LispReader reader(cursor);
00038   if (reader.read_vector("pos1", &pos1) == false
00039       || reader.read_vector("pos2", &pos2) == false)
00040     {
00041       throw ConstruoError("RectCollider entry incomplete");
00042     }
00043 
00044   x1 = pos1.x;
00045   y1 = pos1.y;
00046   x2 = pos2.x;
00047   y2 = pos2.y;
00048 }
00049 
00050 RectCollider::RectCollider (float x1_, float y1_, float x2_, float y2_)
00051   : x1 (x1_), y1 (y1_), x2 (x2_), y2 (y2_)
00052 {
00053 }
00054 
00055 bool
00056 RectCollider::is_at (const Vector2d& pos)
00057 {
00058   return (x1 <= pos.x && x2 > pos.x
00059           && y1 <= pos.y && y2 > pos.y);
00060 }
00061 
00062 Vector2d
00063 RectCollider::get_pos()
00064 {
00065   return Vector2d ((x1 + x2)/2.0f,
00066                    (y1 + y2)/2.0f); 
00067 }
00068 
00069 void
00070 RectCollider::set_pos(const Vector2d& pos)
00071 {
00072   Vector2d center = get_pos();
00073   x1 = x1 - center.x + pos.x;
00074   x2 = x2 - center.x + pos.x;
00075   y1 = y1 - center.y + pos.y;
00076   y2 = y2 - center.y + pos.y;
00077 }
00078 
00079 void
00080 RectCollider::bounce ()
00081 {
00082   ParticleFactory* particle_mgr = Controller::instance()->get_world()->get_particle_mgr();
00083 
00084   float damp = 0.8;
00085   for (ParticleFactory::ParticleIter i = particle_mgr->begin(); i != particle_mgr->end (); ++i)
00086     {
00087       Vector2d& pos = (*i)->pos;
00088       Vector2d& velocity = (*i)->velocity;
00089 
00090       if (pos.x > x1 && pos.x < x2
00091           && pos.y > y1 && pos.y < y2)
00092         {
00093           float left_dist  = pos.x - x1;
00094           float right_dist = x2 - pos.x;
00095 
00096           float top_dist    = pos.y - y1;
00097           float bottom_dist = y2 - pos.y;
00098 
00099           if (left_dist < right_dist
00100               && left_dist < top_dist 
00101               && left_dist < bottom_dist)
00102             {
00103               velocity.x = -fabs(velocity.x);
00104               pos.x = x1;
00105             }
00106           else if (right_dist < left_dist
00107                    && right_dist < top_dist 
00108                    && right_dist < bottom_dist)
00109             {
00110               velocity.x = fabs(velocity.x);
00111               pos.x = x2;
00112             }
00113           else if (top_dist < left_dist
00114                    && top_dist < right_dist
00115                    && top_dist < bottom_dist)
00116             {
00117               velocity.y = -fabs(velocity.y);
00118               pos.y = y1;
00119             }
00120           else
00121             {
00122               velocity.y = fabs(velocity.y);
00123               pos.y = y2;
00124             }
00125           velocity *= damp;
00126         }
00127     }
00128 }
00129 
00130 void
00131 RectCollider::draw (GraphicContext* gc)
00132 {
00133   //std::cout << "Drawing collider" << std::endl;
00134   gc->draw_fill_rect (x1, y1, x2, y2, Colors::rect_collider_bg);
00135   gc->draw_rect (x1, y1, x2, y2, Colors::rect_collider_fg);
00136 }
00137 
00138 void
00139 RectCollider::draw_highlight (GraphicContext* gc)
00140 {
00141   //gc->draw_fill_rect (x1, y1, x2, y2, Colors::rect_collider_bg);
00142   gc->draw_rect (x1, y1, x2, y2, Colors::selection_rect);
00143 }
00144 
00145 lisp_object_t*
00146 RectCollider::serialize()
00147 {
00148   LispWriter obj ("rect");
00149   obj.write_vector ("pos1", Vector2d(x1, y1));
00150   obj.write_vector ("pos2", Vector2d(x2, y2));
00151   return obj.create_lisp ();
00152 }
00153 
00154 /* EOF */

Generated on Thu Jul 24 10:24:30 2003 for Construo by doxygen1.3-rc3