2 Copyright (C) 1998-2001 Andreas Zehender <az@azweb.de>
3 Copyright (C) 2006-2007 Dirk Rathlev <dirkrathlev@gmx.de>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <QAbstractEventDispatcher>
26 #include <QGraphicsSimpleTextItem>
28 #include <QResizeEvent>
29 #include <QTimerEvent>
32 #include <kactioncollection.h>
33 #include <kglobalsettings.h>
35 #include <kstandarddirs.h>
36 #include <ktoggleaction.h>
37 #include <kconfiggroup.h>
39 #include <KSvgRenderer>
44 KToggleAction
*MyMainView::pauseAction
= 0;
53 { ID_EXPLOSION
, "explos%1"},
54 { ID_MINE1
, "mine_red%1"},
55 { ID_MINE2
, "mine_blue%1"},
56 { ID_MINEEXPLO
, "mineex%1"},
60 MyMainView::MyMainView(QWidget
*parent
)
62 field(this),//0,0,DEF_WIDTH,DEF_HEIGHT),
66 setMinimumSize(600,400);
68 QPixmap
backgr(KStandardDirs::locate("appdata", MV_BACKGROUND
));
70 field
.setBackgroundBrush(QBrush(backgr
));
71 view
.setCacheMode(QGraphicsView::CacheBackground
);
73 setFocusPolicy(Qt::StrongFocus
);
74 // FIXME: is this needed anymore?
75 //view.setResizePolicy(Q3ScrollView::AutoOne);
76 view
.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
77 view
.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
78 view
.setFrameStyle(QFrame::NoFrame
);
82 for(i
=0;i
<PlayerKeyNum
;i
++)
83 playerKeyPressed
[p
][i
]=false;
88 svgrender
= new KSvgRenderer(KStandardDirs::locate("appdata", MV_SVG_FILE
));
90 sun
=new SunSprite(svgrender
, MV_SUN
);
92 sun
->setPos(QPointF(width()/2-1-(sun
->width()/2),
93 height()/2-1-(sun
->height()/2)));
95 powerupelements
[0] = MV_POWERMINE
;
96 powerupelements
[1] = MV_POWERBULLET
;
97 powerupelements
[2] = MV_POWERSHIELD
;
98 powerupelements
[3] = MV_POWERENERGY
;
100 ship
[0]=new ShipSprite(svgrender
, MV_SHIP1
, 0);
101 ship
[1]=new ShipSprite(svgrender
, MV_SHIP2
, 1);
102 field
.addItem(ship
[0]);
103 field
.addItem(ship
[1]);
109 // ship[i]->setBoundsAction(QwRealMobileSprite::Wrap);
111 bullets
[i
]=new QList
<BulletSprite
*>;
112 mines
[i
]=new QList
<MineSprite
*>;
121 MyMainView::~MyMainView()
124 QAbstractEventDispatcher::instance()->unregisterTimers(this);
129 qDeleteAll(*mines
[i
]);
131 qDeleteAll(*bullets
[i
]);
135 qDeleteAll(powerups
);
138 qDeleteAll(explosions
);
145 void MyMainView::setActionCollection(KActionCollection
*a
)
147 actionCollection
= a
;
150 /* Assumes that there are no gaps between animation frames. ie 1,2,3 will only have frames 1&2
151 recognized. It also assumes that there is at least one frame. */
152 // FIXME: Add Check for existence of first frame
153 // TODO: Add support for missing frames (ie 1,2,5)
154 bool MyMainView::readSprites()
157 while ( kspd_animations
[i
].id
)
161 QString element
= kspd_animations
[i
].path
;
162 QString elem
= element
.arg(frame
, 2, 10, QLatin1Char('0'));
167 elem
= element
.arg(frame
, 2, 10, QLatin1Char('0'));
168 } while ( svgrender
->elementExists(elem
) );
169 animation
.insert( kspd_animations
[i
].id
, anim
);
173 // FIXME: Perform test!
177 void MyMainView::readConfig()
179 KConfigGroup
game(KGlobal::config(), "Game");
182 customConfig
.gamespeed
=game
.readEntry("gamespeed",
183 predefinedConfig
[0].gamespeed
);
185 customConfig
.gravity
=
186 game
.readEntry("gravity",predefinedConfig
[0].gravity
);
188 game
.readEntry("acceleration",predefinedConfig
[0].acc
);
189 customConfig
.bulletDamage
=
190 game
.readEntry("bulletDamage",predefinedConfig
[0].bulletDamage
);
191 customConfig
.bulletLifeTime
=
192 game
.readEntry("bulletLifeTime",predefinedConfig
[0].bulletLifeTime
);
193 customConfig
.bulletReloadTime
=
194 game
.readEntry("bulletReloadTime",predefinedConfig
[0].bulletReloadTime
);
195 customConfig
.mineDamage
=
196 game
.readEntry("mineDamage",predefinedConfig
[0].mineDamage
);
197 customConfig
.shipDamage
=
198 game
.readEntry("shipDamage",predefinedConfig
[0].shipDamage
);
199 customConfig
.maxBullets
=
200 game
.readEntry("maxBullets",predefinedConfig
[0].maxBullets
);
201 customConfig
.maxMines
=
202 game
.readEntry("maxMines",predefinedConfig
[0].maxMines
);
203 customConfig
.mineReloadTime
=
204 game
.readEntry("mineReloadTime",predefinedConfig
[0].mineReloadTime
);
205 customConfig
.rotationSpeed
=
206 game
.readEntry("rotationSpeed",predefinedConfig
[0].rotationSpeed
);
207 customConfig
.shotSpeed
=
208 game
.readEntry("shotSpeed",predefinedConfig
[0].shotSpeed
);
209 customConfig
.energyNeed
=
210 game
.readEntry("accEnergyNeed",predefinedConfig
[0].energyNeed
);
211 customConfig
.rotationEnergyNeed
=
212 game
.readEntry("rotationEnergyNeed",predefinedConfig
[0].rotationEnergyNeed
);
213 customConfig
.sunEnergy
=
214 game
.readEntry("sunEnergy",predefinedConfig
[0].sunEnergy
);
215 customConfig
.mineActivateTime
=
216 game
.readEntry("mineActivateTime",predefinedConfig
[0].mineActivateTime
);
217 customConfig
.mineFuel
=
218 game
.readEntry("mineFuel",predefinedConfig
[0].mineFuel
);
219 customConfig
.shotEnergyNeed
=
220 game
.readEntry("shotEnergyNeed",predefinedConfig
[0].shotEnergyNeed
);
221 customConfig
.mineEnergyNeed
=
222 game
.readEntry("mineEnergyNeed",predefinedConfig
[0].mineEnergyNeed
);
223 customConfig
.startPosX
=
224 game
.readEntry("startPosX",predefinedConfig
[0].startPosX
);
225 customConfig
.startPosY
=
226 game
.readEntry("startPosY",predefinedConfig
[0].startPosY
);
227 customConfig
.startVelX
=
228 game
.readEntry("startVelX",predefinedConfig
[0].startVelX
);
229 customConfig
.startVelY
=
230 game
.readEntry("startVelY",predefinedConfig
[0].startVelY
);
231 customConfig
.powerupLifeTime
=
232 game
.readEntry("powerupLifeTime",predefinedConfig
[0].powerupLifeTime
);
233 customConfig
.powerupRefreshTime
=
234 game
.readEntry("powerupRefreshTime",predefinedConfig
[0].powerupRefreshTime
);
235 customConfig
.powerupShieldAmount
=
236 game
.readEntry("powerupShieldAmount",
237 predefinedConfig
[0].powerupShieldAmount
);
238 customConfig
.powerupEnergyAmount
=
239 game
.readEntry("powerupEnergyAmount",
240 predefinedConfig
[0].powerupEnergyAmount
);
242 if(Options::lastConfig() < predefinedConfigNum
)
243 config
=modifyConfig(predefinedConfig
[Options::lastConfig()]);
245 config
=modifyConfig(customConfig
);
248 ai
[i
]=new Ai(i
,ship
,bullets
,mines
,&config
);
251 void MyMainView::writeConfig()
253 KConfigGroup
game(KGlobal::config(), "Game");
255 game
.writeEntry("gravity",customConfig
.gravity
);
256 game
.writeEntry("acceleration",customConfig
.acc
);
257 game
.writeEntry("bulletDamage",customConfig
.bulletDamage
);
258 game
.writeEntry("bulletLifeTime",customConfig
.bulletLifeTime
);
259 game
.writeEntry("bulletReloadTime",customConfig
.bulletReloadTime
);
260 game
.writeEntry("mineDamage",customConfig
.mineDamage
);
261 game
.writeEntry("shipDamage",customConfig
.shipDamage
);
262 game
.writeEntry("maxBullets",customConfig
.maxBullets
);
263 game
.writeEntry("maxMines",customConfig
.maxMines
);
264 game
.writeEntry("rotationSpeed",customConfig
.rotationSpeed
);
265 game
.writeEntry("shotSpeed",customConfig
.shotSpeed
);
266 game
.writeEntry("accEnergyNeed",customConfig
.energyNeed
);
267 game
.writeEntry("rotationEnergyNeed",customConfig
.rotationEnergyNeed
);
268 game
.writeEntry("sunEnergy",customConfig
.sunEnergy
);
269 game
.writeEntry("mineActivateTime",customConfig
.mineActivateTime
);
270 game
.writeEntry("mineReloadTime",customConfig
.mineReloadTime
);
271 game
.writeEntry("mineFuel",customConfig
.mineFuel
);
272 game
.writeEntry("shotEnergyNeed",customConfig
.shotEnergyNeed
);
273 game
.writeEntry("mineEnergyNeed",customConfig
.mineEnergyNeed
);
275 game
.writeEntry("startPosX",customConfig
.startPosX
);
276 game
.writeEntry("startPosY",customConfig
.startPosY
);
277 game
.writeEntry("startVelX",customConfig
.startVelX
);
278 game
.writeEntry("startVelY",customConfig
.startVelY
);
280 game
.writeEntry("powerupLifeTime",customConfig
.powerupLifeTime
);
281 game
.writeEntry("powerupRefreshTime",customConfig
.powerupRefreshTime
);
282 game
.writeEntry("powerupShieldAmount",customConfig
.powerupShieldAmount
);
283 game
.writeEntry("powerupEnergyAmount",customConfig
.powerupEnergyAmount
);
286 SConfig
MyMainView::modifyConfig(SConfig conf
)
288 SConfig newConfig
=conf
;
289 newConfig
.gamespeed
*=Options::refreshTime()/33.0;
290 newConfig
.acc
*=newConfig
.gamespeed
;
291 newConfig
.rotationSpeed
*=newConfig
.gamespeed
*M_PI
/ROTNUM
*4;
292 newConfig
.energyNeed
*=newConfig
.gamespeed
;
293 newConfig
.rotationEnergyNeed
*=newConfig
.gamespeed
;
294 newConfig
.mineActivateTime
*=newConfig
.gamespeed
;
299 void MyMainView::keyPressEvent(QKeyEvent
*ev
)
301 // if-statement kept for historical reasons, maybe not needed anymore
302 if ( ((gameEnd
>0.0) || (gameEnd
<=-2.0)) && (!waitForStart
) )
304 if(actionCollection
->action("P1KeyLeft")->shortcuts().contains(ev
->key()))
305 playerKeyPressed
[0][PlayerKeyLeft
]=true;
306 else if(actionCollection
->action("P2KeyLeft")->shortcuts().contains(ev
->key()))
307 playerKeyPressed
[1][PlayerKeyLeft
]=true;
309 else if(actionCollection
->action("P1KeyRight")->shortcuts().contains(ev
->key()))
310 playerKeyPressed
[0][PlayerKeyRight
]=true;
311 else if(actionCollection
->action("P2KeyRight")->shortcuts().contains(ev
->key()))
312 playerKeyPressed
[1][PlayerKeyRight
]=true;
314 else if(actionCollection
->action("P1KeyAcc")->shortcuts().contains(ev
->key()))
315 playerKeyPressed
[0][PlayerKeyAcc
]=true;
316 else if(actionCollection
->action("P2KeyAcc")->shortcuts().contains(ev
->key()))
317 playerKeyPressed
[1][PlayerKeyAcc
]=true;
319 else if(actionCollection
->action("P1Shot")->shortcuts().contains(ev
->key()))
320 playerKeyPressed
[0][PlayerKeyShot
]=true;
321 else if(actionCollection
->action("P2Shot")->shortcuts().contains(ev
->key()))
322 playerKeyPressed
[1][PlayerKeyShot
]=true;
324 else if(actionCollection
->action("P1Mine")->shortcuts().contains(ev
->key()))
325 playerKeyPressed
[0][PlayerKeyMine
]=true;
326 else if(actionCollection
->action("P2Mine")->shortcuts().contains(ev
->key()))
327 playerKeyPressed
[1][PlayerKeyMine
]=true;
333 void MyMainView::keyReleaseEvent(QKeyEvent
*ev
)
335 if(actionCollection
->action("P1KeyLeft")->shortcuts().contains(ev
->key()))
336 playerKeyPressed
[0][PlayerKeyLeft
]=false;
337 else if(actionCollection
->action("P2KeyLeft")->shortcuts().contains(ev
->key()))
338 playerKeyPressed
[1][PlayerKeyLeft
]=false;
340 else if(actionCollection
->action("P1KeyRight")->shortcuts().contains(ev
->key()))
341 playerKeyPressed
[0][PlayerKeyRight
]=false;
342 else if(actionCollection
->action("P2KeyRight")->shortcuts().contains(ev
->key()))
343 playerKeyPressed
[1][PlayerKeyRight
]=false;
345 else if(actionCollection
->action("P1KeyAcc")->shortcuts().contains(ev
->key()))
346 playerKeyPressed
[0][PlayerKeyAcc
]=false;
347 else if(actionCollection
->action("P2KeyAcc")->shortcuts().contains(ev
->key()))
348 playerKeyPressed
[1][PlayerKeyAcc
]=false;
350 else if(actionCollection
->action("P1Shot")->shortcuts().contains(ev
->key()))
351 playerKeyPressed
[0][PlayerKeyShot
]=false;
352 else if(actionCollection
->action("P2Shot")->shortcuts().contains(ev
->key()))
353 playerKeyPressed
[1][PlayerKeyShot
]=false;
355 else if(actionCollection
->action("P1Mine")->shortcuts().contains(ev
->key()))
356 playerKeyPressed
[0][PlayerKeyMine
]=false;
357 else if(actionCollection
->action("P2Mine")->shortcuts().contains(ev
->key()))
358 playerKeyPressed
[1][PlayerKeyMine
]=false;
363 void MyMainView::pause()
367 pauseAction
->setChecked( true );
370 QAbstractEventDispatcher::instance()->unregisterTimers(this);
371 emit
setStatusText(i18n(" paused "), IDS_PAUSE
);
375 void MyMainView::resume()
378 timerID
=startTimer(Options::refreshTime());
379 emit(setStatusText("",IDS_PAUSE
));
380 emit(setStatusText("",IDS_MAIN
));
383 void MyMainView::start( )
385 if( ( gameEnd
<= 0.0 ) && ( gameEnd
> -2.0 ) )
389 else if( waitForStart
)
391 waitForStart
= false;
392 timerID
=startTimer(Options::refreshTime());
393 emit(setStatusText("",IDS_PAUSE
));
394 emit(setStatusText("",IDS_MAIN
));
395 pauseAction
->setEnabled( true );
396 pauseAction
->setChecked( false );
400 void MyMainView::stop()
402 pauseAction
->setEnabled( false );
403 pauseAction
->setChecked( false );
405 QAbstractEventDispatcher::instance()->unregisterTimers(this);
409 void MyMainView::togglePause( )
417 void MyMainView::resizeEvent(QResizeEvent
*event
)
421 int listsize
; // used for caching QtList::size()
423 mx
=(event
->size().width()-event
->oldSize().width())/2.0;
424 my
=(event
->size().height()-event
->oldSize().height())/2.0;
425 QWidget::resizeEvent(event
);
426 view
.resize(width(),height());
427 field
.setSceneRect(0, 0, width(),height());
429 // printf("%d %d\n",field.width(),field.height());
431 sun
->setPos(QPointF(width()/2-1-(sun
->width()/2),
432 height()/2-1-(sun
->height()/2)));
436 // ship[i]->adoptSpritefieldBounds();
437 ship
[i
]->moveBy(mx
,my
);
439 listsize
= mines
[i
]->size();
440 for (current
=0; current
<listsize
; current
++)
442 // mine->adoptSpritefieldBounds();
443 mines
[i
]->value(current
)->moveBy(mx
,my
);
446 listsize
= bullets
[i
]->size();
447 for (current
=0; current
<listsize
; current
++)
449 // bullet->adoptSpritefieldBounds();
450 bullets
[i
]->value(current
)->moveBy(mx
,my
);
454 textSprite
->moveBy((int)mx
,(int)my
);
456 listsize
= powerups
.size();
457 for (current
=0; current
<listsize
; current
++)
459 powerups
[current
]->moveBy(mx
,my
);
463 void MyMainView::newRound()
468 timeToNextPowerup
=random
.getDouble() * config
.powerupRefreshTime
;
469 qDeleteAll(powerups
);
472 QAbstractEventDispatcher::instance()->unregisterTimers(this);
475 ship
[0]->setPos(QPointF(mx
+config
.startPosX
-(ship
[0]->width()/2),
476 my
+config
.startPosY
-(ship
[0]->height()/2)));
477 ship
[0]->setRotation(0.0);
479 ship
[1]->setPos(QPointF(mx
-config
.startPosX
-(ship
[1]->width()/2),
480 my
-config
.startPosY
-(ship
[1]->height()/2)));
481 ship
[1]->setRotation(M_PI
);
483 ship
[0]->setVelocity(config
.startVelX
,config
.startVelY
);
484 ship
[1]->setVelocity(-config
.startVelX
,-config
.startVelY
);
488 ship
[i
]->setEnergy(MAX_ENERGY
);
489 ship
[i
]->setHitPoints(Options::startHitPoints(i
));
490 ship
[i
]->stop(false);
491 ship
[i
]->setExplosion(-1);
492 emit(energy(i
,(int)ship
[i
]->getEnergy()));
493 emit(hitPoints(i
,ship
[i
]->getHitPoints()));
495 qDeleteAll(*bullets
[i
]);
498 qDeleteAll(*mines
[i
]);
502 ship
[i
]->bullet(0.0);
503 ship
[i
]->setBulletPowerups(0);
504 ship
[i
]->setMinePowerups(0);
508 qDeleteAll(explosions
);
511 for(i
=0;i
<PlayerKeyNum
;i
++)
513 playerKeyPressed
[0][i
]=false;
514 playerKeyPressed
[1][i
]=false;
524 QString str
= i18n("Press %1 to start",
525 KShortcut(GAME_START_SHORTCUT
).primary().toString(QKeySequence::NativeText
));
526 emit(setStatusText(str
,IDS_MAIN
));
527 emit(setStatusText( "", IDS_PAUSE
));
531 void MyMainView::newGame()
542 void MyMainView::timerEvent(QTimerEvent
*event
)
546 bool stopped
= false;
548 if(event
->timerId()==timerID
)
550 QAbstractEventDispatcher::instance()->unregisterTimers(this);
563 textSprite
=new QGraphicsSimpleTextItem(0,&field
);
565 // textSprite->setTextFlags(Qt::AlignCenter);
566 textSprite
->setBrush(QBrush(QColor(255,160,0)));
567 textSprite
->setFont(QFont(KGlobalSettings::generalFont().family(),14));
569 if(ship
[0]->getHitPoints()==0)
571 if(ship
[1]->getHitPoints()==0)
572 textSprite
->setText(i18n("draw round"));
575 textSprite
->setText(i18n("blue player won the round"));
576 w
=ship
[1]->getWins()+1;
583 textSprite
->setText(i18n("red player won the round"));
584 w
=ship
[0]->getWins()+1;
588 // must do this after setting text, because length is unknown until now
589 textSprite
->setPos(QPointF((width()-textSprite
->boundingRect().width()) / 2,height()/2-90));
591 QString str
= i18n("Press %1 for new round",
592 KShortcut(GAME_START_SHORTCUT
).primary().toString(QKeySequence::NativeText
));
593 emit(setStatusText(str
,IDS_MAIN
));
601 if(Options::playerIsAi(i
)&&(ship
[i
]->getHitPoints()>0))
610 timerID
=startTimer(Options::refreshTime());
616 void MyMainView::moveShips()
620 BulletSprite
*bullet
;
626 bool playerIsAi
= Options::playerIsAi(i
);
627 olde
=(int)ship
[i
]->getEnergy();
628 if(ship
[i
]->getHitPoints()==0)
630 ship
[i
]->forward(config
.gamespeed
);
631 ship
[i
]->calculateGravityAndEnergy(config
.gravity
,config
.sunEnergy
,
636 ship
[i
]->calculateGravityAndEnergy(config
.gravity
,config
.sunEnergy
,
640 if(!playerIsAi
&&playerKeyPressed
[i
][PlayerKeyRight
]
641 || playerIsAi
&&ai
[i
]->rotateRight())
642 ship
[i
]->rotateRight(config
.rotationEnergyNeed
,
643 config
.rotationSpeed
);
645 if(!playerIsAi
&&playerKeyPressed
[i
][PlayerKeyLeft
]
646 || playerIsAi
&&ai
[i
]->rotateLeft())
647 ship
[i
]->rotateLeft(config
.rotationEnergyNeed
,
648 config
.rotationSpeed
);
650 en
=ship
[i
]->getEnergy();
651 nr
=ship
[i
]->getRotation();
656 if ( ((!playerIsAi
&& playerKeyPressed
[i
][PlayerKeyAcc
])
657 || playerIsAi
&&ai
[i
]->accelerate())
658 && (en
>config
.energyNeed
) )
660 en
-=config
.energyNeed
;
661 ship
[i
]->setVelocity(ship
[i
]->xVelocity()+nx
*config
.acc
,
662 ship
[i
]->yVelocity()-ny
*config
.acc
);
664 // limit speed to avoid "tunneling" through other objects
665 // FIXME: find a more elegant way
666 if (ship
[i
]->xVelocity()*ship
[i
]->xVelocity()+
667 ship
[i
]->yVelocity()*ship
[i
]->yVelocity() > MAX_VELOCITY
*MAX_VELOCITY
)
670 alpha
= fabs(atan(ship
[i
]->yVelocity()/ship
[i
]->xVelocity()));
671 ship
[i
]->setVelocity(MAX_VELOCITY
*cos(alpha
)*fabs(ship
[i
]->xVelocity())/ship
[i
]->xVelocity(),
672 MAX_VELOCITY
*sin(alpha
)*fabs(ship
[i
]->yVelocity())/ship
[i
]->yVelocity());
678 ship
[i
]->forward(config
.gamespeed
);
681 if(!playerIsAi
&&playerKeyPressed
[i
][PlayerKeyShot
]
682 ||playerIsAi
&&ai
[i
]->shootBullet())
684 if((en
>config
.shotEnergyNeed
) && (!ship
[i
]->reloadsBullet()))
686 if(bullets
[i
]->count() <
687 (config
.maxBullets
+ship
[i
]->getBulletPowerups()))
689 ship
[i
]->bullet(config
.bulletReloadTime
);
690 en
-=config
.shotEnergyNeed
;
692 bullet
=new BulletSprite(svgrender
, MV_BULLET2
, i
,
693 config
.bulletLifeTime
);
695 bullet
=new BulletSprite(svgrender
, MV_BULLET1
, i
,
696 config
.bulletLifeTime
);
697 field
.addItem(bullet
);
699 p
= ship
[i
]->mapToScene(ship
[i
]->center());
700 bullet
->setPos(QPointF(p
.x()+nx
*SHOTDIST
,p
.y()-ny
*SHOTDIST
));
701 bullet
->setVelocity(ship
[i
]->xVelocity()+nx
*config
.shotSpeed
,
702 ship
[i
]->yVelocity()-ny
*config
.shotSpeed
);
703 // bullet->setBoundsAction(QwRealMobileSprite::Wrap);
705 bullets
[i
]->append(bullet
);
709 if(!Options::playerIsAi(i
)&&playerKeyPressed
[i
][PlayerKeyMine
]
710 || Options::playerIsAi(i
)&&ai
[i
]->layMine())
712 if((en
>config
.mineEnergyNeed
) && (!ship
[i
]->reloadsMine()))
714 if(mines
[i
]->count() <
715 (config
.maxMines
+ship
[i
]->getMinePowerups()))
717 ship
[i
]->mine(config
.mineReloadTime
);
718 en
-=config
.mineEnergyNeed
;
720 mine
=new MineSprite(svgrender
,animation
[ID_MINE1
],animation
[ID_MINEEXPLO
],i
,
721 config
.mineActivateTime
,config
.mineFuel
);
723 mine
=new MineSprite(svgrender
,animation
[ID_MINE2
],animation
[ID_MINEEXPLO
],i
,
724 config
.mineActivateTime
,config
.mineFuel
);
727 mine
->setPos(ship
[i
]->mapToScene(ship
[i
]->center()));
728 // move mine to center
729 mine
->moveBy(-mine
->center().x(),-mine
->center().y());
730 mine
->setVelocity(0,0);
731 //mine->setBoundsAction(QwRealMobileSprite::Wrap);
733 mines
[i
]->append(mine
);
737 ship
[i
]->setEnergy(en
);
739 emit(energy(i
,(int)en
));
744 void MyMainView::moveMines()
749 int listsize
; // used for caching QtList::size()
754 listsize
= mines
[p
]->size();
757 mine
= mines
[p
]->value(i
);
758 mine
->calculateGravity(config
.gravity
,config
.gamespeed
);
759 mine
->forward(config
.gamespeed
);
763 mines
[p
]->removeAt(i
);
773 void MyMainView::moveBullets()
777 int listsize
; // used for caching QtList::size()
782 listsize
= bullets
[i
]->size();
785 sp
= bullets
[i
]->value(j
);
786 sp
->calculateGravity(config
.gravity
,config
.gamespeed
);
787 sp
->forward(config
.gamespeed
);
791 bullets
[i
]->removeAll(sp
);
800 void MyMainView::moveExplosions()
804 int listsize
; // used for caching QtList::size()
805 listsize
= explosions
.size();
809 ex
->forward(config
.gamespeed
);
812 explosions
.removeAt(i
);
821 void MyMainView::calculatePowerups()
825 int listsize
; // used for caching QtList::size()
826 listsize
= powerups
.size();
830 sp
->setLifetime(sp
->getLifetime()-config
.gamespeed
);
831 if (sp
->getLifetime()<0)
833 powerups
.removeAt(i
);
840 timeToNextPowerup
-=config
.gamespeed
;
841 if(timeToNextPowerup
<0)
844 timeToNextPowerup
= random
.getDouble() * config
.powerupRefreshTime
;
845 type
= random
.getLong(PowerupSprite::PowerupNum
);
846 sp
=new PowerupSprite(svgrender
,powerupelements
[type
],type
,
847 config
.powerupLifeTime
);
851 x
= random
.getLong(width()-40)+20;
852 y
= random
.getLong(height()-40)+20;
854 while(((x
-width()/2)*(x
-width()/2)+(y
-height()/2)*(y
-height()/2))<(50*50));
855 sp
->setPos(QPointF(x
,y
));
861 void MyMainView::collisions()
863 int pl
,hp
,op
,oldhp
[2],ohp
;
864 QList
<QGraphicsItem
*> unexact
;
865 QGraphicsItem
*sprite
;
866 BulletSprite
*bullet
;
868 ExplosionSprite
*expl
;
870 PowerupSprite
*power
;
871 QList
<QGraphicsItem
*> hitlist
;
872 double ndx
[2],ndy
[2];
875 int listsize
; // used for caching QtList::size()
879 if(!ship
[pl
]->isStopped())
882 unexact
= ship
[pl
]->collidingItems(Qt::IntersectsItemBoundingRect
);
883 oldhp
[pl
]=hp
=ship
[pl
]->getHitPoints();
885 foreach (sprite
, unexact
)
887 if((sprite
->type()!=S_EXPLOSION
)
888 && !((sprite
->type()!=S_SUN
)&&(ship
[pl
]->getHitPoints()==0)))
889 if(ship
[pl
]->collidesWithItem(sprite
,Qt::IntersectsItemShape
))
890 if(!hitlist
.contains(sprite
))
891 hitlist
.append(sprite
);
894 foreach (sprite
, hitlist
)
896 switch(sprite
->type())
903 bullet
=(BulletSprite
*)sprite
;
905 //bullets[bullet->getPlayerNumber()]->removeRef(bullet);
906 bullets
[bullet
->getPlayerNumber()]->removeAll(bullet
);
908 hp
-=config
.bulletDamage
;
911 s
=(ShipSprite
*)sprite
;
912 ohp
=s
->getHitPoints();
915 s
->setHitPoints(ohp
-hp
-config
.shipDamage
);
916 emit(hitPoints(s
->getPlayerNumber(),s
->getHitPoints()));
917 ndx
[0]=((1-EPSILON
)*ship
[0]->xVelocity()+(1+EPSILON
)*ship
[1]->xVelocity())/2.0;
918 ndy
[0]=((1-EPSILON
)*ship
[0]->yVelocity()+(1+EPSILON
)*ship
[1]->yVelocity())/2.0;
919 ndx
[1]=((1-EPSILON
)*ship
[1]->xVelocity()+(1+EPSILON
)*ship
[0]->xVelocity())/2.0;
920 ndy
[1]=((1-EPSILON
)*ship
[1]->yVelocity()+(1+EPSILON
)*ship
[0]->yVelocity())/2.0;
921 ship
[0]->setVelocity(ndx
[0],ndy
[0]);
922 ship
[1]->setVelocity(ndx
[1],ndy
[1]);
923 hp
-=ohp
+config
.shipDamage
;
927 mine
=(MineSprite
*)sprite
;
928 if(mine
->isActive()&& !mine
->explodes())
931 ndx
[0]=(ship
[pl
]->xVelocity()+0.3*mine
->xVelocity())/1.3;
932 ndy
[0]=(ship
[pl
]->yVelocity()+0.3*mine
->yVelocity())/1.3;
933 ship
[pl
]->setVelocity(ndx
[0],ndy
[0]);
934 mine
->setVelocity(ndx
[0],ndy
[0]);
935 hp
-=config
.mineDamage
;
939 power
=(PowerupSprite
*)sprite
;
940 switch(power
->getType())
942 case PowerupSprite::PowerupShield
:
943 hp
+=config
.powerupShieldAmount
;
945 case PowerupSprite::PowerupEnergy
:
946 en
=ship
[pl
]->getEnergy()+config
.powerupEnergyAmount
;
949 ship
[pl
]->setEnergy(en
);
951 case PowerupSprite::PowerupMine
:
952 ship
[pl
]->setMinePowerups(
953 ship
[pl
]->getMinePowerups()+1);
955 case PowerupSprite::PowerupBullet
:
956 ship
[pl
]->setBulletPowerups(
957 ship
[pl
]->getMinePowerups()+1);
961 powerups
.removeAll(power
);
968 ship
[pl
]->setHitPoints(hp
);
971 listsize
= mines
[pl
]->size();
972 for (i
=0; i
<listsize
; i
++)
974 mine
= mines
[pl
]->value(i
);
975 if(!mine
->explodes())
978 unexact
=mine
->collidingItems(Qt::IntersectsItemBoundingRect
);
980 foreach (sprite
, unexact
)
982 if(sprite
->type()==S_BULLET
)
983 if(mine
->collidesWithItem(sprite
))
984 if(!hitlist
.contains(sprite
))
985 hitlist
.append(sprite
);
987 if(hitlist
.count()>0)
990 foreach (QGraphicsItem
*item
, hitlist
)
992 // FIXME: why does it crash with qgraphicsitem_cast?
993 bullet
= static_cast<BulletSprite
*>(item
);// qgraphicsitem_cast<BulletSprite*>(item);
994 // bullets[bullet->getPlayerNumber()]->removeRef(bullet);
995 bullets
[bullet
->getPlayerNumber()]->removeAll(bullet
);
1005 unexact
=sun
->collidingItems(Qt::IntersectsItemBoundingRect
);
1006 foreach (sprite
, unexact
)
1008 switch(sprite
->type())
1011 if(sun
->collidesWithItem(sprite
))
1012 if(!hitlist
.contains(sprite
))
1013 hitlist
.append(sprite
);
1016 if(!((MobileSprite
*)sprite
)->isStopped())
1017 if(sun
->collidesWithItem(sprite
))
1018 if(!hitlist
.contains(sprite
))
1019 hitlist
.append(sprite
);
1024 foreach (sprite
, hitlist
)
1026 switch(sprite
->type())
1029 bullet
=(BulletSprite
*)sprite
;
1031 bullets
[bullet
->getPlayerNumber()]->removeAll(bullet
);
1035 mine
=(MineSprite
*)sprite
;
1037 if(!mine
->explodes())
1046 hp
=ship
[pl
]->getHitPoints();
1048 emit(hitPoints(pl
,hp
));
1049 if((hp
==0)&&(ship
[pl
]->getExplosion()<0))
1052 ship
[pl
]->setExplosion((int)(EXPLOSION_TIME
/config
.gamespeed
));
1053 expl
= new ExplosionSprite(svgrender
,animation
[ID_EXPLOSION
],ship
[pl
]);
1054 field
.addItem(expl
);
1056 explosions
.append(expl
);
1057 gameEnd
=Options::timeAfterKill()/config
.gamespeed
;
1062 void MyMainView::gameSetup()
1067 if (KConfigDialog::showDialog("settings"))
1070 SettingsDialog
*settings
=new SettingsDialog(&customConfig
,this,"settings");
1071 connect(settings
, SIGNAL(settingsUpdated()),this,SLOT(closeSettings()));
1075 void MyMainView::closeSettings(){
1076 if(Options::lastConfig()<predefinedConfigNum
)
1077 config
=modifyConfig(predefinedConfig
[Options::lastConfig()]);
1079 config
=modifyConfig(customConfig
);
1082 void MyMainView::focusOutEvent (QFocusEvent
* /*event*/)
1084 /* FIXME: ugly hack, I think
1085 it's maybe better to declare something like QMyScene:public QGraphicsScene and process input there */
1086 setFocus(Qt::OtherFocusReason
);
1089 #include "mainview.moc"