mainview.cpp 34.7 KB
Newer Older
Simon Huerlimann's avatar
Simon Huerlimann committed
1 2 3
/*
    Copyright (C) 1998-2001 Andreas Zehender <az@azweb.de>
    Copyright (C) 2006-2007 Dirk Rathlev <dirkrathlev@gmx.de>
4

Simon Huerlimann's avatar
Simon Huerlimann committed
5
    This program is free software; you can redistribute it and/or modify
6 7 8 9 10 11 12 13 14 15 16 17 18 19
    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

20
#include "mainview.h"
21 22
#include "ai.h"
#include "options.h"
23

24 25 26 27 28
#include <KActionCollection>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include <KToggleAction>
Dirk Rathlev's avatar
Dirk Rathlev committed
29 30

#include <QAbstractEventDispatcher>
Dirk Rathlev's avatar
Dirk Rathlev committed
31
#include <QBrush>
32
#include <QFontDatabase>
Dirk Rathlev's avatar
Dirk Rathlev committed
33
#include <QGraphicsSimpleTextItem>
Dirk Rathlev's avatar
Dirk Rathlev committed
34
#include <QKeyEvent>
35
#include <QKeySequence>
Dirk Rathlev's avatar
Dirk Rathlev committed
36
#include <QResizeEvent>
37
#include <QSvgRenderer>
38
#include <QStandardPaths>
39 40

#include <math.h>
Andreas Zehender's avatar
Andreas Zehender committed
41

Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
42
KToggleAction *MyMainView::pauseAction = nullptr;
43

Dirk Rathlev's avatar
Dirk Rathlev committed
44 45 46 47 48 49 50
static struct
 {
     int id;
     const char *path;
 }
 kspd_animations [] =
 {
51 52 53 54
     { ID_EXPLOSION, "explos%1"},
     { ID_MINE1, "mine_red%1"},
     { ID_MINE2, "mine_blue%1"},
     { ID_MINEEXPLO, "mineex%1"},
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
55
     { 0, nullptr}
Dirk Rathlev's avatar
Dirk Rathlev committed
56 57
 };

58 59
MyMainView::MyMainView(QWidget *parent)
    :QWidget(parent),
Dirk Rathlev's avatar
Dirk Rathlev committed
60
    field(this),//0,0,DEF_WIDTH,DEF_HEIGHT),
61
    view(&field,this)
Andreas Zehender's avatar
Andreas Zehender committed
62 63
{
   int i,p;
64
   setMinimumSize(600,400);
65
   random.seed(QRandomGenerator::global()->generate());
Laurent Montel's avatar
Laurent Montel committed
66
   QPixmap backgr(QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral(MV_BACKGROUND)));
Laurent Montel's avatar
Laurent Montel committed
67

Dirk Rathlev's avatar
Dirk Rathlev committed
68 69
   field.setBackgroundBrush(QBrush(backgr));
   view.setCacheMode(QGraphicsView::CacheBackground);
Waldo Bastian's avatar
Waldo Bastian committed
70

Dirk Rathlev's avatar
Dirk Rathlev committed
71 72 73 74 75
   setFocusPolicy(Qt::StrongFocus);
   // FIXME: is this needed anymore?
   //view.setResizePolicy(Q3ScrollView::AutoOne);
   view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
76
   view.setFrameStyle(QFrame::NoFrame);
77

Yuri Chornoivan's avatar
Yuri Chornoivan committed
78
   for(p=0;p<2;++p)
Andreas Zehender's avatar
Andreas Zehender committed
79
   {
Yuri Chornoivan's avatar
Yuri Chornoivan committed
80
      for(i=0;i<PlayerKeyNum;++i)
Andreas Zehender's avatar
Andreas Zehender committed
81 82 83 84 85
         playerKeyPressed[p][i]=false;
      bulletShot[p]=false;
      minePut[p]=false;
   }

Laurent Montel's avatar
Laurent Montel committed
86
   svgrender = new QSvgRenderer(QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral(MV_SVG_FILE)));
Laurent Montel's avatar
Laurent Montel committed
87

Laurent Montel's avatar
Laurent Montel committed
88
   sun=new SunSprite(svgrender,QStringLiteral( MV_SUN ));
89
   field.addItem(sun);
90 91
   sun->setPos(QPointF(width()/2-1-(sun->width()/2),
                       height()/2-1-(sun->height()/2)));
Laurent Montel's avatar
Laurent Montel committed
92

Laurent Montel's avatar
Laurent Montel committed
93 94 95 96
   powerupelements[0] = QStringLiteral( MV_POWERMINE );
   powerupelements[1] = QStringLiteral( MV_POWERBULLET );
   powerupelements[2] = QStringLiteral( MV_POWERSHIELD );
   powerupelements[3] = QStringLiteral( MV_POWERENERGY );
Laurent Montel's avatar
Laurent Montel committed
97

Laurent Montel's avatar
Laurent Montel committed
98 99
   ship[0]=new ShipSprite(svgrender, QStringLiteral( MV_SHIP1 ), 0);
   ship[1]=new ShipSprite(svgrender, QStringLiteral( MV_SHIP2 ), 1);
100 101
   field.addItem(ship[0]);
   field.addItem(ship[1]);
Laurent Montel's avatar
Laurent Montel committed
102

Dirk Rathlev's avatar
Dirk Rathlev committed
103
   readSprites();
Laurent Montel's avatar
Laurent Montel committed
104

Yuri Chornoivan's avatar
Yuri Chornoivan committed
105
   for(i=0;i<2;++i)
Andreas Zehender's avatar
Andreas Zehender committed
106
   {
107
      // ship[i]->setBoundsAction(QwRealMobileSprite::Wrap);
Andreas Zehender's avatar
Andreas Zehender committed
108
      ship[i]->hide();
109 110
      bullets[i]=new QList<BulletSprite*>;
      mines[i]=new QList<MineSprite*>;
Andreas Zehender's avatar
Andreas Zehender committed
111 112 113 114

   }

   waitForStart=false;
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
115
   textSprite = nullptr;
116
   readConfig();
Andreas Zehender's avatar
Andreas Zehender committed
117 118 119 120
}

MyMainView::~MyMainView()
{
Dirk Rathlev's avatar
Dirk Rathlev committed
121
   int i;
Laurent Montel's avatar
Laurent Montel committed
122
   QAbstractEventDispatcher::instance()->unregisterTimers(this);
Dirk Rathlev's avatar
Dirk Rathlev committed
123 124 125 126

   for(i=0;i<2;i++)
   {
      delete ai[i];
127 128 129 130
      qDeleteAll(*mines[i]);
      delete mines[i];
      qDeleteAll(*bullets[i]);
      delete bullets[i];
Dirk Rathlev's avatar
Dirk Rathlev committed
131
   }
Laurent Montel's avatar
Laurent Montel committed
132

133 134
   qDeleteAll(powerups);
   powerups.clear();
Laurent Montel's avatar
Laurent Montel committed
135

136 137
   qDeleteAll(explosions);
   explosions.clear();
Laurent Montel's avatar
Laurent Montel committed
138

139
   writeConfig();
Laurent Montel's avatar
Laurent Montel committed
140
   delete svgrender;
Andreas Zehender's avatar
Andreas Zehender committed
141 142
}

143
void MyMainView::setActionCollection(KActionCollection *a)
Andreas Zehender's avatar
Andreas Zehender committed
144
{
145 146 147
   actionCollection = a;
}

148 149 150 151
/* Assumes that there are no gaps between animation frames. ie 1,2,3 will only have frames 1&2
   recognized. It also assumes that there is at least one frame. */
