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 * Arrow on top of the active character 00020 *****************************************************************************/ 00021 00022 #include "cursor.h" 00023 #include <SDL.h> 00024 #include "../game/game_loop.h" 00025 #include "../game/time.h" 00026 #include "../graphic/effects.h" 00027 #include "../include/app.h" 00028 #include "../map/camera.h" 00029 #include "../object/physical_obj.h" 00030 #include "../team/teams_list.h" // ActiveCharacter() 00031 #include "../tool/point.h" 00032 #include "../tool/resource_manager.h" 00033 00034 const uint show_hide_time = 200; //time to show and hide the arrow 00035 const uint y_min = 20; //number of pixels between the bottom of the arrow and the top of the sprite 00036 const uint y_max = 90; //number of pixels between the bottom of the arrow and the top of the sprite 00037 //when the arrow is at the top of its movement 00038 const uint rebound_time = 1000; //Duration of a full rebound 00039 00040 CharacterCursor * CharacterCursor::singleton = NULL; 00041 00042 CharacterCursor * CharacterCursor::GetInstance() { 00043 if (singleton == NULL) { 00044 singleton = new CharacterCursor(); 00045 } 00046 return singleton; 00047 } 00048 00049 CharacterCursor::CharacterCursor() 00050 { 00051 actif = false; 00052 want_hide = false; 00053 time_begin_anim = 0; 00054 last_update = 0; 00055 image = NULL; 00056 dy = 0; 00057 00058 Profile *res = resource_manager.LoadXMLProfile( "graphism.xml", false); 00059 image = resource_manager.LoadSprite( res, "gfx/curseur"); 00060 resource_manager.UnLoadXMLProfile( res); 00061 } 00062 00063 CharacterCursor::~CharacterCursor() 00064 { 00065 if(image) delete image; 00066 } 00067 00068 // Dessine le curseur 00069 void CharacterCursor::Draw() 00070 { 00071 if (!IsDisplayed()) return; 00072 if (obj_designe == NULL) return; 00073 if (obj_designe -> IsGhost()) return; 00074 00075 // Dessine le curseur autour du ver 00076 Point2i centre = obj_designe->GetCenter(); 00077 uint x = centre.x - image->GetWidth()/2; 00078 uint y = obj_designe->GetY() - image->GetHeight() - y_min; 00079 00080 image->Draw( Point2i(x, y+dy) ); 00081 } 00082 00083 void CharacterCursor::Refresh() 00084 { 00085 if (!IsDisplayed()) return; 00086 00087 image->Scale(1.0, 1.0); 00088 00089 Time * global_time = Time::GetInstance(); 00090 00091 //The arrow is appearing: 00092 if( actif && global_time->Read() < time_begin_anim + show_hide_time ) 00093 { 00094 dy = (int)((camera.GetPosition().y - ActiveCharacter().GetY()) * (1.0 - (global_time->Read() - time_begin_anim) / (float)show_hide_time)); 00095 return; 00096 } 00097 00098 //If we want to hide the cursor, we have to wait the end of the current rebound to make the cursor disappear 00099 if(want_hide) 00100 { 00101 if( ((global_time->Read() - (time_begin_anim + show_hide_time)) % rebound_time < rebound_time / 2) 00102 && ((last_update - (time_begin_anim + show_hide_time)) % rebound_time > rebound_time / 2)) 00103 { 00104 //We are at the end of the rebound 00105 actif = false; 00106 time_begin_anim = global_time->Read(); 00107 } 00108 } 00109 00110 //The arrow is disappearing: 00111 if( !actif && global_time->Read() < time_begin_anim + show_hide_time ) 00112 { 00113 dy = (int)((camera.GetPosition().y - ActiveCharacter().GetY()) * ((global_time->Read() - time_begin_anim) / (float)show_hide_time)); 00114 return; 00115 } 00116 00117 //The arrow is rebounding: 00118 Rebound(image, dy, time_begin_anim + show_hide_time, rebound_time, -y_max - (-y_min)); 00119 00120 last_update = global_time->Read(); 00121 } 00122 00123 // Hide the cursor 00124 void CharacterCursor::Hide() 00125 { 00126 if(!actif) return; 00127 want_hide = true; 00128 } 00129 00130 void CharacterCursor::Reset() 00131 { 00132 actif = false; 00133 want_hide = false; 00134 obj_designe = NULL; 00135 } 00136 00137 void CharacterCursor::FollowActiveCharacter() 00138 { 00139 PointeObj(&ActiveCharacter()); 00140 } 00141 00142 void CharacterCursor::PointeObj (PhysicalObj *obj) 00143 { 00144 if(actif && obj==obj_designe) 00145 return; 00146 obj_designe = obj; 00147 actif = true; 00148 want_hide = false; 00149 time_begin_anim = Time::GetInstance()->Read(); 00150 } 00151 00152 // Are we displaying the arrow on the screen ? 00153 bool CharacterCursor::IsDisplayed() const { 00154 return actif || (Time::GetInstance()->Read() < time_begin_anim + show_hide_time); 00155 }