⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 projectile.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
字号:
/***************************************************************************                          projectile.cpp  -  description                             -------------------    begin                : Sat May 3 2003    copyright            : (C) 2003 by Gabor Torok    email                : cctorok@yahoo.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "projectile.h"map<Creature*, vector<Projectile*>*> Projectile::projectiles;#define DELTA 1.0fProjectile::Projectile(Creature *creature, Creature *target, Item *item, Shape *shape, float parabolic, bool stopOnImpact, bool seeker) {  this->creature = creature;  this->tx = target->getX();  this->ty = target->getY();  this->tw = target->getShape()->getWidth();  this->td = target->getShape()->getDepth();  this->target = target;  this->item = item;  this->spell = NULL;  this->shape = shape;  this->parabolic = parabolic;  this->stopOnImpact = stopOnImpact;  this->seeker = seeker;  commonInit();}Projectile::Projectile(Creature *creature, Creature *target, Spell *spell, Shape *shape,                        float parabolic, bool stopOnImpact, bool seeker) {  this->creature = creature;  this->tx = target->getX();  this->ty = target->getY();  this->tw = target->getShape()->getWidth();  this->td = target->getShape()->getDepth();  this->target = target;  this->item = NULL;  this->spell = spell;  this->shape = shape;  this->parabolic = parabolic;  this->stopOnImpact = stopOnImpact;  this->seeker = seeker;  commonInit();}Projectile::Projectile(Creature *creature, int x, int y, int w, int d,                        Spell *spell, Shape *shape, float parabolic, bool stopOnImpact) {  this->creature = creature;  this->tx = x;  this->ty = y;  this->tw = w;  this->td = d;  this->target = NULL;  this->item = NULL;  this->spell = spell;  this->shape = shape;  this->parabolic = parabolic;  this->stopOnImpact = stopOnImpact;  this->seeker = false;  commonInit();}void Projectile::commonInit() {  this->sx = creature->getX() + (creature->getShape()->getWidth() / 2);  this->sy = creature->getY() - (creature->getShape()->getDepth() / 2);  calculateAngle();  //  cerr << "NEW PROJECTILE: (" << sx << "," << sy << ")-(" << ex << "," << ey << ") angle=" << angle << " q=" << q << endl;  cx = cy = 0;  steps = 0;  maxDist = (spell ? spell->getDistance() : item->getRpgItem()->getDistance()) + tw;  startX = sx;  startY = sy;  distToTarget = Constants::distance(startX,  startY,                                      1, 1,                                     tx, ty, tw, td);}Projectile::~Projectile() {}bool Projectile::move() {  // are we at the target location?  if(steps >= maxDist ||     (sx == ex && sy == ey)) return true;  steps++;  float oldAngle = angle;  if(parabolic != 0.0f) {    float a = (179.0f * steps) / distToTarget;    angle = angle + parabolic * 40 * sin(Constants::toRadians(a));    sx += (cos(Constants::toRadians(angle)) * DELTA);    sy += (sin(Constants::toRadians(angle)) * DELTA);    angle = oldAngle;  } else {    // angle-based floating pt. movement    if(sx == ex) {      // vertical movement      if(sy < ey) sy+=DELTA;      else sy-=DELTA;     } else if(sy == ey) {      // horizontal movement      if(sx < ex) sx+=DELTA;      else sx-=DELTA;     } else {              sx += (cos(Constants::toRadians(angle)) * DELTA);      sy += (sin(Constants::toRadians(angle)) * DELTA);    }  }  // target-seeking missiles re-adjust their flight paths  if(seeker && target) {    this->tx = target->getX();    this->ty = target->getY();    this->tw = target->getShape()->getWidth();    this->td = target->getShape()->getDepth();    calculateAngle();  }  // recalculate the distance  distToTarget = Constants::distance(startX,  startY,                                      1, 1,                                     tx, ty, tw, td);  // we're not at the target yet  return false;}void Projectile::calculateAngle() {  this->ex = tx + (tw / 2);  this->ey = ty - (td / 2);  int x = (int)(ex - sx);  int y = (int)(ey - sy);  this->angle = Constants::toAngle(atan((float)y / (float)x));  // read about the arctan problem:   // http://hyperphysics.phy-astr.gsu.edu/hbase/ttrig.html#c3  q = 1;  if(x < 0) {     // Quadrant 2 & 3    q = ( y >= 0 ? 2 : 3);    angle += 180;  } else if(y < 0) { // Quadrant 4    q = 4;    angle += 360;  }}// return null if the projectile cannot be launchedProjectile *Projectile::addProjectile(Creature *creature, Creature *target,                                       Item *item, Shape *shape,                                       int maxProjectiles, bool stopOnImpact) {  vector<Projectile*> *v;  if(projectiles.find(creature) == projectiles.end()) {    v = new vector<Projectile*>();    projectiles[creature] = v;  } else {    v = projectiles[creature];  }  // for items this is the max number of proj.-s in the air  if((int)v->size() > maxProjectiles) return NULL;  Projectile *p = new Projectile(creature, target, item, shape, 0.0f, stopOnImpact);  v->push_back(p);  return p;}Projectile *Projectile::addProjectile(Creature *creature, Creature *target,                                       Spell *spell, Shape *shape,                                       int maxProjectiles, bool stopOnImpact) {  vector<Projectile*> *v;  if(projectiles.find(creature) == projectiles.end()) {    v = new vector<Projectile*>();    projectiles[creature] = v;  } else {    v = projectiles[creature];  }  // FIXME: for spells, it's how many to launch at once...  if((int)v->size() > maxProjectiles) return NULL;  // add a straight-flying projectile  Projectile *p = new Projectile(creature, target, spell, shape, 0.0f, stopOnImpact, true);  v->push_back(p);  // add extra projectiles w. parabolic curve  float r = 0.5f;  for(int i = 0; i < maxProjectiles - 1; i+=2) {    if(i < maxProjectiles - 1) {      v->push_back(new Projectile(creature, target, spell, shape, r, stopOnImpact, true));    }    if((i + 1) < maxProjectiles - 1) {      v->push_back(new Projectile(creature, target, spell, shape, -r, stopOnImpact, true));    }    r += (r/2.0f);  }  return p;}Projectile *Projectile::addProjectile(Creature *creature, int x, int y, int w, int d,                                       Spell *spell, Shape *shape,                                       int maxProjectiles, bool stopOnImpact) {  vector<Projectile*> *v;  if(projectiles.find(creature) == projectiles.end()) {    v = new vector<Projectile*>();    projectiles[creature] = v;  } else {    v = projectiles[creature];  }  // FIXME: for spells, it's how many to launch at once...  if((int)v->size() > maxProjectiles) return NULL;  // add a straight-flying projectile  Projectile *p = new Projectile(creature, x, y, w, d, spell, shape, 0.0f, stopOnImpact);  v->push_back(p);  // add extra projectiles w. parabolic curve  float r = 0.5f;  for(int i = 0; i < maxProjectiles - 1; i+=2) {    if(i < maxProjectiles - 1) {      v->push_back(new Projectile(creature, x, y, w, d, spell, shape, r, stopOnImpact));    }    if((i + 1) < maxProjectiles - 1) {      v->push_back(new Projectile(creature, x, y, w, d, spell, shape, -r, stopOnImpact));    }    r += (r/2.0f);  }  return p;}void Projectile::removeProjectile(Projectile *p) {  if(projectiles.find(p->creature) != projectiles.end()) {    vector<Projectile*> *v = projectiles[p->creature];    for(vector<Projectile*>::iterator e=v->begin(); e!=v->end(); ++e) {      Projectile *proj = *e;        if(proj == p) {        v->erase(e);        if(v->size() == 0) {          projectiles.erase(p->creature);        }        return;      }    }  }}void Projectile::moveProjectiles(Scourge *scourge) {  // draw the projectiles  vector<Projectile*> removedProjectiles;  //    cerr << "Projectiles:" << endl;  map<Creature *, vector<Projectile*>*> *proj = Projectile::getProjectileMap();  for(map<Creature *, vector<Projectile*>*>::iterator i=proj->begin(); i!=proj->end(); ++i) {    //	  Creature *creature = i->first;    //	  cerr << "\tcreature: " << creature->getName() << endl;    vector<Projectile*> *p = i->second;    for(vector<Projectile*>::iterator e=p->begin(); e!=p->end(); ++e) {      Projectile *proj = *e;      //	    cerr << "\t\tprojectile at: " << proj->getX() << "," << proj->getY() << endl;      if(proj->move()) {        removedProjectiles.push_back(proj);      }    }  }  // remove projectiles  for(vector<Projectile*>::iterator e=removedProjectiles.begin(); e!=removedProjectiles.end(); ++e) {    Projectile *proj = *e;    // a location-bound projectile reached its target    if(!proj->doesStopOnImpact()) {      Battle::projectileHitTurn(scourge, proj, (int)proj->getX(), (int)proj->getY());    }    Projectile::removeProjectile(proj);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -