StackTheBoxWithEditor Demo
import Felgo 3.0
import QtQuick 2.0
import "entities"
GameWindow {
id: gameWindow
activeScene: scene
EntityManager {
id: entityManager
entityContainer: scene
dynamicCreationEntityList: [ Qt.resolvedUrl("entities/Obstacle.qml") ]
}
Rectangle {
anchors.fill: parent
color: "black"
}
property real maxForce: 30000
property real dampingRatio: 1
property real frequencyHz: 2
property int minIntervalBetweenBoxGeneration: 1000
property int maxIntervalBetweenBoxGeneration: 3000
property int minIntervalReduction: 10
property int maxIntervalReduction: 15
EditableComponent {
target: gameWindow
editableType: "Balancing"
defaultGroup: "Environment"
properties: {
"minIntervalBetweenBoxGeneration": {"min": 100, "max": 10000, "label": "minIntBetwBox"},
"maxIntervalBetweenBoxGeneration": {"min": 100, "max": 50000, "label": "maxIntBetwBox"},
"minIntervalReduction": {"min": 1, "max": 1000, "label": "minIntReduction"},
"maxIntervalReduction": {"min": 1, "max": 1000, "label": "maxIntReduction"},
"maxForce": {"min": 1, "max": 100000},
"dampingRatio": {"min": 0, "max": 1,"stepsize": 0.1 },
"frequencyHz": {"min": 0, "max": 100, "stepsize": 0.1 }
}
}
property int currentMinInterval: minIntervalBetweenBoxGeneration
property int currentMaxInterval: maxIntervalBetweenBoxGeneration
Scene {
id: scene
width: 480
height: 320
property int createdBoxes: 1
property real safetyDistance: -1
property variant selectedEntity
state: "playing"
onStateChanged: {
if(state === "levelEditing") {
stopGame()
}
}
function entitySelected(entity) {
if(selectedEntity && selectedEntity !== entity) {
selectedEntity.entityState = ""
}
selectedEntity = entity
}
function stopGame() {
entityManager.removeEntitiesByFilter(["box"]);
scene.createdBoxes = 0;
currentMinInterval = minIntervalBetweenBoxGeneration
currentMaxInterval = maxIntervalBetweenBoxGeneration
}
ItemEditor {
id: itemEditor
opacity: 0.7
z:1
}
LevelEditor {
id: levelEditor
toRemoveEntityTypes: [ "obstacle" ]
toStoreEntityTypes: [ "obstacle" ]
}
LevelSelectionList {
id: levelSelectionList
width: 150
z: 3
visible: false
anchors.centerIn: parent
levelMetaDataArray: levelEditor.authorGeneratedLevels
onLevelSelected: {
levelEditor.loadSingleLevel(levelData)
levelSelectionList.visible = false
}
}
Text {
z: 2
text: "Current Level:" + levelEditor.currentLevelNameString
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
text: "Boxes: " + scene.createdBoxes
color: "white"
z: 1
}
PhysicsWorld {
id: physicsWorld
gravity.y: 9.81
z: 10
debugDrawVisible: false
updatesPerSecondForPhysics: 60
velocityIterations: 5
positionIterations: 5
}
Component {
id: mouseJoint
MouseJoint {
maxForce: gameWindow.maxForce * physicsWorld.pixelsPerMeter
dampingRatio: gameWindow.dampingRatio
frequencyHz: gameWindow.frequencyHz
}
}
MouseArea {
anchors.fill: parent
property Body selectedBody: null
property MouseJoint mouseJointWhileDragging: null
onPressed: {
scene.entitySelected(null)
selectedBody = physicsWorld.bodyAt(Qt.point(mouseX, mouseY));
console.debug("selected body at position", mouseX, mouseY, ":", selectedBody);
if(selectedBody) {
mouseJointWhileDragging = mouseJoint.createObject(physicsWorld)
mouseJointWhileDragging.target = Qt.point(mouseX, mouseY)
mouseJointWhileDragging.bodyB = selectedBody
}
}
onPositionChanged: {
if (mouseJointWhileDragging)
mouseJointWhileDragging.target = Qt.point(mouseX, mouseY)
}
onReleased: {
if(selectedBody) {
selectedBody = null
if (mouseJointWhileDragging)
mouseJointWhileDragging.destroy()
}
}
}
Box {
id: box1
entityId: "box1"
x: scene.width/2
y: 50
Component.onCompleted: {
if(scene.safetyDistance == -1) {
scene.safetyDistance = box1.width*Math.SQRT2/2 + leftWall.width + 5
console.debug("init safetyZoneHorizontal with", scene.safetyDistance)
}
}
}
Wall {
entityId: "bottomWall"
height: 20
anchors {
bottom: scene.bottom
left: scene.left
right: scene.right
}
}
Wall {
entityId: "leftWall"
id: leftWall
width: 20
height: scene.height
anchors {
left: scene.left
}
}
Wall {
entityId: "rightWall"
width: 20
height: scene.height
anchors {
right: scene.right
}
}
Wall {
entityId: "topWall"
height: 20
width: scene.width
anchors {
top: scene.top
}
color: "red"
onCollidedWithBox: {
scene.stopGame()
}
}
Column {
anchors.right: parent.right
spacing: 5
SimpleButton {
text: "Toggle Audio"
onClicked: settings.soundEnabled = !settings.soundEnabled
anchors.right: parent.right
}
SimpleButton {
text: "Toggle Particles"
onClicked: settings.particlesEnabled = !settings.particlesEnabled
anchors.right: parent.right
}
SimpleButton {
text: "ItemEditor"
onClicked: itemEditor.visible = !itemEditor.visible
anchors.right: parent.right
}
SimpleButton {
text: scene.state === "playing" ? "Level Mode" : "Game Mode"
onClicked: {
if(text === "Level Mode")
scene.state = "levelEditing"
else
scene.state = "playing"
}
anchors.right: parent.right
}
SimpleButton {
text: "New Level"
onClicked: levelEditor.createNewLevel()
anchors.right: parent.right
visible: scene.state === "levelEditing"
}
SimpleButton {
text: "Save Level"
onClicked: nativeUtils.displayTextInput("Enter levelName", "", levelEditor.currentLevelName)
anchors.right: parent.right
visible: scene.state === "levelEditing"
Connections {
target: nativeUtils
onTextInputFinished: {
if(accepted) {
levelEditor.saveCurrentLevel( {levelMetaData: {levelName: enteredText}} )
}
}
}
}
SimpleButton {
text: "Show All Levels"
anchors.right: parent.right
visible: scene.state === "levelEditing"
onClicked: {
levelEditor.loadAllLevelsFromStorageLocation(levelEditor.authorGeneratedLevelsLocation)
levelSelectionList.visible = !levelSelectionList.visible
}
}
BuildEntityButton {
visible: scene.state === "levelEditing"
toCreateEntityTypeUrl: Qt.resolvedUrl("entities/Obstacle.qml")
width: 50
height: 50
anchors.right: parent.right
Rectangle {
color: "grey"
anchors.fill: parent
}
}
}
Timer {
id: timer
interval: generateRandomInterval()
running: scene.state === "playing"
repeat: true
onTriggered: {
var newEntityProperties = {
x: utils.generateRandomValueBetween(scene.safetyDistance, scene.width-scene.safetyDistance),
y: scene.safetyDistance,
rotation: Math.random()*360
}
entityManager.createEntityFromUrlWithProperties(
Qt.resolvedUrl("entities/Box.qml"),
newEntityProperties);
scene.createdBoxes++
timer.interval = generateRandomInterval()
currentMinInterval -= minIntervalReduction
currentMaxInterval -= maxIntervalReduction
timer.restart()
}
function generateRandomInterval() {
return utils.generateRandomValueBetween(currentMinInterval, currentMaxInterval);
}
}