- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# 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 }