// FIXME: Add Check for existence of first frame
// TODO: Add support for missing frames (ie 1,2,5)
Dirk Rathlev's avatar
Dirk Rathlev committed
152 153 154 155 156
bool MyMainView::readSprites()
{
   int i = 0;
   while ( kspd_animations[i].id )
   {
157 158
      QList<QString> anim;
      short frame = 0;
Laurent Montel's avatar
Laurent Montel committed
159
      QString element =QLatin1String( kspd_animations[i].path );
160 161 162 163 164 165 166
      QString elem = element.arg(frame, 2, 10, QLatin1Char('0'));
      do
      {
	 anim.append(elem);
	 frame++;
	 elem = element.arg(frame, 2, 10, QLatin1Char('0'));
      } while ( svgrender->elementExists(elem) );
Dirk Rathlev's avatar
Dirk Rathlev committed
167 168 169 170
      animation.insert( kspd_animations[i].id, anim );
      i++;
   }

171
   // FIXME: Perform test!
Dirk Rathlev's avatar
Dirk Rathlev committed
172 173
   return true;
}
Dirk Rathlev's avatar
Dirk Rathlev committed
174

175 176
void MyMainView::readConfig()
{
Laurent Montel's avatar
Port++  
Laurent Montel committed
177
   KConfigGroup game(KSharedConfig::openConfig(), "Game");
Andreas Zehender's avatar
Andreas Zehender committed
178
   int i;
179

Laurent Montel's avatar
Laurent Montel committed
180
   customConfig.gamespeed=game.readEntry("gamespeed",
Andreas Zehender's avatar
Andreas Zehender committed
181 182 183
                                                  predefinedConfig[0].gamespeed);

   customConfig.gravity=
Laurent Montel's avatar
Laurent Montel committed
184
      game.readEntry("gravity",predefinedConfig[0].gravity);
Andreas Zehender's avatar
Andreas Zehender committed
185
   customConfig.acc=
Laurent Montel's avatar
Laurent Montel committed
186
      game.readEntry("acceleration",predefinedConfig[0].acc);
Andreas Zehender's avatar
Andreas Zehender committed
187
   customConfig.bulletDamage=
Laurent Montel's avatar
Laurent Montel committed
188
      game.readEntry("bulletDamage",predefinedConfig[0].bulletDamage);
Andreas Zehender's avatar
Andreas Zehender committed
189
   customConfig.bulletLifeTime=
Laurent Montel's avatar
Laurent Montel committed
190
      game.readEntry("bulletLifeTime",predefinedConfig[0].bulletLifeTime);
Andreas Zehender's avatar
Andreas Zehender committed
191
   customConfig.bulletReloadTime=
Laurent Montel's avatar
Laurent Montel committed
192
      game.readEntry("bulletReloadTime",predefinedConfig[0].bulletReloadTime);
Andreas Zehender's avatar
Andreas Zehender committed
193
   customConfig.mineDamage=
Laurent Montel's avatar
Laurent Montel committed
194
      game.readEntry("mineDamage",predefinedConfig[0].mineDamage);
Andreas Zehender's avatar
Andreas Zehender committed
195
   customConfig.shipDamage=
Laurent Montel's avatar
Laurent Montel committed
196
      game.readEntry("shipDamage",predefinedConfig[0].shipDamage);
Andreas Zehender's avatar
Andreas Zehender committed
197
   customConfig.maxBullets=
Laurent Montel's avatar
Laurent Montel committed
198
      game.readEntry("maxBullets",predefinedConfig[0].maxBullets);
Andreas Zehender's avatar
Andreas Zehender committed
199
   customConfig.maxMines=
Laurent Montel's avatar
Laurent Montel committed
200
      game.readEntry("maxMines",predefinedConfig[0].maxMines);
Andreas Zehender's avatar
Andreas Zehender committed
201
   customConfig.mineReloadTime=
Laurent Montel's avatar
Laurent Montel committed
202
      game.readEntry("mineReloadTime",predefinedConfig[0].mineReloadTime);
Andreas Zehender's avatar
Andreas Zehender committed
203
   customConfig.rotationSpeed=
Laurent Montel's avatar
Laurent Montel committed
204
      game.readEntry("rotationSpeed",predefinedConfig[0].rotationSpeed);
Andreas Zehender's avatar
Andreas Zehender committed
205
   customConfig.shotSpeed=
Laurent Montel's avatar
Laurent Montel committed
206
      game.readEntry("shotSpeed",predefinedConfig[0].shotSpeed);
Andreas Zehender's avatar
Andreas Zehender committed
207
   customConfig.energyNeed=
Laurent Montel's avatar
Laurent Montel committed
208
      game.readEntry("accEnergyNeed",predefinedConfig[0].energyNeed);
Andreas Zehender's avatar
Andreas Zehender committed
209
   customConfig.rotationEnergyNeed=
Laurent Montel's avatar
Laurent Montel committed
210
      game.readEntry("rotationEnergyNeed",predefinedConfig[0].rotationEnergyNeed);
Andreas Zehender's avatar
Andreas Zehender committed
211
   customConfig.sunEnergy=
Laurent Montel's avatar
Laurent Montel committed
212
      game.readEntry("sunEnergy",predefinedConfig[0].sunEnergy);
Andreas Zehender's avatar
Andreas Zehender committed
213
   customConfig.mineActivateTime=
Laurent Montel's avatar
Laurent Montel committed
214
      game.readEntry("mineActivateTime",predefinedConfig[0].mineActivateTime);
Andreas Zehender's avatar
Andreas Zehender committed
215
   customConfig.mineFuel=
Laurent Montel's avatar
Laurent Montel committed
216
      game.readEntry("mineFuel",predefinedConfig[0].mineFuel);
Andreas Zehender's avatar
Andreas Zehender committed
217
   customConfig.shotEnergyNeed=
Laurent Montel's avatar
Laurent Montel committed
218
      game.readEntry("shotEnergyNeed",predefinedConfig[0].shotEnergyNeed);
Andreas Zehender's avatar
Andreas Zehender committed
219
   customConfig.mineEnergyNeed=
Laurent Montel's avatar
Laurent Montel committed
220
      game.readEntry("mineEnergyNeed",predefinedConfig[0].mineEnergyNeed);
Andreas Zehender's avatar
Andreas Zehender committed
221
   customConfig.startPosX=
Laurent Montel's avatar
Laurent Montel committed
222
      game.readEntry("startPosX",predefinedConfig[0].startPosX);
Andreas Zehender's avatar
Andreas Zehender committed
223
   customConfig.startPosY=
Laurent Montel's avatar
Laurent Montel committed
224
      game.readEntry("startPosY",predefinedConfig[0].startPosY);
Andreas Zehender's avatar
Andreas Zehender committed
225
   customConfig.startVelX=
Laurent Montel's avatar
Laurent Montel committed
226
      game.readEntry("startVelX",predefinedConfig[0].startVelX);
Andreas Zehender's avatar
Andreas Zehender committed
227
   customConfig.startVelY=
Laurent Montel's avatar
Laurent Montel committed
228
      game.readEntry("startVelY",predefinedConfig[0].startVelY);
Andreas Zehender's avatar
Andreas Zehender committed
229
   customConfig.powerupLifeTime=
Laurent Montel's avatar
Laurent Montel committed
230
      game.readEntry("powerupLifeTime",predefinedConfig[0].powerupLifeTime);
Andreas Zehender's avatar
Andreas Zehender committed
231
   customConfig.powerupRefreshTime=
Laurent Montel's avatar
Laurent Montel committed
232
      game.readEntry("powerupRefreshTime",predefinedConfig[0].powerupRefreshTime);
Andreas Zehender's avatar
Andreas Zehender committed
233
   customConfig.powerupShieldAmount=
Laurent Montel's avatar
Laurent Montel committed
234
      game.readEntry("powerupShieldAmount",
Andreas Zehender's avatar
Andreas Zehender committed
235 236
                              predefinedConfig[0].powerupShieldAmount);
   customConfig.powerupEnergyAmount=
Laurent Montel's avatar
Laurent Montel committed
237
      game.readEntry("powerupEnergyAmount",
Andreas Zehender's avatar
Andreas Zehender committed
238
                              predefinedConfig[0].powerupEnergyAmount);
Andreas Zehender's avatar
Andreas Zehender committed
239

240 241
   if(Options::lastConfig() < predefinedConfigNum)
      config=modifyConfig(predefinedConfig[Options::lastConfig()]);
Andreas Zehender's avatar
Andreas Zehender committed
242 243 244
   else
      config=modifyConfig(customConfig);

Yuri Chornoivan's avatar
Yuri Chornoivan committed
245
   for(i=0;i<2;++i)
246
      ai[i]=new Ai(i,ship,bullets,mines,&config);
Andreas Zehender's avatar
Andreas Zehender committed
247 248 249 250
}

