C:/Documents and Settings/jegan/Desktop/projectX/Person.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 
00003 #include "Person.h"
00004 #include "List.h"
00005 #include "CollisionHandler.h"
00006 #include "CommandManager.h"
00007 #include "Command.h"
00008 #include "glfuncs.h"
00009 #include "bullet.h"
00010 #include "level.h"
00011 #include "ShowOneSprite.h"
00012 #include "Screen.h"
00013 #include "Weapon.h"
00014 
00015 
00016 using namespace std;
00017 
00018 /*Person::Person()
00019 :_xVelocity(0),_yVelocity(0),_maxVel(850),_jumping(true), _wallJump(0), 
00020 _gravity(3), _accel(40), _groundDrag(-1.2), _airDrag(-0.3),
00021 _xDirection( LEFT ),
00022 _yDirection( MIDDLE )
00023 {
00024         // FIXME  make this general
00025         _id = "goudy";
00026         _type = PERSON;
00027 
00028         _collidable = true;
00029 
00030         // FIXME  these should be set based on the levels spawn point
00031         _box.x = 400;
00032         _box.y = 400;
00033 
00034         // FIXME this filename should be set based on the type of person it is eventually
00035         _sprite = Sprite::loadSprite("stickman.png");
00036         _box.w = _sprite->width();
00037         _box.h = _sprite->height();
00038 
00039         _previousX = _box.x;
00040         _previousY = _box.y;
00041 
00042 //      CollisionHandler::instance()->registerObject(this);
00043 }*/
00044 
00045 Person::Person(List* personInfo, int x, int y)
00046 :Object(personInfo,x,y),
00047  _xVelocity(0),
00048  _yVelocity(0),
00049  _maxXVel(850),
00050  _invincible(false),
00051 // _jumping(true),
00052 
00053  _maxYVel(800),
00054  _maxFallRate(700),
00055 
00056  _crouching( false ),
00057 // _wallJump(0), 
00058  _gravity(2), 
00059  _accel(40),
00060  _airAccel(20),
00061  _groundDrag(-2.5), 
00062  _airDrag(-0.3),
00063  _xDirection( LEFT ),
00064  _yDirection( MIDDLE ), 
00065  _state( JUMPING ), 
00066  _health(2), 
00067  _jumpTimer(0),
00068  _maxJumpTime(15),
00069  _dropItem(""),
00070  _primaryWeapon(NULL),
00071  _punchWeapon(NULL),
00072  _punchTimer(0),
00073  _wallFallTime(0)
00074 {
00075         _collidable = true;
00076 
00077         load(personInfo);
00078 
00079         _previousX = _box.x;
00080         _previousY = _box.y;
00081 }
00082 
00083 void Person::load(List *personInfo, bool fromConstructor)
00084 {
00085         if(!fromConstructor)
00086                 Object::load(personInfo,fromConstructor);
00087 
00088         while( !personInfo->empty())
00089         {
00090                 List * current = personInfo->firstList();
00091                 
00092                 if(current->firstString() == "maxXVel")
00093                         _maxXVel = current->rest()->firstInt();
00094 
00095                 if(current->firstString() == "maxYVel")
00096                         _maxYVel = current->rest()->firstInt();
00097 
00098                 if(current->firstString() == "maxFallRate")
00099                         _maxFallRate = current->rest()->firstInt();
00100                 
00101                 if(current->firstString() == "gravity")
00102                         _gravity = current->rest()->firstInt();
00103 
00104                 if(current->firstString() == "accel")
00105                         _accel = current->rest()->firstInt();
00106 
00107                 if(current->firstString() == "airAccel")
00108                         _airAccel = current->rest()->firstInt();
00109 
00110                 if(current->firstString() == "groundDrag")
00111                         _groundDrag = current->rest()->firstDouble();
00112 
00113                 if(current->firstString() == "airDrag")
00114                         _airDrag = current->rest()->firstDouble();
00115 
00116                 if(current->firstString () == "sprite")
00117                         _sprite = (ShowOneSprite *)Sprite::loadSprite( current->rest()->firstString() );
00118 
00119                 if(current->firstString () == "maxJumpTime")
00120                         _maxJumpTime = current->rest()->firstInt();
00121                 
00122                 if(current->firstString () == "health")
00123                         _health = current->rest()->firstInt();
00124 
00125                 if(current->firstString () == "dropItem")
00126                         _dropItem = current->rest()->firstString();
00127 
00128                 if(current->firstString () == "primaryWeapon")
00129                         _primaryWeapon = new Weapon(current->rest()->firstString(),this);
00130                 
00131                 if(current->firstString () == "punchWeapon")
00132                         _punchWeapon = new WeaponPunch(current->rest()->firstString(),this);
00133 
00134                 if(current->firstString () == "dX")
00135                         _box.x += current->rest()->firstInt();
00136                 if(current->firstString () == "dY")
00137                         _box.y += current->rest()->firstInt();
00138 
00139                 personInfo = personInfo ->rest();
00140         }
00141 
00142 
00143 
00144         _box.w = _sprite->box().w;
00145         _box.h = _sprite->box().h;
00146 
00147 }
00148 
00149 Person::~Person()
00150 {
00151         if(_primaryWeapon)
00152                 delete _primaryWeapon;
00153         if(_punchWeapon)
00154                 delete _punchWeapon;
00155 }
00156 
00157 Object *Person::copy()
00158 {
00159         Person *copy = new Person(*this);
00160         copy->_primaryWeapon = _primaryWeapon->copy(copy);
00161         return copy;
00162 }
00163 
00164 void Person::setPos(int x, int y)
00165 {
00166         Object::setPos(x,y);
00167         _previousX = x;
00168         _previousY = y;
00169 }
00170 
00171 void Person::collide( Object* o )
00172 {
00173         if(     (o->getType() == TILE)|| (o->getType() == DOOR) ||
00174                 ((_type == PLAYER)&&(o->getType() == ENEMY ))||
00175                 ((_type == ENEMY)&&(o->getType() == PLAYER ))
00176                 )
00177         {
00178                 int x,y;
00179                 if( _previousX != _box.x){
00180 
00181                         glfuncs::intersectX(o->getBox(),_box,&x);
00182 
00183                         //Stairs/ramps special case
00184                         //if we moved our box up by tileHeight, and we don't hit anything
00185                         //then we're on stairs
00186                         if( _type == PLAYER && 
00187                                 !touchingAbove(Level::tileHeight) && 
00188                                 touchingAbove(Level::tileHeight-1) )
00189                         {
00190                                 _box.y-=Level::tileHeight;
00191                                 _previousY -= Level::tileHeight;
00192                         }
00193                         else
00194                         {
00195                                 _box.x += x;
00196                                 _xVelocity = 0;
00197                         }
00198                 }
00199                 if( _previousY != _box.y){
00200 
00201                         glfuncs::intersectY(o->getBox(),_box,&y);
00202                         _box.y += y;
00203                         _yVelocity = 0;
00204                 }
00205         }
00206 }
00207 
00208 void Person::draw()
00209 {
00210         ShowOneSprite* s = (ShowOneSprite*)_sprite;
00211         s->setDirection( _xDirection );
00212         
00213         switch( _state )
00214         {
00215         case STANDING:
00216                 s->show( 0 );
00217                 break;
00218         case RUNNING:
00219                 s->show( 1 );
00220                 break;
00221         case JUMPING:
00222                 s->show( 2 );
00223                 break;
00224         case FALLING:
00225                 s->show( 3 );
00226                 break;
00227         case WALLFALLING:
00228                 s->show( 4 );
00229                 break;
00230         case CROUCHING:
00231                 s->show( 5 );
00232                 break;
00233         case PUNCHING:
00234                 s->show( 6 );
00235                 break;
00236         case DEAD:
00237                 s->show( 7 );
00238                 break;
00239         default:
00240                 s->show( 0 );
00241                 break;
00242         }
00243         s->draw(_box.x,_box.y);
00244 }
00245 
00246 void Person::update()
00247 {
00248         _sprite->update();
00249 
00250         if(_primaryWeapon)
00251                 _primaryWeapon->update();
00252         if(_punchWeapon)
00253                 _punchWeapon->update();
00254 
00255         //If you had the chance to walljump, but moved away from the wall, you're now just falling
00256         /*if((_wallJump * _xVelocity) > 0)
00257         {
00258                 _wallJump = 0;
00259                 _jumping = true;
00260         }*/
00261 
00262         //if(_yVelocity > 0)
00263         //{
00264         //      //you are falling, you shouldn't be allowed to jump until you hit something
00265         //      _jumping = true;
00266         //}
00267         
00268         _box.x += (_xVelocity/Screen::FRAMERATE);
00269         CollisionHandler::instance()->checkCollision(this);
00270         _previousX = _box.x;
00271 
00272         
00273         _box.y += (_yVelocity/Screen::FRAMERATE);
00274         CollisionHandler::instance()->checkCollision(this);
00275         _previousY = _box.y;
00276 
00277         //A little bit of drag force
00278         if(_xVelocity != 0)
00279         {
00280                 if(!touchingBelow())
00281                         incrVelocity((_xVelocity/abs(_xVelocity)) * _airDrag * 1000/Screen::FRAMERATE, 0);
00282                 else
00283                         incrVelocity((_xVelocity/abs(_xVelocity)) * _groundDrag * 1000/Screen::FRAMERATE, 0);
00284         }
00285         //_yVelocity -= _yVelocity *0.3;
00286 
00287         // breakVel is the least amount of velocity the person can have 
00288         // before moving at least 1 pixel
00289         int breakVel = Screen::FRAMERATE;
00290         if(_state !=DEAD){
00291                 if(_state == PUNCHING && _punchTimer > 0)
00292                 {
00293                         _punchTimer--;
00294                 }
00295                 else if( _punchTimer == 0)
00296                 {
00297                         if( abs(_yVelocity) < breakVel )
00298                         {
00299                                 if( _state != JUMPING )
00300                                         _state = STANDING;
00301                         } 
00302                         if( _yVelocity < -breakVel )
00303                         {
00304                                 _state = JUMPING;
00305                         } else if(_crouching)
00306                         {
00307                                 _state = CROUCHING;
00308                         } else if( _yVelocity > breakVel )
00309                         {
00310                                 _state = FALLING;
00311                                 if(touchingLeft()||touchingRight())
00312                                 {
00313                                         //FIXME ?
00314                                         //MAJICK NUMBER
00315                                         if(_wallFallTime > 7)           
00316                                                 _state = WALLFALLING;
00317                                         _wallFallTime++;
00318                                 }
00319                         } else if(abs(_xVelocity) > breakVel)
00320                         {
00321                                 _state = RUNNING;
00322                         }
00323 
00324                         //FIXME ?
00325                         //MAJICK NUMBER
00326                         if(_state != WALLFALLING && _wallFallTime > 8)
00327                                 _wallFallTime = 0;
00328                 }
00329         }
00330 
00331         incrVelocity(0,_gravity * 1000/Screen::FRAMERATE);
00332 }
00333 
00334 void Person::incrVelocity(int xVel, int yVel)
00335 {
00336         if(abs(_xVelocity + xVel) < _maxXVel)
00337                 _xVelocity += xVel;
00338         else
00339                 _xVelocity < 0 ? _xVelocity = -_maxXVel : _xVelocity = _maxXVel;
00340 
00341 
00342         if(abs(_yVelocity + yVel) < _maxFallRate)
00343                 _yVelocity += yVel;
00344         else
00345                 _yVelocity < 0 ? _yVelocity = -_maxFallRate : _yVelocity = _maxFallRate; 
00346 }
00347 
00348 int Person::getAccel()
00349 {
00350         if(!touchingBelow())
00351                 return _airAccel;
00352 
00353         return _accel;
00354 }
00355 
00356 void Person::jump(xDirection xDir)
00357 {
00358         //Don't allow player or scripts to jump if they are already jumping.
00359         /*if(!_jumping && _jumpReset)
00360         {
00361                 //If you're jumping straight off the ground
00362                 if(_wallJump == 0)
00363                 {
00364                         
00365                 }
00366                 //If you're jumping off of some wall
00367                 else if(_wallJump/abs(_wallJump) == xDir)
00368                 {
00369                         _xVelocity = _wallJump * .8 * _maxXVel;
00370                         _yVelocity = -.9 * _maxYVel;
00371                 }
00372                 _jumping = true;
00373                 _jumpTimer = 0;
00374                 _jumpReset = false;
00375         }
00376         else if(_jumping && _jumpTimer < _maxJumpTime && _wallJump == 0)
00377         {
00378                 _yVelocity = -_maxYVel;
00379                 _jumpTimer ++;
00380         }*/
00381 
00382         //we're on top of something, and not directly below something, we can jump
00383         if( !_crouching &&_jumpReset && touchingBelow() && !touchingAbove() )
00384         {
00385                 _yVelocity = -_maxYVel;
00386                 //_jumping = true;
00387                 _jumpTimer = 0;
00388                 _jumpReset = false;
00389                 _wallJumpReset = false;
00390         }
00391         //when we hit something above us the jump resets
00392         else if( touchingAbove() )
00393         {
00394                 _jumpTimer = _maxJumpTime;
00395         }
00396         // we're touching a wall and have changed direction in the last timestep.
00397         // we can walljump
00398         else if(  (_wallJumpReset&& _xDirection == RIGHT && _prevXDirection == LEFT && touchingLeft() ) 
00399                         ||(_wallJumpReset && _xDirection == LEFT && _prevXDirection == RIGHT && touchingRight() )
00400                         )
00401         {
00402                 _xVelocity = (int)_xDirection * .8 * _maxXVel;
00403                 _yVelocity = -_maxYVel;
00404                 _jumpReset = false;
00405                 _wallJumpReset = false;
00406         }
00407         else if(!_jumpReset && _jumpTimer < _maxJumpTime)
00408         {
00409                 _yVelocity = -0.25 * _maxYVel;
00410                 _jumpTimer ++;
00411         }
00412 
00413 }
00414 
00415 void Person::live()
00416 {
00417         _invincible = false;
00418         _state = STANDING;
00419 }
00420 
00421 void Person::jumpReset()
00422 {
00423         _jumpReset = true;
00424         _wallJumpReset = true;
00425         _jumpTimer = _maxJumpTime;
00426         _sprite->reset(2);
00427 }
00428 
00429 void Person::shoot()
00430 {
00431         if(_primaryWeapon)
00432                 _primaryWeapon->shoot();
00433 
00434         if(_punchWeapon && !_crouching)
00435         {
00436                 _punchWeapon->shoot();
00437                 _state = PUNCHING;
00438                 //FIXME?
00439                 //MAGIC number
00440                 _punchTimer = 1;
00441         }
00442 }
00443 
00447 void Person::crouch()
00448 {
00449         if(!_crouching && touchingBelow())
00450         {
00451                 _crouching = true;
00452                 _box.h /= 2;
00453                 _box.y += _box.h;
00454                 _previousY = _box.y;
00455                 _previousX = _box.x;
00456                 _sprite->setHeight( _box.h );
00457         }
00458 }
00462 void Person::uncrouch()
00463 {
00464         if(  _crouching && !touchingAbove( _box.h ) )
00465         {
00466                 _crouching = false;
00467                 _box.y -= _box.h;
00468                 _previousY = _box.y;
00469                 _previousX = _box.x;
00470                 _box.h *= 2;
00471                 _sprite->setHeight( _box.h );
00472         }
00473 }
00474 
00478 void Person::die()
00479 {
00480         _collidable = false;
00481         Level::instance()->scheduleDelete( this );
00482 
00483         if(_dropItem != "") {
00484                 Object *newObject = Object::loadObject(_dropItem,0,0);
00485                 SDL_Rect rect = newObject->getBox();
00486                 newObject->setPos(_box.x, _box.y + _box.h - rect.h);
00487                 Level::instance()->registerObject( newObject );
00488         }
00489 }
00490 
00491 bool Person::touchingAbove(int pels)
00492 {
00493         _box.y-=pels;
00494         vector<Object *> objs = CollisionHandler::ObjsColliding( this , true);
00495         _box.y+=pels;
00496         return !objs.empty();
00497 }
00498 bool Person::touchingBelow(int pels)
00499 {
00500         _box.y+=pels;
00501         vector<Object *> objs = CollisionHandler::ObjsColliding( this , true);
00502         _box.y-=pels;
00503         return !objs.empty();
00504 }
00505 bool Person::touchingLeft(int pels)
00506 {
00507         _box.x-=pels;
00508         vector<Object *> objs = CollisionHandler::ObjsColliding( this , true);
00509         _box.x+=pels;
00510         return !objs.empty();
00511 }
00512 bool Person::touchingRight(int pels)
00513 {
00514         _box.x+=pels;
00515         vector<Object *> objs = CollisionHandler::ObjsColliding( this , true);
00516         _box.x-=pels;
00517         return !objs.empty();
00518 }
00519 
00520 void Person::addHealth(int dHealth)
00521 {
00522         if( !_invincible || dHealth >= 0 ) {
00523                 _health += dHealth;
00524 
00525                 // Check that the person is still alive
00526                 if( _health <= 0 )
00527                 {       
00528                         //SOUNDFX
00529                         if(_type == ENEMY)
00530                                 CommandManager::instance()->execute(new PlaySoundCommand("sounds/death_male08.wav"));
00531                         else if(_type == PLAYER)
00532                                 CommandManager::instance()->execute(new PlaySoundCommand("sounds/death_male02.wav"));
00533 
00534                         die();
00535                 }
00536         }
00537 }

Generated on Fri May 5 00:20:19 2006 for ProjectX by  doxygen 1.4.6-NO