diff --git a/dep/clayground b/dep/clayground index edb22d1..ec9f0ba 160000 --- a/dep/clayground +++ b/dep/clayground @@ -1 +1 @@ -Subproject commit edb22d11eb421a341c1716c921628a620daa08ac +Subproject commit ec9f0ba15e0847b317f6bc342be7af02fd7f8cad diff --git a/devlog/m2_weather_and_protect.png b/devlog/m2_weather_and_protect.png new file mode 100644 index 0000000..be5f018 Binary files /dev/null and b/devlog/m2_weather_and_protect.png differ diff --git a/devlog/m3_from_start_to_end.png b/devlog/m3_from_start_to_end.png new file mode 100644 index 0000000..baa4d3c Binary files /dev/null and b/devlog/m3_from_start_to_end.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 536d837..521276c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,10 +9,6 @@ find_package(Qt5 COMPONENTS Core Quick REQUIRED) add_executable (${PROJECT_NAME} main.cpp -main.qml -Sandbox.qml -Player.qml -Wall.qml res.qrc sound/sound.qrc visual/visual.qrc diff --git a/src/Enemy.qml b/src/Enemy.qml index bd10f58..21393cc 100644 --- a/src/Enemy.qml +++ b/src/Enemy.qml @@ -26,7 +26,7 @@ GameEntity var e = fixture.getBody().target; if (theWorld.isInstanceOf(e, "Player")) { if (e.isDodging) theEnemy.destroy(); - else text = "Got ya!"; + else e.energy -= 1; } } diff --git a/src/GameEnding.qml b/src/GameEnding.qml new file mode 100644 index 0000000..066748e --- /dev/null +++ b/src/GameEnding.qml @@ -0,0 +1,35 @@ +// (c) serein.pfeiffer@gmail.com - zlib license, see "LICENSE" file +import QtQuick 2.12 + +Rectangle { + id: theGameEnding + + property Referee referee: null + + visible: false + anchors.fill: parent + Component.onCompleted: { + referee.playerDied.connect(onPlayerDied); + referee.gardenDied.connect(onGardenDied); + referee.seasonEnded.connect(onSeasonEnded); + } + + function onGardenDied() {showEnd("Garden died!");} + function onPlayerDied() {showEnd("Player died!");} + function onSeasonEnded() {showEnd("Season ended!");} + + function showEnd(txt) { + if (!visible) { + theEndTxt.text = txt; + visible = true; + } + } + + Text { + id: theEndTxt + anchors.centerIn: parent + font.pixelSize: parent.height * .1 + text: "The Game ends ..." + } +} + diff --git a/src/Garden.qml b/src/Garden.qml index 062bb8f..d03daec 100644 --- a/src/Garden.qml +++ b/src/Garden.qml @@ -16,8 +16,9 @@ GameEntity collCat.magicProtection debug: true color: protection > 0 ? "lightgreen" : "green" + property int maxEnergy: widthWu * heightWu // Energy of the garden, if it is 0, the garden dead - property int energy: 100 + property int energy: maxEnergy // Protection decreases dealt damage property int protection: 0 diff --git a/src/Player.qml b/src/Player.qml index 063c9ab..e572c6e 100644 --- a/src/Player.qml +++ b/src/Player.qml @@ -10,6 +10,9 @@ GameEntity id: thePlayer bodyType: Body.Dynamic bullet: true + + property int energy: 3 + property real moveSpeed: 25 property real dodgeSpeed: 0 property real _desiredVeloX: 0 @@ -23,7 +26,8 @@ GameEntity onIsProtectingChanged: { awake = false; awake = true; } debug: true - onIsDodgingChanged: text = isDodging ? "~==>" : "" + text: energy > 0 ? "♥".repeat(energy) : "☠" + categories: collCat.player collidesWith: collCat.enemy | collCat.staticGeo | collCat.garden diff --git a/src/Referee.qml b/src/Referee.qml new file mode 100644 index 0000000..e699e89 --- /dev/null +++ b/src/Referee.qml @@ -0,0 +1,69 @@ +// (c) serein.pfeiffer@gmail.com - zlib license, see "LICENSE" file +import QtQuick 2.12 + +Item { + property var gardens: [] + property var player: undefined + property real gardenPercentage: 100.0 + property int maxEnergyGarden: 0 + property int timeElapsed: 0 + + readonly property int seasonLength: 300 + readonly property real seasonPercentage: Math.round(timeElapsed * 100.0 / seasonLength) + onSeasonPercentageChanged: { + if (seasonPercentage >= 100) { + theOneSecTimer.stop(); + seasonEnded(); + } + } + + onPlayerChanged: { + if (player) { + player.energyChanged.connect(_onPlayerEnergyChanged); + theOneSecTimer.start(); + } + else { + theOneSecTimer.stop(); + gardens=[]; + gardenPercentage=100.0; + maxEnergyGarden=0; + timeElapsed=0; + } + } + + + signal playerDied() + signal gardenDied() + signal seasonEnded() + + Timer { + id: theOneSecTimer + interval: 1000 + Component.onCompleted: start() + onTriggered: timeElapsed++ + repeat: true + } + + onGardenPercentageChanged: { + if (gardenPercentage <= 0) gardenDied() + } + + function addGarden(garden) { + gardens.push(garden); + garden.energyChanged.connect(_onGardenEnergyChanged); + maxEnergyGarden += garden.maxEnergy; + } + + function _onGardenEnergyChanged() { + let energy = 0; + for (const g of gardens) + energy += g.energy; + gardenPercentage = Math.round((energy/maxEnergyGarden) * 100.0); + } + + function _onPlayerEnergyChanged() { + if (player.energy <= 0) + playerDied(); + } + +} diff --git a/src/Sandbox.qml b/src/Sandbox.qml index ab8bbad..391b01f 100644 --- a/src/Sandbox.qml +++ b/src/Sandbox.qml @@ -9,12 +9,13 @@ import Clayground.World 1.0 ClayWorld { id: theWorld - map: "map.svg" + map: "" pixelPerUnit: height/70 gravity: Qt.point(0,0) timeStep: 1/60.0 property var player: null + //physicsDebugging: true QtObject { id: collCat @@ -27,7 +28,10 @@ ClayWorld { readonly property int noCollision: Box.None } - onWorldAboutToBeCreated: player = null; + onWorldAboutToBeCreated: { + player = null; + theWeather.running = false; + } onWorldCreated: { // theGameCtrl.selectKeyboard(Qt.Key_Up, // Qt.Key_Down, @@ -37,9 +41,24 @@ ClayWorld { // Qt.Key_S); theGameCtrl.selectGamepad(0, true); theWorld.observedItem = player; + theWeather.running = true; } - Weather { } + Weather {id: theWeather } + Referee { + id: theReferee + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 0.04 * parent.height + player: theWorld.player + Text { + id: refereeSays + anchors.centerIn: parent + text: Math.round(parent.gardenPercentage) + + (parent.player ? ("/" + parent.player.energy) : "") + + "/" + parent.seasonPercentage + } + } Keys.forwardTo: theGameCtrl GameController { @@ -47,11 +66,13 @@ ClayWorld { anchors.fill: parent onButtonAPressedChanged: { + if (!player) return; if (player.isProtecting) return; player.moveSpeed = buttonAPressed ? 35 : 18; } onButtonBPressedChanged: { + if (!player) return; let p = player; if (buttonBPressed) { if (p.desiresToMove) p.dodgeSpeed = 75; @@ -62,17 +83,20 @@ ClayWorld { } onAxisXChanged: { + if (!player) return; if (player.isProtecting) return; if (axisX > 0) player.moveRight(); else if (axisX < 0) player.moveLeft(); else { player.stopLeft(); player.stopRight();} } onAxisYChanged: { + if (!player) return; if (player.isProtecting) return; if (axisY > 0) player.moveUp(); else if (axisY < 0) player.moveDown(); else { player.stopUp(); player.stopDown();} } + //showDebugOverlay: true } @@ -84,6 +108,9 @@ ClayWorld { else if (isInstanceOf(obj, "Enemy")) { obj.source = theWorld.resource("visual/enemy.png"); } + else if (isInstanceOf(obj, "Garden")) { + theReferee.addGarden(obj); + } } SoundEffect { @@ -93,4 +120,36 @@ ClayWorld { source: theWorld.resource("sound/bgmusic.wav") loops: SoundEffect.Infinite } + + StartScreen { + visible: true + Component.onCompleted: { + theGameCtrl.buttonAPressedChanged.connect(startOnDemand) + theGameCtrl.buttonBPressedChanged.connect(startOnDemand) + } + function startOnDemand() { + if (visible) { + map = ""; + map = "map.svg"; + visible = false; + } + } + } + + GameEnding { + referee: theReferee + Component.onCompleted: { + theGameCtrl.buttonAPressedChanged.connect(restartOnDemand) + theGameCtrl.buttonBPressedChanged.connect(restartOnDemand) + } + + function restartOnDemand() { + if (visible) { + map = ""; + map = "map.svg"; + visible = false; + } + } + } + } diff --git a/src/StartScreen.qml b/src/StartScreen.qml new file mode 100644 index 0000000..15acaaf --- /dev/null +++ b/src/StartScreen.qml @@ -0,0 +1,20 @@ +// (c) serein.pfeiffer@gmail.com - zlib license, see "LICENSE" file +import QtQuick 2.12 + +Rectangle { + id: theStartScreen + + property Referee referee: null + signal requestStart() + + visible: false + anchors.fill: parent + + Text { + anchors.centerIn: parent + font.pixelSize: parent.height * .07 + text: "Welcome to the Game" + } +} + + diff --git a/src/Storm.qml b/src/Storm.qml index 8956cc7..abfd84a 100644 --- a/src/Storm.qml +++ b/src/Storm.qml @@ -32,14 +32,5 @@ GameEntity repeat: true } - Component.onCompleted: { - for (let i=0; i main.qml Player.qml + GameEnding.qml GameEntity.qml Garden.qml Enemy.qml + Referee.qml Sandbox.qml + StartScreen.qml Storm.qml Weather.qml Wall.qml