void MyMainView::writeConfig()
{
Laurent Montel's avatar
Port++  
Laurent Montel committed
251
   KConfigGroup game(KSharedConfig::openConfig(), "Game");
Laurent Montel's avatar
Laurent Montel committed
252

Stephan Kulow's avatar
Stephan Kulow committed
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
   game.writeEntry("gravity",customConfig.gravity);
   game.writeEntry("acceleration",customConfig.acc);
   game.writeEntry("bulletDamage",customConfig.bulletDamage);
   game.writeEntry("bulletLifeTime",customConfig.bulletLifeTime);
   game.writeEntry("bulletReloadTime",customConfig.bulletReloadTime);
   game.writeEntry("mineDamage",customConfig.mineDamage);
   game.writeEntry("shipDamage",customConfig.shipDamage);
   game.writeEntry("maxBullets",customConfig.maxBullets);
   game.writeEntry("maxMines",customConfig.maxMines);
   game.writeEntry("rotationSpeed",customConfig.rotationSpeed);
   game.writeEntry("shotSpeed",customConfig.shotSpeed);
   game.writeEntry("accEnergyNeed",customConfig.energyNeed);
   game.writeEntry("rotationEnergyNeed",customConfig.rotationEnergyNeed);
   game.writeEntry("sunEnergy",customConfig.sunEnergy);
   game.writeEntry("mineActivateTime",customConfig.mineActivateTime);
   game.writeEntry("mineReloadTime",customConfig.mineReloadTime);
   game.writeEntry("mineFuel",customConfig.mineFuel);
   game.writeEntry("shotEnergyNeed",customConfig.shotEnergyNeed);
   game.writeEntry("mineEnergyNeed",customConfig.mineEnergyNeed);

   game.writeEntry("startPosX",customConfig.startPosX);
   game.writeEntry("startPosY",customConfig.startPosY);
   game.writeEntry("startVelX",customConfig.startVelX);
   game.writeEntry("startVelY",customConfig.startVelY);

   game.writeEntry("powerupLifeTime",customConfig.powerupLifeTime);
   game.writeEntry("powerupRefreshTime",customConfig.powerupRefreshTime);
   game.writeEntry("powerupShieldAmount",customConfig.powerupShieldAmount);
   game.writeEntry("powerupEnergyAmount",customConfig.powerupEnergyAmount);
Andreas Zehender's avatar
Andreas Zehender committed
282 283
}

