File indexing completed on 2024-04-28 15:07:52
0001 /* GCompris - gravity.js 0002 * 0003 * SPDX-FileCopyrightText: 2020 Timothée Giet <animtim@gmail.com> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> and Matilda Bernard (GTK+ version) 0007 * Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port) 0008 * Timothée Giet <animtim@gmail.com> (complete activity rewrite) 0009 * 0010 * SPDX-License-Identifier: GPL-3.0-or-later 0011 */ 0012 .pragma library 0013 .import QtQuick 2.12 as Quick 0014 .import "qrc:/gcompris/src/core/core.js" as Core 0015 0016 var url = "qrc:/gcompris/src/activities/gravity/resource/" 0017 0018 var levels = [ 0019 { // Level 1 0020 planetFrequency: 12000, 0021 planetCount: 5 0022 }, 0023 { // Level 2 0024 planetFrequency: 10000, 0025 planetCount: 10 0026 }, 0027 { // Level 3 0028 planetFrequency: 8000, 0029 planetCount: 15 0030 }, 0031 { // Level 4 0032 planetFrequency: 7000, 0033 planetCount: 20 0034 }, 0035 { // Level 5 0036 planetFrequency: 6000, 0037 planetCount: 25 0038 }, 0039 { // Level 6 0040 planetFrequency: 5000, 0041 planetCount: 30 0042 } 0043 ] 0044 0045 var numberOfLevel = levels.length; 0046 var items; 0047 var message; 0048 0049 // delta move 0050 var move = 0; 0051 // control move 0052 var controlMove = 0; 0053 // gravity of current planet 0054 var planetGravity = 0; 0055 // speed for key controls 0056 var controlSpeed = 0.2; 0057 0058 var currentPlanet; 0059 var planetsCounter = 0; 0060 0061 function start(items_,message_) { 0062 items = items_; 0063 items.currentLevel = Core.getInitialLevel(numberOfLevel); 0064 message = message_; 0065 initLevel(); 0066 } 0067 0068 function stop() { 0069 items.processTimer.stop(); 0070 items.planetCreation.stop(); 0071 destroyPlanet(); 0072 planetsCounter = 0; 0073 controlMove = 0; 0074 move = 0; 0075 } 0076 0077 function initLevel() { 0078 stop(); 0079 items.planetFrequency = levels[items.currentLevel].planetFrequency; 0080 items.background.initSpace(); 0081 items.explosion.hide(); 0082 items.spaceship.opacity = 100; 0083 items.spaceshipX = items.background.width * 0.5; 0084 items.stationDown.stop(); 0085 items.station.y = -items.station.height; 0086 controlSpeed = 0.2 * (items.currentLevel * 0.25 + 1); 0087 if(!items.startMessage) { 0088 items.processTimer.start(); 0089 createPlanet(); 0090 items.planetCreation.start(); 0091 message.index = -1; 0092 } else { 0093 message.index = 0; 0094 } 0095 } 0096 0097 function nextLevel() { 0098 items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel); 0099 initLevel(); 0100 } 0101 0102 function previousLevel() { 0103 items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel); 0104 initLevel(); 0105 } 0106 0107 function processKeyPress(event) { 0108 var key = event.key; 0109 event.accepted = true; 0110 if(key === Qt.Key_Left) { 0111 controlMove += -controlSpeed; 0112 } else if(key === Qt.Key_Right) { 0113 controlMove += controlSpeed; 0114 } 0115 } 0116 0117 function processKeyRelease(event) { 0118 var key = event.key; 0119 event.accepted = true; 0120 if(key === Qt.Key_Left || key === Qt.Key_Right) { 0121 controlMove = 0; 0122 } 0123 } 0124 0125 function createPlanet() { 0126 if(planetsCounter < levels[items.currentLevel].planetCount) { 0127 var planetSide = Math.floor( Math.random() * 2); 0128 var planetSize = Math.max(Math.random() * items.maxPlanetSize, items.minPlanetSize); 0129 if(planetSide == 0) { 0130 currentPlanet = items.planet0; 0131 } else if(planetSide == 1) { 0132 currentPlanet = items.planet1; 0133 } 0134 currentPlanet.source = url + "planet" + Math.floor(Math.random() * 2) + ".webp"; 0135 currentPlanet.fallDuration = levels[items.currentLevel].planetFrequency; 0136 currentPlanet.height = planetSize; 0137 currentPlanet.width = planetSize; 0138 currentPlanet.y = currentPlanet.height * -2; 0139 currentPlanet.visible = true; 0140 currentPlanet.startMoving(); 0141 planetGravity = currentPlanet.leftSide ? -currentPlanet.width * 0.5: currentPlanet.width * 0.5; 0142 planetsCounter++; 0143 } else { 0144 items.stationDown.restart(); 0145 } 0146 } 0147 0148 function moveSpaceship() { 0149 // calculate gravity 0150 if(planetsCounter > 0) { 0151 // calculate distance between planet center and spaceship center 0152 var hypothenuse = Math.sqrt( 0153 Math.pow((currentPlanet.x + (currentPlanet.width * 0.5)) - items.spaceshipX, 2) + 0154 Math.pow((currentPlanet.y + (currentPlanet.height * 0.5)) - items.spaceshipY, 2)); 0155 items.gravity = (planetGravity * (items.currentLevel * 0.33 + 1)) / Math.pow(hypothenuse, 2) * 100; 0156 } else { 0157 items.gravity = 0; 0158 } 0159 move += controlMove + (items.gravity); 0160 items.spaceshipX += move; 0161 0162 // Check for crash 0163 computeOverlap(); 0164 0165 // Don't go out of the screen or stay stuck on the borders 0166 if(items.spaceshipX > items.background.width - items.borderMargin) { 0167 move = 0; 0168 controlMove = 0; 0169 items.spaceshipX -= 1; 0170 } else if(items.spaceshipX < items.borderMargin) { 0171 move = 0; 0172 controlMove = 0; 0173 items.spaceshipX += 1; 0174 } 0175 } 0176 0177 function computeOverlap() { 0178 if(planetsCounter > 0) { 0179 // compute overlap with a little margin on the planets to not hit too much on corners 0180 var xOverlap = Math.min(items.spaceship.x + items.spaceship.width, 0181 currentPlanet.x + currentPlanet.width * 0.9) - 0182 Math.max(items.spaceship.x, currentPlanet.x + currentPlanet.width * 0.1); 0183 var yOverlap = Math.min(items.spaceship.y + items.spaceship.height, 0184 currentPlanet.y + currentPlanet.height * 0.9) - 0185 Math.max(items.spaceship.y, currentPlanet.y + 0186 currentPlanet.height * 0.1); 0187 // again add a safety margin to avoid hitting on corners 0188 if(xOverlap > items.spaceship.width * 0.2 && yOverlap > items.spaceship.height * 0.2) { 0189 crash(); 0190 items.bonus.bad("lion"); 0191 } 0192 } 0193 } 0194 0195 function destroyPlanet() { 0196 planetGravity = 0; 0197 items.gravity = 0; 0198 if(planetsCounter > 0) { 0199 currentPlanet.visible = false; 0200 } 0201 } 0202 0203 function crash() { 0204 items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav"); 0205 items.explosion.show(); 0206 items.spaceship.hide(); 0207 stop(); 0208 }