Platformer with Level Editor
import Felgo 3.0
import QtQuick 2.0
import "../common"
import "../entities"
import "../editorElements"
import "../gameElements"
import "dialogs"
SceneBase {
id: gameScene
sceneAlignmentX: "left"
sceneAlignmentY: "top"
gridSize: 32
property int time: 0
property alias editorOverlay: editorOverlay
property alias container: container
property alias player: player
property alias physicsWorld: physicsWorld
property alias bgImage: bgImage
property alias camera: camera
property alias itemEditor: editorOverlay.itemEditor
signal backPressed
state: "play"
states: [
State {
name: "play"
StateChangeScript {script: audioManager.handleMusic()}
},
State {
name: "edit"
PropertyChanges {target: physicsWorld; gravity: Qt.point(0,0)}
PropertyChanges {target: editorUnderlay; enabled: true}
PropertyChanges {target: editorOverlay; visible: true}
PropertyChanges {target: editorOverlay; inEditMode: true}
StateChangeScript {script: resetLevel()}
StateChangeScript {script: editorOverlay.grid.requestPaint()}
StateChangeScript {script: audioManager.handleMusic()}
},
State {
name: "test"
PropertyChanges {target: editorOverlay; visible: true}
StateChangeScript {script: audioManager.playSound("start")}
StateChangeScript {script: audioManager.handleMusic()}
PropertyChanges {target: gameScene; time: 0}
StateChangeScript {script: levelTimer.restart()}
PropertyChanges {target: camera; zoom: 1}
},
State {
name: "finish"
PropertyChanges {target: physicsWorld; running: false}
}
]
BackgroundImage {
id: bgImage
anchors.centerIn: parent.gameWindowAnchorItem
property int bg: 0
property string bg0: "../../assets/backgroundImage/day_bg.png"
property string bg1: "../../assets/backgroundImage/dusk_bg.png"
property string bg2: "../../assets/backgroundImage/night_bg.png"
property int loadedBackground: {
if(gameWindow.levelEditor && gameWindow.levelEditor.currentLevelData
&& gameWindow.levelEditor.currentLevelData["customData"]
&& gameWindow.levelEditor.currentLevelData["customData"]["background"])
parseInt(gameWindow.levelEditor.currentLevelData["customData"]["background"])
else
-1
}
source: bg == 0 ? bg0 : bg == 1 ? bg1 : bg2
}
EditorUnderlay {
id: editorUnderlay
}
Item {
id: container
transformOrigin: Item.TopLeft
PhysicsWorld {
id: physicsWorld
property int gravityY: 40
gravity: Qt.point(0, gravityY)
debugDrawVisible: false
z: 1000
running: true
onPreSolve: {
var entityA = contact.fixtureA.getBody().target
var entityB = contact.fixtureB.getBody().target
if(entityA.entityType === "platform" && (entityB.entityType === "player" || entityB.entityType === "opponent") && entityB.y + entityB.height > entityA.y + 1
|| (entityA.entityType === "player" || entityA.entityType === "opponent") && entityB.entityType === "platform" && entityA.y + entityA.height > entityB.y + 1) {
contact.enabled = false
}
if(entityA.entityType === "player" && entityB.entityType === "opponent"
|| entityB.entityType === "player" && entityA.entityType === "opponent") {
contact.enabled = false
}
}
EditableComponent {
editableType: "Balance"
defaultGroup: "Physics"
properties: {
"gravityY": {"min": 0, "max": 100, "label": "Gravity"}
}
}
}
Player {
id: player
z: 1
onFinish: {
if(gameScene.state == "test")
resetLevel()
else if(gameScene.state == "play") {
gameScene.state = "finish"
handleScore()
finishDialog.score = time
finishDialog.opacity = 1
}
}
}
ResetSensor {
player: player
onContact: {
player.die(true)
}
}
}
Camera {
id: camera
gameWindowSize: Qt.point(gameScene.gameWindowAnchorItem.width, gameScene.gameWindowAnchorItem.height)
entityContainer: container
mouseAreaEnabled: false
focusedObject: gameScene.state != "edit" ? player : null
focusOffset: Qt.point(0.5, 0.3)
limitLeft: 0
limitBottom: 0
freeOffset: gameScene.state != "edit" ? Qt.point(0, 0) : Qt.point(100, 0)
}
MoveTouchButton {
id: moveTouchButton
controller: controller
}
JumpTouchButton {
id: jumpTouchButton
onPressed: player.startJump(true)
onReleased: player.endJump()
}
Keys.forwardTo: controller
TwoAxisController {
id: controller
enabled: gameScene.state != "edit"
onInputActionPressed: {
console.debug("key pressed actionName " + actionName)
if(actionName == "up") {
player.startJump(true)
}
}
onInputActionReleased: {
if(actionName == "up") {
player.endJump()
}
}
onXAxisChanged: player.changeSpriteOrientation()
}
HUDIconAndText {
id: timeDisplay
text: time
icon.source: "../../assets/ui/time.png"
}
Timer {
id: levelTimer
interval: 100
repeat: true
onTriggered: {
time += 1
}
}
HUDIconAndText {
id: scoreDisplay
text: "x "+player.score
icon.source: "../../assets/coin/coin.png"
anchors.left: timeDisplay.right
}
PlatformerImageButton {
id: menuButton
width: 40
height: 30
anchors.right: editorOverlay.right
anchors.top: editorOverlay.top
image.source: "../../assets/ui/home.png"
visible: gameScene.state == "play"
onClicked: backPressed()
}
EditorOverlay {
id: editorOverlay
visible: false
scene: gameScene
}
FinishDialog {
id: finishDialog
}
function handleScore() {
var leaderboard = levelEditor.currentLevelData.levelMetaData ? levelEditor.currentLevelData.levelMetaData.id : undefined
if(!leaderboard)
leaderboard = levelEditor.currentLevelData.levelMetaData ? levelEditor.currentLevelData.levelMetaData.publishedLevelId : undefined
if(leaderboard) {
gameNetwork.reportScore(time, leaderboard, null, "lowest_is_best")
}
}
function initLevel() {
editorOverlay.initEditor()
if(bgImage.loadedBackground && bgImage.loadedBackground != -1)
bgImage.bg = bgImage.loadedBackground
else
bgImage.bg = 0
camera.zoom = 1
camera.freePosition = Qt.point(0, 0)
player.initialize()
player.resetContacts()
controller.xAxis = 0
time = 0
levelTimer.restart()
}
function resetLevel() {
editorOverlay.resetEditor()
player.reset()
var opponents = entityManager.getEntityArrayByType("opponent")
for(var opp in opponents) {
opponents[opp].reset()
}
var coins = entityManager.getEntityArrayByType("coin")
for(var coin in coins) {
coins[coin].reset()
}
var mushrooms = entityManager.getEntityArrayByType("mushroom")
for(var mushroom in mushrooms) {
mushrooms[mushroom].reset()
}
var stars = entityManager.getEntityArrayByType("star")
for(var star in stars) {
stars[star].reset()
}
time = 0