Laurent Montel's avatar
Laurent Montel committed
284
SConfig MyMainView::modifyConfig(const SConfig &conf)
Andreas Zehender's avatar
Andreas Zehender committed
285 286
{
   SConfig newConfig=conf;
287
   newConfig.gamespeed*=Options::refreshTime()/33.0;
Andreas Zehender's avatar
Andreas Zehender committed
288 289 290 291 292 293 294 295 296 297 298
   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)
{
299 300 301
    // if-statement kept for historical reasons, maybe not needed anymore
    if ( ((gameEnd>0.0) || (gameEnd<=-2.0)) && (!waitForStart) )
    {
Laurent Montel's avatar
Laurent Montel committed
302
      if(actionCollection->action(QStringLiteral( "P1KeyLeft" ))->shortcuts().contains(ev->key()))
303
            playerKeyPressed[0][PlayerKeyLeft]=true;
Laurent Montel's avatar
Laurent Montel committed
304
      else if(actionCollection->action(QStringLiteral( "P2KeyLeft" ))->shortcuts().contains(ev->key()))
305
            playerKeyPressed[1][PlayerKeyLeft]=true;
Laurent Montel's avatar
Laurent Montel committed
306

Laurent Montel's avatar
Laurent Montel committed
307
      else if(actionCollection->action(QStringLiteral( "P1KeyRight" ))->shortcuts().contains(ev->key()))
308
            playerKeyPressed[0][PlayerKeyRight]=true;
Laurent Montel's avatar
Laurent Montel committed
309
      else if(actionCollection->action(QStringLiteral( "P2KeyRight" ))->shortcuts().contains(ev->key()))
310
            playerKeyPressed[1][PlayerKeyRight]=true;
Laurent Montel's avatar
Laurent Montel committed
311

Laurent Montel's avatar
Laurent Montel committed
312
      else if(actionCollection->action(QStringLiteral( "P1KeyAcc" ))->shortcuts().contains(ev->key()))
313
            playerKeyPressed[0][PlayerKeyAcc]=true;
Laurent Montel's avatar
Laurent Montel committed
314
      else if(actionCollection->action(QStringLiteral( "P2KeyAcc" ))->shortcuts().contains(ev->key()))
315
            playerKeyPressed[1][PlayerKeyAcc]=true;
Laurent Montel's avatar
Laurent Montel committed
316

Laurent Montel's avatar
Laurent Montel committed
317
      else if(actionCollection->action(QStringLiteral( "P1Shot" ))->shortcuts().contains(ev->key()))
318
            playerKeyPressed[0][PlayerKeyShot]=true;
Laurent Montel's avatar
Laurent Montel committed
319
      else if(actionCollection->action(QStringLiteral( "P2Shot" ))->shortcuts().contains(ev->key()))
320
            playerKeyPressed[1][PlayerKeyShot]=true;
Laurent Montel's avatar
Laurent Montel committed
321

Laurent Montel's avatar
Laurent Montel committed
322
      else if(actionCollection->action(QStringLiteral( "P1Mine" ))->shortcuts().contains(ev->key()))
323
            playerKeyPressed[0][PlayerKeyMine]=true;
Laurent Montel's avatar
Laurent Montel committed
324
      else if(actionCollection->action(QStringLiteral( "P2Mine" ))->shortcuts().contains(ev->key()))
325 326
            playerKeyPressed[1][PlayerKeyMine]=true;
      else
327 328
        ev->ignore();
    }
Andreas Zehender's avatar
Andreas Zehender committed
329 330
}

