123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- /*
- * Copyright (c) 2010 Nokia Corporation.
- */
- #include "gameengine.h"
- #include "plugins/levelplugininterface.h"
- #include "InvSounds.h"
- #include <QDebug>
- #include <QTimerEvent>
- #include <QTime>
- #include <QDesktopServices>
- const int TIMER_SPEED = 80;
- GameEngine::GameEngine(QObject* parent)
- :QObject(parent)
- {
- m_timerId = 0;
- m_doEnemyMissile = 1500 / TIMER_SPEED;
- m_GameGml = 0;
- m_gameLevel = 0;
- clearQmlObjects();
- // For random
- QTime time = QTime::currentTime();
- qsrand((uint)time.msec());
- // Sound engine
- m_soundEngine = new CInvSounds(this);
- // Device profile
- m_silent = false;
- #ifdef Q_OS_SYMBIAN
- iVibrate = CHWRMVibra::NewL();
- #endif
- // Get device profile, is it silent?
- #if defined Q_OS_SYMBIAN || defined Q_WS_MAEMO_5
- m_systemDeviceInfo = new QSystemDeviceInfo(this);
- QObject::connect(m_systemDeviceInfo,SIGNAL(currentProfileChanged(QSystemDeviceInfo::Profile)),this,
- SLOT(currentProfileChanged(QSystemDeviceInfo::Profile)));
- QSystemDeviceInfo::Profile p = m_systemDeviceInfo->currentProfile();
- if (p == QSystemDeviceInfo::SilentProfile) {
- m_silent = true;
- }
- #endif
- }
- GameEngine::~GameEngine()
- {
- #ifdef Q_OS_SYMBIAN
- delete iVibrate;
- #endif
- }
- void GameEngine::gameStartSound()
- {
- if (!m_silent)
- m_soundEngine->gameStartSound();
- }
- #if defined Q_OS_SYMBIAN || defined Q_WS_MAEMO_5
- void GameEngine::currentProfileChanged(QSystemDeviceInfo::Profile p)
- {
- if (p == QSystemDeviceInfo::SilentProfile) {
- enableSounds(QVariant(false));
- } else {
- enableSounds(QVariant(true));
- }
- }
- #endif
- void GameEngine::enableSounds(QVariant enable)
- {
- m_silent = !enable.toBool();
- if (m_silent)
- this->m_soundEngine->enableSounds(false);
- else
- this->m_soundEngine->enableSounds(true);
- }
- QVariant GameEngine::randInt(QVariant low, QVariant high)
- {
- // Random number between low and high
- return qrand() % ((high.toInt() + 1) - low.toInt()) + low.toInt();
- }
- void GameEngine::setGameLevel(LevelPluginInterface* level)
- {
- // Set used game level
- m_gameLevel = level;
- if (m_gameLevel) {
- // Set used sound from the level into sound engine
- m_soundEngine->enableSounds(m_gameLevel->levelSounds());
- // Invoke QML to take new level in use
- QMetaObject::invokeMethod(m_GameGml, "levelReadyForCreation", Qt::AutoConnection);
- m_doEnemyMissile = m_gameLevel->enemyFireSpeed().toInt() / TIMER_SPEED;
- }
- }
- void GameEngine::setPluginList(QList<QPluginLoader*> plugins)
- {
- m_pluginList = plugins;
- }
- QVariant GameEngine::pluginList()
- {
- QStringList list;
- QPluginLoader* loader;
- foreach(loader,m_pluginList) {
- QString s = loader->fileName();
- s = s.mid(s.lastIndexOf("/")+1);
- s = s.left(s.lastIndexOf("."));
- s = s.toUpper();
- #ifdef Q_WS_MAEMO_5
- if (s.contains("LIB")) {
- s = s.right(s.length() - (s.indexOf("LIB")+3));
- }
- #endif
- list.append(s);
- }
- return QVariant(list);
- }
- void GameEngine::pauseLevel(QVariant doPause)
- {
- bool enableTimer = !doPause.toBool();
- enableEngineTimer(QVariant(enableTimer));
- QMetaObject::invokeMethod(m_levelQml, "pause", Qt::AutoConnection,Q_ARG(QVariant, doPause));
- }
- void GameEngine::findQmlObjects()
- {
- if (m_GameGml) {
- qDebug() << "GameEngine::findQmlObjects()";
- // Find Missiles objects
- m_missileList.clear();
- m_enemyMissileList.clear();
- findMissiles(m_GameGml);
- // Set QMLs
- setLevelQml(m_GameGml->findChild<QObject*>("level"));
- setEnemiesGridQml(m_GameGml->findChild<QObject*>("enemiesGrid"));
- setMyShipQml(m_GameGml->findChild<QObject*>("myShip"));
- // Find Enemies objects
- m_enemyList.clear();
- qDebug() << "GameEngine::findQmlObjects() find enemies from: level QML";
- findEnemies(m_levelQml);
- } else {
- qDebug() << "GameEngine::findQmlObjects() rootObject NULL";
- }
- }
- void GameEngine::clearQmlObjects()
- {
- m_missileList.clear();
- m_enemyMissileList.clear();
- m_enemyList.clear();
- m_levelQml = 0;
- m_enemiesGridGml = 0;
- m_myShipGml = 0;
- //m_GameGml = 0; // NOTE: Do not delete this
- }
- void GameEngine::findMissiles(QObject *rootObject)
- {
- if (rootObject) {
- QObjectList list = rootObject->children();
- QObject* item;
- foreach(item,list) {
- if (item->children().count()>0) {
- findMissiles(item);
- } else {
- if (rootObject->objectName()=="missile") {
- QDeclarativeItem* missile = static_cast<QDeclarativeItem*>(rootObject);
- m_missileList.append(missile);
- } else if (rootObject->objectName()=="enemy_missile") {
- QDeclarativeItem* enemyMissile = static_cast<QDeclarativeItem*>(rootObject);
- m_enemyMissileList.append(enemyMissile);
- }
- }
- }
- } else {
- qDebug() << "GameEngine::findMissiles() rootObject NULL";
- }
- }
- void GameEngine::findEnemies(QObject *rootObject)
- {
- if (rootObject) {
- QObjectList list = rootObject->children();
- QObject* item;
- foreach(item,list) {
- if (item->children().count()>0 && item->objectName()!="enemy") {
- //qDebug() << "Enemy childs founds from: " << item->objectName();
- findEnemies(item);
- } else {
- if (item->objectName()=="enemy") {
- //qDebug() << "Enemy child founds: " << item->objectName();
- QDeclarativeItem* enemy = static_cast<QDeclarativeItem*>(item);
- m_enemyList.append(enemy);
- }
- }
- }
- } else {
- qDebug() << "GameEngine::findEnemies() rootObject NULL";
- }
- }
- void GameEngine::setEnemiesGridQml(QObject* o)
- {
- m_enemiesGridGml = static_cast<QDeclarativeItem*>(o);
- }
- void GameEngine::setMyShipQml(QObject* o)
- {
- m_myShipGml = static_cast<QDeclarativeItem*>(o);
- }
- void GameEngine::setGameQml(QObject* o)
- {
- m_GameGml = static_cast<QDeclarativeItem*>(o);
- }
- void GameEngine::timerEvent(QTimerEvent *e)
- {
- if (e->timerId()==m_timerId) {
- // Do hit test
- doHitTest();
- m_doEnemyMissile--;
- if (m_gameLevel && m_doEnemyMissile<0) {
- m_doEnemyMissile = m_gameLevel->enemyFireSpeed().toInt() / TIMER_SPEED;
- // Do emeny missile launch
- doEnemyMissile();
- }
- }
- }
- void GameEngine::enableEngineTimer(QVariant enable)
- {
- if (m_gameLevel) {
- if (m_timerId==0 && enable.toBool()) {
- m_timerId = QObject::startTimer(TIMER_SPEED);
- }
- else if (m_timerId != 0 && !enable.toBool()) {
- QObject::killTimer(m_timerId);
- m_timerId = 0;
- }
- }
- }
- void GameEngine::selectVisibleEnemy(int& start, int& end)
- {
- QDeclarativeItem* enemy = 0;
- for(int i=0 ; i<m_enemyList.count() ; i++) {
- enemy = m_enemyList[i];
- if (enemy->opacity()==1) {
- start = i;
- break;
- }
- }
- enemy = 0;
- for(int e=m_enemyList.count()-1 ; e>0 ; e--) {
- enemy = m_enemyList[e];
- if (enemy->opacity()==1) {
- end = e;
- break;
- }
- }
- }
- void GameEngine::doEnemyMissile()
- {
- QMutexLocker locker(&m_enemyListMutex);
- QDeclarativeItem* missile = 0;
- QDeclarativeItem* enemy = 0;
- // Find free missile
- foreach(missile, m_enemyMissileList) {
- if (missile->opacity()==0){
- // Random select enemy who fire
- int start=0; int end=0;
- selectVisibleEnemy(start,end);
- int whoWillFire = randInt(QVariant(start),QVariant(end)).toInt();
- if (m_enemyList.count() < whoWillFire+1)
- break;
- enemy = m_enemyList.at(whoWillFire);
- if (enemy && enemy->opacity()==1) {
- QPointF enemyP = enemy->pos();
- if (m_enemiesGridGml) {
- enemyP += m_enemiesGridGml->pos();
- }
- //qDebug() << "QMetaObject::invokeMethod() - fireEnemyMissile";
- QMetaObject::invokeMethod(m_GameGml, "fireEnemyMissile", Qt::AutoConnection,
- Q_ARG(QVariant, enemyP.x()+enemy->boundingRect().width()/4),
- Q_ARG(QVariant, enemyP.y()+enemy->boundingRect().height()),
- Q_ARG(QVariant, m_GameGml->boundingRect().height()));
- }
- break;
- }
- }
- }
- void GameEngine::doHitTest()
- {
- QMutexLocker locker(&m_enemyListMutex);
- QDeclarativeItem* missile = 0;
- QDeclarativeItem* enemy = 0;
- // No enemies?
- if (m_enemyList.count()==0) {
- enableEngineTimer(QVariant(false));
- qDebug() << "No enemies left";
- gameOver(true);
- return;
- }
- if (!m_myShipGml) {
- return;
- }
- // Check ship collision
- if (m_myShipGml->opacity()==1) {
- for(int e=0; e<m_enemyList.count(); e++) {
- enemy = m_enemyList[e];
- if (enemy->opacity()==0) {
- break;
- }
- QPointF enemyP = enemy->pos();
- if (m_enemiesGridGml) {
- enemyP += m_enemiesGridGml->pos();
- }
- QRectF enemyR(enemyP,QSize(enemy->boundingRect().width(),enemy->boundingRect().height()));
- // Collision?
- if (enemyR.contains(m_myShipGml->pos())) {
- enableEngineTimer(QVariant(false));
- // Collision explosion
- QPointF myP = m_myShipGml->pos();
- playSound(1);
- QMetaObject::invokeMethod(m_levelQml, "explode", Qt::AutoConnection,
- Q_ARG(QVariant, myP.x()+m_myShipGml->boundingRect().width()/2),
- Q_ARG(QVariant, myP.y()+m_myShipGml->boundingRect().height()));
- m_myShipGml->setOpacity(0);
- gameOver(false);
- qDebug() << "Collision";
- return;
- }
- // Enemy too deep?
- else if(enemyR.bottomLeft().y() > m_myShipGml->pos().y()+m_myShipGml->pos().y()*0.1) {
- enableEngineTimer(QVariant(false));
- // Enemy too deep explosion
- QPointF myP = m_myShipGml->pos();
- playSound(1);
- QMetaObject::invokeMethod(m_levelQml, "explode", Qt::AutoConnection,
- Q_ARG(QVariant, myP.x()+m_myShipGml->boundingRect().width()/2),
- Q_ARG(QVariant, myP.y()+m_myShipGml->boundingRect().height()));
- m_myShipGml->setOpacity(0);
- gameOver(false);
- qDebug() << "Enemy too deep";
- return;
- }
- }
- }
- // Check your missiles hit to enemies
- foreach(missile, m_missileList) {
- if (missile->opacity()==1){
- for(int e=0; e<m_enemyList.count(); e++) {
- enemy = m_enemyList[e];
- if (enemy->opacity()<1) {
- break;
- }
- QPointF missileP = missile->pos();
- missileP.setX(missileP.rx() + missile->boundingRect().width()/2);
- QPointF enemyP = enemy->pos();
- if (m_enemiesGridGml) {
- enemyP += m_enemiesGridGml->pos();
- }
- QRectF r(enemyP,QSize(enemy->boundingRect().width(),enemy->boundingRect().height()));
- if (r.contains(missileP)) {
- // Hit !
- playSound(0);
- //qDebug() << "QMetaObject::invokeMethod() - explode";
- QMetaObject::invokeMethod(m_levelQml, "explode", Qt::AutoConnection,
- Q_ARG(QVariant, enemyP.x()+enemy->boundingRect().width()/2),
- Q_ARG(QVariant, enemyP.y()+enemy->boundingRect().height()));
- missile->setOpacity(0);
- //fastVibra();
- if (m_enemiesGridGml) {
- // Set transparent placeholder for enemy when using GridView
- enemy->setProperty("source",QVariant("file:/"+m_gameLevel->pathToTransparentEnemyPic().toString()));
- } else {
- // Hide enemy after explode
- enemy->setOpacity(0);
- }
- // Remove enemy from list
- m_enemyList.removeAt(e);
- e--;
- }
- enemy = 0;
- }
- }
- }
- // Check enemies missiles hit to you
- if (m_myShipGml->opacity()==1) {
- foreach(missile, m_enemyMissileList) {
- if (missile->opacity()==1){
- QPointF missileP = missile->pos();
- missileP.setX(missileP.rx() + missile->boundingRect().width()/2);
- QPointF myP = m_myShipGml->pos();
- QRectF r(myP,QSize(m_myShipGml->boundingRect().width(),m_myShipGml->boundingRect().height()));
- if (r.contains(missileP)) {
- // Hit !
- playSound(1);
- //qDebug() << "QMetaObject::invokeMethod() - explode";
- QMetaObject::invokeMethod(m_levelQml, "explode", Qt::AutoConnection,
- Q_ARG(QVariant, myP.x()+m_myShipGml->boundingRect().width()/2),
- Q_ARG(QVariant, myP.y()+m_myShipGml->boundingRect().height()));
- missile->setOpacity(0);
- m_myShipGml->setOpacity(0);
- break;
- }
- }
- }
- } else {
- // You was killed
- enableEngineTimer(QVariant(false));
- gameOver(false);
- qDebug() << "You was killed by enemy missile";
- }
- }
- void GameEngine::playSound(QVariant index)
- {
- if (!m_silent) {
- int i = index.toInt();
- m_soundEngine->playSound(i);
- }
- }
- void GameEngine::playSounds(QVariant index, QVariant count)
- {
- if (!m_silent) {
- m_soundEngine->playSounds(index.toInt(),count.toInt());
- }
- }
- void GameEngine::playInternalSound(QVariant index)
- {
- if (!m_silent) {
- m_soundEngine->playInternalSound(index.toInt());
- }
- }
- void GameEngine::playInternalSounds(QVariant index, QVariant count)
- {
- if (!m_silent) {
- m_soundEngine->playInternalSounds(index.toInt(),count.toInt());
- }
- }
- void GameEngine::gameOver(bool youWin)
- {
- qDebug() << "GameEngine::gameOver() "<< youWin;
- QMetaObject::invokeMethod(m_GameGml, "gameOver", Qt::AutoConnection,Q_ARG(QVariant, youWin));
- }
- void GameEngine::pauseGame() {
- QMetaObject::invokeMethod(m_GameGml, "pauseGame", Qt::AutoConnection);
- }
- QVariant GameEngine::isSymbian()
- {
- #ifdef Q_OS_SYMBIAN
- return QVariant(true);
- #else
- return QVariant(false);
- #endif
- }
- QVariant GameEngine::isMaemo()
- {
- #ifdef Q_WS_MAEMO_5
- return QVariant(true);
- #else
- return QVariant(false);
- #endif
- }
- QVariant GameEngine::isWindows()
- {
- #ifdef Q_OS_WIN
- return QVariant(true);
- #else
- return QVariant(false);
- #endif
- }
- void GameEngine::vibra()
- {
- #ifdef Q_OS_SYMBIAN
- if (iVibrate){
- TRAPD(err, iVibrate->StartVibraL(4000,KHWRMVibraMaxIntensity));
- }
- #endif
- }
- void GameEngine::fastVibra()
- {
- #ifdef Q_OS_SYMBIAN
- if (iVibrate){
- TRAPD(err, iVibrate->StartVibraL(100,KHWRMVibraMaxIntensity));
- }
- #endif
- }
- void GameEngine::openLink(QVariant link)
- {
- QDesktopServices::openUrl(QUrl(link.toString()));
- }
|