C:/Documents and Settings/mtauraso/Desktop/proj3/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 
00014 
00015 using namespace std;
00016 
00017 /*Person::Person()
00018 :_xVelocity(0),_yVelocity(0),_maxVel(850),_jumping(true), _wallJump(0), 
00019 _gravity(3), _accel(40), _groundDrag(-1.2), _airDrag(-0.3),
00020 _xDirection( LEFT ),
00021 _yDirection( MIDDLE )
00022 {
00023         // FIXME  make this general
00024         _id = "goudy";
00025         _type = PERSON;
00026 
00027         _collidable = true;
00028 
00029         // FIXME  these should be set based on the levels spawn point
00030         _box.x = 400;
00031         _box.y = 400;
00032 
00033         // FIXME this filename should be set based on the type of person it is eventually
00034         _sprite = Sprite::loadSprite("stickman.png");
00035         _box.w = _sprite->width();
00036         _box.h = _sprite->height();
00037 
00038         _previousX = _box.x;
00039         _previousY = _box.y;
00040 
00041 //      CollisionHandler::instance()->registerObject(this);
00042 }*/
00043 
00044 Person::Person(List* personInfo, int x, int y)
00045 :Object(personInfo,x,y),
00046  _xVelocity(0),
00047  _yVelocity(0),
00048  _maxXVel(850),
00049 
00050 // _jumping(true),
00051 
00052  _maxYVel(800),
00053  _maxFallRate(700),
00054 
00055  _crouching( false ),
00056 // _wallJump(0), 
00057  _gravity(2), 
00058  _accel(40),
00059  _airAccel(20),
00060  _groundDrag(-2.5), 
00061  _airDrag(-0.3),
00062  _xDirection( LEFT ),
00063  _yDirection( MIDDLE ), 
00064  _state( JUMPING ), 
00065  _health(2), 
00066  _waitShoot(15), 
00067  _framesSinceShoot(0),
00068  _jumpTimer(0),
00069  _bulletSpeed(500),
00070  _maxJumpTime(15)
00071 {
00072         _collidable = true;
00073 
00074         load(personInfo);
00075 
00076         _previousX = _box.x;
00077         _previousY = _box.y;
00078 }
00079 
00080 void Person::load(List *personInfo)
00081 {
00082         while( !personInfo->empty())
00083         {
00084                 List * current = personInfo->firstList();
00085                 
00086                 if(current->firstString() == "maxXVel")
00087                         _maxXVel = current->rest()->firstInt();
00088 
00089                 if(current->firstString() == "maxYVel")
00090                         _maxYVel = current->rest()->firstInt();
00091 
00092                 if(current->firstString() == "maxFallRate")
00093                         _maxFallRate = current->rest()->firstInt();
00094                 
00095                 if(current->firstString() == "gravity")
00096                         _gravity = current->rest()->firstInt();
00097 
00098                 if(current->firstString() == "accel")
00099                         _accel = current->rest()->firstInt();
00100 
00101                 if(current->firstString() == "airAccel")
00102                         _airAccel = current->rest()->firstInt();
00103 
00104                 if(current->firstString() == "groundDrag")
00105                         _groundDrag = current->rest()->firstDouble();
00106 
00107                 if(current->firstString() == "airDrag")
00108                         _airDrag = current->rest()->firstDouble();
00109 
00110                 if(current->firstString () == "sprite")
00111                         _sprite = Sprite::loadSprite( current->rest()->firstString() );
00112 
00113                 if(current->firstString () == "waitShoot")
00114                         _waitShoot = current->rest()->firstInt();
00115 
00116                 if(current->firstString () == "bulletSpeed")
00117                         _bulletSpeed = current->rest()->firstInt();
00118 
00119                 if(current->firstString () == "maxJumpTime")
00120                         _maxJumpTime = current->rest()->firstInt();
00121                 
00122                 if(current->firstString () == "health")
00123                         _health = current->rest()->firstInt();
00124 
00125                 personInfo = personInfo ->rest();
00126         }
00127 
00128         _box.w = _sprite->width();
00129         _box.h = _sprite->height();
00130 }
00131 
00132 void Person::collide( Object* o )
00133 {
00134         if(     (o->getType() == TILE)|| (o->getType() == DOOR) ||
00135                 ((_type == PLAYER)&&(o->getType() == ENEMY ))||
00136                 ((_type == ENEMY)&&(o->getType() == PLAYER ))
00137                 )
00138         {
00139                 int x,y;
00140                 if( _previousX != _box.x){
00141 
00142                         //If you're pressing against a wall, get ready to jump off the wall in the opposite direction
00143                         /*if(_xVelocity != 0)
00144                         {
00145                                 _jumping = false;
00146                                 _wallJump = -(_xVelocity / abs(_xVelocity));
00147                         }*/
00148 
00149                         glfuncs::intersectX(o->getBox(),_box,&x);
00150                         _box.x += x;
00151                         _xVelocity = 0;
00152                 }
00153                 if( _previousY != _box.y){
00154 
00155                         //When you hit the ground, reset these
00156                         /*if(_yVelocity > 0)
00157                         {
00158                                 _jumping = false;
00159                                 _wallJump = 0;
00160                         }*/
00161 
00162                         glfuncs::intersectY(o->getBox(),_box,&y);
00163                         _box.y += y;
00164                         _yVelocity = 0;
00165                 }
00166         }
00167 }
00168 
00169 void Person::draw()
00170 {
00171         ShowOneSprite* s = (ShowOneSprite*)_sprite;
00172         s->setDirection( _xDirection ); 
00173         
00174         switch( _state )
00175         {
00176         case STANDING:
00177                 s->show( 0 );
00178                 break;
00179         case RUNNING:
00180                 s->show( 1 );
00181                 break;
00182         case JUMPING:
00183                 s->show( 2 );
00184                 break;
00185         case FALLING:
00186                 s->show( 3 );
00187                 break;
00188         default:
00189                 s->show( 0 );
00190                 break;
00191         }
00192         s->draw(_box.x,_box.y);
00193 }
00194 
00195 void Person::update()
00196 {
00197         // Check that the person is still alive
00198         if( _health <= 0 )
00199         {       
00200                 die();
00201                 return;
00202         }
00203         
00204         _framesSinceShoot++;
00205 
00206         //If you had the chance to walljump, but moved away from the wall, you're now just falling
00207         /*if((_wallJump * _xVelocity) > 0)
00208         {
00209                 _wallJump = 0;
00210                 _jumping = true;
00211         }*/
00212 
00213         //if(_yVelocity > 0)
00214         //{
00215         //      //you are falling, you shouldn't be allowed to jump until you hit something
00216         //      _jumping = true;
00217         //}
00218         
00219         _box.x += (_xVelocity/Screen::FRAMERATE);
00220         CollisionHandler::instance()->checkCollision(this);
00221         _previousX = _box.x;
00222 
00223         
00224         _box.y += (_yVelocity/Screen::FRAMERATE);
00225         CollisionHandler::instance()->checkCollision(this);
00226         _previousY = _box.y;
00227 
00228         //A little bit of drag force
00229         if(_xVelocity != 0)
00230         {
00231                 if(!touchingBelow())
00232                         incrVelocity((_xVelocity/abs(_xVelocity)) * _airDrag * 1000/Screen::FRAMERATE, 0);
00233                 else
00234                         incrVelocity((_xVelocity/abs(_xVelocity)) * _groundDrag * 1000/Screen::FRAMERATE, 0);
00235         }
00236         //_yVelocity -= _yVelocity *0.3;
00237 
00238         // breakVel is the least amount of velocity the person can have 
00239         // before moving at least 1 pixel
00240         int breakVel = Screen::FRAMERATE;
00241         if( abs(_yVelocity) < breakVel )
00242         {
00243                 if( _state != JUMPING )
00244                         _state = STANDING;
00245         } else if( _yVelocity < -breakVel )
00246         {
00247                 _state = JUMPING;
00248         } else if( _yVelocity > breakVel )
00249         {
00250                 _state = FALLING;
00251         }
00252 
00253         incrVelocity(0,_gravity * 1000/Screen::FRAMERATE);
00254 }
00255 
00256 void Person::incrVelocity(int xVel, int yVel)
00257 {
00258         if(abs(_xVelocity + xVel) < _maxXVel)
00259                 _xVelocity += xVel;
00260         else
00261                 _xVelocity < 0 ? _xVelocity = -_maxXVel : _xVelocity = _maxXVel;
00262 
00263 
00264         if(abs(_yVelocity + yVel) < _maxFallRate)
00265                 _yVelocity += yVel;
00266         else
00267                 _yVelocity < 0 ? _yVelocity = -_maxFallRate : _yVelocity = _maxFallRate; 
00268 }
00269 
00270 int Person::getAccel()
00271 {
00272         if(!touchingBelow())
00273                 return _airAccel;
00274 
00275         return _accel;
00276 }
00277 
00278 void Person::jump(xDirection xDir)
00279 {
00280         //Don't allow player or scripts to jump if they are already jumping.
00281         /*if(!_jumping && _jumpReset)
00282         {
00283                 //If you're jumping straight off the ground
00284                 if(_wallJump == 0)
00285                 {
00286                         
00287                 }
00288                 //If you're jumping off of some wall
00289                 else if(_wallJump/abs(_wallJump) == xDir)
00290                 {
00291                         _xVelocity = _wallJump * .8 * _maxXVel;
00292                         _yVelocity = -.9 * _maxYVel;
00293                 }
00294                 _jumping = true;
00295                 _jumpTimer = 0;
00296                 _jumpReset = false;
00297         }
00298         else if(_jumping && _jumpTimer < _maxJumpTime && _wallJump == 0)
00299         {
00300                 _yVelocity = -_maxYVel;
00301                 _jumpTimer ++;
00302         }*/
00303 
00304         //we're on top of something, we can jump
00305         if( touchingBelow() && _jumpReset )
00306         {
00307                 _yVelocity = -_maxYVel;
00308                 //_jumping = true;
00309                 _jumpTimer = 0;
00310                 _jumpReset = false;
00311                 _wallJumpReset = false;
00312         }
00313         // we're touching a wall and have changed direction in the last timestep.
00314         // we can walljump
00315         else if(  (_wallJumpReset&& _xDirection == RIGHT && _prevXDirection == LEFT && touchingLeft() ) 
00316                         ||(_wallJumpReset && _xDirection == LEFT && _prevXDirection == RIGHT && touchingRight() )
00317                         )
00318         {
00319                 _xVelocity = (int)_xDirection * .8 * _maxXVel;
00320                 _yVelocity = -.9 * _maxYVel;
00321                 _jumpReset = false;
00322                 _wallJumpReset = false;
00323         }
00324         else if(!_jumpReset && _jumpTimer < _maxJumpTime)
00325         {
00326                 _yVelocity = -_maxYVel;
00327                 _jumpTimer ++;
00328         }
00329 
00330 }
00331 
00332 void Person::jumpReset()
00333 {
00334         _jumpReset = true;
00335         _wallJumpReset = true;
00336         _jumpTimer = _maxJumpTime;
00337 }
00338 
00339 void Person::shoot()
00340 {
00341         
00342         if(_framesSinceShoot >= _waitShoot)
00343         {
00344                 Level::instance()->registerObject( new Bullet( this, _bulletSpeed, _xDirection, _yDirection ) );
00345                 _framesSinceShoot = 0;
00346         }
00347 }
00348 
00352 void Person::crouch()
00353 {
00354         _crouching = true;
00355         _box.h /= 2;
00356         _box.y += _box.h;
00357         _sprite->setHeight( _box.h );
00358 }
00362 void Person::uncrouch()
00363 {
00364         if( !touchingAbove())
00365         {
00366                 _crouching = false;
00367                 _box.y -= _box.h;
00368                 _box.h *= 2;
00369                 _sprite->setHeight( _box.h );
00370         }
00371 }
00372 
00376 void Person::die()
00377 {
00378         _collidable = false;
00379         Level::instance()->scheduleDelete( this );
00380 }
00381 
00382 
00383 bool Person::touchingAbove()
00384 {
00385         _box.y--;
00386         vector<Object *> objs = CollisionHandler::ObjsColliding( this );
00387         _box.y++;
00388         return !objs.empty();
00389 }
00390 bool Person::touchingBelow()
00391 {
00392         _box.y++;
00393         vector<Object *> objs = CollisionHandler::ObjsColliding( this );
00394         _box.y--;
00395         return !objs.empty();
00396 }
00397 bool Person::touchingLeft()
00398 {
00399         _box.x--;
00400         vector<Object *> objs = CollisionHandler::ObjsColliding( this );
00401         _box.x++;
00402         return !objs.empty();
00403 }
00404 bool Person::touchingRight()
00405 {
00406         _box.x++;
00407         vector<Object *> objs = CollisionHandler::ObjsColliding( this );
00408         _box.x--;
00409         return !objs.empty();
00410 }

Generated on Sat Apr 22 15:05:20 2006 for ProjectX by  doxygen 1.4.6-NO