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
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
00051
00052 _maxYVel(800),
00053 _maxFallRate(700),
00054
00055 _crouching( false ),
00056
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
00143
00144
00145
00146
00147
00148
00149 glfuncs::intersectX(o->getBox(),_box,&x);
00150 _box.x += x;
00151 _xVelocity = 0;
00152 }
00153 if( _previousY != _box.y){
00154
00155
00156
00157
00158
00159
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
00198 if( _health <= 0 )
00199 {
00200 die();
00201 return;
00202 }
00203
00204 _framesSinceShoot++;
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
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
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
00237
00238
00239
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
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 if( touchingBelow() && _jumpReset )
00306 {
00307 _yVelocity = -_maxYVel;
00308
00309 _jumpTimer = 0;
00310 _jumpReset = false;
00311 _wallJumpReset = false;
00312 }
00313
00314
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 }