331
void MyMainView::keyReleaseEvent(QKeyEvent *ev)
Andreas Zehender's avatar
Andreas Zehender committed
332
{
Laurent Montel's avatar
Laurent Montel committed
333
   if(actionCollection->action(QStringLiteral( "P1KeyLeft" ))->shortcuts().contains(ev->key()))
334
      playerKeyPressed[0][PlayerKeyLeft]=false;
Laurent Montel's avatar
Laurent Montel committed
335
   else if(actionCollection->action(QStringLiteral( "P2KeyLeft" ))->shortcuts().contains(ev->key()))
336
      playerKeyPressed[1][PlayerKeyLeft]=false;
Laurent Montel's avatar
Laurent Montel committed
337

Laurent Montel's avatar
Laurent Montel committed
338
   else if(actionCollection->action(QStringLiteral( "P1KeyRight" ))->shortcuts().contains(ev->key()))
339
      playerKeyPressed[0][PlayerKeyRight]=false;
Laurent Montel's avatar
Laurent Montel committed
340
   else if(actionCollection->action(QStringLiteral( "P2KeyRight" ))->shortcuts().contains(ev->key()))
341
      playerKeyPressed[1][PlayerKeyRight]=false;
Laurent Montel's avatar
Laurent Montel committed
342

Laurent Montel's avatar
Laurent Montel committed
343
   else if(actionCollection->action(QStringLiteral( "P1KeyAcc" ))->shortcuts().contains(ev->key()))
344
      playerKeyPressed[0][PlayerKeyAcc]=false;
Laurent Montel's avatar
Laurent Montel committed
345
   else if(actionCollection->action(QStringLiteral( "P2KeyAcc" ))->shortcuts().contains(ev->key()))
346
      playerKeyPressed[1][PlayerKeyAcc]=false;
Laurent Montel's avatar
Laurent Montel committed
347

Laurent Montel's avatar
Laurent Montel committed
348
   else if(actionCollection->action(QStringLiteral( "P1Shot" ))->shortcuts().contains(ev->key()))
349
      playerKeyPressed[0][PlayerKeyShot]=false;
Laurent Montel's avatar
Laurent Montel committed
350
   else if(actionCollection->action(QStringLiteral( "P2Shot" ))->shortcuts().contains(ev->key()))
351
      playerKeyPressed[1][PlayerKeyShot]=false;
Laurent Montel's avatar
Laurent Montel committed
352

Laurent Montel's avatar
Laurent Montel committed
353
   else if(actionCollection->action(QStringLiteral( "P1Mine" ))->shortcuts().contains(ev->key()))
354
      playerKeyPressed[0][PlayerKeyMine]=false;
Laurent Montel's avatar
Laurent Montel committed
355
   else if(actionCollection->action(QStringLiteral( "P2Mine" ))->shortcuts().contains(ev->key()))
356 357
      playerKeyPressed[1][PlayerKeyMine]=false;
   else
358
      ev->ignore();
Andreas Zehender's avatar
Andreas Zehender committed
359 360 361 362
}

void MyMainView::pause()
{
363 364 365
   if( !waitForStart )
   {
      pauseAction->setChecked( true );
366

367
      waitForStart=true;
Laurent Montel's avatar
Laurent Montel committed
368
      QAbstractEventDispatcher::instance()->unregisterTimers(this);
369
      Q_EMIT setStatusText(i18n(" paused "), IDS_PAUSE);
370
   }
Andreas Zehender's avatar
Andreas Zehender committed
371 372 373 374 375
}

void MyMainView::resume()
{
   waitForStart=false;
376
   timerID=startTimer(Options::refreshTime());
377 378
   Q_EMIT setStatusText(QLatin1String( "" ),IDS_PAUSE);
   Q_EMIT setStatusText(QLatin1String( "" ),IDS_MAIN);
Andreas Zehender's avatar
Andreas Zehender committed
379 380
}

381 382 383 384 385 386 387 388 389
void MyMainView::start( )
{
   if( ( gameEnd <= 0.0 ) && ( gameEnd > -2.0 ) )
   {
      newRound( );
   }
   else if( waitForStart )
   {
      waitForStart = false;
390
      timerID=startTimer(Options::refreshTime());
391 392
      Q_EMIT setStatusText(QLatin1String( "" ),IDS_PAUSE);
      Q_EMIT setStatusText(QLatin1String( "" ),IDS_MAIN);
393 394 395 396 397 398 399 400 401
      pauseAction->setEnabled( true );
      pauseAction->setChecked( false );
   }
}

void MyMainView::stop()
{
   pauseAction->setEnabled( false );
   pauseAction->setChecked( false );
402

Laurent Montel's avatar
Laurent Montel committed
403
   QAbstractEventDispatcher::instance()->unregisterTimers(this);
404 405 406 407 408 409 410 411 412 413 414
   waitForStart = true;
}

void MyMainView::togglePause( )
{
   if( waitForStart )
      resume( );
   else
      pause( );
}

Andreas Zehender's avatar
Andreas Zehender committed
415 416 417 418
void MyMainView::resizeEvent(QResizeEvent *event)
{
   double mx,my;
   int i,current;
419
   int listsize; // used for caching QtList::size()
Andreas Zehender's avatar
Andreas Zehender committed
420 421 422 423 424

   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());
Dirk Rathlev's avatar
Dirk Rathlev committed
425
   field.setSceneRect(0, 0, width(),height());
426 427

   // printf("%d %d\n",field.width(),field.height());
Dirk Rathlev's avatar
Dirk Rathlev committed
428

429 430
   sun->setPos(QPointF(width()/2-1-(sun->width()/2),
                       height()/2-1-(sun->height()/2)));
Andreas Zehender's avatar
Andreas Zehender committed
431

Yuri Chornoivan's avatar
Yuri Chornoivan committed
432
   for(i=0;i<2;++i)
Andreas Zehender's avatar
Andreas Zehender committed
433
   {
434
      // ship[i]->adoptSpritefieldBounds();
435
      ship[i]->moveBy(mx,my);
Laurent Montel's avatar
Laurent Montel committed
436

437
      listsize = mines[i]->size();
Yuri Chornoivan's avatar
Yuri Chornoivan committed
438
      for (current=0; current<listsize; ++current)
439 440 441 442
      {
         // mine->adoptSpritefieldBounds();
         mines[i]->value(current)->moveBy(mx,my);
      }
Laurent Montel's avatar
Laurent Montel committed
443

444
      listsize = bullets[i]->size();
Yuri Chornoivan's avatar
Yuri Chornoivan committed
445
      for (current=0; current<listsize; ++current)
446 447 448 449
      {
         // bullet->adoptSpritefieldBounds();
         bullets[i]->value(current)->moveBy(mx,my);
      }
Andreas Zehender's avatar
Andreas Zehender committed
450
   }
Andreas Zehender's avatar
Andreas Zehender committed
451 452
   if(textSprite)
      textSprite->moveBy((int)mx,(int)my);
Laurent Montel's avatar
Laurent Montel committed
453

454
   listsize = powerups.size();
455
   for (current=0; current<listsize; ++current)
456 457 458
   {
      powerups[current]->moveBy(mx,my);
   }
Andreas Zehender's avatar
Andreas Zehender committed
459 460 461 462 463 464
}

