1
/* GCompris - land_safe.js
3
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
6
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
7
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 3 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, see <https://www.gnu.org/licenses/>.
24
* - check for shader availability
25
* - test more generic on-screen controls
26
* (- use polygon fixture for rocket)
28
* Some gravitational forces:
31
* !- Titan: 1,352 m/s²
38
* !- Earth: 9,807 m/s²
39
* - Jupiter: 24,79 m/s²
43
.import QtQuick 2.6 as Quick
44
.import GCompris 1.0 as GCompris
48
{ "planet": qsTr("Ceres"), "gravity": 0.27, "maxAccel": 0.054,
49
"accelSteps": 2, "alt": 75.0 , "mode": "simple",
51
{ "planet": qsTr("Pluto"), "gravity": 0.62, "maxAccel": 0.186,
52
"accelSteps": 3, "alt": 100.0, "mode": "simple",
54
{ "planet": qsTr("Titan"), "gravity": 1.352, "maxAccel": 0.406,
55
"accelSteps": 3, "alt": 100.0, "mode": "simple",
57
{ "planet": qsTr("Moon"), "gravity": 1.622, "maxAccel": 0.324,
58
"accelSteps": 4, "alt": 150.0, "mode": "simple",
60
{ "planet": qsTr("Mars"), "gravity": 3.711, "maxAccel": 0.619,
61
"accelSteps": 5, "alt": 200.0, "mode": "simple",
63
{ "planet": qsTr("Venus"), "gravity": 8.87, "maxAccel": 1.331,
64
"accelSteps": 6, "alt": 300.0, "mode": "simple",
66
{ "planet": qsTr("Earth"), "gravity": 9.807, "maxAccel": 1.373,
67
"accelSteps": 7, "alt": 350.0, "mode": "simple",
71
{ "planet": qsTr("Ceres"), "gravity": 0.27, "maxAccel": 0.054,
72
"accelSteps": 2, "alt": 75.0 , "mode": "rotation",
74
{ "planet": qsTr("Pluto"), "gravity": 0.62, "maxAccel": 0.186,
75
"accelSteps": 3, "alt": 100.0, "mode": "rotation",
77
{ "planet": qsTr("Titan"), "gravity": 1.352, "maxAccel": 0.406,
78
"accelSteps": 3, "alt": 100.0, "mode": "rotation",
80
{ "planet": qsTr("Moon"), "gravity": 1.62, "maxAccel": 0.324,
81
"accelSteps": 4, "alt": 150.0, "mode": "rotation",
83
{ "planet": qsTr("Mars"), "gravity": 3.71, "maxAccel": 0.619,
84
"accelSteps": 5, "alt": 200.0, "mode": "rotation",
86
{ "planet": qsTr("Venus"), "gravity": 8.87, "maxAccel": 1.331,
87
"accelSteps": 5, "alt": 300.0, "mode": "rotation",
89
{ "planet": qsTr("Earth"), "gravity": 9.807, "maxAccel": 1.373,
90
"accelSteps": 7, "alt": 350.0, "mode": "rotation",
95
var introTextSimple = qsTr("Use the up and down keys to control the thrust."
96
+ "<br/>Use the right and left keys to control direction."
97
+ "<br/>You must drive Tux's ship towards the landing platform."
98
+ "<br/>The landing platform turns green when the velocity is safe to land.")
100
var introTextRotate = qsTr("The up and down keys control the thrust of the rear engine."
101
+ "<br/>The right and left keys now control the rotation of the ship."
102
+ "<br/>To move the ship in horizontal direction you must first rotate and then accelerate it.")
104
var currentLevel = 0;
107
var baseUrl = "qrc:/gcompris/src/activities/land_safe/resource";
108
var startingAltitudeReal = 100.0;
109
var startingOffsetPx = 10; // y-value for setting rocket initially
110
var maxLandingVelocity = 10;
111
var leftRightAccel = 0.1; // accel force set on horizontal accel
112
//var minAccel = 0.1;
115
var dAccel = maxAccel / accelSteps;//- minAccel;
118
var currentFuel = 0.0;
120
var debugDraw = false;
121
var zoomStack = new Array;
123
function start(items_) {
127
numberOfLevel = levels.length;
128
barAtStart = GCompris.ApplicationSettings.isBarHidden;
129
GCompris.ApplicationSettings.isBarHidden = true;
134
GCompris.ApplicationSettings.isBarHidden = barAtStart;
137
function initLevel() {
141
items.bar.level = currentLevel + 1
146
items.accelerometer.min = -levels[currentLevel].gravity;
147
items.accelerometer.max = levels[currentLevel].maxAccel*10-levels[currentLevel].gravity;
148
maxAccel = levels[currentLevel].maxAccel;
149
accelSteps = levels[currentLevel].accelSteps;
150
dAccel = maxAccel / accelSteps;//- minAccel;
151
startingAltitudeReal = levels[currentLevel].alt;
152
items.gravity = levels[currentLevel].gravity;
153
items.mode = levels[currentLevel].mode;
154
maxFuel = levels[currentLevel].fuel;
155
currentFuel = (maxFuel == -1 ? 1 : maxFuel); // -1 means unlimited fuel
158
items.explosion.hide();
160
// place rocket randomly:
161
var max = items.background.width - items.accelerometer.width - items.landing.width - items.rocket.width;
163
items.rocket.x = Math.random() * (max- min) + min;
164
items.rocket.y = startingOffsetPx;
165
items.rocket.rotation = 0;
166
items.rocket.accel = 0;
167
items.rocket.leftAccel = 0;
168
items.rocket.rightAccel = 0;
169
items.rocket.body.linearVelocity = Qt.point(0,0)
170
// for landing random placement shall not intersect with bar -- or osd
171
// controls on mobile:
172
min = items.onScreenControls ? items.leftRightControl.width : items.bar.fullButton * items.bar.barZoom;
173
max = items.onScreenControls ? items.background.width - items.upDownControl.width - items.landing.width : max;
174
items.landing.anchors.leftMargin = Math.random() * (max- min) + min;
175
items.landing.overlayColor = "-g";
178
items.world.pixelsPerMeter = pxYToAltitude(items.rocket.y) / startingAltitudeReal;
179
items.world.gravity = Qt.point(0, items.gravity)
180
items.world.running = false;
182
// console.log("Starting level (surfaceOff=" + items.ground.surfaceOffset + ", ppm=" + items.world.pixelsPerMeter + ")");
184
if (currentLevel === 0 && lastLevel !== 0) {
185
items.ok.visible = false;
186
items.intro.intro = [introTextSimple];
187
items.intro.index = 0;
188
} else if (currentLevel === levels.length / 2 && lastLevel !== 0) {
189
items.ok.visible = false;
190
items.intro.intro = [introTextRotate];
191
items.intro.index = 0;
194
items.intro.index = -1;
195
items.ok.visible = true;
197
lastLevel = currentLevel;
200
function pxAltitudeToY(alt)
202
var y = items.background.height - items.ground.height + items.ground.surfaceOffset
203
- items.rocket.height - 1 - alt;
207
function pxYToAltitude(y)
209
var altPx = items.background.height - items.ground.height + items.ground.surfaceOffset
210
- y - items.rocket.height
211
- 1; // landing is 1 pixel above ground surface
215
// calc real height of rocket in meters above surface
216
function getAltitudeReal()
218
var altPx = pxYToAltitude(items.rocket.y);
219
var altReal = altPx / items.world.pixelsPerMeter;
223
function nextLevel() {
224
if(numberOfLevel <= ++currentLevel ) {
230
function previousLevel() {
231
if(--currentLevel < 0) {
232
currentLevel = numberOfLevel - 1
237
function processKeyPress(event)
240
event.accepted = true;
241
if (!items.world.running) {
245
if (key === Qt.Key_Up || key === Qt.Key_Down) {
246
if (key === Qt.Key_Up) {
247
if (items.rocket.accel === 0)
250
newAccel = items.rocket.accel + dAccel;
251
} else if (key === Qt.Key_Down)
252
newAccel = items.rocket.accel - dAccel;
256
if (newAccel > maxAccel)
259
if (newAccel !== items.rocket.accel && currentFuel > 0)
260
items.rocket.accel = newAccel;
261
} else if (key === Qt.Key_Right || key === Qt.Key_Left) {
262
if (items.mode === "simple") {
263
if (key === Qt.Key_Right && !event.isAutoRepeat && currentFuel > 0) {
264
items.rocket.leftAccel = leftRightAccel;
265
items.rocket.rightAccel = 0.0;
266
} else if (key === Qt.Key_Left && !event.isAutoRepeat && currentFuel > 0) {
267
items.rocket.rightAccel = leftRightAccel;
268
items.rocket.leftAccel = 0.0;
270
} else { // "rotation"
271
if (key === Qt.Key_Right)
272
items.rocket.rotation += 10;
273
else if (key === Qt.Key_Left)
274
items.rocket.rotation -= 10;
275
//console.log("XXX rotation=" + items.rocket.rotation + " bodyRot=" + items.rocket.body.rotation);
280
function processKeyRelease(event)
282
if (!items.world.running) {
283
event.accepted = false;
287
event.accepted = true;
288
//console.log("XXX release " + key + " = " + event.isAutoRepeat + " = " + Qt.Key_Right);
289
if (key === Qt.Key_Right && !event.isAutoRepeat) {
290
items.rocket.leftAccel = 0;
291
} else if (key === Qt.Key_Left && !event.isAutoRepeat) {
292
items.rocket.rightAccel = 0;
294
event.accepted = false;
297
function finishLevel(success)
299
items.rocket.accel = 0;
300
items.rocket.leftAccel = 0;
301
items.rocket.rightAccel = 0;
302
items.rocket.body.linearVelocity = Qt.point(0,0)
304
items.bonus.good("lion");
306
items.explosion.show();
308
items.bonus.bad("lion");
312
function degToRad(degrees) {
313
return degrees * Math.PI / 180;