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 }