void MyMainView::newRound()
{
   double mx,my;
   int i;
Andreas Zehender's avatar
Andreas Zehender committed
465

466
   timeToNextPowerup=random.bounded(config.powerupRefreshTime);
467
   qDeleteAll(powerups);
Andreas Zehender's avatar
Andreas Zehender committed
468
   powerups.clear();
Andreas Zehender's avatar
Andreas Zehender committed
469

Laurent Montel's avatar
Laurent Montel committed
470
   QAbstractEventDispatcher::instance()->unregisterTimers(this);
Andreas Zehender's avatar
Andreas Zehender committed
471 472
   mx=width()/2.0;
   my=height()/2.0;
473 474
   ship[0]->setPos(QPointF(mx+config.startPosX-(ship[0]->width()/2),
                           my+config.startPosY-(ship[0]->height()/2)));
Andreas Zehender's avatar
Andreas Zehender committed
475
   ship[0]->setRotation(0.0);
476

477 478
   ship[1]->setPos(QPointF(mx-config.startPosX-(ship[1]->width()/2),
                           my-config.startPosY-(ship[1]->height()/2)));
Andreas Zehender's avatar
Andreas Zehender committed
479 480 481 482
   ship[1]->setRotation(M_PI);

   ship[0]->setVelocity(config.startVelX,config.startVelY);
   ship[1]->setVelocity(-config.startVelX,-config.startVelY);
Yuri Chornoivan's avatar
Yuri Chornoivan committed
483
   for(i=0;i<2;++i)
Andreas Zehender's avatar
Andreas Zehender committed
484 485
   {
      ship[i]->show();
486
      ship[i]->setEnergy(MAX_ENERGY);
487
      ship[i]->setHitPoints(Options::startHitPoints(i));
Andreas Zehender's avatar
Andreas Zehender committed
488 489
      ship[i]->stop(false);
      ship[i]->setExplosion(-1);
490 491
      Q_EMIT energy(i,(int)ship[i]->getEnergy());
      Q_EMIT hitPoints(i,ship[i]->getHitPoints());
Andreas Zehender's avatar
Andreas Zehender committed
492
      bulletShot[i]=false;
493
      qDeleteAll(*bullets[i]);
Andreas Zehender's avatar
Andreas Zehender committed
494
      bullets[i]->clear();
Laurent Montel's avatar
Laurent Montel committed
495

496
      qDeleteAll(*mines[i]);
Andreas Zehender's avatar
Andreas Zehender committed
497
      mines[i]->clear();
Laurent Montel's avatar
Laurent Montel committed
498

Andreas Zehender's avatar
Andreas Zehender committed
499 500
      ship[i]->mine(0.0);
      ship[i]->bullet(0.0);
Andreas Zehender's avatar
Andreas Zehender committed
501 502
      ship[i]->setBulletPowerups(0);
      ship[i]->setMinePowerups(0);
Andreas Zehender's avatar
Andreas Zehender committed
503 504 505

      ai[i]->newRound();
   }
506
   qDeleteAll(explosions);
Andreas Zehender's avatar
Andreas Zehender committed
507 508
   explosions.clear();
   gameEnd=-10.0;
Yuri Chornoivan's avatar
Yuri Chornoivan committed
509
   for(i=0;i<PlayerKeyNum;++i)
Andreas Zehender's avatar
Andreas Zehender committed
510 511 512 513 514 515 516 517
   {
      playerKeyPressed[0][i]=false;
      playerKeyPressed[1][i]=false;
   }
   if(textSprite)
   {
      textSprite->hide();
      delete textSprite;
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
518
      textSprite = nullptr;
Andreas Zehender's avatar
Andreas Zehender committed
519
   }
520
   //field.update();
521

522
   QString str = i18n("Press %1 to start",
Laurent Montel's avatar
Laurent Montel committed
523
                  actionCollection->action(QStringLiteral("game_start"))->shortcut().toString(QKeySequence::NativeText));
524 525
   Q_EMIT setStatusText(str,IDS_MAIN);
   Q_EMIT setStatusText( QLatin1String( "" ), IDS_PAUSE );
526
   stop( );
Andreas Zehender's avatar
Andreas Zehender committed
527 528 529 530 531 532 533 534
}

void MyMainView::newGame()
{
   int i;
   for(i=0;i<2;i++)
   {
      ship[i]->setWins(0);
535
      Q_EMIT wins(i,0);
Andreas Zehender's avatar
Andreas Zehender committed
536 537 538 539 540 541 542 543
   }
   newRound();
}

