diff --git a/src/activities/land_safe/ActivityInfo.qml b/src/activities/land_safe/ActivityInfo.qml index c2836c801..688aee6f7 100644 --- a/src/activities/land_safe/ActivityInfo.qml +++ b/src/activities/land_safe/ActivityInfo.qml @@ -1,41 +1,41 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Holger Kaelberer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import GCompris 1.0 ActivityInfo { name: "land_safe/LandSafe.qml" difficulty: 4 icon: "land_safe/land_safe.svg" author: "Matilda Bernard <serah4291@gmail.com> (Gtk+), Holger Kaelberer <holger.k@elberer.de> (Qt Quick)" demo: true title: qsTr("Land Safe") description: qsTr("Understanding acceleration due to gravity.") goal: qsTr("Pilot the spaceship towards the green landing area.") prerequisite: "" manual: qsTr("Acceleration due to gravity experienced by the spaceship is directly proportional to the mass of the planet and inversely proportional to the square of the distance from the center of the planet. Thus, with every planet the acceleration will differ and as the spaceship comes closer and closer to the planet the acceleration increases. Use the up/down keys to control the thrust and the right/left keys to control direction. On touch screens you can control the rocket through the corresponding on-screen buttons. In higher levels, you can use the right/left keys to rotate the spaceship. By rotating the spaceship you can trigger an acceleration in non-vertical direction using the up/down keys. The landing platform is green if your speed is fine for a safe landing.") credit: "" section: "experiments" - enabled: ApplicationInfo.hasShader + enabled: true //ApplicationInfo.hasShader createdInVersion: 6000 } diff --git a/src/activities/land_safe/LandSafe.qml b/src/activities/land_safe/LandSafe.qml index 3351905e6..90caf0b20 100644 --- a/src/activities/land_safe/LandSafe.qml +++ b/src/activities/land_safe/LandSafe.qml @@ -1,635 +1,637 @@ /* GCompris - LandSafe.qml * * Copyright (C) 2016 Holger Kaelberer * * Authors: * Matilda Bernard (GTK+ version) * Holger Kaelberer (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.1 import Box2D 2.0 import QtQuick.Particles 2.0 import GCompris 1.0 import "../../core" import "land_safe.js" as Activity ActivityBase { id: activity property bool inForeground: false // to avoid unneeded reconfigurations onStart: { inForeground = true; focus = true; } onStop: inForeground = false; Keys.onPressed: Activity.processKeyPress(event) Keys.onReleased: Activity.processKeyRelease(event) onWidthChanged: if (inForeground) Activity.initLevel(); onHeightChanged: if (inForeground) Activity.initLevel(); pageComponent: Image { id: background source: Activity.baseUrl + "/background4.jpg"; anchors.centerIn: parent anchors.fill: parent fillMode: Image.PreserveAspectCrop signal start signal stop Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property Item main: activity.main property alias background: background property alias bar: bar property alias bonus: bonus property alias rocket: rocket property alias world: physicsWorld property alias landing: landing property alias ground: ground property alias stats: stats property alias intro: intro property alias ok: ok + property alias leftRightControl: leftRightControl + property alias upDownControl: upDownControl property var rocketCategory: Fixture.Category1 property var groundCategory: Fixture.Category2 property var landingCategory: Fixture.Category3 property var borderCategory: Fixture.Category4 property string mode: "rotate" // "simple" property double lastVelocity: 0.0 property double scale: background.height / 400 } onStart: { Activity.start(items) } onStop: { Activity.stop() } World { id: physicsWorld running: false; gravity: Qt.point(0, Activity.gravity) pixelsPerMeter: 0 autoClearForces: false //timeStep: 1.0/60.0 // default: 60Hz onStepped: { if (Math.abs(rocket.body.linearVelocity.y) > 0.01) // need to store velocity before it is aaaalmost 0 because of ground/landing contact items.lastVelocity = stats.velocity.y; stats.velocity = rocket.body.linearVelocity; if (rocket.body.linearVelocity.y > Activity.maxLandingVelocity) landing.source = Activity.baseUrl + "/landing_red.png"; else landing.source = Activity.baseUrl + "/landing_green.png"; stats.height = Math.max(0, Math.round(Activity.getRealHeight())); // update fuel: var dt = timeStep; var dFuel = -(dt * (items.rocket.accel + items.rocket.leftAccel + items.rocket.rightAccel)); Activity.currentFuel = Math.max(0, Activity.currentFuel + dFuel); stats.fuel = Math.round(Activity.currentFuel / Activity.maxFuel * 100); if (Activity.currentFuel === 0) // fuel consumed: items.rocket.accel = items.rocket.leftAccel = items.rocket.rightAccel = 0; // console.log("VVV changed: " + items.lastVelocity + " --> " + stats.velocity.y + " / " + rocket.body.linearVelocity.y); } } MouseArea { id: mouse anchors.fill: parent onClicked: debugDraw.visible = !debugDraw.visible; enabled: Activity.debugDraw } // bounding fixtures Item { id: leftBorder width: 1 height: parent.height anchors.left: parent.left anchors.top: parent.top readonly property string collisionName: "leftBorder" Body { id: leftBody target: leftBorder bodyType: Body.Static sleepingAllowed: false fixedRotation: true linearDamping: 0 fixtures: Box { id: leftFixture categories: items.borderCategory collidesWith: items.rocketCategory density: 1 friction: 0 restitution: 0 width: leftBorder.width height: leftBorder.height } } } Item { id: rightBorder width: 1 height: parent.height anchors.right: parent.right anchors.rightMargin: 1 anchors.top: parent.top readonly property string collisionName: "rightBorder" Body { id: rightBody target: rightBorder bodyType: Body.Static sleepingAllowed: false fixedRotation: true linearDamping: 0 fixtures: Box { id: rightFixture categories: items.borderCategory collidesWith: items.rocketCategory density: 1 friction: 0 restitution: 0 width: rightBorder.width height: rightBorder.height } } } GCText { id: stats z: 0 property var velocity: rocket.body.linearVelocity property double fuel: 100.0 property double heigth: Activity.startingHeightReal anchors.left: background.left anchors.leftMargin: 20 anchors.top: background.top anchors.topMargin: 20 width: 100 height: 100 color: "gray" fontSize: tinySize text: qsTr("Planet: ") + Activity.levels[Activity.currentLevel].planet + "
" + qsTr("Velocity: ") + Math.round(velocity.y * 10) / 10 + "
" + qsTr("Fuel: ") + fuel + "
" + qsTr("Altitude: ") + height + "
" + qsTr("Gravity: ") + Math.round(Activity.gravity * 100)/100 } Item { id: rocket property double accel: 0.0 property double leftAccel: 0.0 property double rightAccel: 0.0 property alias body: rocketBody property alias leftEngine: leftEngine property alias rightEngine: rightEngine property alias explosion: explosion //property float rotate rotation: 0 width: items.scale * 28// * ApplicationInfo.ratio height: width / 232 * 385 x: 300 y: 50 z: 3 Component.onCompleted: rocket.body.applyForceToCenter(Qt.point(0, 5)); onAccelChanged: applyForces(); onLeftAccelChanged: applyForces(); onRightAccelChanged: applyForces(); onRotationChanged: if (accel > 0) // should only happen in applyForces(); // "rotation" mode // map acceleration to box2d forces applying appropriate factors: function applyForces() { var totForce = (accel / 0.5 * 5) var xForce; var yForce; if (items.mode === "simple") { yForce = -totForce; xForce = (leftAccel-rightAccel) * 10 /* base of 10 m/s^2 */ * 5 /* factor to make movement smooth */; } else { // "rotation" yForce = -(totForce * Math.cos(Activity.degToRad(items.rocket.rotation))); xForce = (totForce * Math.sin(Activity.degToRad(items.rocket.rotation))); } var yFForce = yForce * items.rocket.body.getMass(); var xFForce = xForce * items.rocket.body.getMass(); var force = Qt.point(xFForce, yFForce); // console.log("applying force " + force + " - " + " - mass=" + items.rocket.body.getMass() + " v=" + items.rocket.body.linearVelocity + " totForce=" + totForce + " - rotation=" + items.rocket.rotation + " - xForce=" + xForce + " xFForce=" + xFForce + " mass=" + items.rocket.body.getMass()); physicsWorld.clearForces(); items.rocket.body.applyForceToCenter(force); } Image { id: rocketImage width: parent.width height: parent.height sourceSize.width: 1024 source: Activity.baseUrl + "/rocket.svg"; anchors.centerIn: parent anchors.fill: parent } Image { id: explosion // width: parent.height // height: width/785*621 width: height/621 * 785 height: 2*parent.height sourceSize.width: 1024 source: Activity.baseUrl + "/explosion.svg"; anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter scale: 0 function show() { visible = true; scale = 1; } function hide() { visible = false; scale = 0; } Behavior on scale { NumberAnimation { duration: 150 easing.type: Easing.InExpo } } } Body { id: rocketBody target: rocket bodyType: Body.Dynamic sleepingAllowed: false fixedRotation: true linearDamping: 0 property double rotation: Activity.degToRad(rocket.rotation % 360) fixtures: Box { id: rocketFixture categories: items.rocketCategory collidesWith: items.groundCategory | items.landingCategory | items.borderCategory density: 1 friction: 0 restitution: 0 width: rocket.width height: rocket.height rotation: rocketBody.rotation onBeginContact: { //console.log("XXX beginning contact with " + other.getBody().target.collisionName + " abs v=" + Math.abs(items.lastVelocity) + + " maxV=" + Activity.maxLandingVelocity); if (other.getBody().target === leftBorder || other.getBody().target === rightBorder) ; //nothing to do else if (other.getBody().target === landing && Math.abs(items.lastVelocity) <= Activity.maxLandingVelocity && (items.mode === "simple" || rocket.rotation === 0)) Activity.finishLevel(true); else // ground Activity.finishLevel(false); // crash } // onEndContact: console.log("XXX ending contact with " + other.getBody().target.collisionName); } } ParticleSystem { id: leftEngine anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter height: 30 ImageParticle { groups: ["flameLeft"] source: "qrc:///particleresources/glowdot.png" color: "#11ff400f" colorVariation: 0.1 } Emitter { anchors.centerIn: parent group: "flameLeft" emitRate: rocket.leftAccel > 0 ? 50 * items.scale / 1.9 : 0 // 50 lifeSpan: rocket.leftAccel > 0 ? 600 * items.scale / 1.9 : 0 // 600 size: rocket.leftAccel > 0 ? leftEngine.height : 0 endSize: 5 sizeVariation: 5 acceleration: PointDirection { x: -40 } velocity: PointDirection { x: -40 } } } ParticleSystem { id: rightEngine anchors.right: parent.right anchors.rightMargin: 10 anchors.verticalCenter: parent.verticalCenter height: 30 ImageParticle { groups: ["flameRight"] source: "qrc:///particleresources/glowdot.png" color: "#11ff400f" colorVariation: 0.1 } Emitter { anchors.centerIn: parent group: "flameRight" emitRate: rocket.rightAccel > 0 ? 50 * items.scale / 1.9 : 0 // 50 lifeSpan: rocket.rightAccel > 0 ? 600 * items.scale / 1.9 : 0 // 600 size: rocket.rightAccel > 0 ? rightEngine.height : 0 endSize: 5 sizeVariation: 5 acceleration: PointDirection { x: 40 } velocity: PointDirection { x: 40 } } } ParticleSystem { id: bottomEngine anchors.top: parent.bottom anchors.topMargin: 5 anchors.horizontalCenter: parent.horizontalCenter width: rocket.width ImageParticle { groups: ["flame"] source: "qrc:///particleresources/glowdot.png" color: "#11ff400f" colorVariation: 0.1 } Emitter { anchors.centerIn: parent group: "flame" emitRate: rocket.accel > 0 ? (80 + 60 * rocket.accel) : 0 // 75-150 lifeSpan: (700 + 450 * rocket.accel) * items.scale / 2.5 // 500 - 1000 size: rocket.width/1.8 + rocket.width/2*rocket.accel // width*-0.5 - width endSize: size/1.85 sizeVariation: 10 acceleration: PointDirection { y: 80 } velocity: PointDirection { y: 80 } } } } Image { id: ground z: 1 width: parent.width // height: parent.height source: Activity.baseUrl + "/land4.png"; anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom readonly property string collisionName: "ground" property int surfaceOffset: height/2 Body { id: groundBody target: ground bodyType: Body.Static sleepingAllowed: true fixedRotation: true linearDamping: 0 fixtures: Box { id: groundFixture categories: items.groundCategory collidesWith: items.rocketCategory density: 1 friction: 0 restitution: 0 width: ground.width height: ground.height - ground.surfaceOffset x: 0 y: ground.surfaceOffset } } } Image { id: landing readonly property string collisionName: "landing" property int surfaceOffset: landing.height - 1 z: 2 source: Activity.baseUrl + "/landing_green.png"; anchors.left: ground.left anchors.leftMargin: 270 anchors.top: ground.top anchors.topMargin: ground.surfaceOffset - height sourceSize.width: 1024 width: 66 * items.scale height: width / 116 * 34 Body { id: landingBody target: landing bodyType: Body.Static sleepingAllowed: true fixedRotation: true linearDamping: 0 fixtures: Box { id: landingFixture categories: items.landingCategory collidesWith: items.rocketCategory density: 1 friction: 0 restitution: 0 width: landing.width height: landing.height - landing.surfaceOffset y: landing.surfaceOffset } } } Column { - id: updownControl + id: upDownControl anchors.right: parent.right anchors.rightMargin: 10 * ApplicationInfo.ratio anchors.bottom: bar.top anchors.bottomMargin: 10 * ApplicationInfo.ratio width: upButton.width + 20 * ApplicationInfo.ratio height: upButton.height + downButton.height + 20 * ApplicationInfo.ratio visible: items.world.running && ApplicationInfo.isMobile z: 19 // below intro, above the rest opacity: 0.4 spacing: 10 * ApplicationInfo.ratio ControlButton { id: upButton source: Activity.baseUrl + "/arrow_up.svg" onPressed: Activity.processKeyPress({key: Qt.Key_Up}); } ControlButton { id: downButton source: Activity.baseUrl + "/arrow_down.svg" onPressed: Activity.processKeyPress({key: Qt.Key_Down}); } } Row { - id: leftrightControl + id: leftRightControl anchors.left: parent.left anchors.leftMargin: 10 * ApplicationInfo.ratio anchors.bottom: bar.top anchors.bottomMargin: 10 * ApplicationInfo.ratio width: leftButton.width + rightButton.width + 20 * ApplicationInfo.ratio height: leftButton.height + 10 * ApplicationInfo.ratio visible: items.world.running && ApplicationInfo.isMobile z: 19 // below intro, above the rest opacity: 0.4 spacing: 10 * ApplicationInfo.ratio ControlButton { id: leftButton source: Activity.baseUrl + "/arrow_left.svg" onPressed: Activity.processKeyPress({key: Qt.Key_Left}); onReleased: Activity.processKeyRelease({key: Qt.Key_Left}); } ControlButton { id: rightButton source: Activity.baseUrl + "/arrow_right.svg" onPressed: Activity.processKeyPress({key: Qt.Key_Right}); onReleased: Activity.processKeyRelease({key: Qt.Key_Right}); } } DebugDraw { id: debugDraw world: physicsWorld visible: false z: 1 } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level } onHelpClicked: { Activity.initLevel(); displayDialog(dialogHelp); } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() } Bonus { id: bonus Component.onCompleted: { loose.connect(Activity.initLevel); win.connect(Activity.nextLevel) } } IntroMessage { id: intro onIntroDone: { items.world.running = true; } intro: [ Activity.introText1 ] z: 20 anchors { top: parent.top topMargin: 10 right: parent.right rightMargin: 5 left: parent.left leftMargin: 5 } } BarButton { id: ok source: "qrc:/gcompris/src/core/resource/bar_ok.svg"; sourceSize.width: 75 * ApplicationInfo.ratio visible: false anchors.centerIn: background onClicked: { visible = false; items.world.running = true; } } } } diff --git a/src/activities/land_safe/land_safe.js b/src/activities/land_safe/land_safe.js index 77396e5c9..16166bf81 100644 --- a/src/activities/land_safe/land_safe.js +++ b/src/activities/land_safe/land_safe.js @@ -1,271 +1,278 @@ /* GCompris - land_safe.js * * Copyright (C) 2016 Holger Kaelberer * * Authors: * Matilda Bernard (GTK+ version) * Holger Kaelberer (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ /* ToDo: * (- zoom out if too high!) * - check for shader availability * (- use polygon fixture for rocket) * (- improve graphics of velocity etc.) * * Some gravitational forces: * !- Pluto: 0,62 m/s² * - Titan: 1,352 m/s² * !- Moon: 1,622 m/s² * - Io: 1,796 m/s² * !- Mars: 3,711 m/s² * - Merkur: 3,7 m/s² * !- Venus: 8,87 m/s² * - Earth: 9,807 m/s² * - Jupiter: 24,79 m/s² */ .pragma library .import QtQuick 2.0 as Quick .import GCompris 1.0 as GCompris var levels = [ /** simple **/ { "planet": "Pluto", "gravity": 0.62, "maxAccel": 0.2, "accelSteps": 3, "alt": 100.0, "mode": "simple", "fuel" : 5 }, { "planet": "Moon", "gravity": 1.62, "maxAccel": 0.4, "accelSteps": 4, "alt": 150.0, "mode": "simple", "fuel" : 10 }, { "planet": "Mars", "gravity": 3.71, "maxAccel": 0.6, "accelSteps": 5, "alt": 200.0, "mode": "simple", "fuel" : 20 }, { "planet": "Vulc@n", "gravity": 5.55, "maxAccel": 1.0, "accelSteps": 5, "alt": 300.0, "mode": "simple", "fuel" : 30 }, { "planet": "Venus", "gravity": 8.87, "maxAccel": 1.2, "accelSteps": 5, "alt": 300.0, "mode": "simple", "fuel" : 70 }, /** rotation **/ { "planet": "Pluto", "gravity": 0.62, "maxAccel": 0.2, "accelSteps": 3, "alt": 100.0, "mode": "rotation", "fuel" : 5 }, { "planet": "Moon", "gravity": 1.62, "maxAccel": 0.4, "accelSteps": 4, "alt": 150.0, "mode": "rotation", "fuel" : 10 }, { "planet": "Mars", "gravity": 3.71, "maxAccel": 0.6, "accelSteps": 5, "alt": 200.0, "mode": "rotation", "fuel" : 20 }, { "planet": "Vulc@n", "gravity": 5.55, "maxAccel": 1.0, "accelSteps": 5, "alt": 300.0, "mode": "rotation", "fuel" : 30 }, { "planet": "Venus", "gravity": 8.87, "maxAccel": 1.2, "accelSteps": 5, "alt": 300.0, "mode": "rotation", "fuel" : 70 } ]; var introTextSimple = qsTr("Use the up and down keys to control the thrust." + "
Use the right and left keys to control direction." + "
You must drive Tux's ship towards the landing platform." + "
The landing platform turns green when the velocity is safe to land.") var introTextRotate = qsTr("The up and down keys control the thrust of the rear engine." + "
The right and left keys now control the rotation of the ship." + "
To move the ship in horizontal direction you must first rotate and then accelerate it.") var currentLevel = 0; var numberOfLevel; var items = null; var baseUrl = "qrc:/gcompris/src/activities/land_safe/resource"; var startingHeightReal = 100.0; var startingOffsetPx = 10; // y-value for setting rocket initially var gravity = 1; var maxLandingVelocity = 10; var leftRightAccel = 0.1; // accel force set on horizontal accel //var minAccel = 0.1; var maxAccel = 0.15; var accelSteps = 3; var dAccel = maxAccel / accelSteps;//- minAccel; var barAtStart; var maxFuel = 100.0; var currentFuel = 0.0; var lastLevel = -1; var debugDraw = false; function start(items_) { items = items_; currentLevel = 0; numberOfLevel = levels.length; barAtStart = GCompris.ApplicationSettings.isBarHidden; GCompris.ApplicationSettings.isBarHidden = true; initLevel() } function stop() { GCompris.ApplicationSettings.isBarHidden = barAtStart; } function initLevel() { if (items === null) return; items.bar.level = currentLevel + 1 + items.rocket.explosion.hide(); + // place rocket randomly: var max = items.background.width - items.landing.width-20; var min = 20; - items.rocket.explosion.hide(); items.rocket.x = Math.random() * (max- min) + min; items.rocket.y = startingOffsetPx; items.rocket.rotation = 0; items.rocket.accel = 0; items.rocket.leftAccel = 0; items.rocket.rightAccel = 0; items.rocket.body.linearVelocity = Qt.point(0,0) + + // for landing random placement shall not intersect with bar -- + // or osd controls on mobile: + min = GCompris.ApplicationInfo.isMobile ? items.leftRightControl.width : items.bar.fullButton * items.bar.barZoom; + max = GCompris.ApplicationInfo.isMobile ? items.background.width - items.upDownControl.width - items.landing.width : max; + items.landing.anchors.leftMargin = Math.random() * (max- min) + min; maxAccel = levels[currentLevel].maxAccel; accelSteps = levels[currentLevel].accelSteps; dAccel = maxAccel / accelSteps;//- minAccel; startingHeightReal = levels[currentLevel].alt; gravity = levels[currentLevel].gravity; items.mode = levels[currentLevel].mode; maxFuel = currentFuel = levels[currentLevel].fuel; items.world.pixelsPerMeter = getHeightPx() / startingHeightReal; items.world.gravity = Qt.point(0, gravity) items.world.running = false; items.landing.source = baseUrl + "/landing_green.png"; // console.log("Starting level (surfaceOff=" + items.ground.surfaceOffset + ", ppm=" + items.world.pixelsPerMeter + ")"); if (currentLevel === 0 && lastLevel !== 0) { items.ok.visible = false; items.intro.intro = [introTextSimple]; items.intro.index = 0; } else if (currentLevel === 5 && lastLevel !== 0) { items.ok.visible = false; items.intro.intro = [introTextRotate]; items.intro.index = 0; } else { // go items.intro.index = -1; items.ok.visible = true; } lastLevel = currentLevel; } function getHeightPx() { var heightPx = items.background.height - items.ground.height + items.ground.surfaceOffset - items.rocket.y - items.rocket.height - 1; // landing is 1 pixel above ground surface return heightPx; } // calc real height of rocket in meters above surface function getRealHeight() { var heightPx = getHeightPx(); var heightReal = heightPx / items.world.pixelsPerMeter; return heightReal; } function nextLevel() { if(numberOfLevel <= ++currentLevel ) { currentLevel = 0 } initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } function processKeyPress(event) { var key = event.key; event.accepted = true; var newAccel = 0; if (key === Qt.Key_Up || key === Qt.Key_Down) { if (key === Qt.Key_Up) { if (items.rocket.accel === 0) newAccel = dAccel; else newAccel = items.rocket.accel + dAccel; } else if (key === Qt.Key_Down) newAccel = items.rocket.accel - dAccel; if (newAccel < dAccel) newAccel = 0; if (newAccel > maxAccel) newAccel = maxAccel; if (newAccel !== items.rocket.accel && currentFuel > 0) items.rocket.accel = newAccel; } else if (key === Qt.Key_Right || key === Qt.Key_Left) { if (items.mode === "simple") { if (key === Qt.Key_Right && !event.isAutoRepeat && currentFuel > 0) { items.rocket.leftAccel = leftRightAccel; items.rocket.rightAccel = 0.0; } else if (key === Qt.Key_Left && !event.isAutoRepeat && currentFuel > 0) { items.rocket.rightAccel = leftRightAccel; items.rocket.leftAccel = 0.0; } } else { // "rotation" if (key === Qt.Key_Right) items.rocket.rotation += 10; else if (key === Qt.Key_Left) items.rocket.rotation -= 10; //console.log("XXX rotation=" + items.rocket.rotation + " bodyRot=" + items.rocket.body.rotation); } } else event.accepted = false; } function processKeyRelease(event) { var key = event.key; event.accepted = true; //console.log("XXX release " + key + " = " + event.isAutoRepeat + " = " + Qt.Key_Right); if (key === Qt.Key_Right && !event.isAutoRepeat) { items.rocket.leftAccel = 0; } else if (key === Qt.Key_Left && !event.isAutoRepeat) { items.rocket.rightAccel = 0; } else event.accepted = false; } function finishLevel(success) { items.rocket.accel = 0; items.rocket.leftAccel = 0; items.rocket.rightAccel = 0; items.rocket.body.linearVelocity = Qt.point(0,0) if (success) items.bonus.good("lion"); else { items.rocket.explosion.show(); items.bonus.bad("lion"); } } function degToRad(degrees) { return degrees * Math.PI / 180; }