diff options
Diffstat (limited to 'kspaceduel/mainview.cpp')
-rw-r--r-- | kspaceduel/mainview.cpp | 1052 |
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" |