Game.qml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /**
  2. * Copyright (c) 2011 Nokia Corporation.
  3. */
  4. import QtQuick 1.0
  5. import "Game.js" as GameScript
  6. AppWindow {
  7. id: gameArea
  8. property bool gameOverProperty: false // Who wins, you or computer
  9. property variant messageBox // For info message to user
  10. property variant buyView: 0
  11. property variant levelPlugin: 0
  12. // Width and height are the other way around on Harmattan compared to
  13. // Symbian.
  14. property int xDim: width < height ? width : height;
  15. property int yDim: width < height ? height : width;
  16. // Signals from QML to Qt side
  17. signal levelActivated(int index)
  18. signal reloadPlugins()
  19. objectName: "gameArea"
  20. function foreground()
  21. {
  22. if (buyView) {
  23. buyView.foreground();
  24. }
  25. }
  26. function closeBuyView()
  27. {
  28. buyView.doBack();
  29. btnBack.opacity = 0;
  30. endGame();
  31. reloadPlugins();
  32. menu.showMainMenu();
  33. buyView.destroy();
  34. buyView = 0;
  35. }
  36. function pauseGame()
  37. {
  38. if (levelPlugin) {
  39. GameScript.pauseGame(true)
  40. myShip.focus = false
  41. btnPause.opacity = 0
  42. menu.showPauseMenu();
  43. }
  44. }
  45. function showMainMenu()
  46. {
  47. menu.showMainMenu();
  48. }
  49. /**
  50. * This function is called from the Qt C++ code in order for the QML code
  51. * to take a new level into use.
  52. */
  53. function levelReadyForCreation()
  54. {
  55. // Hide menu
  56. menu.hideMenu();
  57. // Show message
  58. message.showMessage("Loading level...", 2000);
  59. // Wait before create level
  60. levelCreationTimer.restart();
  61. }
  62. /**
  63. * Fires enemy missile. This function is called from the Qt C++ code.
  64. *
  65. * @param aXpox
  66. * @param aFromYpos
  67. * @param aToYpos
  68. */
  69. function fireEnemyMissile(aXpox, aFromYpos, aToYpos)
  70. {
  71. GameScript.fireEnemyMissile(aXpox, aFromYpos, aToYpos);
  72. }
  73. /**
  74. * Game Over handling. This function is called from the Qt C++ code.
  75. *
  76. * @param youWin If true, the player won the game. Otherwise the computer
  77. * has won.
  78. */
  79. function gameOver(youWin)
  80. {
  81. gameOverProperty = youWin;
  82. // Delayed game over for to user see all explositions
  83. gameOverTimer.restart();
  84. if (gameOverProperty) {
  85. GameEngine.playInternalSound(4);
  86. message.showMessage("Game over, you win!", 2000);
  87. }
  88. else {
  89. GameEngine.playInternalSounds(3,3);
  90. message.showMessage("Game over, you lost", 2000);
  91. }
  92. }
  93. /**
  94. * Ends the game and shows the main menu.
  95. *
  96. * @param showMessage If true will show a message.
  97. */
  98. function endGame(showMessage)
  99. {
  100. backgroundPic.opacity = 1;
  101. // Do game over and hide the missiles
  102. GameScript.gameOver();
  103. GameScript.hideMissiles();
  104. // Clear GameEngine QML objects
  105. myShip.opacity = 0;
  106. myShip.focus = false;
  107. btnPause.opacity = 0;
  108. idMainLogo.opacity = 1;
  109. if (showMessage) {
  110. message.showMessage("Game over", 2000)
  111. }
  112. menu.showMainMenu();
  113. }
  114. // Timer for level creationing
  115. Timer {
  116. id: levelCreationTimer
  117. running: false
  118. repeat: false
  119. interval: 2500
  120. onTriggered: {
  121. btnPause.opacity = 1;
  122. myShip.opacity = 1;
  123. myShip.focus = true;
  124. // Create new level
  125. var ret = GameScript.createLevel();
  126. if (!ret) {
  127. backgroundPic.opacity = 0;
  128. // Find QML object for GameEngine
  129. GameEngine.findQmlObjects();
  130. // Enable GameEngine timer
  131. GameEngine.enableEngineTimer(true);
  132. }
  133. else {
  134. console.debug("Failed to load a level");
  135. endGame(false);
  136. }
  137. }
  138. }
  139. // Timer for game over
  140. Timer {
  141. id: gameOverTimer
  142. running: false
  143. repeat: false
  144. interval: 2000
  145. onTriggered: {
  146. GameScript.gameOver();
  147. GameScript.hideMissiles();
  148. backgroundPic.opacity = 1;
  149. idMainLogo.opacity = 1;
  150. menu.showMainMenu();
  151. }
  152. }
  153. // Background image for the game
  154. Image {
  155. id: backgroundPic
  156. z: 1
  157. source: "qrc:/gfx/background2.png"
  158. fillMode: Image.PreserveAspectCrop
  159. smooth: true
  160. anchors.fill: parent
  161. }
  162. // The animated big ship in the menu view
  163. Image {
  164. id: bigShip
  165. source: "qrc:/gfx/bigship.png"
  166. z: 1.5
  167. smooth: true
  168. x: width * -1
  169. y: parent.height * 0.55
  170. }
  171. SequentialAnimation {
  172. id: bigShipAnim
  173. NumberAnimation {
  174. target: bigShip
  175. property: "x"
  176. to: gameArea.xDim
  177. easing.type: Easing.Linear
  178. duration: 80000
  179. }
  180. PropertyAction {
  181. target: bigShip
  182. properties: "opacity"
  183. value: 0
  184. }
  185. }
  186. // Enemies grid
  187. Item {
  188. // This is general level QML plaseholder
  189. // Into this is level QML created in createLevel()
  190. id: levelId
  191. anchors.fill: parent
  192. z: 2
  193. }
  194. // Buy levels
  195. Item {
  196. id: buyLevels
  197. opacity: 1
  198. z: 2.1
  199. }
  200. Image {
  201. id: idMainLogo
  202. z: 19
  203. source: "qrc:/gfx/quickhit_logo.png"
  204. smooth: true
  205. anchors.horizontalCenter: parent.horizontalCenter
  206. y: gameArea.yDim * 0.10
  207. }
  208. // Game menu
  209. Menu {
  210. id: menu
  211. z: 20
  212. opacity: 0
  213. width: parent.width * 0.8
  214. height: parent.height * 0.6
  215. // Level selected
  216. onLevelSelected: {
  217. // Stop bigship animation
  218. bigShipAnim.stop();
  219. bigShip.opacity = 0;
  220. // Hide logo
  221. idMainLogo.opacity = 0;
  222. // Signal level activated
  223. gameArea.levelActivated(levelIndex);
  224. }
  225. }
  226. // Info
  227. Item {
  228. z: 21
  229. id: infoView
  230. anchors.fill: parent
  231. }
  232. // My ship
  233. MyShip {
  234. z: 10
  235. id: myShip
  236. opacity: 0
  237. }
  238. // Mouse area of your ship
  239. MouseArea {
  240. property int startPos: 0
  241. property int dragCount: 0
  242. width: gameArea.xDim
  243. height: myShip.height
  244. x: 0
  245. y: gameArea.yDim - myShip.height
  246. drag.target: myShip
  247. drag.axis: Drag.XAxis
  248. drag.minimumX: 0
  249. drag.maximumX: gameArea.xDim - myShip.width
  250. onPressed: {
  251. startPos = mouseX;
  252. dragCount = 0;
  253. }
  254. onReleased: {
  255. myShip.fire();
  256. }
  257. }
  258. // Toggle sound button
  259. Button {
  260. id: btnSound
  261. z: 12
  262. anchors.top: parent.top
  263. anchors.topMargin: 10
  264. anchors.right: parent.right
  265. anchors.rightMargin: 15
  266. buttonPath: "qrc:/gfx/soundOn.png"
  267. buttonId: 4
  268. width: gameArea.xDim / 10
  269. height: width
  270. opacity: 1
  271. onBtnClicked: {
  272. if (btnSound.buttonId == 4) {
  273. // Sound off
  274. btnSound.buttonPath = "qrc:/gfx/soundOff.png";
  275. btnSound.buttonId = 5;
  276. GameEngine.enableSounds(false);
  277. }
  278. else {
  279. // Sound on
  280. btnSound.buttonPath = "qrc:/gfx/soundOn.png";
  281. btnSound.buttonId = 4;
  282. GameEngine.enableSounds(true);
  283. }
  284. }
  285. }
  286. // Pause button
  287. Button {
  288. id: btnPause
  289. z: 13
  290. anchors.top: parent.top
  291. anchors.topMargin: 10
  292. anchors.right: btnSound.left
  293. anchors.rightMargin: 15
  294. buttonPath: "qrc:/gfx/pause.png"
  295. buttonId: 3
  296. width: btnSound.width
  297. height: width
  298. opacity: 0
  299. onBtnClicked: {
  300. GameScript.pauseGame(true);
  301. myShip.focus = false;
  302. btnPause.opacity = 0;
  303. menu.showPauseMenu();
  304. }
  305. }
  306. // Back button
  307. Button {
  308. id: btnBack
  309. z: 13.1
  310. anchors.top: parent.top
  311. anchors.topMargin: 10
  312. anchors.right: btnSound.left
  313. anchors.rightMargin: 15
  314. buttonPath: "qrc:/gfx/back.png"
  315. width: btnSound.width
  316. height: width
  317. opacity: 0
  318. onBtnClicked: {
  319. closeBuyView();
  320. }
  321. }
  322. // Hidden missiles ready for to be launched
  323. Missile {
  324. z: 3
  325. id: missile_1
  326. x: 0
  327. y: 10
  328. }
  329. Missile {
  330. z: 4
  331. id: missile_2
  332. x: 20
  333. y: 10
  334. }
  335. Missile {
  336. z: 5
  337. id: missile_3
  338. x: 40
  339. y: 10
  340. }
  341. Missile {
  342. z: 6
  343. id: missile_4
  344. x: 60
  345. y: 10
  346. }
  347. Missile {
  348. z: 7
  349. id: missile_5
  350. x: 80
  351. y: 10
  352. }
  353. Missile {
  354. z: 8
  355. objectName: "enemy_missile"
  356. id: enemy_missile_1
  357. enemyMissile: true
  358. }
  359. Missile {
  360. z: 9
  361. objectName: "enemy_missile"
  362. id: enemy_missile_2
  363. enemyMissile: true
  364. }
  365. // Messages to the user
  366. MessageProgress {
  367. id: messageProgress
  368. z: 19.9
  369. }
  370. Message {
  371. id: message
  372. z: 21
  373. }
  374. // Splach screen
  375. Rectangle {
  376. id: blackFace
  377. x: -2
  378. y: 0
  379. width: parent.width + 2
  380. height: parent.height
  381. z: 100
  382. color: "black"
  383. opacity: 1
  384. MouseArea {
  385. anchors.fill: parent
  386. onPressed: {
  387. mouse.accepted = true;
  388. fadeAnim.stop();
  389. rotAnim.stop();
  390. blackFace.opacity = 0;
  391. idLogo.opacity = 1;
  392. menu.showMainMenu();
  393. }
  394. }
  395. Image {
  396. id: idLogo
  397. source: "qrc:/gfx/quickhit_logo.png"
  398. smooth: true
  399. anchors.horizontalCenter: parent.horizontalCenter
  400. anchors.verticalCenter: parent.verticalCenter
  401. opacity: 0
  402. }
  403. NumberAnimation {
  404. id: rotAnim
  405. target: idLogo
  406. property: "rotation"
  407. to: 20
  408. duration: 9000
  409. }
  410. }
  411. // Splach screen animation
  412. SequentialAnimation {
  413. id: fadeAnim
  414. NumberAnimation { target: idLogo; property: "opacity"; from: 0; to: 1; duration: 2000 }
  415. PauseAnimation { duration: 1000 }
  416. NumberAnimation { target: idLogo; property: "opacity"; from: 1; to: 0; duration: 2000 }
  417. NumberAnimation { target: blackFace; property: "opacity"; from: 1; to: 0; duration: 1000 }
  418. PauseAnimation { duration: 200 }
  419. ScriptAction { script: showMainMenu() }
  420. }
  421. Component.onCompleted: {
  422. // Start big ship animation
  423. bigShipAnim.restart();
  424. // Set variable
  425. messageBox = message;
  426. // Play game start sound
  427. GameEngine.gameStartSound();
  428. // Fade splash screen
  429. fadeAnim.restart();
  430. // Rotate splash logo
  431. rotAnim.restart();
  432. }
  433. }