void MyMainView::timerEvent(QTimerEvent *event)
{
   unsigned w;
   int i;
Andreas Zehender's avatar
Andreas Zehender committed
544
   bool stopped = false;
Andreas Zehender's avatar
Andreas Zehender committed
545 546 547

   if(event->timerId()==timerID)
   {
Laurent Montel's avatar
Laurent Montel committed
548
      QAbstractEventDispatcher::instance()->unregisterTimers(this);
Andreas Zehender's avatar
Andreas Zehender committed
549 550 551 552 553
      if(gameEnd>0.0)
      {
         gameEnd-=1.0;
         if(gameEnd<=0.0)
         {
Andreas Zehender's avatar
Andreas Zehender committed
554 555 556 557 558
            stopped = true;
            if(textSprite)
            {
               textSprite->hide();
               delete textSprite;
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
559
               textSprite = nullptr;
Andreas Zehender's avatar
Andreas Zehender committed
560
            }
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
561
            textSprite = new QGraphicsSimpleTextItem(nullptr);
Laurent Montel's avatar
Laurent Montel committed
562
            field.addItem(textSprite);
Dirk Rathlev's avatar
Dirk Rathlev committed
563 564
	    // FIXME
           // textSprite->setTextFlags(Qt::AlignCenter);
565
	    textSprite->setBrush(QBrush(QColor(255,160,0)));
Laurent Montel's avatar
Port++  
Laurent Montel committed
566
            textSprite->setFont(QFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family(),14));
567
            textSprite->show( );
Andreas Zehender's avatar
Andreas Zehender committed
568 569 570
            if(ship[0]->getHitPoints()==0)
            {
               if(ship[1]->getHitPoints()==0)
571
                  textSprite->setText(i18n("draw round"));
Andreas Zehender's avatar
Andreas Zehender committed
572 573
               else
               {
574
                  textSprite->setText(i18n("blue player won the round"));
Andreas Zehender's avatar
Andreas Zehender committed
575 576
                  w=ship[1]->getWins()+1;
                  ship[1]->setWins(w);
577
                  Q_EMIT wins(1,w);
Andreas Zehender's avatar
Andreas Zehender committed
578 579 580 581
               }
            }
            else
            {
582
               textSprite->setText(i18n("red player won the round"));
Andreas Zehender's avatar
Andreas Zehender committed
583 584
               w=ship[0]->getWins()+1;
               ship[0]->setWins(w);
585
               Q_EMIT wins(0,w);
Andreas Zehender's avatar
Andreas Zehender committed
586
            }
Dirk Rathlev's avatar
Dirk Rathlev committed
587 588
            // must do this after setting text, because length is unknown until now
            textSprite->setPos(QPointF((width()-textSprite->boundingRect().width()) / 2,height()/2-90));
Laurent Montel's avatar
Laurent Montel committed
589

590
            QString str = i18n("Press %1 for new round",
Laurent Montel's avatar
Laurent Montel committed
591
                          actionCollection->action(QStringLiteral("game_start"))->shortcut().toString(QKeySequence::NativeText));
592
            Q_EMIT setStatusText(str,IDS_MAIN);
593
            stop( );
Andreas Zehender's avatar
Andreas Zehender committed
594 595 596
         }
      }

Andreas Zehender's avatar
Andreas Zehender committed
597 598
      if( !stopped )
      {
Yuri Chornoivan's avatar
Yuri Chornoivan committed
599
         for(i=0;i<2;++i)
600
            if(Options::playerIsAi(i)&&(ship[i]->getHitPoints()>0))
Andreas Zehender's avatar
Andreas Zehender committed
601
               ai[i]->think();
602

Andreas Zehender's avatar
Andreas Zehender committed
603 604 605 606 607 608
         moveMines();
         moveBullets();
         moveExplosions();
         moveShips();
         calculatePowerups();
         collisions();
609
         timerID=startTimer(Options::refreshTime());
Andreas Zehender's avatar
Andreas Zehender committed
610
      }
611
     //field.update();
Andreas Zehender's avatar
Andreas Zehender committed
612 613 614 615 616
   }
}

