Warning, /games/kbreakout/src/qml/main.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2012 Viranch Mehta <viranch.mehta@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.3 0008 import org.kde.games.core 0.1 as KgCore 0009 import "globals.js" as Globals 0010 import "logic.js" as Logic 0011 0012 Item { 0013 id: canvas 0014 0015 signal levelComplete() 0016 signal gameEnded(int score, int level, int elapsedTime) 0017 signal mousePressed() 0018 0019 property real speed 0020 property bool paused: false 0021 property bool gameOver: false 0022 property bool gameWon: false 0023 readonly property Item jailItem: bgOverlay 0024 readonly property bool ballMoving: !paused && fireBallMessage.opacity !== 1 0025 0026 function updateGeometry() { 0027 var bw = Globals.BRICK_WIDTH*Globals.WIDTH + 1; 0028 // bh = (overlayHeight = BRICK_HEIGHT*HEIGHT+1) 0029 // +(headerItemsHeight = BRICK_HEIGHT*1.5) 0030 // +(margin = headerItemHeight*0.2) 0031 var bh = Globals.BRICK_HEIGHT*Globals.HEIGHT + 1 + Globals.BRICK_HEIGHT*1.5*1.2; 0032 0033 var w = canvas.height*bw/bh; 0034 var h = canvas.width*bh/bw; 0035 0036 if (w > canvas.width) { 0037 container.width = canvas.width-20; 0038 container.height = container.width*bh/bw; 0039 } else if (h > canvas.height) { 0040 container.height = canvas.height-50; 0041 container.width = container.height*bw/bh; 0042 } else { 0043 // Never happens, don't know what to do in case it does! 0044 } 0045 } 0046 0047 property real m_scale: container.width/(Globals.BRICK_WIDTH*Globals.WIDTH) 0048 0049 CanvasItem { 0050 id: background 0051 spriteKey: "Background" 0052 anchors.fill: parent 0053 } 0054 0055 Item { 0056 id: container 0057 anchors.centerIn: parent 0058 } 0059 0060 property int barCenter: mapFromItem(bgOverlay, Math.round(bar.x + bar.width/2), 0).x 0061 0062 CanvasItem { 0063 id: bgOverlay 0064 spriteKey: "BackgroundOverlay" 0065 anchors { 0066 left: container.left 0067 bottom: container.bottom 0068 } 0069 width: m_scale * (Globals.BRICK_WIDTH*Globals.WIDTH + 1) 0070 height: m_scale * (Globals.BRICK_HEIGHT*Globals.HEIGHT + 1) 0071 0072 Bar { 0073 id: bar 0074 anchors { 0075 bottom: parent.bottom 0076 } 0077 posX: 300 0078 } 0079 } 0080 0081 Rectangle { 0082 id: pauseOverlay 0083 anchors.fill: parent 0084 color: "#646464" 0085 opacity: paused ? 0.6 : 0 0086 z: 1 // to show above all the elements (except messageBox) 0087 0088 Behavior on opacity { NumberAnimation { duration: 100 } } 0089 } 0090 function setGamePaused(paused) { 0091 Logic.setGamePaused(paused); 0092 } 0093 0094 TextItem { 0095 id: messageBox 0096 anchors.centerIn: bgOverlay 0097 z: 2 // to make it display above the pause overlay 0098 width: m_scale * Globals.BRICK_WIDTH*9 0099 height: m_scale * Globals.BRICK_HEIGHT*5 0100 opacity: 0 0101 0102 Behavior on opacity { NumberAnimation { duration: 100 } } 0103 } 0104 0105 property string fireShortcut: "Space" 0106 TextItem { 0107 id: fireBallMessage 0108 anchors { 0109 horizontalCenter: bgOverlay.horizontalCenter 0110 bottom: bgOverlay.bottom 0111 bottomMargin: (bgOverlay.height-height)/4 0112 } 0113 width: m_scale * Globals.BRICK_WIDTH*9 0114 height: m_scale * Globals.BRICK_HEIGHT*2 0115 text: i18n("Press %1 to fire the ball", fireShortcut) 0116 opacity: 0 0117 0118 Behavior on opacity { NumberAnimation { duration: 100 } } 0119 } 0120 0121 property int score 0122 TextItem { 0123 id: scoreDisplay 0124 width: m_scale * (Globals.BRICK_WIDTH*Globals.WIDTH)/6 0125 height: m_scale * Globals.BRICK_HEIGHT*1.5 0126 anchors { 0127 left: bgOverlay.left 0128 bottom: bgOverlay.top 0129 bottomMargin: height/5 0130 } 0131 text: Logic.scoreString(parent.score) 0132 } 0133 0134 property int level 0135 TextItem { 0136 id: levelDisplay 0137 width: m_scale * (Globals.BRICK_WIDTH*Globals.WIDTH)/5 0138 height: m_scale * Globals.BRICK_HEIGHT*1.5 0139 anchors { 0140 left: scoreDisplay.right 0141 leftMargin: width-scoreDisplay.width 0142 bottom: bgOverlay.top 0143 bottomMargin: height/5 0144 } 0145 text: i18n("Level %1", parent.level) 0146 } 0147 0148 property int lives 0149 Row { 0150 id: lifeBars 0151 spacing: m_scale * Globals.BRICK_WIDTH*0.23 0152 anchors { 0153 right: bgOverlay.right 0154 rightMargin: 20 0155 bottom: bgOverlay.top 0156 bottomMargin: levelDisplay.height/5 0157 } 0158 0159 Repeater { 0160 model: canvas.lives 0161 Bar { 0162 width: m_scale * Globals.BRICK_WIDTH/1.3 0163 height: m_scale * Globals.BRICK_HEIGHT/1.3 0164 } 0165 } 0166 } 0167 0168 function reset() { 0169 Logic.reset(); 0170 } 0171 0172 function loadLine(line, lineNumber) { 0173 Logic.showLine(line, lineNumber); 0174 } 0175 0176 function loadGift(gift, times, pos) { 0177 Logic.putGift(gift, times, pos); 0178 } 0179 0180 function updateBarDirection(direction) { 0181 bar.direction = direction; 0182 } 0183 0184 function startGame() { 0185 Logic.startLevel(); 0186 } 0187 0188 Timer { 0189 id: gameTimer 0190 interval: Globals.REPAINT_INTERVAL 0191 repeat: true 0192 onTriggered: { 0193 for (x = 0; x < Logic.substeps; ++x) { 0194 Logic.moveBalls() 0195 Logic.detectCollisions() 0196 } 0197 } 0198 } 0199 0200 Timer { 0201 id: elapsedTimeTimer 0202 interval: 1000 0203 repeat: true 0204 property int elapsedTime: 0 0205 onTriggered: elapsedTime++; 0206 } 0207 0208 Timer { 0209 id: handleDeathTimer 0210 interval: 1000 0211 onTriggered: Logic.handleDeath() 0212 } 0213 0214 // hides the current showed message by target 0215 // unless the game is paused, won or game over 0216 Timer { 0217 id: hideTimer 0218 property variant target 0219 onTriggered: { 0220 if (paused) return; 0221 target.opacity = 0; 0222 } 0223 } 0224 0225 function fire() { 0226 Logic.fireBall(); 0227 } 0228 0229 function cheatAddLife() { 0230 Logic.addLife(); 0231 } 0232 0233 function cheatSkipLevel() { 0234 Logic.loadNextLevel(); 0235 } 0236 0237 Timer { 0238 id: burnBricksTimer 0239 property variant target 0240 interval: Globals.BURNING_SPEED 0241 onTriggered: Logic.burnNearbyBricks(target); 0242 } 0243 0244 MouseArea { 0245 id: mouseArea 0246 enabled: false 0247 anchors.fill: parent 0248 hoverEnabled: true 0249 onPositionChanged: mouse => { 0250 if (paused) return; 0251 0252 // avoids accidentally moving the mouse while playing using the keys 0253 if (bar.direction != 0) return; 0254 0255 var barX = canvas.mapToItem(bgOverlay, mouse.x, 0).x - bar.width/2; 0256 bar.moveTo(barX/m_scale); 0257 } 0258 onClicked: canvas.mousePressed() 0259 } 0260 0261 Item { 0262 id: keyEventHandler 0263 focus: true 0264 anchors.fill: parent 0265 Keys.onPressed: event => { 0266 if (event.key == Qt.Key_Right) { 0267 updateBarDirection(1); 0268 } else if (event.key == Qt.Key_Left) { 0269 updateBarDirection(-1); 0270 } 0271 } 0272 0273 Keys.onReleased: event => { 0274 if (event.key == Qt.Key_Right || event.key == Qt.Key_Left) { 0275 updateBarDirection(0); 0276 } 0277 } 0278 } 0279 }