File indexing completed on 2022-09-27 13:19:26

0001 /*
0002     SPDX-FileCopyrightText: 1998-2001 Andreas Zehender <az@azweb.de>
0003     SPDX-FileCopyrightText: 2006-2008 Dirk Rathlev <dirkrathlev@gmx.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "sprites.h"
0009 
0010 #include <math.h>
0011 
0012 #include <QGraphicsScene>
0013 #include <QTransform>
0014 
0015 #include "mathroutines.h"
0016 
0017 SunSprite::SunSprite(QSvgRenderer* svg, const QString& element)
0018       :SimpleSprite(svg, element)
0019 {
0020     setZValue(0);
0021 }
0022 
0023 
0024 PowerupSprite::PowerupSprite(QSvgRenderer* svg, const QString& element, int t,
0025                              double lifetime)
0026       :SimpleSprite(svg, element)
0027 {
0028    time=lifetime;
0029    mtype=t;
0030 }
0031 
0032 ShipSprite::ShipSprite(QSvgRenderer* svg, const QString& element, int pn)
0033       :MobileSprite(svg, element,pn)
0034 {
0035    hitpoints=MAX_HP;
0036    energy=MAX_ENERGY;
0037    explosion=-1;
0038    setZValue(-20);
0039    rotation=0;
0040    bulletPowerups=0;
0041    minePowerups=0;
0042    angle = 0;
0043 }
0044 
0045 void ShipSprite::setRotation(double r)
0046 {
0047    rotation=r;
0048    if(rotation<0)
0049       rotation-=((int)(rotation/(2*M_PI))-1)*2*M_PI;
0050    if(rotation>=2*M_PI)
0051       rotation-=(int)(rotation/(2*M_PI))*2*M_PI;
0052 
0053    setTransform(QTransform::fromTranslate(center().x(),center().y()), true);
0054    setTransform(QTransform().rotate(-(rotation-angle)*57.3), true);
0055    setTransform(QTransform::fromTranslate(-center().x(),-center().y()), true);
0056    angle = rotation;
0057 }
0058 
0059 void ShipSprite::forward(double mult)
0060 {
0061    MobileSprite::forward(mult);
0062    if(explosion>0)
0063    {
0064       explosion--;
0065       if(explosion==0)
0066          hide();
0067    }
0068    if(reloadBulletTime>0)
0069       reloadBulletTime-=mult;
0070    if(reloadMineTime>0)
0071       reloadMineTime-=mult;
0072 }
0073 
0074 void ShipSprite::forward(double mult,int fr)
0075 {
0076    MobileSprite::forward(mult,fr);
0077    rotation=fr/ROTNUM*M_PI*2;
0078    if(explosion>0)
0079    {
0080       explosion--;
0081       if(explosion==0)
0082          hide();
0083    }
0084    if(reloadBulletTime>0)
0085       reloadBulletTime-=mult;
0086    if(reloadMineTime>0)
0087       reloadMineTime-=mult;
0088 }
0089 
0090 void ShipSprite::calculateGravityAndEnergy(double gravity,double sunEnergy,
0091                                            double mult)
0092 {
0093    double nx,ny,ex,ey,abs_2,phi,sq,eg;
0094 
0095    if(!stopped)
0096    {
0097       ex=x()+center().x()-scene()->width()/2.0;
0098       ey=y()+center().y()-scene()->height()/2.0;
0099 
0100       abs_2=ex*ex+ey*ey;
0101       sq=sqrt(abs_2);
0102 
0103       if ( explodes() && (sq<20) )
0104          stopped = true;
0105       else
0106       {
0107          nx=ex/sq;
0108          ny=ey/sq;
0109          eg=gravity*mult;
0110          setVelocity(xVelocity()-eg*nx/abs_2,
0111                      yVelocity()-eg*ny/abs_2);
0112          if(hitpoints!=0)
0113          {
0114             if(energy<99.8)
0115             {
0116                phi=rectToAngle(nx,ny);
0117                energy+=fabs(sunEnergy*mult/(abs_2)*cos(phi+rotation));
0118             }
0119          }
0120       }
0121    }
0122 }
0123 
0124 void ShipSprite::rotateRight(double rotationEnergyNeed,double rotationSpeed)
0125 {
0126    if(energy>rotationEnergyNeed)
0127    {
0128       energy-=rotationEnergyNeed;
0129       setRotation(rotation-rotationSpeed);
0130    }
0131 }
0132 
0133 void ShipSprite::rotateLeft(double rotationEnergyNeed,double rotationSpeed)
0134 {
0135    if(energy>rotationEnergyNeed)
0136    {
0137       energy-=rotationEnergyNeed;
0138       setRotation(rotation+rotationSpeed);
0139    }
0140 }
0141 
0142 BulletSprite::BulletSprite(QSvgRenderer* svg, const QString& element, int pn,double lifetime)
0143       :MobileSprite(svg,element,pn)
0144 {
0145    setZValue(-10);
0146    time=lifetime;
0147 }
0148 
0149 void BulletSprite::forward(double mult)
0150 {
0151    MobileSprite::forward(mult);
0152    time-=mult;
0153 }
0154 
0155 void BulletSprite::forward(double mult,int fr)
0156 {
0157    MobileSprite::forward(mult,fr);
0158    time-=mult;
0159 }
0160 
0161 MineSprite::MineSprite(QSvgRenderer* svg, const QList<QString>& animation, const QList<QString>& exploanimation, int pn,double atime,double f)
0162       :AnimatedSprite(svg, animation,pn)
0163 {
0164    exploframes = exploanimation;
0165    activateTime=atime;
0166    setZValue(-25);
0167    fuel=f;
0168    explosiontime=0;
0169    timeToGo=0.0;
0170    expl=false;
0171    active=false;
0172 }
0173 
0174 void MineSprite::explode()
0175 {
0176    setAnimation(exploframes);
0177    timeToGo=frameCount();
0178    expl=true;
0179    explosiontime=0.0;
0180    setZValue(-8);
0181    setFuel(0.0);
0182 }
0183 
0184 void MineSprite::forward(double mult)
0185 {
0186    if(active)
0187    {
0188       if(expl)
0189       {
0190          explosiontime+=mult;
0191          if(explosiontime>(timeToGo-0.001))
0192             explosiontime=timeToGo-0.01;
0193          setFrame((int)explosiontime);
0194       }
0195    }
0196    else
0197    {
0198       activateTime-=(double)mult;
0199       if(activateTime<0.0)
0200       {
0201          active=true;
0202          setFrame(1);
0203       }
0204    }
0205    if(fuel<0.001)
0206       MobileSprite::forward(mult);
0207 }
0208 
0209 void MineSprite::calculateGravity(double gravity,double mult)
0210 {
0211    double abs_2,nx,ny,ex,ey,sq,eg;
0212 
0213    if(!stopped)
0214    {
0215       ex=x()-scene()->width()/2.0;
0216       ey=y()-scene()->height()/2.0;
0217 
0218       abs_2=ex*ex+ey*ey;
0219       sq=sqrt(abs_2);
0220       nx=ex/sq;
0221       ny=ey/sq;
0222       eg=gravity*mult;
0223       if(fuel<0.001)
0224          setVelocity(xVelocity()-eg*nx/abs_2,
0225                      yVelocity()-eg*ny/abs_2);
0226       else
0227          fuel-=eg/abs_2;
0228    }
0229 }
0230 
0231 ExplosionSprite::ExplosionSprite(QSvgRenderer* svg, const QList<QString>& animation, MobileSprite *sp)
0232       :AnimatedSprite(svg, animation)
0233 {
0234    over=false;
0235    setZValue(5);
0236    obj=sp;
0237    timeToGo = frameCount();
0238    time=0;
0239 
0240    setPos(QPointF(sp->x(),sp->y()));
0241 }
0242 
0243 void ExplosionSprite::forward(double mult)
0244 {
0245    int of=frame();
0246    setPos(QPointF(obj->x(),obj->y()));
0247    time+=mult;
0248 
0249    if(time>=timeToGo)
0250    {
0251       over=true;
0252       hide();
0253    }
0254    else
0255       if((int)time!=of)
0256          setFrame((int)time);
0257 }