void MyMainView::moveShips()
{
617
   int i,olde;
Andreas Zehender's avatar
Andreas Zehender committed
618 619 620 621 622
   double nx,ny,en,nr;
   BulletSprite *bullet;
   MineSprite *mine;


Yuri Chornoivan's avatar
Yuri Chornoivan committed
623
   for(i=0;i<2;++i)
Andreas Zehender's avatar
Andreas Zehender committed
624
   {
625
      bool playerIsAi = Options::playerIsAi(i);
Andreas Zehender's avatar
Andreas Zehender committed
626 627 628 629 630 631 632 633 634 635 636 637
      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);

638

639 640
         if ((!playerIsAi && playerKeyPressed[i][PlayerKeyRight]) ||
             (playerIsAi && ai[i]->rotateRight()))
Andreas Zehender's avatar
Andreas Zehender committed
641 642 643
            ship[i]->rotateRight(config.rotationEnergyNeed,
                                 config.rotationSpeed);

644 645
         if (!(playerIsAi && playerKeyPressed[i][PlayerKeyLeft]) ||
             (playerIsAi && ai[i]->rotateLeft()))
Andreas Zehender's avatar
Andreas Zehender committed
646 647
            ship[i]->rotateLeft(config.rotationEnergyNeed,
                                config.rotationSpeed);
648

Andreas Zehender's avatar
Andreas Zehender committed
649 650 651 652 653
         en=ship[i]->getEnergy();
         nr=ship[i]->getRotation();

         nx=cos(nr);
         ny=sin(nr);
654 655
         if (((!playerIsAi && playerKeyPressed[i][PlayerKeyAcc]) ||
              (playerIsAi && ai[i]->accelerate()))
656
	     && (en>config.energyNeed) )
Andreas Zehender's avatar
Andreas Zehender committed
657 658
         {
            en-=config.energyNeed;
659 660
            ship[i]->setVelocity(ship[i]->xVelocity()+nx*config.acc,
                                 ship[i]->yVelocity()-ny*config.acc);
Laurent Montel's avatar
Laurent Montel committed
661

662 663 664 665 666 667 668 669 670 671
	    // limit speed to avoid "tunneling" through other objects
	    // FIXME: find a more elegant way
	    if (ship[i]->xVelocity()*ship[i]->xVelocity()+
		ship[i]->yVelocity()*ship[i]->yVelocity() > MAX_VELOCITY*MAX_VELOCITY)
	    {
		    double alpha;
		    alpha = fabs(atan(ship[i]->yVelocity()/ship[i]->xVelocity()));
		    ship[i]->setVelocity(MAX_VELOCITY*cos(alpha)*fabs(ship[i]->xVelocity())/ship[i]->xVelocity(),
                                 MAX_VELOCITY*sin(alpha)*fabs(ship[i]->yVelocity())/ship[i]->yVelocity());
	    }
Andreas Zehender's avatar
Andreas Zehender committed
672
         }
673 674
         if(en>MAX_ENERGY)
            en=MAX_ENERGY;
Andreas Zehender's avatar
Andreas Zehender committed
675 676

         ship[i]->forward(config.gamespeed);
Laurent Montel's avatar
Laurent Montel committed
677

Andreas Zehender's avatar
Andreas Zehender committed
678
             //Bullets and Mines
679 680
         if ((!playerIsAi && playerKeyPressed[i][PlayerKeyShot]) ||
             (playerIsAi && ai[i]->shootBullet()))
Andreas Zehender's avatar
Andreas Zehender committed
681 682 683
         {
            if((en>config.shotEnergyNeed) && (!ship[i]->reloadsBullet()))
            {
Andreas Zehender's avatar
Andreas Zehender committed
684
               if(bullets[i]->count() <
685
                  (static_cast<int>(config.maxBullets) + ship[i]->getBulletPowerups()))
Andreas Zehender's avatar
Andreas Zehender committed
686 687 688
               {
                  ship[i]->bullet(config.bulletReloadTime);
                  en-=config.shotEnergyNeed;
689
		  if(i)
Laurent Montel's avatar
Laurent Montel committed
690
		     bullet=new BulletSprite(svgrender, QStringLiteral( MV_BULLET2 ), i,
691 692
					     config.bulletLifeTime);
		  else
Laurent Montel's avatar
Laurent Montel committed
693
		     bullet=new BulletSprite(svgrender, QStringLiteral( MV_BULLET1 ), i,
Andreas Zehender's avatar
Andreas Zehender committed
694
                                          config.bulletLifeTime);
695
		  field.addItem(bullet);
Dirk Rathlev's avatar
Dirk Rathlev committed
696
		  QPointF p;
697
		  p = ship[i]->mapToScene(ship[i]->center());
Dirk Rathlev's avatar
Dirk Rathlev committed
698
		  bullet->setPos(QPointF(p.x()+nx*SHOTDIST,p.y()-ny*SHOTDIST));
699 700 701
                  bullet->setVelocity(ship[i]->xVelocity()+nx*config.shotSpeed,
                                      ship[i]->yVelocity()-ny*config.shotSpeed);
                  // bullet->setBoundsAction(QwRealMobileSprite::Wrap);
Andreas Zehender's avatar
Andreas Zehender committed
702 703 704 705 706
                  bullet->show();
                  bullets[i]->append(bullet);
               }
            }
         }
707 708
         if ((!Options::playerIsAi(i) && playerKeyPressed[i][PlayerKeyMine]) ||
             (Options::playerIsAi(i) && ai[i]->layMine()))
Andreas Zehender's avatar
Andreas Zehender committed
709 710 711
         {
            if((en>config.mineEnergyNeed) && (!ship[i]->reloadsMine()))
            {
Andreas Zehender's avatar
Andreas Zehender committed
712
               if(mines[i]->count() <
713
                  (static_cast<int>(config.maxMines) + ship[i]->getMinePowerups()))
Andreas Zehender's avatar
Andreas Zehender committed
714 715 716
               {
                  ship[i]->mine(config.mineReloadTime);
                  en-=config.mineEnergyNeed;
Dirk Rathlev's avatar
Dirk Rathlev committed
717
		  if (i==0)
718
                     mine=new MineSprite(svgrender,animation[ID_MINE1],animation[ID_MINEEXPLO],i,
Dirk Rathlev's avatar
Dirk Rathlev committed
719 720
                                      config.mineActivateTime,config.mineFuel);
		  else
721
		     mine=new MineSprite(svgrender,animation[ID_MINE2],animation[ID_MINEEXPLO],i,
Andreas Zehender's avatar
Andreas Zehender committed
722
                                      config.mineActivateTime,config.mineFuel);
723
		  field.addItem(mine);
724 725 726
		  mine->setPos(ship[i]->mapToScene(ship[i]->center()));
                  // move mine to center
                  mine->moveBy(-mine->center().x(),-mine->center().y());
Andreas Zehender's avatar
Andreas Zehender committed
727
                  mine->setVelocity(0,0);
728
                  //mine->setBoundsAction(QwRealMobileSprite::Wrap);
Andreas Zehender's avatar
Andreas Zehender committed
729 730 731 732 733 734 735
                  mine->show();
                  mines[i]->append(mine);
               }
            }
         }
         ship[i]->setEnergy(en);
         if(olde!=(int)en)
736
            Q_EMIT energy(i,(int)en);
Andreas Zehender's avatar
Andreas Zehender committed
737 738 739 740 741 742
      }
   }
}

void MyMainView::moveMines()
{
743
   int i;
Andreas Zehender's avatar
Andreas Zehender committed
744 745
   MineSprite* mine;
   int p;
746
   int listsize; // used for caching QtList::size()
Andreas Zehender's avatar
Andreas Zehender committed
747 748 749

   for(p=0;p<2;p++)
   {
750
      i=0;
751 752
      listsize = mines[p]->size();
      while (i<listsize)
753 754 755 756 757 758 759 760 761
      {
         mine = mines[p]->value(i);
         mine->calculateGravity(config.gravity,config.gamespeed);
         mine->forward(config.gamespeed);
         if(mine->over())
         {
            mine->hide();
            mines[p]->removeAt(i);
            delete mine;
762
            listsize--;
763 764 765 766
         }
         else
            i++;
      }
Andreas Zehender's avatar
Andreas Zehender committed
767 768 769 770 771
   }
}

void MyMainView::moveBullets()
{
772
   int i,j;
Andreas Zehender's avatar
Andreas Zehender committed
773
   BulletSprite *sp;
774
   int listsize; // used for caching QtList::size()
Andreas Zehender's avatar
Andreas Zehender committed
775 776 777

   for(i=0;i<2;i++)
   {
778
      j=0;
779 780
      listsize = bullets[i]->size();
      while (j<listsize)
781 782 783 784 785 786 787 788
      {
         sp = bullets[i]->value(j);
         sp->calculateGravity(config.gravity,config.gamespeed);
         sp->forward(config.gamespeed);
         if(sp->timeOut())
         {
            sp->hide();
            bullets[i]->removeAll(sp);
789
            listsize--;
790 791 792 793
         }
         else
            j++;
      }
Andreas Zehender's avatar
Andreas Zehender committed
794 795 796 797 798
   }
}

void MyMainView::moveExplosions()
{
799
   int i=0;
Andreas Zehender's avatar
Andreas Zehender committed
800
   ExplosionSprite *ex;
801
   int