Warning, /education/gcompris/src/activities/submarine/Submarine.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - submarine.qml 0002 * 0003 * SPDX-FileCopyrightText: 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com> 0004 * 0005 * Authors: 0006 * Pascal Georges <pascal.georges1@free.fr> (GTK+ version) 0007 * Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port) 0008 * 0009 * SPDX-License-Identifier: GPL-3.0-or-later 0010 */ 0011 import QtQuick 2.12 0012 import QtQuick.Particles 2.12 0013 import Box2D 2.0 0014 import QtGraphicalEffects 1.0 0015 import GCompris 1.0 0016 0017 import "../../core" 0018 import "submarine.js" as Activity 0019 0020 ActivityBase { 0021 id: activity 0022 0023 onStart: focus = true 0024 onStop: {} 0025 0026 property string url: "qrc:/gcompris/src/activities/submarine/resource/" 0027 0028 pageComponent: Image { 0029 id: background 0030 source: url + "background.svg" 0031 anchors.fill: parent 0032 sourceSize.height: parent.height 0033 sourceSize.width: parent.width 0034 0035 onWidthChanged: updateOnWidthReset.start() 0036 onHeightChanged: Activity.resetUpperGate() 0037 onVisibleChanged: visible ? physicalWorld.running = true : 0038 physicalWorld.running = false 0039 0040 property bool hori: background.width >= background.height 0041 0042 signal start 0043 signal stop 0044 0045 Component.onCompleted: { 0046 activity.start.connect(start) 0047 activity.stop.connect(stop) 0048 } 0049 0050 // Needed to get keyboard focus on IntroMessage 0051 Keys.forwardTo: tutorial 0052 0053 /* Testing purposes, A / Left Key => Reduces velocity, D / Right Key => Increases velocity */ 0054 Keys.onPressed: { 0055 if (event.key === Qt.Key_D || event.key === Qt.Key_Right) { 0056 submarine.increaseHorizontalVelocity(1) 0057 } 0058 if (event.key === Qt.Key_A || event.key === Qt.Key_Left) { 0059 submarine.decreaseHorizontalVelocity(1) 0060 } 0061 if (event.key === Qt.Key_W || event.key === Qt.Key_Up) { 0062 centralBallastTank.fillBallastTanks() 0063 controls.updateVannes(centralBallastTank.waterFilling, controls.rotateCentralFill) 0064 } 0065 if (event.key === Qt.Key_S || event.key === Qt.Key_Down){ 0066 centralBallastTank.flushBallastTanks() 0067 controls.updateVannes(centralBallastTank.waterFlushing, controls.rotateCentralFlush) 0068 } 0069 if (event.key === Qt.Key_Plus) { 0070 submarine.increaseWingsAngle(1) 0071 } 0072 if (event.key === Qt.Key_Minus) { 0073 submarine.decreaseWingsAngle(1) 0074 } 0075 0076 if (event.key === Qt.Key_R) { 0077 leftBallastTank.fillBallastTanks() 0078 controls.updateVannes(leftBallastTank.waterFilling, controls.rotateLeftFill) 0079 } 0080 if (event.key === Qt.Key_F) { 0081 leftBallastTank.flushBallastTanks() 0082 controls.updateVannes(leftBallastTank.waterFlushing, controls.rotateLeftFlush) 0083 } 0084 0085 if (event.key === Qt.Key_T) { 0086 rightBallastTank.fillBallastTanks() 0087 controls.updateVannes(rightBallastTank.waterFilling, controls.rotateRightFill) 0088 } 0089 if (event.key === Qt.Key_G) { 0090 rightBallastTank.flushBallastTanks() 0091 controls.updateVannes(rightBallastTank.waterFlushing, controls.rotateRightFlush) 0092 } 0093 } 0094 0095 // Add here the QML items you need to access in javascript 0096 QtObject { 0097 id: items 0098 property Item main: activity.main 0099 property alias background: background 0100 property int currentLevel: activity.currentLevel 0101 property alias bonus: bonus 0102 property alias crown: crown 0103 property alias whale: whale 0104 property var submarineCategory: Fixture.Category1 0105 property var crownCategory: Fixture.Category2 0106 property var whaleCategory: Fixture.Category3 0107 property var upperGatefixerCategory: Fixture.Category4 0108 property var lowerGatefixerCategory: Fixture.Category5 0109 property var shipCategory: Fixture.Category6 0110 property var rockCategory: Fixture.Category7 0111 property var maxDepthCategory: Fixture.Category8 0112 property alias submarine: submarine 0113 property alias tutorial: tutorial 0114 property alias upperGate: upperGate 0115 property alias ship: ship 0116 property alias controls: controls 0117 property alias physicalWorld: physicalWorld 0118 property bool processingAnswer: false 0119 } 0120 0121 IntroMessage { 0122 id: tutorial 0123 textContainerHeight: 0.5 * parent.height 0124 z: 100 0125 onIntroDone: { 0126 tutorial.visible = false 0127 } 0128 } 0129 0130 onStart: { Activity.start(items) } 0131 onStop: { 0132 smoothHorizontalVelocity.stop() 0133 updateVerticalVelocity.stop() 0134 removeSparkleTimer.stop() 0135 updateOnWidthReset.stop() 0136 Activity.stop() 0137 } 0138 0139 World { 0140 id: physicalWorld 0141 running: !tutorial.visible && !items.processingAnswer 0142 gravity: Qt.point(0,0) 0143 autoClearForces: false 0144 } 0145 0146 Item { 0147 id: waterLevel 0148 x: 0 0149 y: background.height / 15 0150 } 0151 0152 Rectangle { 0153 id: maximumWaterDepth 0154 0155 width: background.width 0156 height: 10 0157 color: "transparent" 0158 0159 y: background.height * 0.65 0160 0161 Body { 0162 id: maxDepthBody 0163 target: maximumWaterDepth 0164 bodyType: Body.Static 0165 sleepingAllowed: true 0166 linearDamping: 0 0167 0168 fixtures: Box { 0169 categories: items.maxDepthCategory 0170 collidesWith: items.submarineCategory 0171 width: maximumWaterDepth.width 0172 height: maximumWaterDepth.height 0173 density: 1 0174 friction: 0 0175 restitution: 0 0176 } 0177 } 0178 } 0179 0180 Item { 0181 id: submarine 0182 0183 z: 1 0184 0185 property point initialPosition: Qt.point(0,waterLevel.y - submarineImage.height/2) 0186 property bool isHit: false 0187 property int terminalVelocityIndex: 75 0188 property int maxAbsoluteRotationAngle: 15 0189 0190 /* Maximum depth the submarine can dive when ballast tank is full */ 0191 property real maximumDepthOnFullTanks: maximumWaterDepth.y * 0.45 0192 property real ballastTankDiveSpeed: 10 0193 0194 /* Engine properties */ 0195 property point velocity 0196 property int maximumXVelocity: 5 0197 property int currentFinalVelocity: 0 0198 0199 /* Wings property */ 0200 property int wingsAngle 0201 property int initialWingsAngle: 0 0202 property int maxWingsAngle: 2 0203 property int minWingsAngle: -2 0204 0205 function destroySubmarine() { 0206 isHit = true 0207 } 0208 0209 function resetSubmarine() { 0210 isHit = false 0211 submarineImage.reset() 0212 0213 leftBallastTank.resetBallastTanks() 0214 rightBallastTank.resetBallastTanks() 0215 centralBallastTank.resetBallastTanks() 0216 0217 currentFinalVelocity = 0 0218 velocity = Qt.point(0,0) 0219 smoothHorizontalVelocity.stop() 0220 wingsAngle = initialWingsAngle 0221 } 0222 0223 /* While increasing or decreasing, we can't use submarine.velocity.x since it is interpolating */ 0224 function increaseHorizontalVelocity(amount) { 0225 if (submarine.currentFinalVelocity + amount <= submarine.maximumXVelocity) { 0226 submarine.currentFinalVelocity += amount 0227 smoothHorizontalVelocity.stop() 0228 smoothHorizontalVelocity.setFinalVelocity(submarine.currentFinalVelocity) 0229 smoothHorizontalVelocity.setIncreaseVelocity(true) 0230 smoothHorizontalVelocity.start() 0231 } 0232 } 0233 0234 function decreaseHorizontalVelocity(amount) { 0235 if (submarine.currentFinalVelocity - amount >= 0) { 0236 submarine.currentFinalVelocity -= amount 0237 smoothHorizontalVelocity.stop() 0238 smoothHorizontalVelocity.setFinalVelocity(submarine.currentFinalVelocity) 0239 smoothHorizontalVelocity.setIncreaseVelocity(false) 0240 smoothHorizontalVelocity.start() 0241 } 0242 } 0243 0244 function increaseWingsAngle(amount) { 0245 if (wingsAngle + amount <= maxWingsAngle) { 0246 wingsAngle += amount 0247 } else { 0248 wingsAngle = maxWingsAngle 0249 } 0250 } 0251 0252 function decreaseWingsAngle(amount) { 0253 if (wingsAngle - amount >= minWingsAngle) { 0254 wingsAngle -= amount 0255 } else { 0256 wingsAngle = minWingsAngle 0257 } 0258 } 0259 0260 function changeVerticalVelocity() { 0261 /* Check if we are currently using diving planes or ballast tanks */ 0262 var isDivingPlanesActive 0263 if (submarineImage.y > 0 && submarine.velocity.x > 0 && wingsAngle != 0) { 0264 /* 0265 * Movement due to planes 0266 * Movement is affected only when the submarine is moving forward 0267 * When the submarine is on the surface, the planes cannot be used 0268 */ 0269 isDivingPlanesActive = true 0270 } else { 0271 isDivingPlanesActive = false 0272 } 0273 0274 var yPosition 0275 if (isDivingPlanesActive) { 0276 /* Currently using diving planes */ 0277 var multiplier 0278 if (wingsAngle == 1) { 0279 multiplier = 0.6 0280 } else if (wingsAngle == 2) { 0281 multiplier = 0.8 0282 } else if (wingsAngle == -1) { 0283 multiplier = 0.2 0284 } else if (wingsAngle == -2) { 0285 multiplier = 0.1 0286 } 0287 yPosition = multiplier * maximumWaterDepth.y 0288 } else { 0289 /* Currently under the influence of Ballast Tanks */ 0290 yPosition = submarineImage.currentWaterLevel / submarineImage.totalWaterLevel * submarine.maximumDepthOnFullTanks 0291 0292 if (bar.level >= 7) { 0293 var finalAngle = ((rightBallastTank.waterLevel - leftBallastTank.waterLevel) / leftBallastTank.maxWaterLevel) * submarine.maxAbsoluteRotationAngle 0294 submarineRotation.angle = finalAngle 0295 } 0296 } 0297 var depthToMove 0298 if (submarineImage.y <= submarine.initialPosition.y && yPosition == 0){ 0299 depthToMove = 0 0300 }else { 0301 depthToMove = yPosition - submarineImage.y 0302 } 0303 submarine.velocity.y = ballastTankDiveSpeed * (depthToMove / background.width) 0304 } 0305 0306 Timer { 0307 id: smoothHorizontalVelocity 0308 running: false 0309 repeat: true 0310 interval: 100 0311 0312 property real finalVelocity 0313 property real smoothRate: 0.1 0314 property bool increaseVelocity 0315 0316 function increaseVelocitySmoothly() { 0317 if (submarine.velocity.x + smoothRate > finalVelocity) { 0318 submarine.velocity.x = finalVelocity 0319 smoothHorizontalVelocity.stop() 0320 } else { 0321 submarine.velocity.x += smoothRate 0322 } 0323 } 0324 0325 function decreaseVelocitySmoothly() { 0326 if (submarine.velocity.x - smoothRate <= finalVelocity) { 0327 submarine.velocity.x = finalVelocity 0328 smoothHorizontalVelocity.stop() 0329 } else { 0330 submarine.velocity.x -= smoothRate 0331 } 0332 } 0333 0334 function setFinalVelocity(_finalVelocity) { 0335 finalVelocity = _finalVelocity 0336 } 0337 0338 function setIncreaseVelocity(value) { 0339 increaseVelocity = value 0340 } 0341 0342 onTriggered: { 0343 if (increaseVelocity) { 0344 increaseVelocitySmoothly() 0345 } else { 0346 decreaseVelocitySmoothly() 0347 } 0348 } 0349 } 0350 0351 BallastTank { 0352 id: leftBallastTank 0353 } 0354 0355 BallastTank { 0356 id: rightBallastTank 0357 } 0358 0359 BallastTank { 0360 id: centralBallastTank 0361 } 0362 0363 Image { 0364 id: submarineImage 0365 source: submarine.isHit ? url + "submarine-broken.svg" : url + "submarine.svg" 0366 0367 property int currentWaterLevel: bar.level < 7 ? centralBallastTank.waterLevel : leftBallastTank.waterLevel + rightBallastTank.waterLevel 0368 property int totalWaterLevel: bar.level < 7 ? centralBallastTank.maxWaterLevel : leftBallastTank.maxWaterLevel + rightBallastTank.maxWaterLevel 0369 0370 width: background.width / 9 0371 sourceSize.width: submarineImage.width 0372 fillMode: Image.PreserveAspectFit 0373 0374 function reset() { 0375 x = submarine.initialPosition.x 0376 y = submarine.initialPosition.y 0377 } 0378 0379 onXChanged: { 0380 if (submarineImage.x >= background.width) { 0381 Activity.finishLevel(true) 0382 } 0383 } 0384 0385 transform: Rotation { 0386 id: submarineRotation 0387 origin.x: submarineImage.width / 2; 0388 origin.y: 0; 0389 angle: 0; 0390 Behavior on angle { 0391 NumberAnimation { 0392 duration: 1000 0393 } 0394 } 0395 } 0396 0397 Loader { 0398 anchors.fill: parent 0399 active: ApplicationInfo.hasShader && submarine.velocity.x > 0 && submarineImage.y > 0 && !submarine.isHit 0400 sourceComponent: ParticleSystem { 0401 anchors.fill: parent 0402 Emitter { 0403 x: parent.x 0404 y: parent.y + parent.height / 1.75 0405 width: 1 0406 height: 1 0407 emitRate: 0.8 0408 lifeSpan: 800 0409 lifeSpanVariation: 2500 0410 acceleration: PointDirection { 0411 x: -20 0412 xVariation: 5 0413 y: 0 0414 yVariation: 0 0415 } 0416 velocity: PointDirection { 0417 x: -20 0418 xVariation: 10 0419 y: 0 0420 yVariation: 0 0421 } 0422 size: 12 0423 sizeVariation: 8 0424 } 0425 0426 ImageParticle { 0427 source: "qrc:/gcompris/src/activities/clickgame/resource/bubble.svg" 0428 } 0429 } 0430 } 0431 } 0432 0433 Body { 0434 id: submarineBody 0435 target: submarineImage 0436 bodyType: Body.Dynamic 0437 fixedRotation: true 0438 linearDamping: 0 0439 linearVelocity: submarine.isHit ? Qt.point(0,0) : submarine.velocity 0440 0441 fixtures: [ 0442 Box { 0443 id: submarineFixer 0444 y: submarineImage.height * 0.50 0445 width: submarineImage.width 0446 height: submarineImage.height * 0.50 0447 categories: items.submarineCategory 0448 collidesWith: Fixture.All 0449 density: 1 0450 friction: 0 0451 restitution: 0 0452 onBeginContact: { 0453 var collidedObject = other.getBody().target 0454 0455 if (collidedObject == whale) { 0456 whale.hit() 0457 } 0458 if (collidedObject == crown) { 0459 crown.captureCrown() 0460 } else { 0461 Activity.finishLevel(false) 0462 } 0463 } 0464 }, 0465 Box { 0466 id: submarinePeriscopeFixer 0467 x: submarineImage.width * 0.5 0468 width: submarineImage.width * 0.25 0469 height: submarineImage.height 0470 categories: items.submarineCategory 0471 collidesWith: Fixture.All 0472 density: 1 0473 friction: 0 0474 restitution: 0 0475 onBeginContact: { 0476 var collidedObject = other.getBody().target 0477 0478 if (collidedObject === whale) { 0479 whale.hit() 0480 } 0481 if (collidedObject === crown) { 0482 crown.captureCrown() 0483 } else { 0484 Activity.finishLevel(false) 0485 } 0486 } 0487 } 0488 ] 0489 } 0490 0491 Timer { 0492 id: updateVerticalVelocity 0493 interval: 50 0494 running: true 0495 repeat: true 0496 0497 onTriggered: submarine.changeVerticalVelocity() 0498 } 0499 } 0500 0501 Image { 0502 id: sparkle 0503 source: "qrc:/gcompris/src/activities/mining/resource/sparkle.svg" 0504 0505 x: crown.x 0506 y: crown.y 0507 z: 1 0508 0509 width: crown.width 0510 height: width * 0.7 0511 0512 property bool isCaptured: false 0513 0514 scale: isCaptured ? 1 : 0 0515 0516 function createSparkle() { 0517 isCaptured = true 0518 0519 removeSparkleTimer.start() 0520 } 0521 0522 function removeSparkle() { 0523 isCaptured = false 0524 } 0525 0526 Behavior on scale { 0527 NumberAnimation { 0528 duration: 100 0529 } 0530 } 0531 0532 Timer { 0533 id: removeSparkleTimer 0534 interval: 3000 0535 repeat: false 0536 running: false 0537 0538 onTriggered: sparkle.removeSparkle() 0539 } 0540 } 0541 0542 Rectangle { 0543 id: upperGate 0544 visible: (bar.level > 1) ? true : false 0545 width: background.width / 18 0546 height: isGateOpen ? background.height * (5 / 36) : background.height * (5 / 12) + 4 0547 y: -2 0548 z: 2 0549 color: "#9E948A" 0550 border.color: "#766C62" 0551 border.width: 2 0552 anchors.right: background.right 0553 anchors.rightMargin: -2 0554 0555 property bool isGateOpen: false 0556 0557 Body { 0558 id: upperGateBody 0559 target: upperGate 0560 bodyType: Body.Static 0561 sleepingAllowed: true 0562 fixedRotation: true 0563 linearDamping: 0 0564 0565 fixtures: Box { 0566 id: upperGatefixer 0567 width: upperGate.width 0568 height: upperGate.height 0569 categories: items.upperGatefixerCategory 0570 collidesWith: upperGate.visible ? items.submarineCategory : Fixture.None 0571 density: 1 0572 friction: 0 0573 restitution: 0 0574 } 0575 } 0576 0577 Behavior on height { 0578 NumberAnimation { 0579 duration: 1000 0580 } 0581 } 0582 } 0583 0584 Rectangle { 0585 id: lowerGate 0586 z: 1 0587 visible: upperGate.visible 0588 width: background.width / 18 0589 height: background.height * (5 / 12) - subSchemaImage.height / 1.4 0590 y: background.height * (5 / 12) 0591 color: "#9E948A" 0592 border.color: "#766C62" 0593 border.width: 2 0594 anchors.right:background.right 0595 anchors.rightMargin: -2 0596 0597 Body { 0598 id: lowerGateBody 0599 target: lowerGate 0600 bodyType: Body.Static 0601 sleepingAllowed: true 0602 fixedRotation: true 0603 linearDamping: 0 0604 0605 fixtures: Box { 0606 id: lowerGatefixer 0607 width: lowerGate.width 0608 height: lowerGate.height 0609 categories: items.lowerGatefixerCategory 0610 collidesWith: lowerGate.visible ? items.submarineCategory : Fixture.None 0611 density: 1 0612 friction: 0 0613 restitution: 0 0614 } 0615 } 0616 } 0617 0618 Rectangle { 0619 id: subSchemaImage 0620 width: background.width/1.3 0621 height: background.height/4 0622 x: background.width/9 0623 y: background.height/1.5 0624 visible: false 0625 } 0626 0627 Image { 0628 id: crown 0629 0630 width: submarineImage.width * 0.85 0631 height: crown.width * 0.5 0632 sourceSize.width: crown.width 0633 sourceSize.height: crown.height 0634 visible: ((bar.level > 2) && !isCaptured) ? true : false 0635 source: url + "crown.svg" 0636 0637 property bool isCaptured: false 0638 0639 function captureCrown() { 0640 upperGate.isGateOpen = true 0641 isCaptured = true 0642 sparkle.createSparkle() 0643 } 0644 0645 function reset() { 0646 isCaptured = false 0647 upperGate.isGateOpen = false 0648 } 0649 0650 x: background.width / 2 0651 y: background.height - (subSchemaImage.height * 2) 0652 z: 1 0653 0654 Body { 0655 id: crownbody 0656 target: crown 0657 bodyType: Body.Static 0658 sleepingAllowed: true 0659 fixedRotation: true 0660 linearDamping: 0 0661 0662 fixtures: Box { 0663 id: crownfixer 0664 width: crown.width 0665 height: crown.height 0666 sensor: true 0667 categories: items.crownCategory 0668 collidesWith: crown.visible ? items.submarineCategory : Fixture.None 0669 density: 0.1 0670 friction: 0 0671 restitution: 0 0672 } 0673 } 0674 } 0675 0676 Whale { 0677 id: whale 0678 visible: (bar.level > 5) ? true : false 0679 0680 y: rock2.y - (rock2.height * 1.15) 0681 z: 1 0682 0683 leftLimit: 0 0684 rightLimit: background.width - whale.width - (upperGate.visible ? upperGate.width : 0) 0685 } 0686 0687 Image { 0688 id: ship 0689 0690 width: background.width / 9 0691 sourceSize.width: ship.width 0692 fillMode: Image.PreserveAspectFit 0693 0694 visible: (bar.level > 3) ? true : false 0695 source: collided ? url + "boat-hit.svg" : url + "boat.svg" 0696 x: initialXPosition 0697 z: 1 0698 0699 anchors.bottom: waterLevel.top 0700 0701 property bool movingLeft: true 0702 property bool collided: false 0703 property real initialXPosition: background.width - ship.width - (upperGate.visible ? upperGate.width : 0) 0704 property real horizontalSpeed: 1 0705 0706 function reset() { 0707 ship.collided = false 0708 ship.x = initialXPosition 0709 } 0710 0711 function collide() { 0712 /* Add few visual effects */ 0713 collided = true 0714 } 0715 0716 transform: Rotation { 0717 id: rotateShip 0718 origin.x: ship.width / 2; 0719 origin.y: 0; 0720 axis { x: 0; y: 1; z: 0 } angle: 0 0721 } 0722 0723 SequentialAnimation { 0724 id: rotateShipLeft 0725 loops: 1 0726 PropertyAnimation { 0727 target: rotateShip 0728 properties: "angle" 0729 from: 0 0730 to: 180 0731 duration: 500 0732 } 0733 } 0734 0735 SequentialAnimation { 0736 id: rotateShipRight 0737 loops: 1 0738 PropertyAnimation { 0739 target: rotateShip 0740 properties: "angle" 0741 from: 180 0742 to: 0 0743 duration: 500 0744 } 0745 } 0746 0747 onXChanged: { 0748 if (x <= 0) { 0749 rotateShipLeft.start() 0750 movingLeft = false 0751 } else if (x >= background.width - ship.width - (upperGate.visible ? upperGate.width : 0)) { 0752 rotateShipRight.start() 0753 movingLeft = true 0754 } 0755 } 0756 0757 Body { 0758 id: shipbody 0759 target: ship 0760 bodyType: Body.Dynamic 0761 sleepingAllowed: true 0762 fixedRotation: true 0763 linearDamping: 0 0764 linearVelocity: Qt.point( (ship.collided ? 0 : ((ship.movingLeft ? -1 : 1) * ship.horizontalSpeed)), 0) 0765 0766 fixtures: Box { 0767 id: shipfixer 0768 width: ship.width 0769 height: ship.height 0770 categories: items.shipCategory 0771 collidesWith: ship.visible ? items.submarineCategory : Fixture.None 0772 density: 1 0773 friction: 0 0774 restitution: 0 0775 0776 onBeginContact: ship.collide() 0777 } 0778 } 0779 } 0780 0781 Image { 0782 id: rock2 0783 width: background.width / 6 0784 height: rock2.width * 0.48 0785 z: 5 0786 0787 visible: (bar.level > 4) ? true : false 0788 anchors.bottom: crown.bottom 0789 anchors.left: crown.right 0790 source: "qrc:/gcompris/src/activities/mining/resource/stone2.svg" 0791 0792 transform: Rotation { 0793 origin.x: rock2.width / 2; 0794 origin.y: rock2.height / 2 0795 axis { x: 0; y: 0; z: 1 } angle: 180 0796 } 0797 0798 Body { 0799 id: rock2Body 0800 target: rock2 0801 bodyType: Body.Static 0802 sleepingAllowed: true 0803 linearDamping: 0 0804 0805 fixtures: Box { 0806 id: rock2Fixer 0807 categories: items.rockCategory 0808 collidesWith: rock2.visible ? items.submarineCategory : Fixture.None 0809 x: rock2.width / 8 0810 y: rock2.height / 12 0811 width: rock2.width / 1.2 0812 height: rock2.height / 1.5 0813 density: 1 0814 friction: 0 0815 restitution: 0 0816 } 0817 } 0818 } 0819 0820 /* Just a space */ 0821 Rectangle { 0822 id: space 0823 width: bar.level < 8 ? rock1.width : rock1.width * (1 - (Math.random() * 0.5)) 0824 height: rock1.height 0825 0826 color: "transparent" 0827 anchors { 0828 right: crown.left 0829 bottom: crown.bottom 0830 } 0831 } 0832 0833 Image { 0834 id: rock1 0835 width: rock2.width 0836 height: rock2.width * 0.46 0837 z: 5 0838 visible: (bar.level > 6) ? true : false 0839 anchors.bottom: crown.bottom 0840 anchors.right: space.left 0841 source: "qrc:/gcompris/src/activities/mining/resource/stone1.svg" 0842 0843 Body { 0844 id: rock1Body 0845 target: rock1 0846 bodyType: Body.Static 0847 sleepingAllowed: true 0848 linearDamping: 0 0849 0850 fixtures: [ 0851 Circle { 0852 id: rock1FixerLeft 0853 categories: items.rockCategory 0854 collidesWith: rock1.visible ? items.submarineCategory : Fixture.None 0855 x: rock1.width / 10 0856 radius: rock1.width / 4 0857 density: 1 0858 friction: 0 0859 restitution: 0 0860 },Circle { 0861 id: rock1FixerRight 0862 categories: items.rockCategory 0863 collidesWith: rock1.visible ? items.submarineCategory : Fixture.None 0864 x: rock1.width / 1.6 0865 y: rock1.height / 4 0866 radius: rock1.width / 6 0867 density: 1 0868 friction: 0 0869 restitution: 0 0870 } 0871 ] 0872 } 0873 } 0874 0875 Image { 0876 id: rock3 0877 width: background.width 0878 height: background.height * 0.25 0879 sourceSize.width: rock3.width 0880 sourceSize.height: rock3.height 0881 0882 visible: (bar.level > 2) ? true : false 0883 anchors.top: crown.top 0884 anchors.horizontalCenter: crown.left 0885 // anchors.topMargin: height * 0.5 0886 source: url + "rocks.svg" 0887 } 0888 0889 Timer { 0890 /* 0891 * A delay is used since on setting fullscreen on/off 0892 * first the onWidthChanged is executed, followed by 0893 * the width change 0894 */ 0895 id: updateOnWidthReset 0896 repeat: false 0897 interval: 100 0898 running: false 0899 onTriggered: { 0900 whale.reset() 0901 ship.reset() 0902 } 0903 } 0904 0905 Controls { 0906 id: controls 0907 z: 10 0908 enginePosition.x: background.width * 0.1 0909 enginePosition.y: buttonPlusY + buttonSize * 0.2 0910 engineWidth: background.width / 8 0911 engineHeight: hori ? buttonSize * 1.8 : buttonSize * 2.5 0912 submarineHorizontalSpeed: submarine.currentFinalVelocity * 1000 0913 0914 leftTankVisible: bar.level >= 7 ? true : false 0915 leftBallastTankPosition.x: background.width * 0.35 0916 leftBallastTankPosition.y: enginePosition.y 0917 leftBallastTankWidth: background.width / 8 0918 leftBallastTankHeight: engineHeight 0919 0920 centralTankVisible: bar.level < 7 ? true : false 0921 centralBallastTankPosition.x: background.width * 0.45 0922 centralBallastTankPosition.y: enginePosition.y 0923 centralBallastTankWidth: background.width / 8 0924 centralBallastTankHeight: engineHeight 0925 0926 rightTankVisible: bar.level >= 7 ? true : false 0927 rightBallastTankPosition.x: background.width * 0.6 0928 rightBallastTankPosition.y: enginePosition.y 0929 rightBallastTankWidth: background.width / 8 0930 rightBallastTankHeight: engineHeight 0931 0932 divingPlaneVisible: true 0933 divingPlanePosition.x: background.width * 0.8 0934 divingPlanePosition.y: enginePosition.y + (engineHeight * 0.5) - (divingPlaneHeight * 0.5) 0935 divingPlaneWidth: hori ? background.width * 0.08 : background.width * 0.12 0936 divingPlaneHeight: divingPlaneWidth * 0.33 0937 buttonSize: hori ? subSchemaImage.height * 0.3 : subSchemaImage.height * 0.2 0938 buttonPlusY: hori ? background.height * 0.61 : background.height * 0.63 0939 buttonMinusY: enginePosition.y + engineHeight - buttonSize * 0.8 0940 } 0941 0942 DialogHelp { 0943 id: dialogHelp 0944 onClose: home() 0945 } 0946 0947 Bar { 0948 id: bar 0949 level: items.currentLevel + 1 0950 content: BarEnumContent { value: help | home | reload | level } 0951 onHelpClicked: { 0952 displayDialog(dialogHelp) 0953 } 0954 onReloadClicked: Activity.initLevel() 0955 onPreviousLevelClicked: Activity.previousLevel() 0956 onNextLevelClicked: Activity.nextLevel() 0957 onHomeClicked: home() 0958 } 0959 0960 Bonus { 0961 id: bonus 0962 onLoose: Activity.initLevel() 0963 Component.onCompleted: win.connect(Activity.nextLevel) 0964 } 0965 /* 0966 DebugDraw { 0967 id: debugDraw 0968 world: physicalWorld 0969 anchors.fill: parent 0970 opacity: 0.75 0971 visible: false 0972 } 0973 0974 MouseArea { 0975 id: debugMouseArea 0976 anchors.fill: parent 0977 onPressed: debugDraw.visible = !debugDraw.visible 0978 } 0979 */ 0980 } 0981 0982 }