summaryrefslogtreecommitdiffstats
path: root/kspaceduel/mainview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kspaceduel/mainview.cpp')
-rw-r--r--kspaceduel/mainview.cpp1052
1 files changed, 1052 insertions, 0 deletions
diff --git a/kspaceduel/mainview.cpp b/kspaceduel/mainview.cpp
new file mode 100644
index 00000000..0d385a49
--- /dev/null
+++ b/kspaceduel/mainview.cpp
@@ -0,0 +1,1052 @@
+#include "mainview.h"
+
+#include <math.h>
+#include <qbitmap.h>
+#include <qfile.h>
+#include <qvbox.h>
+
+#include <kapplication.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kglobalsettings.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+
+#include "ai.h"
+#include "options.h"
+
+KToggleAction *MyMainView::pauseAction = 0;
+
+MyMainView::MyMainView(QWidget *parent)
+ :QWidget(parent),
+ field(DEF_WIDTH,DEF_HEIGHT),
+ view(&field,this)
+{
+ int i,p;
+ setMinimumSize(600,400);
+ random.setSeed(0);
+ QPixmap backgr(locate("appdata", MV_BACKGROUND));
+ field.setBackgroundPixmap(backgr);
+
+ view.setResizePolicy(QScrollView::AutoOne);
+ view.setHScrollBarMode(QScrollView::AlwaysOff);
+ view.setVScrollBarMode(QScrollView::AlwaysOff);
+
+ for(p=0;p<2;p++)
+ {
+ for(i=0;i<PlayerKeyNum;i++)
+ playerKeyPressed[p][i]=false;
+ bulletShot[p]=false;
+ minePut[p]=false;
+ }
+
+ QString tmp = KGlobal::dirs()->findResourceDir("appdata", (QString)MV_BACKGROUND);
+
+ QCanvasPixmapArray *sunsequence
+ = loadOldPixmapSequence( tmp + MV_SUN_PPM, tmp + MV_SUN_PBM );
+ sun=new SunSprite(sunsequence, &field);
+ sun->move(width()/2-1,height()/2-1);
+ sun->show();
+
+ explosionsequence = loadOldPixmapSequence( tmp + MV_EXPLOSION_PPM,
+ tmp + MV_EXPLOSION_PBM, 31 );
+ mineexplosionsequence = loadOldPixmapSequence(tmp + MV_MINEEX_PPM,
+ tmp + MV_MINEEX_PBM, 18 );
+
+ shipsequence[0] = loadOldPixmapSequence( tmp + MV_SHIP1_PPM,
+ tmp + MV_SHIP1_PBM, ROTNUM );
+ shipsequence[1] = loadOldPixmapSequence( tmp + MV_SHIP2_PPM,
+ tmp + MV_SHIP2_PBM, ROTNUM);
+ ship[0]=new ShipSprite(shipsequence[0],&field,0);
+ ship[1]=new ShipSprite(shipsequence[1],&field,1);
+
+ bulletsequence[0] = loadOldPixmapSequence( tmp + MV_BULLET1_PPM,
+ tmp + MV_BULLET1_PBM );
+ bulletsequence[1] = loadOldPixmapSequence( tmp + MV_BULLET2_PPM,
+ tmp + MV_BULLET2_PBM );
+ minesequence[0] = loadOldPixmapSequence( tmp + MV_MINE1_PPM,
+ tmp + MV_MINE1_PBM, 2);
+ minesequence[1] = loadOldPixmapSequence( tmp + MV_MINE2_PPM,
+ tmp + MV_MINE2_PBM, 2);
+ powerupsequence[PowerupSprite::PowerupMine]
+ = loadOldPixmapSequence( tmp + MV_POWERMINE_PPM, tmp + MV_POWERMINE_PBM );
+ powerupsequence[PowerupSprite::PowerupBullet]
+ = loadOldPixmapSequence( tmp + MV_POWERBULLET_PPM, tmp + MV_POWERBULLET_PBM );
+ powerupsequence[PowerupSprite::PowerupShield]
+ = loadOldPixmapSequence( tmp + MV_POWERSHIELD_PPM, tmp + MV_POWERSHIELD_PBM );
+ powerupsequence[PowerupSprite::PowerupEnergy]
+ = loadOldPixmapSequence( tmp + MV_POWERENERGY_PPM, tmp + MV_POWERENERGY_PBM );
+
+ for(i=0;i<2;i++)
+ {
+ // ship[i]->setBoundsAction(QwRealMobileSprite::Wrap);
+ ship[i]->hide();
+ bullets[i]=new QPtrList<BulletSprite>;
+ bullets[i]->setAutoDelete(true);
+ mines[i]=new QPtrList<MineSprite>;
+ mines[i]->setAutoDelete(true);
+
+ }
+
+ explosions.setAutoDelete(true);
+ powerups.setAutoDelete(true);
+
+ waitForStart=false;
+ textSprite=0;
+ readConfig();
+}
+
+MyMainView::~MyMainView()
+{
+ killTimers();
+ writeConfig();
+}
+
+void MyMainView::setActionCollection(KActionCollection *a)
+{
+ actionCollection = a;
+}
+
+void MyMainView::readConfig()
+{
+ KConfig *cfg = kapp->config();
+ int i;
+
+ cfg->setGroup("Game");
+ customConfig.gamespeed=cfg->readDoubleNumEntry("gamespeed",
+ predefinedConfig[0].gamespeed);
+
+ customConfig.gravity=
+ cfg->readDoubleNumEntry("gravity",predefinedConfig[0].gravity);
+ customConfig.acc=
+ cfg->readDoubleNumEntry("acceleration",predefinedConfig[0].acc);
+ customConfig.bulletDamage=
+ cfg->readUnsignedNumEntry("bulletDamage",predefinedConfig[0].bulletDamage);
+ customConfig.bulletLifeTime=
+ cfg->readDoubleNumEntry("bulletLifeTime",predefinedConfig[0].bulletLifeTime);
+ customConfig.bulletReloadTime=
+ cfg->readDoubleNumEntry("bulletReloadTime",predefinedConfig[0].bulletReloadTime);
+ customConfig.mineDamage=
+ cfg->readUnsignedNumEntry("mineDamage",predefinedConfig[0].mineDamage);
+ customConfig.shipDamage=
+ cfg->readUnsignedNumEntry("shipDamage",predefinedConfig[0].shipDamage);
+ customConfig.maxBullets=
+ cfg->readUnsignedNumEntry("maxBullets",predefinedConfig[0].maxBullets);
+ customConfig.maxMines=
+ cfg->readUnsignedNumEntry("maxMines",predefinedConfig[0].maxMines);
+ customConfig.mineReloadTime=
+ cfg->readDoubleNumEntry("mineReloadTime",predefinedConfig[0].mineReloadTime);
+ customConfig.rotationSpeed=
+ cfg->readDoubleNumEntry("rotationSpeed",predefinedConfig[0].rotationSpeed);
+ customConfig.shotSpeed=
+ cfg->readDoubleNumEntry("shotSpeed",predefinedConfig[0].shotSpeed);
+ customConfig.energyNeed=
+ cfg->readDoubleNumEntry("accEnergyNeed",predefinedConfig[0].energyNeed);
+ customConfig.rotationEnergyNeed=
+ cfg->readDoubleNumEntry("rotationEnergyNeed",predefinedConfig[0].rotationEnergyNeed);
+ customConfig.sunEnergy=
+ cfg->readDoubleNumEntry("sunEnergy",predefinedConfig[0].sunEnergy);
+ customConfig.mineActivateTime=
+ cfg->readDoubleNumEntry("mineActivateTime",predefinedConfig[0].mineActivateTime);
+ customConfig.mineFuel=
+ cfg->readDoubleNumEntry("mineFuel",predefinedConfig[0].mineFuel);
+ customConfig.shotEnergyNeed=
+ cfg->readDoubleNumEntry("shotEnergyNeed",predefinedConfig[0].shotEnergyNeed);
+ customConfig.mineEnergyNeed=
+ cfg->readDoubleNumEntry("mineEnergyNeed",predefinedConfig[0].mineEnergyNeed);
+ customConfig.startPosX=
+ cfg->readDoubleNumEntry("startPosX",predefinedConfig[0].startPosX);
+ customConfig.startPosY=
+ cfg->readDoubleNumEntry("startPosY",predefinedConfig[0].startPosY);
+ customConfig.startVelX=
+ cfg->readDoubleNumEntry("startVelX",predefinedConfig[0].startVelX);
+ customConfig.startVelY=
+ cfg->readDoubleNumEntry("startVelY",predefinedConfig[0].startVelY);
+ customConfig.powerupLifeTime=
+ cfg->readDoubleNumEntry("powerupLifeTime",predefinedConfig[0].powerupLifeTime);
+ customConfig.powerupRefreshTime=
+ cfg->readDoubleNumEntry("powerupRefreshTime",predefinedConfig[0].powerupRefreshTime);
+ customConfig.powerupShieldAmount=
+ cfg->readUnsignedNumEntry("powerupShieldAmount",
+ predefinedConfig[0].powerupShieldAmount);
+ customConfig.powerupEnergyAmount=
+ cfg->readDoubleNumEntry("powerupEnergyAmount",
+ predefinedConfig[0].powerupEnergyAmount);
+
+ if(Options::lastConfig() < predefinedConfigNum)
+ config=modifyConfig(predefinedConfig[Options::lastConfig()]);
+ else
+ config=modifyConfig(customConfig);
+
+ for(i=0;i<2;i++)
+ ai[i]=new Ai(i,ship,bullets,mines,&config);
+}
+
+void MyMainView::writeConfig()
+{
+ KConfig *cfg;
+ cfg=KApplication::kApplication()->config();
+ cfg->setGroup("Game");
+
+ cfg->writeEntry("gravity",customConfig.gravity);
+ cfg->writeEntry("acceleration",customConfig.acc);
+ cfg->writeEntry("bulletDamage",customConfig.bulletDamage);
+ cfg->writeEntry("bulletLifeTime",customConfig.bulletLifeTime);
+ cfg->writeEntry("bulletReloadTime",customConfig.bulletReloadTime);
+ cfg->writeEntry("mineDamage",customConfig.mineDamage);
+ cfg->writeEntry("shipDamage",customConfig.shipDamage);
+ cfg->writeEntry("maxBullets",customConfig.maxBullets);
+ cfg->writeEntry("maxMines",customConfig.maxMines);
+ cfg->writeEntry("rotationSpeed",customConfig.rotationSpeed);
+ cfg->writeEntry("shotSpeed",customConfig.shotSpeed);
+ cfg->writeEntry("accEnergyNeed",customConfig.energyNeed);
+ cfg->writeEntry("rotationEnergyNeed",customConfig.rotationEnergyNeed);
+ cfg->writeEntry("sunEnergy",customConfig.sunEnergy);
+ cfg->writeEntry("mineActivateTime",customConfig.mineActivateTime);
+ cfg->writeEntry("mineReloadTime",customConfig.mineReloadTime);
+ cfg->writeEntry("mineFuel",customConfig.mineFuel);
+ cfg->writeEntry("shotEnergyNeed",customConfig.shotEnergyNeed);
+ cfg->writeEntry("mineEnergyNeed",customConfig.mineEnergyNeed);
+
+ cfg->writeEntry("startPosX",customConfig.startPosX);
+ cfg->writeEntry("startPosY",customConfig.startPosY);
+ cfg->writeEntry("startVelX",customConfig.startVelX);
+ cfg->writeEntry("startVelY",customConfig.startVelY);
+
+ cfg->writeEntry("powerupLifeTime",customConfig.powerupLifeTime);
+ cfg->writeEntry("powerupRefreshTime",customConfig.powerupRefreshTime);
+ cfg->writeEntry("powerupShieldAmount",customConfig.powerupShieldAmount);
+ cfg->writeEntry("powerupEnergyAmount",customConfig.powerupEnergyAmount);
+}
+
+SConfig MyMainView::modifyConfig(SConfig conf)
+{
+ SConfig newConfig=conf;
+ newConfig.gamespeed*=Options::refreshTime()/33.0;
+ newConfig.acc*=newConfig.gamespeed;
+ newConfig.rotationSpeed*=newConfig.gamespeed*M_PI/ROTNUM*4;
+ newConfig.energyNeed*=newConfig.gamespeed;
+ newConfig.rotationEnergyNeed*=newConfig.gamespeed;
+ newConfig.mineActivateTime*=newConfig.gamespeed;
+
+ return newConfig;
+}
+
+void MyMainView::keyPressEvent(QKeyEvent *ev)
+{
+ if((gameEnd<=0.0)&&(gameEnd>-2.0))
+ {
+ /*
+ if(key==options.functionKey[FunctionKeyStart])
+ newRound();
+ */
+ }
+ else if(waitForStart)
+ {
+ /*
+ if((key==options.functionKey[FunctionKeyStart])
+ && (!functionKeyPressed[FunctionKeyStart]))
+ {
+ functionKeyPressed[FunctionKeyStart]=true;
+ resume();
+ }
+ */
+ }
+ else
+ {
+ KKey key(ev);
+ bool accept=true;
+
+ if(actionCollection->action("P1KeyLeft")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyLeft]=true;
+ else if(actionCollection->action("P2KeyLeft")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyLeft]=true;
+
+ else if(actionCollection->action("P1KeyRight")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyRight]=true;
+ else if(actionCollection->action("P2KeyRight")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyRight]=true;
+
+ else if(actionCollection->action("P1KeyAcc")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyAcc]=true;
+ else if(actionCollection->action("P2KeyAcc")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyAcc]=true;
+
+ else if(actionCollection->action("P1Shot")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyShot]=true;
+ else if(actionCollection->action("P2Shot")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyShot]=true;
+
+ else if(actionCollection->action("P1Mine")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyMine]=true;
+ else if(actionCollection->action("P2Mine")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyMine]=true;
+ else
+ accept = false;
+ /*
+ if((key==options.functionKey[FunctionKeyStart])
+ && (!functionKeyPressed[FunctionKeyStart]))
+ {
+ functionKeyPressed[FunctionKeyStart]=true;
+ pause();
+ }
+ */
+ if(!accept)
+ ev->ignore();
+ }
+}
+
+void MyMainView::keyReleaseEvent(QKeyEvent *ev)
+{
+ KKey key(ev);
+ bool accept=true;
+
+ if(actionCollection->action("P1KeyLeft")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyLeft]=false;
+ else if(actionCollection->action("P2KeyLeft")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyLeft]=false;
+
+ else if(actionCollection->action("P1KeyRight")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyRight]=false;
+ else if(actionCollection->action("P2KeyRight")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyRight]=false;
+
+ else if(actionCollection->action("P1KeyAcc")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyAcc]=false;
+ else if(actionCollection->action("P2KeyAcc")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyAcc]=false;
+
+ else if(actionCollection->action("P1Shot")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyShot]=false;
+ else if(actionCollection->action("P2Shot")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyShot]=false;
+
+ else if(actionCollection->action("P1Mine")->shortcut().contains(key))
+ playerKeyPressed[0][PlayerKeyMine]=false;
+ else if(actionCollection->action("P2Mine")->shortcut().contains(key))
+ playerKeyPressed[1][PlayerKeyMine]=false;
+ else
+ accept = false;
+
+ if(!accept)
+ ev->ignore();
+}
+
+void MyMainView::pause()
+{
+ if( !waitForStart )
+ {
+ pauseAction->setChecked( true );
+
+ waitForStart=true;
+ killTimers();
+ emit setStatusText(i18n(" paused "), IDS_PAUSE);
+ }
+}
+
+void MyMainView::resume()
+{
+ waitForStart=false;
+ timerID=startTimer(Options::refreshTime());
+ emit(setStatusText("",IDS_PAUSE));
+ emit(setStatusText("",IDS_MAIN));
+}
+
+void MyMainView::start( )
+{
+ if( ( gameEnd <= 0.0 ) && ( gameEnd > -2.0 ) )
+ {
+ newRound( );
+ }
+ else if( waitForStart )
+ {
+ waitForStart = false;
+ timerID=startTimer(Options::refreshTime());
+ emit(setStatusText("",IDS_PAUSE));
+ emit(setStatusText("",IDS_MAIN));
+ pauseAction->setEnabled( true );
+ pauseAction->setChecked( false );
+ }
+}
+
+void MyMainView::stop()
+{
+ pauseAction->setEnabled( false );
+ pauseAction->setChecked( false );
+
+ killTimers();
+ waitForStart = true;
+}
+
+void MyMainView::togglePause( )
+{
+ if( waitForStart )
+ resume( );
+ else
+ pause( );
+}
+
+void MyMainView::resizeEvent(QResizeEvent *event)
+{
+ double mx,my;
+ MineSprite *mine;
+ BulletSprite *bullet;
+ PowerupSprite *powerup;
+ int i,current;
+
+ mx=(event->size().width()-event->oldSize().width())/2.0;
+ my=(event->size().height()-event->oldSize().height())/2.0;
+ QWidget::resizeEvent(event);
+ view.resize(width(),height());
+ field.resize(width(),height());
+
+ // printf("%d %d\n",field.width(),field.height());
+ sun->move(width()/2-1,height()/2-1);
+
+ for(i=0;i<2;i++)
+ {
+ // ship[i]->adoptSpritefieldBounds();
+ ship[i]->moveBy(mx,my);
+ current=mines[i]->at();
+ for(mine=mines[i]->first();mine;mine=mines[i]->next())
+ {
+ // mine->adoptSpritefieldBounds();
+ mine->moveBy(mx,my);
+ }
+ if(current>=0)
+ mines[i]->at(current);
+
+ current=bullets[i]->at();
+ for(bullet=bullets[i]->first();bullet;bullet=bullets[i]->next())
+ {
+ // bullet->adoptSpritefieldBounds();
+ bullet->moveBy(mx,my);
+ }
+ if(current>=0)
+ bullets[i]->at(current);
+
+ }
+ if(textSprite)
+ textSprite->moveBy((int)mx,(int)my);
+ current=powerups.at();
+ for(powerup=powerups.first();powerup;powerup=powerups.next())
+ powerup->moveBy(mx,my);
+ if(current>=0)
+ powerups.at(current);
+}
+
+void MyMainView::newRound()
+{
+ double mx,my;
+ int i;
+
+ timeToNextPowerup=random.getDouble() * config.powerupRefreshTime;
+ powerups.clear();
+
+ killTimers();
+ mx=width()/2.0;
+ my=height()/2.0;
+ ship[0]->move(mx+config.startPosX,my+config.startPosY);
+ ship[0]->setRotation(0.0);
+ ship[0]->setFrame(0);
+
+ ship[1]->move(mx-config.startPosX,my-config.startPosY);
+ ship[1]->setRotation(M_PI);
+ ship[1]->setFrame(ROTNUM/2);
+
+ ship[0]->setVelocity(config.startVelX,config.startVelY);
+ ship[1]->setVelocity(-config.startVelX,-config.startVelY);
+ for(i=0;i<2;i++)
+ {
+ ship[i]->show();
+ ship[i]->setEnergy(99.9);
+ ship[i]->setHitPoints(Options::startHitPoints(i));
+ ship[i]->stop(false);
+ ship[i]->setExplosion(-1);
+ emit(energy(i,(int)ship[i]->getEnergy()));
+ emit(hitPoints(i,ship[i]->getHitPoints()));
+ bulletShot[i]=false;
+ bullets[i]->clear();
+ mines[i]->clear();
+ ship[i]->mine(0.0);
+ ship[i]->bullet(0.0);
+ ship[i]->setBulletPowerups(0);
+ ship[i]->setMinePowerups(0);
+
+ ai[i]->newRound();
+ }
+ explosions.clear();
+ gameEnd=-10.0;
+ for(i=0;i<PlayerKeyNum;i++)
+ {
+ playerKeyPressed[0][i]=false;
+ playerKeyPressed[1][i]=false;
+ }
+ if(textSprite)
+ {
+ textSprite->hide();
+ delete textSprite;
+ textSprite=0;
+ }
+ field.update();
+
+ QString str = i18n("Press %1 to start")
+ .arg(KShortcut(GAME_START_SHORTCUT).toString());
+ emit(setStatusText(str,IDS_MAIN));
+ emit( setStatusText( "", IDS_PAUSE ) );
+ stop( );
+}
+
+void MyMainView::newGame()
+{
+ int i;
+ for(i=0;i<2;i++)
+ {
+ ship[i]->setWins(0);
+ emit(wins(i,0));
+ }
+ newRound();
+}
+
+void MyMainView::timerEvent(QTimerEvent *event)
+{
+ unsigned w;
+ int i;
+ bool stopped = false;
+
+ if(event->timerId()==timerID)
+ {
+ killTimers();
+ if(gameEnd>0.0)
+ {
+ gameEnd-=1.0;
+ if(gameEnd<=0.0)
+ {
+ stopped = true;
+ if(textSprite)
+ {
+ textSprite->hide();
+ delete textSprite;
+ textSprite=0;
+ }
+
+ textSprite=new QCanvasText(&field);
+ textSprite->move(width()/2,height()/2-90);
+ textSprite->setTextFlags(AlignCenter);
+ textSprite->setColor(qRgb(255,160,0));
+ textSprite->setFont(QFont(KGlobalSettings::generalFont().family(),14));
+ textSprite->show( );
+ if(ship[0]->getHitPoints()==0)
+ {
+ if(ship[1]->getHitPoints()==0)
+ textSprite->setText(i18n("draw round"));
+ else
+ {
+ textSprite->setText(i18n("blue player won the round"));
+ w=ship[1]->getWins()+1;
+ ship[1]->setWins(w);
+ emit(wins(1,w));
+ }
+ }
+ else
+ {
+ textSprite->setText(i18n("red player won the round"));
+ w=ship[0]->getWins()+1;
+ ship[0]->setWins(w);
+ emit(wins(0,w));
+ }
+ QString str = i18n("Press %1 for new round")
+ .arg(KShortcut(GAME_START_SHORTCUT).toString());
+ emit(setStatusText(str,IDS_MAIN));
+ stop( );
+ }
+ }
+
+ if( !stopped )
+ {
+ for(i=0;i<2;i++)
+ if(Options::playerIsAi(i)&&(ship[i]->getHitPoints()>0))
+ ai[i]->think();
+
+ moveMines();
+ moveBullets();
+ moveExplosions();
+ moveShips();
+ calculatePowerups();
+ collisions();
+ timerID=startTimer(Options::refreshTime());
+ }
+ field.update();
+ }
+}
+
+void MyMainView::moveShips()
+{
+ int i,nf,olde;
+ double nx,ny,en,nr;
+ BulletSprite *bullet;
+ MineSprite *mine;
+
+
+ for(i=0;i<2;i++)
+ {
+ bool playerIsAi = Options::playerIsAi(i);
+ olde=(int)ship[i]->getEnergy();
+ if(ship[i]->getHitPoints()==0)
+ {
+ ship[i]->forward(config.gamespeed);
+ ship[i]->calculateGravityAndEnergy(config.gravity,config.sunEnergy,
+ config.gamespeed);
+ }
+ else
+ {
+ ship[i]->calculateGravityAndEnergy(config.gravity,config.sunEnergy,
+ config.gamespeed);
+
+
+ if(!playerIsAi&&playerKeyPressed[i][PlayerKeyRight]
+ || playerIsAi&&ai[i]->rotateRight())
+ ship[i]->rotateRight(config.rotationEnergyNeed,
+ config.rotationSpeed);
+
+ if(!playerIsAi&&playerKeyPressed[i][PlayerKeyLeft]
+ || playerIsAi&&ai[i]->rotateLeft())
+ ship[i]->rotateLeft(config.rotationEnergyNeed,
+ config.rotationSpeed);
+
+ en=ship[i]->getEnergy();
+ nr=ship[i]->getRotation();
+
+
+ nf=ship[i]->frame();
+ nx=cos(nr);
+ ny=sin(nr);
+ if((!playerIsAi&&playerKeyPressed[i][PlayerKeyAcc]
+ || playerIsAi&&ai[i]->accelerate())
+ &&(en>config.energyNeed))
+ {
+ en-=config.energyNeed;
+ ship[i]->setVelocity(ship[i]->xVelocity()+nx*config.acc,
+ ship[i]->yVelocity()-ny*config.acc);
+ }
+ if(en>99.9)
+ en=99.9;
+
+ ship[i]->forward(config.gamespeed);
+ //Bullets and Mines
+ if(!playerIsAi&&playerKeyPressed[i][PlayerKeyShot]
+ ||playerIsAi&&ai[i]->shootBullet())
+ {
+ if((en>config.shotEnergyNeed) && (!ship[i]->reloadsBullet()))
+ {
+ if(bullets[i]->count() <
+ (config.maxBullets+ship[i]->getBulletPowerups()))
+ {
+ ship[i]->bullet(config.bulletReloadTime);
+ en-=config.shotEnergyNeed;
+ bullet=new BulletSprite(bulletsequence[i],&field,i,
+ config.bulletLifeTime);
+ bullet->move(ship[i]->x()+nx*SHOTDIST,
+ ship[i]->y()-ny*SHOTDIST);
+ bullet->setVelocity(ship[i]->xVelocity()+nx*config.shotSpeed,
+ ship[i]->yVelocity()-ny*config.shotSpeed);
+ // bullet->setBoundsAction(QwRealMobileSprite::Wrap);
+ bullet->show();
+
+ bullets[i]->append(bullet);
+ }
+ }
+ }
+ if(!Options::playerIsAi(i)&&playerKeyPressed[i][PlayerKeyMine]
+ || Options::playerIsAi(i)&&ai[i]->layMine())
+ {
+ if((en>config.mineEnergyNeed) && (!ship[i]->reloadsMine()))
+ {
+ if(mines[i]->count() <
+ (config.maxMines+ship[i]->getMinePowerups()))
+ {
+ ship[i]->mine(config.mineReloadTime);
+ en-=config.mineEnergyNeed;
+ mine=new MineSprite(minesequence[i],&field,i,
+ config.mineActivateTime,config.mineFuel);
+ mine->move(ship[i]->x(),ship[i]->y());
+ mine->setVelocity(0,0);
+ //mine->setBoundsAction(QwRealMobileSprite::Wrap);
+ mine->show();
+ mines[i]->append(mine);
+ }
+ }
+ }
+ ship[i]->setEnergy(en);
+ if(olde!=(int)en)
+ emit(energy(i,(int)en));
+ }
+ }
+}
+
+void MyMainView::moveMines()
+{
+ MineSprite* mine;
+ int p;
+
+ for(p=0;p<2;p++)
+ {
+ mine=mines[p]->first();
+ while(mine)
+ {
+ mine->calculateGravity(config.gravity,config.gamespeed);
+ mine->forward(config.gamespeed);
+ if(mine->over())
+ {
+ mine->hide();
+ mines[p]->remove();
+ mine=mines[p]->current();
+ }
+ else
+ mine=mines[p]->next();
+ }
+ }
+}
+
+void MyMainView::moveBullets()
+{
+ int i;
+ BulletSprite *sp;
+
+ for(i=0;i<2;i++)
+ {
+ sp=bullets[i]->first();
+ while(sp)
+ {
+ sp->calculateGravity(config.gravity,config.gamespeed);
+ sp->forward(config.gamespeed);
+ if(sp->timeOut())
+ {
+ sp->hide();
+ bullets[i]->removeRef(sp);
+ sp=bullets[i]->current();
+ }
+ else
+ sp=bullets[i]->next();
+ }
+ }
+}
+
+void MyMainView::moveExplosions()
+{
+ ExplosionSprite *ex;
+ ex=explosions.first();
+ while(ex)
+ {
+ ex->forward(config.gamespeed);
+ if(ex->isOver())
+ {
+ explosions.removeRef(ex);
+ ex=explosions.current();
+ }
+ else
+ ex=explosions.next();
+ }
+}
+
+void MyMainView::calculatePowerups()
+{
+ PowerupSprite *sp;
+ int type,x,y;
+
+ sp=powerups.first();
+ while(sp)
+ {
+ sp->setLifetime(sp->getLifetime()-config.gamespeed);
+ if(sp->getLifetime()<0)
+ {
+ powerups.removeRef(sp);
+ sp=powerups.current();
+ }
+ else
+ sp=powerups.next();
+ }
+ timeToNextPowerup-=config.gamespeed;
+ if(timeToNextPowerup<0)
+ {
+ timeToNextPowerup= random.getDouble() * config.powerupRefreshTime;
+ type= random.getLong(PowerupSprite::PowerupNum);
+ sp=new PowerupSprite(powerupsequence[type],&field,type,
+ config.powerupLifeTime);
+ do
+ {
+ x = random.getLong(width()-40)+20;
+ y = random.getLong(height()-40)+20;
+ }
+ while(((x-width()/2)*(x-width()/2)+(y-height()/2)*(y-height()/2))<(50*50));
+ sp->move(x,y);
+ powerups.append(sp);
+ sp->show();
+ }
+}
+
+void MyMainView::collisions()
+{
+ int pl,hp,op,oldhp[2],ohp;
+ QCanvasItemList unexact;
+ QCanvasItem *sprite;
+ BulletSprite *bullet;
+ MineSprite *mine;
+ ExplosionSprite *expl;
+ ShipSprite *s;
+ PowerupSprite *power;
+ QCanvasItemList hitlist;
+ double ndx[2],ndy[2];
+ double en;
+ QCanvasItemList::Iterator it;
+
+ for(pl=0;pl<2;pl++)
+ {
+ if(!ship[pl]->isStopped())
+ {
+ unexact.clear();
+ unexact=ship[pl]->collisions(false);
+ oldhp[pl]=hp=ship[pl]->getHitPoints();
+ hitlist.clear();
+ for(it=unexact.begin(); it != unexact.end(); ++it)
+ {
+ sprite = (*it);
+ if((sprite->rtti()!=S_EXPLOSION)
+ && !((sprite->rtti()!=S_SUN)&&(ship[pl]->getHitPoints()==0)))
+ if(ship[pl]->collidesWith(sprite))
+ if(!hitlist.contains(sprite))
+ hitlist.append(sprite);
+ }
+
+ for(it=hitlist.begin(); it != hitlist.end(); ++it)
+ {
+ sprite = (*it);
+ switch(sprite->rtti())
+ {
+ case S_SUN:
+ hp=0;
+ ship[pl]->stop();
+ break;
+ case S_BULLET:
+ bullet=(BulletSprite *)sprite;
+ bullet->hide();
+ bullets[bullet->getPlayerNumber()]->removeRef(bullet);
+ hp-=config.bulletDamage;
+ break;
+ case S_SHIP:
+ s=(ShipSprite*)sprite;
+ ohp=s->getHitPoints();
+ if(ohp>0)
+ {
+ s->setHitPoints(ohp-hp-config.shipDamage);
+ emit(hitPoints(s->getPlayerNumber(),s->getHitPoints()));
+ ndx[0]=((1-EPSILON)*ship[0]->xVelocity()+(1+EPSILON)*ship[1]->xVelocity())/2.0;
+ ndy[0]=((1-EPSILON)*ship[0]->yVelocity()+(1+EPSILON)*ship[1]->yVelocity())/2.0;
+ ndx[1]=((1-EPSILON)*ship[1]->xVelocity()+(1+EPSILON)*ship[0]->xVelocity())/2.0;
+ ndy[1]=((1-EPSILON)*ship[1]->yVelocity()+(1+EPSILON)*ship[0]->yVelocity())/2.0;
+ ship[0]->setVelocity(ndx[0],ndy[0]);
+ ship[1]->setVelocity(ndx[1],ndy[1]);
+ hp-=ohp+config.shipDamage;
+ }
+ break;
+ case S_MINE:
+ mine=(MineSprite *)sprite;
+ if(mine->isActive()&& !mine->explodes())
+ {
+ mine->explode(mineexplosionsequence);
+ ndx[0]=(ship[pl]->xVelocity()+0.3*mine->xVelocity())/1.3;
+ ndy[0]=(ship[pl]->yVelocity()+0.3*mine->yVelocity())/1.3;
+ ship[pl]->setVelocity(ndx[0],ndy[0]);
+ mine->setVelocity(ndx[0],ndy[0]);
+ hp-=config.mineDamage;
+ }
+ break;
+ case S_POWERUP:
+ power=(PowerupSprite *)sprite;
+ switch(power->getType())
+ {
+ case PowerupSprite::PowerupShield:
+ hp+=config.powerupShieldAmount;
+ break;
+ case PowerupSprite::PowerupEnergy:
+ en=ship[pl]->getEnergy()+config.powerupEnergyAmount;
+ if(en>99)
+ en=99;
+ ship[pl]->setEnergy(en);
+ break;
+ case PowerupSprite::PowerupMine:
+ ship[pl]->setMinePowerups(
+ ship[pl]->getMinePowerups()+1);
+ break;
+ case PowerupSprite::PowerupBullet:
+ ship[pl]->setBulletPowerups(
+ ship[pl]->getMinePowerups()+1);
+ break;
+ }
+ power->hide();
+ powerups.removeRef(power);
+ break;
+ }
+ }
+ if(hp>99)
+ hp=99;
+ ship[pl]->setHitPoints(hp);
+ }
+
+ for(mine=mines[pl]->first();mine;mine=mines[pl]->next())
+ {
+ if(!mine->explodes())
+ {
+ unexact.clear();
+ unexact=mine->collisions(false);
+ hitlist.clear();
+ for( it=unexact.begin(); it != unexact.end(); ++it )
+ {
+ sprite = (*it);
+ if(sprite->rtti()==S_BULLET)
+ if(mine->collidesWith(sprite))
+ if(!hitlist.contains(sprite))
+ hitlist.append(sprite);
+ }
+ if(hitlist.count()>0)
+ {
+ mine->explode(mineexplosionsequence);
+ for(it=hitlist.begin(); it != hitlist.end(); ++it)
+ {
+ bullet=(BulletSprite*)(*it);
+ bullets[bullet->getPlayerNumber()]->removeRef(bullet);
+ }
+ }
+ }
+ }
+ }
+
+ hitlist.clear();
+ unexact.clear();
+ unexact=sun->collisions(false);
+ for( it = unexact.begin(); it != unexact.end(); ++it)
+ {
+ sprite=(*it);
+ switch(sprite->rtti())
+ {
+ case S_BULLET:
+ if(sun->collidesWith(sprite))
+ if(!hitlist.contains(sprite))
+ hitlist.append(sprite);
+ break;
+ case S_MINE:
+ if(!((MobileSprite*)sprite)->isStopped())
+ if(sun->collidesWith(sprite))
+ if(!hitlist.contains(sprite))
+ hitlist.append(sprite);
+ break;
+ }
+ }
+
+ for(it=hitlist.begin(); it != hitlist.end(); ++it)
+ {
+ sprite=(*it);
+ switch(sprite->rtti())
+ {
+ case S_BULLET:
+ bullet=(BulletSprite *)sprite;
+ bullet->hide();
+ bullets[bullet->getPlayerNumber()]->removeRef(bullet);
+ break;
+ case S_MINE:
+ mine=(MineSprite*)sprite;
+ mine->stop();
+ if(!mine->explodes())
+ mine->explode(mineexplosionsequence);
+ break;
+ }
+ }
+
+
+ for(pl=0;pl<2;pl++)
+ {
+ hp=ship[pl]->getHitPoints();
+ if(hp!=oldhp[pl])
+ emit(hitPoints(pl,hp));
+ if((hp==0)&&(ship[pl]->getExplosion()<0))
+ {
+ op=(pl+1)%2;
+ ship[pl]->setExplosion((int)(EXPLOSION_TIME/config.gamespeed));
+ expl=new ExplosionSprite(explosionsequence,&field,ship[pl]);
+ expl->show();
+ explosions.append(expl);
+ gameEnd=Options::timeAfterKill()/config.gamespeed;
+ }
+ }
+}
+
+void MyMainView::gameSetup()
+{
+ if(!waitForStart)
+ pause();
+
+ if (KConfigDialog::showDialog("settings"))
+ return;
+
+ SettingsDialog *settings=new SettingsDialog(&customConfig,this,"settings");
+ connect(settings, SIGNAL(settingsUpdated()),this,SLOT(closeSettings()));
+ settings->show();
+}
+
+void MyMainView::closeSettings(){
+ if(Options::lastConfig()<predefinedConfigNum)
+ config=modifyConfig(predefinedConfig[Options::lastConfig()]);
+ else
+ config=modifyConfig(customConfig);
+}
+
+QCanvasPixmapArray* MyMainView::loadOldPixmapSequence(const QString& datapattern,
+ const QString& maskpattern, int framecount)
+{
+ int image;
+ QPtrList<QPixmap> pixmaplist;
+ QPtrList<QPoint> pointlist;
+ QString dataname, maskname;
+ QPixmap *pix;
+ QBitmap *bitmap;
+ int hotx=0, hoty=0;
+ QPoint *point;
+
+ for( image=0; image < framecount; image++ )
+ {
+ // #### Why is this a QString??
+ dataname.sprintf( datapattern.ascii(), image );
+ maskname.sprintf( maskpattern.ascii(), image );
+
+ QFile file(dataname);
+ if( file.open( IO_ReadOnly ) )
+ {
+ char line[128];
+ file.readLine( line, 128 ); // Skip "P6"/"P3" line
+ file.readLine( line, 128 );
+
+ while ( line[0] == '#' )
+ {
+ // Comment line - see if it has additional parameters
+ if ( 0 == strncmp( line,"# HOTSPOT ", 10 ) )
+ sscanf( line+10, "%d %d", &hotx, &hoty);
+
+ file.readLine( line, 128 );
+ }
+ point = new QPoint( hotx, hoty );
+ pointlist.append( point );
+ }
+
+ pix = new QPixmap( dataname );
+ bitmap = new QBitmap( maskname );
+ pix->setMask( *bitmap );
+
+ pixmaplist.append( pix );
+ }
+
+ QCanvasPixmapArray* newarray = new QCanvasPixmapArray( pixmaplist, pointlist );
+ return newarray;
+}
+
+#include "mainview.moc"