move all prepared code from the crawl game

This commit is contained in:
Andrei Yankovich 2023-07-31 10:43:50 +02:00
parent c7fbe94bf4
commit 5aa2b28b60
187 changed files with 11636 additions and 75 deletions

View File

@ -32,18 +32,18 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test QUIET)
include(submodules/CMake/QuasarApp.cmake)
updateGitVars()
set(ButterflyEngine_VERSION "0.${GIT_COMMIT_COUNT}.${GIT_COMMIT_HASH}")
set(ButterflyEngine_PACKAGE_ID "quasarapp.core.ButterflyEngine")
set(BUTTERFLY_ENGINE_VERSION "0.${GIT_COMMIT_COUNT}.${GIT_COMMIT_HASH}")
set(BUTTERFLY_ENGINE_PACKAGE_ID "quasarapp.core.ButterflyEngine")
option(ButterflyEngine_TESTS "This option disables or enables tests of the ${PROJECT_NAME} project" ON)
option(ButterflyEngine_EXAMPLE "This option disables or enables example app of the ${PROJECT_NAME} project" ON)
option(BUTTERFLY_ENGINE_TESTS "This option disables or enables tests of the ${PROJECT_NAME} project" ON)
option(BUTTERFLY_ENGINE_EXAMPLE "This option disables or enables example app of the ${PROJECT_NAME} project" ON)
if (ANDROID OR IOS OR NOT QT_VERSION_MAJOR OR QA_WASM32)
set(ButterflyEngine_TESTS OFF CACHE BOOL "This option force disbled for ANDROID IOS QA_WASM32 and Not Qt projects" FORCE)
set(BUTTERFLY_ENGINE_TESTS OFF CACHE BOOL "This option force disbled for ANDROID IOS QA_WASM32 and Not Qt projects" FORCE)
endif()
if (NOT QT_VERSION_MAJOR)
set(ButterflyEngine_EXAMPLE OFF CACHE BOOL "This option force disbled for Not Qt projects" FORCE)
set(BUTTERFLY_ENGINE_EXAMPLE OFF CACHE BOOL "This option force disbled for Not Qt projects" FORCE)
endif()
make_directory(Distro)
@ -52,11 +52,11 @@ initAll()
add_subdirectory(src/Library)
if (DEFINED ButterflyEngine_EXAMPLE)
if (DEFINED BUTTERFLY_ENGINE_EXAMPLE)
add_subdirectory(src/Example)
endif()
if (ButterflyEngine_TESTS)
if (BUTTERFLY_ENGINE_TESTS)
add_subdirectory(tests)
else()
message("The ${PROJECT_NAME} tests is disabled.")

View File

@ -37,7 +37,7 @@ PROJECT_NAME = ButterflyEngine
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = @ButterflyEngine_VERSION@
PROJECT_NUMBER = @BUTTERFLY_ENGINE_VERSION@
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

35
init.sh
View File

@ -1,35 +0,0 @@
#!/bin/sh
echo "Project name: $1"
if [ $# -ne 1 ]
then
echo "You call this script wtth wrong arguments."
echo "Example for start script:"
echo "./init.sh MyCmakeProject"
exit 1
fi
REPLACESTRING="s+ButterflyEngine+$1+g"
echo $REPLACESTRING
find . -not -path '*/\.*' -type f -exec sed -i $REPLACESTRING {} +
find . -not -path '*/\.*' -type f -exec sed -i $REPLACESTRING {} +
find src -type d -name '*ButterflyEngine*' -exec sh -c 'x="{}"; NEWSTR=$(echo "$x" | sed "s/ButterflyEngine/'$1'/"); mv "$x" "$NEWSTR"' \;
find src -type f -name '*ButterflyEngine*' -exec sh -c 'x="{}"; NEWSTR=$(echo "$x" | sed "s/ButterflyEngine/'$1'/"); mv "$x" "$NEWSTR"' \;
find Deploy -type f -name '*ButterflyEngine*' -exec sh -c 'x="{}"; NEWSTR=$(echo "$x" | sed "s/ButterflyEngine/'$1'/"); mv "$x" "$NEWSTR"' \;
set -e
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
while read path_key path
do
url_key=$(echo $path_key | sed 's/\.path/.url/')
url=$(git config -f .gitmodules --get "$url_key")
git submodule add $url $path
done

View File

@ -1,9 +0,0 @@
<RCC>
<qresource prefix="/">
<file>src/ButterflyEngineModule/qmldir</file>
<file>src/ButterflyEngineModule/ButterflyEngine.qml</file>
</qresource>
<qresource prefix="/ButterflyEngineTr">
<file>languages/en.qm</file>
</qresource>
</RCC>

View File

@ -1,3 +0,0 @@
module ButterflyEngineModule
ButterflyEngine 1.0 ButterflyEngine.qml

View File

@ -0,0 +1,33 @@
<RCC>
<qresource prefix="/">
<file>CrawlModule/qmldir</file>
<file>CrawlModule/Crawl.qml</file>
<file>CrawlModule/GraphicItem.qml</file>
<file>CrawlModule/MainMenu.qml</file>
<file>CrawlModule/MainMenuButton.qml</file>
<file>CrawlModule/Metrix.qml</file>
<file>CrawlModule/PagePopUp.qml</file>
<file>CrawlModule/Scene.qml</file>
<file>CrawlModule/SettingsView.qml</file>
<file>CrawlModule/SnakeItem.qml</file>
<file>CrawlModule/DefaultMenu.qml</file>
<file>CrawlModule/AbstractMenuView.qml</file>
<file>CrawlModule/Light.qml</file>
<file>CrawlModule/DayLight.qml</file>
<file>CrawlModule/particles/ParticleEffect.qml</file>
<file>CrawlModule/particles/CrawlVectorDirection.qml</file>
<file>CrawlModule/particles/CrawlTargetDirection.qml</file>
<file>CrawlModule/particles/FireParticel.qml</file>
<file>CrawlCoreAssets/particles/fireColorTable.png</file>
<file>CrawlCoreAssets/particles/sphere.png</file>
<file>CrawlCoreAssets/particles/smokeSprite.png</file>
<file>CrawlModule/particles/Fire.qml</file>
<file>CrawlModule/particles/Wint.qml</file>
<file>CrawlModule/PreviewControl.qml</file>
<file>CrawlModule/StoreView.qml</file>
<file>CrawlModule/SelectLevelView.qml</file>
</qresource>
<qresource prefix="/ButterflyEngineTr">
<file>languages/en.qm</file>
</qresource>
</RCC>

View File

@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.18)
get_filename_component(CURRENT_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME)
set(CURRENT_PROJECT "${PROJECT_NAME}${CURRENT_PROJECT_DIR}")
add_definitions(-DButterflyEngine_LIBRARY)
add_definitions(-DBUTTERFLY_ENGINE_LIBRARY)
file(GLOB_RECURSE SOURCE_CPP

View File

@ -0,0 +1,8 @@
import QtQuick
import QtQuick.Layouts
GridLayout {
property var model: null
anchors.fill: parent
}

View File

@ -5,7 +5,7 @@
//# of this license document, but changing it is not allowed.
//#
import QtQuick 2.15
import QtQuick
Item {

View File

@ -0,0 +1,130 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
//import QtQuick.Window
import QtQuick.Controls
import NotifyModule
ApplicationWindow {
id: mainWindow;
visible: true;
width: 1024;
height: 720;
title: qsTr("Crawl");
property var model: engine
Metrix {id: metrix}
Label {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 25
wrapMode: Text.WordWrap
text: qsTr("Please Select level. If level is not availabel please bue it first.")
}
Scene {
id: scane;
worldModel: (model)? model.world : null;
anchors.fill: parent;
}
Scene {
id: nest;
worldModel: (model)? model.nest : null;
anchors.fill: parent;
}
ToolButton {
text: "👾"
font.pixelSize: 35
onClicked: {
mainMenuPopUp.open()
}
visible: !mainMenuPopUp.visible
}
Drawer {
id: mainMenuPopUp
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
height: parent.height
width: parent.width / 3
MainMenu {
id: mainMenu
model: (mainWindow.model)? mainWindow.model.menu: null;
anchors.fill: parent;
}
}
PagePopUp {
id: settingsPopUp
source: SettingsView {
id: settingsView
model: mainMenu.model ? mainMenu.model.userSettingsModel: null
}
standardButtons: Dialog.Save | Dialog.Cancel | Dialog.RestoreDefaults
modal: false;
width: parent.width * 0.8
height: parent.height * 0.8;
onAccepted: {
settingsView.save();
}
onReset: {
settingsView.reset();
}
onOpened: {
settingsView.update();
}
}
PagePopUp {
id: storePopUp
source: StoreView {
id: view
model: mainMenu.model ? mainMenu.model.storeView: null
}
modal: false;
width: parent.width * 0.8
height: parent.height * 0.8;
}
PagePopUp {
id: selectLvl
source: SelectLevelView {
id: selectLvlView
model: mainMenu.model ? mainMenu.model.selectLevelModle: null
}
modal: false;
width: parent.width * 0.8
height: parent.height * 0.8;
}
NotificationServiceView {
anchors.fill: parent;
}
}

View File

@ -0,0 +1,42 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
Node {
id: graphicItem
property var model: null
property int guiId: (model) ? model.guiId : -1;
PointLight {
id : sun
brightness: (model)? model.lightForce * model.visible: 100
color: (model)? model.color: "#ffffff"
castsShadow: (model)? model.castsShadow: 0
shadowFactor: (model)? model.shadowFactor: 0
shadowFilter: (model)? model.shadowFilter: 0
shadowMapFar: (model)? model.shadowMapFar: 0
shadowBias: (model)? model.shadowBias: 0
shadowMapQuality: Light.ShadowMapQualityHigh
Behavior on brightness {
NumberAnimation {
duration: 5000
}
}
}
rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
scale: (model)? model.size: Qt.vector3d(0, 0, 0);
position: (model) ? model.position: Qt.vector3d(0,0,0);
visible: sun.brightness
}

View File

@ -0,0 +1,40 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
AbstractMenuView {
columns: 2
rows: 2
Button {
text: qsTr("Back to menu.")
onClicked: {
if (model) {
model.backToMenu()
}
}
}
MouseArea {
cursorShape: Qt.DragMoveCursor
Layout.fillHeight: true
Layout.fillWidth: true
Layout.columnSpan: 2
Layout.rowSpan: 2
onClicked: {
model.userTap()
}
}
}

View File

@ -0,0 +1,78 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
Model {
id: graphicItem
property var model: null
property int guiId: (model) ? model.guiId : -1;
property bool fMapColor: model && (model.baseColorMap.length ||
model.emissiveMap.length ||
model.roughnessMap.length ||
model.normalMap.length)
property int tilies: 1
DefaultMaterial {
id: defaultMaterial
diffuseColor: (model)? model.color: "#ff1111"
}
PrincipledMaterial {
id: objMaterial
roughness : 1
baseColorMap: Texture {
source: (model)? model.baseColorMap: ""
tilingModeHorizontal: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
tilingModeVertical: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
scaleU: tilies
scaleV: tilies
}
emissiveMap: Texture {
source: (model)? model.emissiveMap: ""
tilingModeHorizontal: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
tilingModeVertical: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
scaleU: tilies
scaleV: tilies
}
roughnessMap: Texture {
source: (model)? model.roughnessMap: ""
tilingModeHorizontal: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
tilingModeVertical: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
scaleU: tilies
scaleV: tilies
}
normalMap: Texture {
source: (model)? model.normalMap: ""
tilingModeHorizontal: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
tilingModeVertical: (tilies > 1)? Texture.Repeat : Texture.ClampToEdge
scaleU: tilies
scaleV: tilies
}
}
materials: [
(fMapColor)? objMaterial: defaultMaterial
]
rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
scale: (model)? model.size: Qt.vector3d(0, 0, 0);
source: (model)? model.mash: "#Cube";
position: (model) ? model.position: Qt.vector3d(0,0,0);
visible: (model)? model.visible: false
}

View File

@ -0,0 +1,33 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
Node {
id: graphicItem
property var model: null
property int guiId: (model) ? model.guiId : -1;
DirectionalLight {
position: Qt.vector3d(0, 0, 0);
brightness: (model)? model.lightForce: 100
color: (model)? model.color: "#ffffff"
castsShadow: (model)? model.castsShadow: 0
shadowFactor: (model)? model.shadowFactor: 0
shadowFilter: (model)? model.shadowFilter: 0
shadowMapFar: (model)? model.shadowMapFar: 0
shadowBias: (model)? model.shadowBias: 0
}
rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
scale: (model)? model.size: Qt.vector3d(0, 0, 0);
position: (model) ? model.position: Qt.vector3d(0,0,0);
}

View File

@ -0,0 +1,83 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
Item {
id: root
property var model: null
visible: Boolean(model && model.visible)
z: 1
GridLayout {
id: columnLayout
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 0
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.topMargin: 0
columns: 1
rows: 10
transformOrigin: Item.Center
MainMenuButton {
id: play
text: qsTr("Select level")
onClicked: {
selectLvl.open()
}
}
MainMenuButton {
id: store
text: qsTr("Store")
onClicked: {
storePopUp.open()
}
}
MainMenuButton {
id: settings
text: qsTr("My Settings")
onClicked: {
settingsPopUp.open();
}
}
MainMenuButton {
id: exit
text: qsTr("Exit")
onClicked: {
Qt.quit();
}
}
}
}
/*##^## Designer {
D{i:0;autoSize:true;height:480;width:640}
}
##^##*/

View File

@ -0,0 +1,24 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
Button {
id: exit
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
font.pixelSize: height * 0.2
display: AbstractButton.TextBesideIcon
spacing: 4
focusPolicy: Qt.StrongFocus
Layout.preferredHeight: parent.height / (parent.rows + 1)
Layout.preferredWidth: parent.width / (parent.columns + 0.5)
}

View File

@ -0,0 +1,34 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Window
import QtQuick.Controls.Material
import QtQuick.Controls
Item {
readonly property int pointCount: 100;
readonly property real mm: Screen.pixelDensity
readonly property real sm: 10 * mm
readonly property real dsm: Math.sqrt(Math.pow(Screen.desktopAvailableWidth, 2) + Math.pow(Screen.desktopAvailableHeight, 2)) / sm
readonly property real pt: getfactor(dsm) * sm
readonly property real controlPtMaterial: Material.buttonHeight
readonly property real gamePt: (width < height) ? width / pointCount : height / pointCount;
function getfactor(dsm) {
if (dsm < 30) {
return 0.5
} else if ( dsm < 70) {
return 1
} else if (dsm < 140) {
return 2;
} else
return 4;
}
anchors.fill: parent;
}

View File

@ -0,0 +1,32 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
Dialog {
id: pagePopUp
property var source: null
Item {
id: sourceVal
anchors.fill: parent
}
onSourceChanged: {
if (!source)
return;
source.parent = sourceVal;
source.anchors.fill = sourceVal;
}
x: parent.width / 2 - width / 2
y: parent.height / 2 - height / 2
}

View File

@ -0,0 +1,72 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
AbstractMenuView {
columns: 4
rows: 2
MouseArea {
cursorShape: Qt.DragMoveCursor
Layout.fillHeight: true
Layout.fillWidth: true
Layout.columnSpan: 4
Layout.rowSpan: 1
property bool track: false
property real oldX: 0
property real oldY: 0
onPressed: (mouse) => {
track = true
oldX = mouse.x
oldY = mouse.y
}
onReleased: {
track = false
}
onPositionChanged: (mouse) => {
if (!model) {
return;
}
if (!track) {
return;
}
let delta = mouse.y - oldY;
let radianDeltaY = (delta / (parent.height / 2)) * 45
delta = mouse.x - oldX;
let radianDeltaX = (delta / (parent.width / 2)) * 45
model.mousePositionChanged(radianDeltaX, radianDeltaY)
oldY = mouse.y;
oldX = mouse.x;
}
}
Button {
text: qsTr("Start")
onClicked: {
if (model) {
model.start()
}
}
}
}

View File

@ -0,0 +1,145 @@
import QtQuick
import QtQuick3D
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D.Particles3D
View3D {
id: scene;
property var worldModel: null;
renderMode: View3D.Offscreen
visible: worldModel && worldModel.visible
Label {
text: scane.renderStats.fps
x: 200
}
PerspectiveCamera {
id: camera
position: (privateRoot.player && privateRoot.releativeCameraPosition)?
Qt.vector3d(privateRoot.player.position.x + privateRoot.releativeCameraPosition.x,
privateRoot.player.position.y + privateRoot.releativeCameraPosition.y,
privateRoot.player.position.z + privateRoot.releativeCameraPosition.z)
:
Qt.vector3d(0,0,100)
rotation: (privateRoot.world)? privateRoot.world.cameraRotation: Qt.quaternion(0,0,0,0)
}
SceneEnvironment {
id: defautlBackground
backgroundMode: SceneEnvironment.Color
clearColor: "#777777"
}
environment: /*(privateRoot.world)? background:*/ defautlBackground
ParticleSystem3D {
id: privateRoot
property var arrayObjects: []
property var gameMenuModel: (worldModel)? worldModel.menu: null
property var player: (worldModel)? worldModel.player: null
property var releativeCameraPosition: (worldModel)? worldModel.cameraReleativePosition: null
property var gameMenu: null
function add (cppObjId) {
if (!worldModel) {
console.log("create object fail")
return;
}
const objModel = worldModel.getItem(cppObjId);
if (!objModel) {
console.log("model of the crawl object is not found");
return;
}
var viewTemplate = objModel.viewTemplate;
var temp = Qt.createComponent(viewTemplate)
if (temp.status === Component.Ready) {
var obj = temp.createObject(privateRoot)
obj.model = objModel;
arrayObjects.push(obj)
} else {
console.log("wrong viewTemplate in model " + temp.errorString());
}
}
function remove(id) {
if (typeof id !== "number" || id < 0) {
console.log("id not found");
return;
}
for (var i = 0; i < arrayObjects.length; ++i) {
if (id === arrayObjects[i].guiId) {
arrayObjects[i].destroy();
arrayObjects.splice(i,1);
}
}
}
Connections {
target: worldModel;
function onSigOBjctsListChanged(diff) {
if (!diff) {
console.log("diff not found");
return;
}
let tempDifRem = [];
tempDifRem = diff.getRemoveIds();
let tempDifAdd = [];
tempDifAdd = diff.getAddedIds();
for (let i = 0; i < tempDifAdd.length; ++i) {
privateRoot.add(tempDifAdd[i]);
}
for (let j = 0; j < tempDifRem.length; ++j) {
privateRoot.remove(tempDifRem[j]);
}
}
}
Connections {
target: privateRoot;
function onGameMenuModelChanged() {
if (!privateRoot.gameMenuModel) {
return;
}
const comp = Qt.createComponent(privateRoot.gameMenuModel.view);
if (comp.status === Component.Ready) {
if (privateRoot.gameMenu) {
privateRoot.gameMenu.destroy()
}
privateRoot.gameMenu = comp.createObject(scene);
if (privateRoot.gameMenu === null) {
// Error Handling
console.log("Error creating object");
}
privateRoot.gameMenu.model = privateRoot.gameMenuModel;
} else if (comp.status === Component.Error) {
// Error Handling
console.log("Error loading component: " + privateRoot.gameMenuModel.view, comp.errorString());
}
}
}
}
}

View File

@ -0,0 +1,72 @@
import QtQuick
import ViewSolutionsModule
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
Page {
id: store
property var model: null;
ColumnLayout {
anchors.fill: parent
ListView {
id: listView
Layout.fillHeight: true
Layout.fillWidth: true
model: store.model
delegate: delegateRow
Component {
id: delegateRow
Rectangle {
width: listView.width
height: 100
color: (itemId === store.model.currentLevel) ? "#ffaf2c": "#00000000"
Behavior on color {
ColorAnimation {
duration: 200
}
}
RowLayout {
anchors.fill: parent
Image {
id: img
fillMode: Image.PreserveAspectCrop
source: itemImage
Layout.fillHeight: true
Layout.preferredWidth: height * 2
}
Label {
text: itemName
Layout.fillHeight: true
}
Label {
text: itemDescription
Layout.fillWidth: true
Layout.fillHeight: true
}
Button {
text: qsTr("Select");
visible: itemId !== store.model.currentLevel
onClicked: () => {
if (store.model)
store.model.select(itemId);
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,94 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import QtQuick.Layouts
Item {
id: settingsView
property var model: null
function save() {
if (!model) {
return;
}
model.setPort(port.value);
model.setHost(host.text);
model.setTheme(themeBox.currentIndex);
}
function reset() {
if (!model) {
return;
}
model.toDefault();
}
function update() {
if (!model) {
return;
}
model.forceUpdate();
}
GridLayout {
id: columnLayout
rows: 4
columns: 2
anchors.fill: parent
Label {
text: qsTr("Use Them")
Layout.fillWidth: true
}
ComboBox {
id: themeBox;
Layout.fillWidth: true
focusPolicy: Qt.NoFocus
model: [qsTr("Light"), qsTr("Dark")];
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
currentIndex: (settingsView.model)? settingsView.model.theme: 0
onCurrentIndexChanged: {
if (((settingsView.model)? settingsView.model.theme: 0)
!== currentIndex) {
themeWarning.visible = true;
}
}
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
Label {
id: themeWarning
text: qsTr("In order for the new theme to take effect, you need to reload the game.");
color: "#FF0000"
wrapMode: Label.WordWrap
Layout.maximumWidth: themeBox.width
visible: false;
}
}
}

View File

@ -0,0 +1,12 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
GraphicItem {
}

View File

@ -0,0 +1,64 @@
import QtQuick
import ViewSolutionsModule
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
Page {
id: store
property var model: null;
ColumnLayout {
anchors.fill: parent
ListView {
id: listView
Layout.fillHeight: true
Layout.fillWidth: true
model: store.model
delegate: delegateRow
Component {
id: delegateRow
RowLayout {
width: listView.width
height: 100
Image {
id: img
fillMode: Image.PreserveAspectCrop
source: itemImage
Layout.fillHeight: true
Layout.preferredWidth: height * 2
}
Label {
text: itemName
Layout.fillHeight: true
}
Label {
text: itemDescription
Layout.fillWidth: true
Layout.fillHeight: true
}
CheckBox {
id: buyStatus
tristate: false
checkState: (itemWasBuy)? Qt.Checked: Qt.Unchecked
enabled: false
}
Button {
text: qsTr("Buy");
visible: !itemWasBuy
onClicked: () => {
if (store.model)
store.model.buy(itemId);
}
}
}
}
}
}
}

View File

@ -0,0 +1,22 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
TargetDirection3D {
property var model: null
property string path: ""
position: (model)? model.velosityTargetPosition : Qt.vector3d(0, 0, 0)
normalized: (model)? model.velosityNormalized : false
magnitude: (model)? model.velosityMagnitude : 1
magnitudeVariation: (model)? model.velosityMagnitudeVariation : 0
positionVariation: (model)? model.velosityTargetPositionVariation : Qt.vector3d(0, 0, 0)
}

View File

@ -0,0 +1,18 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
VectorDirection3D {
property var model: null
property string path: ""
direction: (model)? model.velosityDirection : Qt.vector3d(0, 0, 0)
directionVariation: (model)? model.velosityDirectionValatility : Qt.vector3d(0, 0, 0)
}

View File

@ -0,0 +1,17 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
ParticleEffect {
PointLight {
brightness: (model)? Math.sqrt(model.fireStrength): 0;
color: (model)? model.color: "#ffffff";
}
}

View File

@ -0,0 +1,27 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
SpriteParticle3D {
id: particleFire
sprite: Texture {
source: "qrc:/CrawlCoreAssets/particles/sphere.png"
}
colorTable: Texture {
source: "qrc:/CrawlCoreAssets/particles/fireColorTable.png"
}
maxAmount: 300
color: "#ffffff"
colorVariation: Qt.vector4d(0.0, 0.6, 0.8, 0.0)
billboard: true
blendMode: SpriteParticle3D.Screen
fadeInDuration: 100
}

View File

@ -0,0 +1,114 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
ParticleEmitter3D {
id: root
property var model: null
property int guiId: (model) ? model.guiId : -1;
rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
scale: (model)? model.size: Qt.vector3d(0, 0, 0);
position: (model) ? model.position: Qt.vector3d(0,0,0);
visible: (model)? model.visible: false
depthBias: (model)? model.depthBias: 0
emitRate: (model)? model.emitRate: 0
enabled: (model)? model.enabled: true
lifeSpan: (model)? model.lifeSpan: 0
lifeSpanVariation: (model)? model.lifeSpanVariation: 0
particleEndScale: (model)? model.particleEndScale: 0
particleRotation: (model)? model.particleRotation: Qt.vector3d(0, 0, 0)
particleRotationVariation: (model)? model.particleRotationVariation: Qt.vector3d(0, 0, 0)
particleRotationVelocity: (model)? model.particleRotationVelocity: Qt.vector3d(0, 0, 0)
particleRotationVelocityVariation: (model)? model.particleRotationVelocityVariation: Qt.vector3d(0, 0, 0)
particleScaleVariation: (model)? model.particleScaleVariation: 0
onModelChanged: () => {
if (root.model) {
root.model.viewObject = root;
}
}
Item {
id: privateRoot
property var velosity: (model)? model.velocity: null
property string delegate: (model)? model.particleDelegate: ""
property string particleShape: (model)? model.particleShape: ""
property var view: null
onVelosityChanged: () => {
if (!root.model)
return;
const objModel = root.model.velocity;
if (!objModel) {
if (view) {
view.distory();
}
root.velocity = view = null;
return;
}
const viewTemplate = objModel.viewTemplate;
if (!view || (view.path !== viewTemplate)) {
let temp = Qt.createComponent(viewTemplate)
if (!temp)
return
if (temp.status === Component.Ready) {
let obj = temp.createObject(root)
obj.model = objModel;
if (view) {
view.distory();
}
root.velocity = view = obj;
} else {
console.log("wrong path (viewTemplate property) ot thq velosity module " + temp.errorString());
}
}
}
onDelegateChanged: () => {
let temp = Qt.createComponent(privateRoot.delegate)
if (!temp)
return
if (temp.status === Component.Ready) {
root.particle = temp.createObject(root.parent);
} else {
console.log("wrong path to the in model " + temp.errorString());
}
}
onParticleShapeChanged: () => {
let temp = Qt.createComponent(privateRoot.particleShape)
if (!temp)
return
if (temp.status === Component.Ready) {
root.shape = temp.createObject(root.parent);
} else {
console.log("wrong viewTemplate in model " + temp.errorString());
}
}
}
}

View File

@ -0,0 +1,39 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
Gravity3D {
property var model: null
property int guiId: (model) ? model.guiId : -1;
enabled: (model)? model.enabled: false
magnitude: (model)? model.magnitude: 0
direction: (model)? model.direction: Qt.vector3d(0, 0, 0)
Behavior on magnitude {
NumberAnimation {
duration: 5000
easing.type: Easing.InQuad
}
}
Behavior on direction {
Vector3dAnimation {
duration: 5000
easing.type: Easing.InQuad
}
}
}

View File

@ -0,0 +1,6 @@
module CrawlModule
Crawl 1.0 Crawl.qml
DefaultMenu 1.0 DefaultMenu.qml
GraphicItem 1.0 GraphicItem.qml
ParticleEffect 1.0 ParticleEffect.qml
Light 1.0 Light.qml

View File

@ -0,0 +1,30 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "asyncimageresponse.h"
AsyncImageResponse::AsyncImageResponse() = default;
AsyncImageResponse::~AsyncImageResponse() = default;
QQuickTextureFactory *AsyncImageResponse::textureFactory() const {
return _texture;
}
// memory leak ?
void AsyncImageResponse::setResult(const QImage& image) {
_texture = QQuickTextureFactory::textureFactoryForImage(image);
emit finished();
// deleteLater();
}
void AsyncImageResponse::error(const QString &err) {
_errorString = " " + err;
}
QString AsyncImageResponse::errorString() const {
return QQuickImageResponse::errorString() + _errorString;
}

View File

@ -0,0 +1,31 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef ASYNCIMAGERESPONSE_H
#define ASYNCIMAGERESPONSE_H
#include <QQuickImageResponse>
class AsyncImageResponse : public QQuickImageResponse {
private:
QQuickTextureFactory *_texture = nullptr;
QString _errorString;
public:
AsyncImageResponse ();
~AsyncImageResponse () override;
QQuickTextureFactory *textureFactory() const override;
void setResult(const QImage &image);
void error(const QString &err);
QString errorString() const override;
};
#endif // ASYNCIMAGERESPONSE_H

View File

@ -0,0 +1,36 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "availablelevelsmodel.h"
#include "user.h"
#include <Crawl/iitem.h>
namespace CRAWL {
AvailableLevelsModel::AvailableLevelsModel() {
}
int AvailableLevelsModel::getCurrentLevel() const {
return currentLevel;
}
void AvailableLevelsModel::setCurrentLevel(int newCurrentLevel) {
if (currentLevel == newCurrentLevel)
return;
currentLevel = newCurrentLevel;
emit currentLevelChanged();
}
void AvailableLevelsModel::select(int levelId) {
if (getUser()->isUnlocked(levelId)) {
setCurrentLevel(levelId);
emit sigUserSelectLevel(levelId);
}
}
}

View File

@ -0,0 +1,83 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef AVAILABLELEVELSMODEL_H
#define AVAILABLELEVELSMODEL_H
#include "baseuserlistmodel.h"
namespace CRAWL {
class User;
class IItem;
/**
* @brief The AvailableLevelsModel class is model of the available levels qml view.
* This model just show available levels of the current user.
* @see the SelectLevelView.qml module.
*/
class AvailableLevelsModel: public BaseUserListModel
{
Q_OBJECT
/**
* @brief currentLevel This property contains id of the loaded level.
* @see AvailableLevelsModel::getCurrentLevel
* @see AvailableLevelsModel::setCurrentLevel
* @see AvailableLevelsModel::currentLevelChanged
*/
Q_PROPERTY(int currentLevel READ getCurrentLevel WRITE setCurrentLevel NOTIFY currentLevelChanged)
public:
AvailableLevelsModel();
/**
* @brief getCurrentLevel This method return value of the curernt level property
* @return value of the curernt level property
* @see AvailableLevelsModel::currentLevel
* @see AvailableLevelsModel::setCurrentLevel
* @see AvailableLevelsModel::currentLevelChanged
*/
int getCurrentLevel() const;
/**
* @brief setCurrentLevel This method sets new current level.
* @param newCurrentLevel This is new value of the current level.
* @see AvailableLevelsModel::getCurrentLevel
* @see AvailableLevelsModel::currentLevel
* @see AvailableLevelsModel::currentLevelChanged
*/
void setCurrentLevel(int newCurrentLevel);
/**
* @brief select This method select new level of user.
* @param levelId This is id of the selected level.
*/
Q_INVOKABLE void select(int levelId);
signals:
/**
* @brief currentLevelChanged This signal emited when the currentLevel propertye is changed.
* @see AvailableLevelsModel::getCurrentLevel
* @see AvailableLevelsModel::setCurrentLevel
* @see AvailableLevelsModel::currentLevel
*/
void currentLevelChanged();
/**
* @brief sigUserSelectLevel This signal emited when user select new level.
* @param level This is level id that user selected.
*/
void sigUserSelectLevel(int level);
private:
int currentLevel = -1;
};
}
#endif // AVAILABLELEVELSMODEL_H

View File

@ -0,0 +1,176 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "baseuserlistmodel.h"
#include "user.h"
#include "store.h"
#include <Crawl/iitem.h>
namespace CRAWL {
BaseUserListModel::BaseUserListModel() {
}
void BaseUserListModel::setUser(User *newUser) {
if (_user) {
disconnect(_user, &User::sigDropped,
this, &BaseUserListModel::handleDroppedItem);
disconnect(_user, &User::sigUnlcoked,
this, &BaseUserListModel::handleUnlockedItem);
disconnect(_user, &User::sigUlockedItemsChanged,
this, &BaseUserListModel::handleUnlockedItemsListChanged);
}
_user = newUser;
if (_user) {
connect(_user, &User::sigDropped,
this, &BaseUserListModel::handleDroppedItem);
connect(_user, &User::sigUnlcoked,
this, &BaseUserListModel::handleUnlockedItem);
connect(_user, &User::sigUlockedItemsChanged,
this, &BaseUserListModel::handleUnlockedItemsListChanged);
}
}
int BaseUserListModel::getIndexById(int id) const {
return _keysIndexes.value(id, -1);
}
Store *BaseUserListModel::store() const {
return _store;
}
void BaseUserListModel::setStore(Store *newStore) {
_store = newStore;
}
const QList<int> &BaseUserListModel::keys() const {
return _keys;
}
void BaseUserListModel::setKeys(const QList<int> &visibleKeysList) {
int diff = visibleKeysList.size() - _keys.size();
auto update = [this](const QList<int> & list) {
_keys = list;
for (int index = 0; index < _keys.size(); ++index) {
_keysIndexes[_keys[index]] = index;
}
};
if (diff > 0) {
beginInsertRows({}, _keys.size(), visibleKeysList.size() - 1);
update(visibleKeysList);
endInsertRows();
} else if (diff == 0) {
emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1));
} else {
beginRemoveRows({}, visibleKeysList.size(), _keys.size() - 1);
update(visibleKeysList);
endRemoveRows();
}
}
void BaseUserListModel::addKey(int newKey) {
beginInsertRows({}, _keys.size(), _keys.size());
_keys.push_back(newKey);
_keysIndexes[newKey] = _keys.size() - 1;
endInsertRows();
}
void BaseUserListModel::removeKey(int oldKey) {
int idx = getIndexById(oldKey);
if (idx >= 0) {
beginRemoveRows({}, _keys.size(), _keys.size());
_keys.removeAt(idx);
_keysIndexes.remove(oldKey);
endRemoveRows();
}
}
int BaseUserListModel::rowCount(const QModelIndex &) const {
return _keys.size();
}
int BaseUserListModel::columnCount(const QModelIndex &) const {
return 1;
}
QVariant BaseUserListModel::data(const QModelIndex &index, int role) const {
if (index.row() >= rowCount()) {
return {};
}
int id = _keys.at(index.row());
const IItem* item = getItem(id);
if (!item)
return {};
switch (role) {
case ItemId: return id;
case ItemName: return item->itemName();
case ItemImage: return item->image();
case ItemDescription: return item->description();
case ItemWasBuy: return getUser() && getUser()->isUnlocked(id);
default:
return {};
}
}
QHash<int, QByteArray> BaseUserListModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[ItemId] = "itemId";
roles[ItemName] = "itemName";
roles[ItemDescription] = "itemDescription";
roles[ItemImage] = "itemImage";
roles[ItemWasBuy] = "itemWasBuy";
return roles;
}
User *BaseUserListModel::getUser() const {
return _user;
}
void BaseUserListModel::handleUnlockedItem(int item) {
int idx = _keysIndexes.value(item, -1);
if (idx >= 0) {
emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy});
}
}
void BaseUserListModel::handleDroppedItem(int item) {
int idx = _keysIndexes.value(item, -1);
if (idx >= 0) {
emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy});
}
}
void BaseUserListModel::handleUnlockedItemsListChanged(const QSet<int> &) {
emit dataChanged(index(0,0), index(_keys.size() - 1, 0), {ItemWasBuy});
}
const IItem *BaseUserListModel::getItem(int id) const {
return _store->getItemById(id);
}
}

View File

@ -0,0 +1,134 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef BASEUSERLISTMODEL_H
#define BASEUSERLISTMODEL_H
#include <QAbstractListModel>
namespace CRAWL {
class User;
class IItem;
class Store;
/**
* @brief The BaseUserListModel class This is base class wint implementation methods for working with user object.
*/
class BaseUserListModel: public QAbstractListModel
{
Q_OBJECT
public:
BaseUserListModel();
/**
* @brief setUser This method update user pointer
* @param user This is new pointer to current user.
*/
void setUser(User *newUser);
/**
* @brief keys This method retutn curent visible items list.
* @return visible items list.
* @see BaseUserListModel::setKeys
*/
const QList<int> &keys() const;
/**
* @brief setKeys This method sets lsit of the keys for view.
* @param visibleKeysList This is new valud of the visible keys list.
* @see BaseUserListModel::keys
*/
void setKeys(const QList<int>& visibleKeysList);
/**
* @brief addKey This method add new key value for view.
* @param newKey new key value.
*/
void addKey(int newKey);
/**
* @brief removeKey This method remove old key from view.
* @param oldKey This is old key that will be removed.
*/
void removeKey(int oldKey);
int rowCount(const QModelIndex &parent = {}) const override;
int columnCount(const QModelIndex &parent = {}) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
/**
* @brief store This method return pointer to current store object.
* @return current store object.
*/
Store *store() const;
/**
* @brief setStore This method sets new pointer value for the store property.
* @param newStore This is new value of the store property
*/
void setStore(Store *newStore);
protected:
enum ViewItemRoles {
ItemId,
ItemName,
ItemImage,
ItemDescription,
ItemWasBuy
};
/**
* @brief getUser This method return pointer to current user.
* @return pointer to current user.
*/
User* getUser() const;
/**
* @brief handleUnlockedItem This slot invoked when emited the User::unclokItem signal.
* @param item This is id of the unlocked item
*/
virtual void handleUnlockedItem(int item);
/**
* @brief handleUnlockedItem This slot invoked when emited the User::droppItem signal.
* @param item This is id of the dropped item
*/
virtual void handleDroppedItem(int item);
/**
* @brief handleUnlockedItem This slot invoked when emited the User::setUnlockedItems signal.
* @param item This is new list of the unclod items.
*/
virtual void handleUnlockedItemsListChanged(const QSet<int>& newSet);
/**
* @brief getItem This method should be return the item by id. Override this method for correct works this model.
* @param id This is item id
* @return const pointer to item object.
*/
virtual const IItem* getItem(int id) const;
/**
* @brief getIndexById This method return index of the item by id.
* @param id This is id of the needed item
* @return index of the needed item. If the item with id not exists then return -1
*/
int getIndexById(int id) const;
private:
User * _user = nullptr;
QList<int> _keys;
QHash<int, int> _keysIndexes;
Store *_store = nullptr;
};
}
#endif // BASEUSERLISTMODEL_H

View File

@ -0,0 +1,39 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "defaultbackgroundai.h"
#include <QTimer>
namespace CRAWL {
DefaultBackgroundAI::DefaultBackgroundAI() {
_timer = new QTimer();
_timer->setInterval(1000);
connect(_timer, &QTimer::timeout, this, &DefaultBackgroundAI::handleTimerTriger);
}
DefaultBackgroundAI::~DefaultBackgroundAI() {
_timer->stop();
delete _timer;
}
void DefaultBackgroundAI::startAI() {
_timer->start();
}
void DefaultBackgroundAI::stopAI() {
_timer->stop();
}
void DefaultBackgroundAI::handleTimerTriger() {
_timer->setInterval(rand() % 2000 + 200);
emit userTap();
}
}

View File

@ -0,0 +1,36 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DEFAULTBACKGROUNDAI_H
#define DEFAULTBACKGROUNDAI_H
#include "Crawl/defaultcontrol.h"
#include <Crawl/iai.h>
class QTimer;
namespace CRAWL {
class DefaultBackgroundAI: public DefaultControl, public IAI {
Q_OBJECT
public:
DefaultBackgroundAI();
~DefaultBackgroundAI();
// IAI interface
public:
void startAI() override;
void stopAI() override;
private slots:
void handleTimerTriger();
private:
QTimer *_timer = nullptr;
};
}
#endif // DEFAULTBACKGROUNDAI_H

View File

@ -0,0 +1,252 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "availablelevelsmodel.h"
#include "engine.h"
#include "mainmenumodel.h"
#include <QQmlComponent>
#include <Crawl/guiobject.h>
#include <Crawl/ipreviewscaneworld.h>
#include "Crawl/iworld.h"
#include <QThread>
#include <quasarapp.h>
#include <storeviewmodel.h>
#include "Crawl/icontrol.h"
#include "QDateTime"
#include "QtConcurrent"
#include "store.h"
namespace CRAWL {
Engine::Engine(QObject *parent): QObject(parent) {
_store = new Store();
_menu = new MainMenuModel();
setNewUser(new User());
}
Engine::~Engine() {
for (auto it = _availableLvls.begin(); it != _availableLvls.end(); ++it) {
delete it.value();
}
_availableLvls.clear();
delete _menu;
delete _currentUser;
}
QObject *Engine::scane() {
return _scane;
}
void Engine::setLevel(ILevel *world) {
if (_currentLevel == world)
return ;
if (_currentLevel) {
_currentLevel->reset();
}
_currentLevel = world;
emit worldChanged();
if (!_currentLevel) {
QuasarAppUtils::Params::log("Failed to init world. The World object is null! ",
QuasarAppUtils::Error);
_currentLevel = nullptr;
return;
}
if (!_currentLevel->world()) {
QuasarAppUtils::Params::log("Failed to init world. The World Object is null: " +
_currentLevel->world()->itemName(),
QuasarAppUtils::Error);
_currentLevel = nullptr;
return;
}
if (!_currentLevel->previewScane()) {
QuasarAppUtils::Params::log("Failed to init world. The World Preview scane is null. World Name: " +
_currentLevel->world()->itemName(),
QuasarAppUtils::Error);
_currentLevel = nullptr;
return;
}
connect(_currentLevel->previewScane(), &IPreviewScaneWorld::sigPrepareIsFinished,
this, &Engine::start);
connect(_currentLevel->world(), &IPreviewScaneWorld::sigGameFinished,
this, &Engine::stop);
_currentLevel->previewScane()->start({});
}
void Engine::setScane(QObject *newScane) {
if (_scane == newScane)
return;
_scane = newScane;
emit scaneChanged();
}
QObject *Engine::player() const {
if (_currentLevel && _currentLevel->world())
return _currentLevel->world()->player();
return nullptr;
}
QObject *Engine::world() const {
if (!_currentLevel)
return nullptr;
return _currentLevel->world();
}
void Engine::start(const StartData& config) const {
if (!_currentLevel)
return;
if (!_currentLevel->previewScane()->stop()) {
return;
}
_currentLevel->world()->start(config);
}
void Engine::stop() const {
if (!_currentLevel)
return;
_currentLevel->previewScane()->start(_currentLevel->previewScane()->configuration());
}
void Engine::handleUnlockedItem(int item) {
static_cast<AvailableLevelsModel*>(_menu->selectLevelModle())->addKey(item);
}
void Engine::handleDroppedItem(int item) {
static_cast<AvailableLevelsModel*>(_menu->selectLevelModle())->removeKey(item);
}
void Engine::handleUnlockedItemsListChanged(const QSet<int> &newSet) {
static_cast<AvailableLevelsModel*>(_menu->selectLevelModle())->setKeys(QList<int>(newSet.begin(), newSet.end()));
}
void Engine::handleLevelChanged(int levelId) {
ILevel* data = _availableLvls.value(levelId, nullptr);
if (!data) {
QuasarAppUtils::Params::log("Failed to start lvl.", QuasarAppUtils::Error);
return;
}
setLevel(data);
}
ILevel *Engine::getLastLevel() {
for (const auto &data : qAsConst(_availableLvls)) {
if (data && data->world() && currentUser() &&
currentUser()->isUnlocked(data->world()->itemId())) {
return data;
}
}
return nullptr;
}
QObject *Engine::menu() const {
return _menu;
}
void Engine::setNewUser(User *user) {
if (_currentUser) {
disconnect(_currentUser, &User::sigUnlcoked, this, &Engine::handleUnlockedItem);
disconnect(_currentUser, &User::sigDropped, this, &Engine::handleDroppedItem);
disconnect(_currentUser, &User::sigUlockedItemsChanged,
this, &Engine::handleUnlockedItemsListChanged);
}
_currentUser = user;
static_cast<StoreViewModel*>(_menu->storeView())->setUser(_currentUser);
static_cast<AvailableLevelsModel*>(_menu->selectLevelModle())->setUser(_currentUser);
if (_currentUser) {
connect(_currentUser, &User::sigUnlcoked, this, &Engine::handleUnlockedItem);
connect(_currentUser, &User::sigDropped, this, &Engine::handleDroppedItem);
connect(_currentUser, &User::sigUlockedItemsChanged,
this, &Engine::handleUnlockedItemsListChanged);
}
}
void Engine::addLvl(ILevel *levelWordl) {
if (!levelWordl->world()) {
QuasarAppUtils::Params::log("The Level not contains world object!!!");
return;
}
_availableLvls.insert(levelWordl->world()->itemId(), levelWordl);
}
Store *Engine::store() const {
return _store;
}
QObject *Engine::nest() const {
if (!_currentLevel)
return nullptr;
return _currentLevel->previewScane();
}
User *Engine::currentUser() const {
return _currentUser;
}
void Engine::init() {
QMultiHash<int, const IItem *> availabelItems;
for (const auto &data : qAsConst(_availableLvls)) {
if (data && data->world())
availabelItems.unite(data->world()->childItemsRecursive());
}
_store->init(availabelItems);
static_cast<StoreViewModel*>(_menu->storeView())->init(_store, _currentUser);
QList<int> availableWorlds;
for (int id : _currentUser->unlockedItems()) {
auto item = availabelItems.value(id);
if (item->itemType() == IWorld::type()) {
availableWorlds.push_back(item->itemId());
}
}
#define selectedLevelModel static_cast<AvailableLevelsModel*>(_menu->selectLevelModle())
selectedLevelModel->setStore(_store);
selectedLevelModel->setKeys(availableWorlds);
connect(selectedLevelModel, &AvailableLevelsModel::sigUserSelectLevel,
this, &Engine::handleLevelChanged);
}
}

View File

@ -0,0 +1,182 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef ENGINE_H
#define ENGINE_H
#include <QFuture>
#include <QObject>
#include <QQmlEngine>
#include <Crawl/diff.h>
#include <Crawl/ilevel.h>
namespace CRAWL {
class IWorld;
class Store;
class StartData;
class User;
class StoreViewModel;
class MainMenuModel;
/**
* @brief The Engine class
*/
class Engine : public QObject {
Q_OBJECT
Q_PROPERTY(QObject* player READ player NOTIFY playerChanged)
Q_PROPERTY(QObject* world READ world NOTIFY worldChanged)
Q_PROPERTY(QObject* nest READ nest NOTIFY worldChanged)
Q_PROPERTY(QObject* scane READ scane WRITE setScane NOTIFY scaneChanged)
Q_PROPERTY(QObject * menu READ menu NOTIFY menuChanged)
public:
Engine(QObject * parent = nullptr);
~Engine();
/**
* @brief scane This method return main scane of the game.
* @return pointer to main game scane.
*/
Q_INVOKABLE QObject* scane();
/**
* @brief setLevel This method set new world level for game.
* @param world This is pointer to new world level.
*/
void setLevel(ILevel *world);
/**
* @brief setScane This method sets new scane object. The scane object are
* @param newScane are Qt Quick 3d node object form qml.
*/
void setScane(QObject *newScane);
/**
* @brief currentWorld return pointer to current world object.
* @return raw pointer to current world object.
*/
IWorld *currentWorld() const;
/**
* @brief player return player object.
* @return player object
*/
QObject* player() const;
/**
* @brief world return player object.
* @return world object
*/
QObject* world() const;
/**
* @brief currentUser This method return pointer too current user.
* @return pointer too current user.
*/
User *currentUser() const;
/**
* @brief init This method initialize the main model. Sets available levels and items.
* @param availabelItems This is list of available items.
*/
void init();
/**
* @brief store This pointer return pointer to store.
* @return pointer to store.
*/
Store *store() const;
/**
* @brief nest This method return pointer to the nest model.
* @return pointer to the nest model.
*/
QObject *nest() const ;
/**
* @brief menu This is a main menu model.
* @return main menu model object.
*/
QObject *menu() const;
/**
* @brief setNewUser This method will initialise the new user profile.
* @param user This is pointer to new user profile.
*/
void setNewUser(User* user);
/**
* @brief addLvl This method should be add level to game.
* @param levelWordl This is world instance
*/
void addLvl(ILevel* levelWordl);
signals:
void scaneChanged();
void playerChanged();
void worldChanged();
void menuChanged();
private slots:
/**
* @brief start This method run current lvl ( move prepared data from the nest to game world)
* @param config This is confuguration that created new game world.
* @return true if lvl started successful.
*/
void start(const StartData &config) const;
/**
* @brief stop This slots invoked when world finished own session.
*/
void stop() const;
/**
* @brief handleUnlockedItem This slot invoked when emited the User::unclokItem signal.
* @param item This is id of the unlocked item
*/
void handleUnlockedItem(int item);
/**
* @brief handleUnlockedItem This slot invoked when emited the User::droppItem signal.
* @param item This is id of the dropped item
*/
void handleDroppedItem(int item);
/**
* @brief handleUnlockedItem This slot invoked when emited the User::setUnlockedItems signal.
* @param item This is new list of the unclod items.
*/
void handleUnlockedItemsListChanged(const QSet<int>& newSet);
/**
* @brief handleLevelChanged This slot invoked when user select new level.
* @param levelId level id
*/
void handleLevelChanged(int levelId);
private:
ILevel * getLastLevel();
void renderLoop();
QObject *_scane = nullptr;
ILevel* _currentLevel = nullptr;
QHash<int, ILevel*> _availableLvls;
MainMenuModel *_menu = nullptr;
User *_currentUser = nullptr;
Store *_store = nullptr;
};
}
#endif // ENGINE_H

View File

@ -0,0 +1,116 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "eventserver.h"
#include <Crawl/iworlditem.h>
#include <Crawl/iworld.h>
#include <QtConcurrent>
#include <thread>
namespace CRAWL {
EventServer::EventServer(IWorld *instance) {
debug_assert(instance, "Invalid World pointer in EventServer");
_worldInstance = instance;
_supportedEventsKeys = {Events::Intersects};
}
EventServer::~EventServer() {
stop();
}
void EventServer::start() {
if (_renderLoopFuture.isRunning())
return;
_renderLoop = true;
_renderLoopFuture = QtConcurrent::run([this](){renderLoop();});
}
void EventServer::stop() {
_renderLoop = false;
_renderLoopFuture.waitForFinished();
}
void EventServer::handleAvailableObjectChanges(const Diff &diff) {
for (int added: diff.addedIds) {
auto obj = _worldInstance->getItem(added);
if (obj->isDecorative()) {
continue;
}
for (int event: qAsConst(_supportedEventsKeys)) {
addToSupportedEvents(obj, event);
}
_objects.insert(obj->guiId(), obj);
}
for (int removed: diff.removeIds) {
for (int event: qAsConst(_supportedEventsKeys)) {
_supportedEvents[event].remove(removed);
}
_objects.remove(removed);
}
}
void EventServer::eventProcess() {
for (auto it = _supportedEvents.begin(); it != _supportedEvents.end(); ++it) {
for (const IWorldItem* item : qAsConst(it.value())) {
switch (it.key()) {
case Events::Intersects : {
QList<const IWorldItem*> result;
for (const IWorldItem *object : qAsConst(_objects)) {
if (item != object && item->intersects(*object)) {
result.append(object);
}
}
if (result.size()) {
emit sigIntersect(item, result);
}
break;
}
default: {
QuasarAppUtils::Params::log("Not supported event", QuasarAppUtils::Error);
}
}
}
}
}
void EventServer::addToSupportedEvents(const IWorldItem * obj, int event) {
if (obj->isSopportEvent(event)) {
_supportedEvents[event].insert(obj->guiId(), obj);
};
}
void EventServer::renderLoop() {
while (_renderLoop) {
quint64 currentTime = QDateTime::currentMSecsSinceEpoch();
if (!_oldTimeRender) {
_oldTimeRender = currentTime;
continue;
}
eventProcess();
int waitTime = 100 - currentTime + _oldTimeRender;
_oldTimeRender = currentTime;
if (waitTime > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
}
}
}

View File

@ -0,0 +1,77 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include <QFuture>
#include <QObject>
#include <Crawl/diff.h>
#include <QMultiHash>
#ifndef EVENTSERVER_H
#define EVENTSERVER_H
namespace CRAWL {
class IWorldItem;
class IWorld;
/**
* @brief The EventServer class process all game events.
* This class process all game events on the separate thread and do not change the game objects. All signal of the events return constant object pointers.
*/
class EventServer: public QObject
{
Q_OBJECT
public:
EventServer(IWorld * instance);
~EventServer();
/**
* @brief start This method start a processing og the objects events.
*/
void start();
/**
* @brief stop This method stop the processing of the objects.
*/
void stop();
public slots:
/**
* @brief handleAvailableObjectChanges This slots handle all changes of the world.
* @param diff This is changes on the world.
*/
void handleAvailableObjectChanges(const Diff& diff);
signals:
/**
* @brief sigIntersect This signal emit when objects intersect on the world.
* @param trigger This is pointer to object that support this evvent.
* @param objects This is list of the intersects objects.
*/
void sigIntersect(const IWorldItem* trigger, QList<const IWorldItem*> objects);
private:
void eventProcess();
void addToSupportedEvents(const IWorldItem *obj, int event);
void renderLoop();
IWorld * _worldInstance = nullptr;
QHash<int, const IWorldItem*> _objects;
QHash<int, QHash<int, const IWorldItem*>> _supportedEvents;
QList<int> _supportedEventsKeys;
QFuture<void> _renderLoopFuture;
bool _renderLoop = false;
quint64 _oldTimeRender = 0;
};
}
#endif // EVENTSERVER_H

View File

@ -0,0 +1,46 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "asyncimageresponse.h"
#include "imageprovider.h"
#include <QQuickImageResponse>
#include <QtConcurrent>
ImageProvider::ImageProvider() = default;
ImageProvider::~ImageProvider() = default;
#define IgnoreQFuture(x) x.isRunning()
QQuickImageResponse *ImageProvider::requestImageResponse(const QString &id,
const QSize &requestedSize) {
AsyncImageResponse* response = new AsyncImageResponse();
auto readImage = [id, requestedSize, response]() mutable {
Q_UNUSED(requestedSize);
auto params = id.split("/");
if (params.contains("player")) {
response->setResult(QImage(":/img/defaultuser").
scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
} else if (params.contains("item")) {
response->setResult(QImage(":/img/defaultsnake").
scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
} else {
response->error("Wrong first parametr example 'first/last'");
}
};
IgnoreQFuture(QtConcurrent::run(readImage));
return response;
}

View File

@ -0,0 +1,26 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef IMAGEPROVIDER_H
#define IMAGEPROVIDER_H
#include <QQuickAsyncImageProvider>
#include <QPixmap>
class ImageProvider: public QQuickAsyncImageProvider
{
private:
public:
explicit ImageProvider();
~ImageProvider() override;
QQuickImageResponse *requestImageResponse(const QString &id,
const QSize &requestedSize) override;
};
#endif // IMAGEPROVIDER_H

View File

@ -0,0 +1,54 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include <listviewmodel.h>
#include "availablelevelsmodel.h"
#include "mainmenumodel.h"
#include "settingsviewmodel.h"
#include "storeviewmodel.h"
#include <quasarapp.h>
namespace CRAWL {
MainMenuModel::MainMenuModel(QObject *ptr): QObject (ptr) {
_conf = QuasarAppUtils::Settings::instance();
_userSettingsModel = new SettingsViewModel(this);
_storeView = new StoreViewModel();
_selectLevelModle = new AvailableLevelsModel();
}
MainMenuModel::~MainMenuModel() {
delete _storeView;
delete _selectLevelModle;
}
QObject *MainMenuModel::userSettingsModel() const {
return _userSettingsModel;
}
bool MainMenuModel::getVisible() const {
return visible;
}
void MainMenuModel::setVisible(bool newVisible) {
if (visible == newVisible)
return;
visible = newVisible;
emit visibleChanged();
}
QObject *MainMenuModel::storeView() const {
return _storeView;
}
QObject *MainMenuModel::selectLevelModle() const {
return _selectLevelModle;
}
}

View File

@ -0,0 +1,87 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef NETWORKPROFILEMAINMODEL_H
#define NETWORKPROFILEMAINMODEL_H
#include <QObject>
#include "settings.h"
namespace ViewSolutions {
class ListViewModel;
}
namespace CRAWL {
class WorldInfo;
class StoreViewModel;
class AvailableLevelsModel;
/**
* @brief The MainMenuModel class This is main class for controll user interface
*/
class MainMenuModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* userSettingsModel READ userSettingsModel NOTIFY userSettingsModelChanged)
Q_PROPERTY(bool visible READ getVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(QObject * storeView READ storeView NOTIFY storeViewChanged)
Q_PROPERTY(QObject * selectLevelModle READ selectLevelModle NOTIFY selectLevelModleChanged)
public:
MainMenuModel(QObject *ptr = nullptr);
~MainMenuModel();
/**
* @brief userSettingsModel This method return pointer to the setting model.
* @return This is pointer to setting model.
*/
QObject* userSettingsModel() const;
/**
* @brief getVisible This method return visible property of the main game menu.
* @return true if the menu is visble.
*/
bool getVisible() const;
/**
* @brief setVisible This method will change visible of the main menu.
* @param newVisible This is new vlaue of the visible.
*/
void setVisible(bool newVisible);
/**
* @brief storeView This method return pointer to store view model
* @return pointer to store view model
*/
QObject *storeView() const;
/**
* @brief selectLevelModle This method return pointer to the available levels model.
* @return pointer to main available levels model.
*/
QObject *selectLevelModle() const;
signals:
void userSettingsModelChanged(QObject* userSettingsModel);
void visibleChanged();
void storeViewChanged();
void selectLevelModleChanged();
private:
Settings *_conf = nullptr;
QObject* _userSettingsModel = nullptr;
bool visible = true;
StoreViewModel *_storeView = nullptr;
AvailableLevelsModel *_selectLevelModle = nullptr;
};
}
#endif // NETWORKPROFILEMAINMODEL_H

View File

@ -0,0 +1,42 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "pluginloader.h"
#include <QLibrary>
#include <quasarapp.h>
typedef IWorld* (*worldInstance)();
PluginLoader::PluginLoader() {
}
IWorld* PluginLoader::load(const QString &pluginPath) {
QLibrary lib(pluginPath);
if (!lib.load()) {
QuasarAppUtils::Params::log("Fail to load game module. Message: " + lib.errorString(),
QuasarAppUtils::Error);
return nullptr;
}
worldInstance worldFunc = (worldInstance)lib.resolve("worldInstance");
if (!worldFunc) {
QuasarAppUtils::Params::log("Fail to load game module."
" Message: Failed to find a instance function in the %0 module",
QuasarAppUtils::Error);
lib.unload();
return nullptr;
}
return worldFunc();
}

View File

@ -0,0 +1,31 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef PLUGINLOADER_H
#define PLUGINLOADER_H
#include <QString>
class IWorld;
/**
* @brief The PluginLoader class This class load shared objects like a plugins.
*/
class PluginLoader {
public:
PluginLoader();
/**
* @brief load This method load a plugin game module.
* @param pluginPath Path to so or dll plugin file.
* @return Snake WorldInstance;
* @note The plugin shiold be implement instance function and if you youse Windows systems marked as a DLL_EXPORT symbol.
*/
static IWorld* load(const QString& pluginPath);
};
#endif // PLUGINLOADER_H

View File

@ -0,0 +1,8 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "settings.h"

View File

@ -0,0 +1,16 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef SNAKESETTINGS_H
#define SNAKESETTINGS_H
#include <quasarapp.h>
#define THEME "THEME_GUI"
#define THEME_DEFAULT 0
using Settings = QuasarAppUtils::Settings;
#endif // SNAKESETTINGS_H

View File

@ -0,0 +1,39 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "settingsviewmodel.h"
#include <QSettings>
#include "settings.h"
void SettingsViewModel::handleValueChanged(QString key, QVariant value) {
if (key == THEME) {
emit themeChanged(value.toInt());
}
}
SettingsViewModel::SettingsViewModel(QObject *ptr):
QObject (ptr) {
_cfg = Settings::instance();
connect(_cfg, &Settings::valueChanged, this , &SettingsViewModel::handleValueChanged);
}
int SettingsViewModel::theme() const {
return _cfg->getValue(THEME, THEME_DEFAULT).toInt();
}
void SettingsViewModel::forceUpdate() {
emit themeChanged(0);
}
void SettingsViewModel::toDefault() {
setTheme(THEME_DEFAULT);
}
void SettingsViewModel::setTheme(int theme) {
_cfg->setValue(THEME, theme);
}

View File

@ -0,0 +1,41 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef SETTINGSVIEWMODEL_H
#define SETTINGSVIEWMODEL_H
#include <QObject>
#include "settings.h"
class SettingsViewModel: public QObject
{
Q_OBJECT
Q_PROPERTY(int theme READ theme WRITE setTheme NOTIFY themeChanged)
private:
Settings *_cfg = nullptr;
private slots:
void handleValueChanged(QString key, QVariant value);
public:
SettingsViewModel(QObject* ptr = nullptr);
int theme() const;
Q_INVOKABLE void forceUpdate();
Q_INVOKABLE void toDefault();
public slots:
void setTheme(int theme);
signals:
void themeChanged(int theme);
};
#endif // SETTINGSVIEWMODEL_H

View File

@ -0,0 +1,54 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "store.h"
#include <Crawl/iitem.h>
namespace CRAWL {
Store::Store()
{
}
bool Store::buy(User &buyer, int itemId) {
auto item = getItemById(itemId);
if (buyer.getTier() < item->requiredTier()) {
return false;
}
if (buyer.getMoney() < item->cost()) {
return false;
}
buyer.setMoney(buyer.getMoney() - item->cost());
buyer.unclokItem(itemId);
return true;
}
bool Store::init(const QMultiHash<int, const IItem *> &availabelItems) {
_store = availabelItems;
return true;
}
const IItem *Store::getItemById(int id) const {
return _store.value(id, nullptr);
}
int Store::size() const {
return _store.size();
}
QList<int> Store::keysList() const {
return QList<int>{_store.keyBegin(), _store.keyEnd()};
}
}

View File

@ -0,0 +1,64 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef STORE_H
#define STORE_H
#include "user.h"
namespace CRAWL {
class IItem;
/**
* @brief The Store class contains method for control all game items beetwin users.
*/
class Store
{
public:
Store();
/**
* @brief buy This method unlock the item with @a itemId for @a buyer. The
* @param buyer This is user that will be buy item with @a itemId id.
* @param itemId This is id of the item that @a buyer will be buy
* @return true if the deal gas been completed successfully
*/
bool buy(User& buyer, int itemId);
/**
* @brief init This method initialise store of the game.
* @param availabelItems This is hash of the available item.
* @return true if the items inited successfuly else false.
*/
bool init(const QMultiHash<int, const IItem *> &availabelItems);
/**
* @brief getItemById This method return item by id.
* @param id This is id of the required item.
* @return pointer to item. if The item with @a id not found then return nullptr.
*/
const IItem* getItemById(int id) const;
/**
* @brief size This method return count of the available items in store.
* @return count of the available items.
*/
int size() const;
/**
* @brief keysList This method return a list of available keys
* @return a list of available keys
*/
QList<int> keysList() const;
private:
QMultiHash<int, const IItem*> _store;
};
}
#endif // STORE_H

View File

@ -0,0 +1,32 @@
#include "storeviewmodel.h"
#include "store.h"
#include "user.h"
#include <Crawl/iitem.h>
namespace CRAWL {
StoreViewModel::StoreViewModel() {
}
void StoreViewModel::init(Store *store, User *user) {
setUser(user);
setStore(store);
setKeys(store->keysList());
}
void StoreViewModel::buy(int item) {
if (store() && getUser()) {
store()->buy(*getUser(), item);
}
}
const IItem *StoreViewModel::getItem(int id) const {
if (!store())
return nullptr;
return store()->getItemById(id);
}
}

View File

@ -0,0 +1,49 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef STOREVIEWMODEL_H
#define STOREVIEWMODEL_H
#include "baseuserlistmodel.h"
namespace CRAWL {
class Store;
class User;
/**
* @brief The StoreViewModel class This is view model of the store. The object of this class should be initialized it he Store class.
*/
class StoreViewModel: public BaseUserListModel
{
Q_OBJECT
public:
StoreViewModel();
/**
* @brief init This method initialize data of the view model.
* @param _store This is poiter to store that contains all inforamtion about store items.
* @param user This is new pointer to current user.
* @see StoreViewModel::setUser
*/
void init(Store * store, User* user);
/**
* @brief buy This is qml method for receive signal from view about buying item.
* @param item This is item id that user want to buy.
*/
Q_INVOKABLE void buy(int item);
// BaseUserListModel interface
protected:
const IItem *getItem(int id) const;
};
}
#endif // STOREVIEWMODEL_H

View File

@ -0,0 +1,80 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "targetdirection.h"
namespace CRAWL {
TargetDirection::TargetDirection(float velosityMagnitude,
float velosityMagnitudeVariation,
bool velosityNormalized,
const QVector3D &velosityTargetPosition,
const QVector3D &velosityTargetPositionVariation,
QObject *parent):
ViewTemaplateModel("qrc:/CrawlModule/particles/CrawlTargetDirection.qml", parent)
{
setVelosityMagnitude(velosityMagnitude);
setVelosityMagnitudeVariation(velosityMagnitudeVariation);
setVelosityNormalized(velosityNormalized);
setVelosityTargetPosition(velosityTargetPosition);
setVelosityTargetPositionVariation(velosityTargetPositionVariation);
}
float TargetDirection::velosityMagnitude() const {
return _velosityMagnitude;
}
void TargetDirection::setVelosityMagnitude(float newVelosityMagnitude) {
if (qFuzzyCompare(_velosityMagnitude, newVelosityMagnitude))
return;
_velosityMagnitude = newVelosityMagnitude;
emit velosityMagnitudeChanged();
}
float TargetDirection::velosityMagnitudeVariation() const {
return _velosityMagnitudeVariation;
}
void TargetDirection::setVelosityMagnitudeVariation(float newVelosityMagnitudeVariation) {
if (qFuzzyCompare(_velosityMagnitudeVariation, newVelosityMagnitudeVariation))
return;
_velosityMagnitudeVariation = newVelosityMagnitudeVariation;
emit velosityMagnitudeVariationChanged();
}
bool TargetDirection::velosityNormalized() const {
return _velosityNormalized;
}
void TargetDirection::setVelosityNormalized(bool newVelosityNormalized) {
if (_velosityNormalized == newVelosityNormalized)
return;
_velosityNormalized = newVelosityNormalized;
emit velosityNormalizedChanged();
}
const QVector3D &TargetDirection::velosityTargetPosition() const {
return _velosityTargetPosition;
}
void TargetDirection::setVelosityTargetPosition(const QVector3D &newVelosityTargetPosition) {
if (_velosityTargetPosition == newVelosityTargetPosition)
return;
_velosityTargetPosition = newVelosityTargetPosition;
emit velosityTargetPositionChanged();
}
const QVector3D &TargetDirection::velosityTargetPositionVariation() const {
return _velosityTargetPositionVariation;
}
void TargetDirection::setVelosityTargetPositionVariation(const QVector3D &newVelosityTargetPositionVariation) {
if (_velosityTargetPositionVariation == newVelosityTargetPositionVariation)
return;
_velosityTargetPositionVariation = newVelosityTargetPositionVariation;
emit velosityTargetPositionVariationChanged();
}
}

View File

@ -0,0 +1,191 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "Crawl/viewtemaplatemodel.h"
#include <QVector3D>
#include "global.h"
#ifndef TARGETDIRECTION_H
#define TARGETDIRECTION_H
namespace CRAWL {
/**
* @brief The TargetDirection class.
* This element sets emitted particle velocity towards the target position.
* For example, to emit particles towards position (100, 0, 0) with random magnitude between 10..20:
* @code
TargetDirection {
position: Qt.vector3d(100, 0, 0)
normalized: true
magnitude: 15.0
magnitudeVariation: 5.0
}
}
@endcode
* @note This class use the CrawlTargetDirection.qml template as a view temaplate.
*/
class TargetDirection: public ViewTemaplateModel
{
Q_OBJECT
/**
* @brief velosityMagnitude This property defines the magnitude in position change per second.
* Negative magnitude accelerates the opposite way from the position.
* When the normalized is false, this is multiplied with the distance to the target position.
* The default value is 1.0.
*/
Q_PROPERTY(float velosityMagnitude READ velosityMagnitude WRITE setVelosityMagnitude NOTIFY velosityMagnitudeChanged)
/**
* @brief velosityMagnitudeVariation This property defines the magnitude variation in position change per second.
* When the normalized is false, this is multiplied with the distance to the target position.
* The default value is 0.0.
*/
Q_PROPERTY(float velosityMagnitudeVariation READ velosityMagnitudeVariation WRITE setVelosityMagnitudeVariation NOTIFY velosityMagnitudeVariationChanged)
/**
* @brief velosityNormalized This property defines if the distance to position should be considered as normalized or not.
* When this is false, distance to the position affects the magnitude of the particles velocity.
* When set to true, distance is normalized and velocity amount comes only from magnitude and magnitudeVariation.
* The default value is false.
*/
Q_PROPERTY(bool velosityNormalized READ velosityNormalized WRITE setVelosityNormalized NOTIFY velosityNormalizedChanged)
/**
* @brief velosityTargetPosition This property defines the position for particles target.
* The default value is (0, 0, 0) (the center of the emitter).
*/
Q_PROPERTY(QVector3D velosityTargetPosition READ velosityTargetPosition WRITE setVelosityTargetPosition NOTIFY velosityTargetPositionChanged)
/**
* @brief velosityTargetPositionVariation This property defines the position variation for particles target.
* The default value is (0, 0, 0) (no variation).
*/
Q_PROPERTY(QVector3D velosityTargetPositionVariation READ velosityTargetPositionVariation WRITE setVelosityTargetPositionVariation NOTIFY velosityTargetPositionVariationChanged)
public:
TargetDirection(float velosityMagnitude = 1,
float velosityMagnitudeVariation = 0,
bool velosityNormalized = false,
const QVector3D& velosityTargetPosition = {0,0,0},
const QVector3D& velosityTargetPositionVariation = {0,0,0},
QObject * parent = nullptr);
/**
* @brief velosityMagnitude This property defines the magnitude in position change per second.
* Negative magnitude accelerates the opposite way from the position.
* When the normalized is false, this is multiplied with the distance to the target position.
* The default value is 1.0.
* @return current value of the velosityMagnitude property
*/
float velosityMagnitude() const;
/**
* @brief setVelosityMagnitude This method sets new value of the ParticleEffect::velosityMagnitude property.
* @param newVelosityMagnitude This is a new value of the ParticleEffect::velosityMagnitude property
* @note This property will be workd only after invoke the useTargetVelosity method.
*/
void setVelosityMagnitude(float newVelosityMagnitude);
/**
* @brief velosityMagnitudeVariation This property defines the magnitude variation in position change per second.
* When the normalized is false, this is multiplied with the distance to the target position.
* The default value is 0.0.
* @return current value of the velosityMagnitudeVariation property
*/
float velosityMagnitudeVariation() const;
/**
* @brief setVelosityMagnitudeVariation This method sets new value of the ParticleEffect::velosityMagnitudeVariation property.
* @param newVelosityMagnitudeVariation This is a new value of the ParticleEffect::velosityMagnitudeVariation property
* @note This property will be workd only after invoke the useTargetVelosity method.
*/
void setVelosityMagnitudeVariation(float newVelosityMagnitudeVariation);
/**
* @brief velosityNormalized This property defines if the distance to position should be considered as normalized or not.
* When this is false, distance to the position affects the magnitude of the particles velocity.
* When set to true, distance is normalized and velocity amount comes only from magnitude and magnitudeVariation.
* The default value is false.
* @return current value of the velosityNormalized property
*/
bool velosityNormalized() const;
/**
* @brief setVelosityNormalized This method sets new value of the ParticleEffect::velosityNormalized property.
* @param newVelosityNormalized This is a new value of the ParticleEffect::velosityNormalized property
* @note This property will be workd only after invoke the useTargetVelosity method.
*/
void setVelosityNormalized(bool newVelosityNormalized);
/**
* @brief velosityTargetPosition This property defines the position for particles target.
* The default value is (0, 0, 0) (the center of the emitter).
* @return current value of the velosityNormalized property
*/
const QVector3D &velosityTargetPosition() const;
/**
* @brief setVelosityTargetPosition This method sets new value of the ParticleEffect::velosityTargetPosition property.
* @param newVelosityTargetPosition This is a new value of the ParticleEffect::velosityTargetPosition property
* @note This property will be workd only after invoke the useTargetVelosity method.
*/
void setVelosityTargetPosition(const QVector3D &newVelosityTargetPosition);
/**
* @brief velosityTargetPositionVariation This property defines the position variation for particles target.
* The default value is (0, 0, 0) (no variation).
* @return current value of the velosityTargetPositionVariation property
*/
const QVector3D &velosityTargetPositionVariation() const;
/**
* @brief setVelosityTargetPositionVariation This method sets new value of the ParticleEffect::velosityTargetPositionVariation property.
* @param newVelosityTargetPositionVariation This is a new value of the ParticleEffect::velosityTargetPositionVariation property
* @note This property will be workd only after invoke the useTargetVelosity method.
*/
void setVelosityTargetPositionVariation(const QVector3D &newVelosityTargetPositionVariation);
signals:
/**
* @brief velosityMagnitudeChanged This signal emited when the velosityMagnitude property changed.
*/
void velosityMagnitudeChanged();
/**
* @brief velosityMagnitudeVariationChanged This signal emited when the velosityMagnitudeVariation property changed.
*/
void velosityMagnitudeVariationChanged();
/**
* @brief velosityNormalizedChanged This signal emited when the velosityNormalized property changed.
*/
void velosityNormalizedChanged();
/**
* @brief velosityTargetPositionChanged This signal emited when the velosityTargetPosition property changed.
*/
void velosityTargetPositionChanged();
/**
* @brief velosityTargetPositionVariationChanged This signal emited when the velosityTargetPositionVariation property changed.
*/
void velosityTargetPositionVariationChanged();
private:
float _velosityMagnitude = 1;
float _velosityMagnitudeVariation = 0;
bool _velosityNormalized = false;
QVector3D _velosityTargetPosition = {};
QVector3D _velosityTargetPositionVariation = {};
};
}
#endif // TARGETDIRECTION_H

View File

@ -0,0 +1,124 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "user.h"
namespace CRAWL {
constexpr float tierMul = 1.2;
constexpr int firstTierCount = 10;
/// @private
template <int N>
struct Tiers
{
enum { value = static_cast<const int>(tierMul * Tiers<N - 1>::value)};
};
/// @private
template <>
struct Tiers<0>
{
enum { value = 0 };
};
/// @private
template <>
struct Tiers<1>
{
enum { value = firstTierCount };
};
// End Tiers table
constexpr int maximumTear = 100;
#define T(X) Tiers<X>::value
constexpr int tiersTable[maximumTear] = {T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9),
T(10), T(11), T(12), T(13), T(14), T(15), T(16), T(17), T(18), T(19),
T(20), T(21), T(22), T(23), T(24), T(25), T(26), T(27), T(28), T(29),
T(30), T(31), T(32), T(33), T(34), T(35), T(36), T(37), T(38), T(39),
T(40), T(41), T(42), T(43), T(44), T(45), T(46), T(47), T(48), T(49),
T(50), T(51), T(52), T(53), T(54), T(55), T(56), T(57), T(58), T(59),
T(60), T(61), T(62), T(63), T(64), T(65), T(66), T(67), T(68), T(69),
T(70), T(71), T(72), T(73), T(74), T(75), T(76), T(77), T(78), T(79),
T(80), T(81), T(82), T(83), T(84), T(85), T(86), T(87), T(88), T(89),
T(90), T(91), T(92), T(93), T(94), T(95), T(96), T(97), T(98), T(99)};
User::User() {
}
const QSet<int> &User::unlockedItems() const {
return _unlockedItems;
}
bool User::isUnlocked(int item) const {
return _unlockedItems.contains(item);
}
void User::unclokItem(int item) {
_unlockedItems.insert(item);
emit sigUnlcoked(item);
}
void User::droppItem(int item) {
_unlockedItems.remove(item);
emit sigDropped(item);
}
void User::setUnlockedItems(const QSet<int> &newUnlockedItems) {
_unlockedItems = newUnlockedItems;
emit sigUlockedItemsChanged(newUnlockedItems);
}
int User::recalcTier() {
int _tier = 0;
while (getXp() > tiersTable[_tier]) {
_tier++;
}
return _tier;
}
void User::setTier(int tier) {
if (_tier == tier)
return;
_tier = tier;
emit tierChanged();
}
int User::getXp() const {
return _xp;
}
void User::setXp(int newXp) {
if (_xp == newXp)
return;
_xp = newXp;
setTier(recalcTier());
emit xpChanged();
}
int User::getTier() {
return _tier;
}
int User::getMoney() const {
return _money;
}
void User::setMoney(int newMoney) {
if (_money == newMoney)
return;
_money = newMoney;
emit moneyChanged();
}
}

View File

@ -0,0 +1,192 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include <QSet>
#include <QObject>
#ifndef USER_H
#define USER_H
namespace CRAWL {
/**
* @brief The User class This is internal class for collection all user data and user state.
*/
class User : public QObject
{
Q_OBJECT
/**
* @brief money This current user money count. An user can buy and sell game items using own money amount.
* @see User::setMoney
* @see User::getMoney
*/
Q_PROPERTY(int money READ getMoney WRITE setMoney NOTIFY moneyChanged)
/**
* @brief xp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
* @see User::setXp
* @see User::getXp
* @see User::tier
* @see User::getTier
*/
Q_PROPERTY(int xp READ getXp WRITE setXp NOTIFY xpChanged)
/**
* @brief tier This us user tier. This value automaticaly generated by cuuren user experience count.
* @see User::xp
* @see User::getXp
* @see User::getTier
*/
Q_PROPERTY(int tier READ getTier NOTIFY tierChanged)
public:
User();
/**
* @brief getMoney This current user money count. An user can buy and sell game items using own money amount.
* @return current value of the User::money property
* @see User::setMoney
* @see User::money
*/
int getMoney() const;
/**
* @brief setMoney This method sets new value of the user money amount.
* @param newMoney this is new value of users money.
* @see User::getMoney
* @see User::money
*/
void setMoney(int newMoney);
/**
* @brief getXp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
* @return current user xpereans.
* @see User::setXp
* @see User::getXp
* @see User::tier
* @see User::getTier
*/
int getXp() const;
/**
* @brief setXp This method sets new value of the user experience.
* @param newXp This is new value of the users experience.
* @note This method can be change the User::tier property
* @see User::xp
* @see User::getXp
* @see User::tier
* @see User::getTier
*/
void setXp(int newXp);
/**
* @brief getTier This us user tier. This value automaticaly generated by cuuren user experience count.
* @return current value of the users tier.
* @see User::xp
* @see User::getXp
* @see User::tier
*/
int getTier();
/**
* @brief unlockedItems This method return set of the unlocked items of this user.
* @return Set of the unlocked items of this user.
* @see User::unclokItem
* @see User::unlockedItems
* @see User::droppItem
* @see User::isUnlocked
* @see User::setUnlockedItems
*/
const QSet<int> &unlockedItems() const;
/**
* @brief isUnlocked This method check if the @a item is unlocked for this user.
* @param item This is id of the checked item.
* @return true if the item is uncloked else false.
* @see User::unclokItem
* @see User::unlockedItems
* @see User::droppItem
* @see User::isUnlocked
* @see User::setUnlockedItems
*/
bool isUnlocked(int item) const;
/**
* @brief unclokItem This method unclok the @a item for current user.
* @param item This is id of item that need to unclok.
* @see User::unclokItem
* @see User::unlockedItems
* @see User::droppItem
* @see User::isUnlocked
* @see User::setUnlockedItems
*/
void unclokItem(int item);
/**
* @brief droppItem This method dropp item from user.
* @param item This is id of the dropped item
* @see User::unclokItem
* @see User::unlockedItems
* @see User::droppItem
* @see User::isUnlocked
* @see User::setUnlockedItems
*/
void droppItem(int item);
signals:
void moneyChanged();
void tierChanged();
void xpChanged();
/**
* @brief sigUlockedItemsChanged This signal emited when users list of unclode items is changed..
* @param unclokedItems This is unlocked items set. Each items in the set is id of the unclocked item.
*/
void sigUlockedItemsChanged(const QSet<int> & unclokedItems);
/**
* @brief sigUnlcoked This signal emmited when user unlock one item.
* @param item This is unlocked item id.
* @see User::unclokItem
*/
void sigUnlcoked(int item);
/**
* @brief sigDropped This signal emmited when user dropped one item.
* @param item This is dpopped item id.
* @see User::droppItem
*/
void sigDropped(int item);
protected:
/**
* @brief setUnlockedItems This method sets new set of uncloked items
* @param newUnlockedItems This is new set of the uncloked items
* @see User::unclokItem
* @see User::unlockedItems
* @see User::droppItem
* @see User::isUnlocked
* @see User::setUnlockedItems
*/
void setUnlockedItems(const QSet<int> &newUnlockedItems);
private:
int recalcTier();
void setTier(int tier);
int _money = 0;
int _xp = 0;
int _tier = 0;
QSet<int> _unlockedItems;
};
}
#endif // USER_H

View File

@ -0,0 +1,44 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "vectordirection.h"
namespace CRAWL {
VectorDirection::VectorDirection(const QVector3D &direction,
const QVector3D &directionValatility,
QObject *parent):
ViewTemaplateModel("qrc:/CrawlModule/particles/CrawlVectorDirection.qml", parent) {
setVelosityDirection(direction);
setVelosityDirectionValatility(directionValatility);
}
const QVector3D &VectorDirection::velosityDirection() const {
return _velosityDirection;
}
void VectorDirection::setVelosityDirection(const QVector3D &newVelosityDirection) {
if (_velosityDirection == newVelosityDirection)
return;
_velosityDirection = newVelosityDirection;
emit velosityDirectionChanged();
}
const QVector3D &VectorDirection::velosityDirectionValatility() const {
return _velosityDirectionValatility;
}
void VectorDirection::setVelosityDirectionValatility(const QVector3D &newVelosityDirectionValatility) {
if (_velosityDirectionValatility == newVelosityDirectionValatility)
return;
_velosityDirectionValatility = newVelosityDirectionValatility;
emit velosityDirectionValatilityChanged();
}
}

View File

@ -0,0 +1,99 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef VECTORDIRECTION_H
#define VECTORDIRECTION_H
#include "Crawl/viewtemaplatemodel.h"
#include <QVector3D>
#include "global.h"
namespace CRAWL {
/**
* @brief The VectorDirection class.
* This element sets emitted particle velocity towards the target direction vector.
* The length of the direction vector is used as the velocity magnitude.
* For example, to emit particles towards some random direction within x: 50..150, y: -20..20, z: 0:
* @code
* VectorDirection {
direction: Qt.vector3d(100, 0, 0)
directionVariation: Qt.vector3d(50, 20, 0)
}
@endcode
*
* @note This class use the CrawlVectorDirection.qml template as a view temaplate.
*/
class VectorDirection: public ViewTemaplateModel
{
Q_OBJECT
/**
* @brief velosityDirection this property defines the direction for particles target.
* The default value is (0, 100, 0) (upwards on the y-axis).
*/
Q_PROPERTY(QVector3D velosityDirection READ velosityDirection WRITE setVelosityDirection NOTIFY velosityDirectionChanged)
/**
* @brief velosityDirectionValatility This property defines the direction variation for particles target.
* The default value is (0, 0, 0) (no variation).
*/
Q_PROPERTY(QVector3D velosityDirectionValatility READ velosityDirectionValatility WRITE setVelosityDirectionValatility NOTIFY velosityDirectionValatilityChanged)
public:
VectorDirection(const QVector3D& direction = {},
const QVector3D& directionValatility = {},
QObject * parent = nullptr);
/**
* @brief velosityDirection this property defines the direction for particles target.
* The default value is (0, 100, 0) (upwards on the y-axis).
* @return current value of the velosityDirection property
*/
const QVector3D &velosityDirection() const;
/**
* @brief setVelosityDirection This method sets new value of the ParticleEffect::velosityDirection property.
* @param newVelosityDirection This is a new value of the ParticleEffect::velosityDirection property
* @note This property will be workd only after invoke the useDirectionVelosity method.
*/
void setVelosityDirection(const QVector3D &newVelosityDirection);
/**
* @brief velosityDirectionValatility This property defines the direction variation for particles target.
* The default value is (0, 0, 0) (no variation).
* @return current value of the velosityDirectionValatility property
*/
const QVector3D &velosityDirectionValatility() const;
/**
* @brief setVelosityDirectionValatility This method sets new value of the ParticleEffect::velosityDirectionValatility property.
* @param newVelosityDirectionValatility This is a new value of the ParticleEffect::velosityDirectionValatility property
* @note This property will be workd only after invoke the useDirectionVelosity method.
*/
void setVelosityDirectionValatility(const QVector3D &newVelosityDirectionValatility);
signals:
/**
* @brief velosityDirectionChanged This signal emited when the velosityDirection property changed.
*/
void velosityDirectionChanged();
/**
* @brief velosityDirectionValatilityChanged This signal emited when the velosityDirectionValatility property changed.
*/
void velosityDirectionValatilityChanged();
private:
QVector3D _velosityDirection = {};
QVector3D _velosityDirectionValatility = {};
};
}
#endif // VECTORDIRECTION_H

View File

@ -0,0 +1,9 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "worldstatus.h"

View File

@ -0,0 +1,35 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef WORLDSTATUS_H
#define WORLDSTATUS_H
#include <QObject>
/**
* @brief The WorldStatus enum This enum contains statuses of the world.
* @note This statuses available only internal in main engine library.
*/
namespace WorldStatus
{
Q_NAMESPACE // required for meta object creation
/**
* @brief The WorldStatus enum This enum contains statuses of the world.
* @note This statuses available only internal in main engine library.
*/
enum Status {
/// Undefined status. Using by default
Undefined = 0,
/// World with this status emit random control signals for the player object fir emulate game session of the AI.
Background,
/// World with this status show hame control menu and listem player signals.
Game
};
Q_ENUM_NS(Status) // register the enum in meta object data
}
#endif // WORLDSTATUS_H

View File

@ -16,7 +16,7 @@ bool init() {
}
QString version() {
return ButterflyEngine_VERSION;
return BUTTERFLY_ENGINE_VERSION;
}

View File

@ -16,12 +16,12 @@ namespace ButterflyEngine {
* @brief init main initialize method of The ButterflyEngine library
* @return true if library initialized successfull
*/
bool ButterflyEngine_EXPORT init();
bool BUTTERFLY_ENGINE_EXPORT init();
/**
* @brief version This method return string value of a library version
* @return string value of a library version
*/
QString ButterflyEngine_EXPORT version();
QString BUTTERFLY_ENGINE_EXPORT version();
};

View File

@ -0,0 +1,110 @@
# Extension concept
The extension it is separate module class with custom function.
## How to use
1. Create own child class from IRender interface.
2. Override the IRender::render method of base interface
3. Check compatibility betwin this type and requred type using the IRender::checkminimumRequariedType method.
4. In the render method using dynamic_cast operator get neede interface of class object.
5. Implement needed functions for object.
## Example:
Movable object header:
```cpp
class CRAWL_EXPORT MovableObject: public virtual IRender
{
public:
MovableObject();
void render(unsigned int tbfMsec) override;
const QVector3D &movableVector() const;
void setMovableVector(const QVector3D &newMovableVector);
float angularVelocity() const;
void setAngularVelocity(float newAngularVelocity);
float breakingForce() const;
void setBreakingForce(float newBreakingForce);
private:
QVector3D _movableVector;
QVector3D _currentMovableVector;
float _angularVelocity = 0;
float _breakingForce = 0;
};
```
Movable object source:
```cpp
MovableObject::MovableObject()
{
}
void MovableObject::render(unsigned int tbfMsec) {
auto _this = checkminimumRequariedType<IWorldItem>();
// get object center position
QVector3D currentPosition = _this->position();
// move object to vector
currentPosition += (_currentMovableVector * (tbfMsec / 1000.0));
_this->setposition(currentPosition);
// calc temp vector betvin user moveble vector and real moveble vector
QVector3D tempVector = _movableVector - _currentMovableVector ;
// calc change on this iteration for new moveble vector
float delta = std::min(_angularVelocity * (tbfMsec / 1000.0), static_cast<double>(tempVector.length()));
// resize temp vector for calc changes of the movableVector
tempVector = tempVector.normalized() * delta;
// recalc new currentMovable vector (applay changes)
_currentMovableVector += tempVector;
float newMovableVectorLength = std::max(_movableVector.length() - (_breakingForce * (tbfMsec / 1000.0)), 0.0);
// update movable vector
_movableVector = _movableVector.normalized() * newMovableVectorLength;
}
const QVector3D &MovableObject::movableVector() const {
return _movableVector;
}
void MovableObject::setMovableVector(const QVector3D &newMovableVector) {
_movableVector = newMovableVector;
}
float MovableObject::angularVelocity() const {
return _angularVelocity;
}
void MovableObject::setAngularVelocity(float newAngularVelocity) {
_angularVelocity = newAngularVelocity;
}
float MovableObject::breakingForce() const {
return _breakingForce;
}
void MovableObject::setBreakingForce(float newBreakingForce) {
_breakingForce = newBreakingForce;
}
```

View File

@ -0,0 +1,39 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "autogenerateclaster.h"
namespace CRAWL {
AutoGenerateClaster::AutoGenerateClaster() {
}
void AutoGenerateClaster::generateItems() {
for (unsigned int count = itemsCount(); count > 0; count--) {
if (!_factory) {
QuasarAppUtils::Params::log("Please use the registerItemType method"
" before invoke parent constructor.",
QuasarAppUtils::Error);
return;
}
add(factory());
}
}
ClasterItem *AutoGenerateClaster::factory() const {
if (!_factory) {
QuasarAppUtils::Params::log("Please use the registerBodyitem method"
" before invoke parent constructor.",
QuasarAppUtils::Error);
return nullptr;
}
return _factory();
}
}

View File

@ -0,0 +1,65 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef AUTOGENERATECLASTER_H
#define AUTOGENERATECLASTER_H
#include "claster.h"
namespace CRAWL {
/**
* @brief The AutoGenerateClaster class hs support the registration default claster item class and factory method for the items.
*/
class CRAWL_EXPORT AutoGenerateClaster: public Claster
{
public:
AutoGenerateClaster();
/**
* @brief itemsCount This method sould be return count of the registered items on the claster object.
* @return items count of the child objects.
*/
virtual unsigned int itemsCount() const = 0;
template<class Type>
/**
* @brief registerItemType This method register claster item type. Items will be generated in the generateItems method. The size of body companents calc from the itemsCount property.
*/
void registerItemType() {
_factory = [](){
return new Type;
};
}
protected:
/**
* @brief generateItems This method invoked after iit object on the world and generate list of the default claster items.
* @note This method should be invked after initialized of this object.
*/
virtual void generateItems();
/**
* @brief factory This method create new item of the claster. See the registerItemType for get more information.
* @return return new item of the claster item. If the object not registered return nullptr.
*/
ClasterItem *factory() const;
/**
* @brief isClasterItemRegistered
* @return tru if the class is registered.
*/
bool isClasterItemRegistered() const;
private:
std::function<ClasterItem*()> _factory = nullptr;
};
}
#endif // AUTOGENERATECLASTER_H

View File

@ -0,0 +1,32 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "basemotion.h"
#include "Crawl/guiobject.h"
namespace CRAWL {
BaseMotion::BaseMotion() {
}
const QQuaternion &BaseMotion::staticRotation() const {
return _staticRotation;
}
void BaseMotion::setStaticRotation(const QQuaternion &newStaticRotation) {
_staticRotation = newStaticRotation;
}
void BaseMotion::render(unsigned int tbfMsec) {
if (auto _this = checkminimumRequariedType<GuiObject>()) {
renderPosition(_this, tbfMsec);
renderRotation(_this, tbfMsec);
}
}
}

View File

@ -0,0 +1,72 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef BASEMOTION_H
#define BASEMOTION_H
#include "Crawl/irender.h"
#include <QQuaternion>
namespace CRAWL {
class GuiObject;
/**
* @brief The BaseMotion class contains base functions of the motion.
* For Create your own motion alghoritm you need to override two methods:
* * renderPosition
* * renderRotation
*
*/
class CRAWL_EXPORT BaseMotion : public virtual IRender
{
public:
BaseMotion();
// IRender interface
public:
void render(unsigned int tbfMsec);
/**
* @brief staticRotation This method retur nstatic rotation in quaternion. The static rotation rotate object to setted value independet then movable vector.
* @return quterion of the static rotation
*/
const QQuaternion &staticRotation() const;
/**
* @brief setStaticRotation This metho sets new value of the static rotation of this object.
* @param newStaticRotation new value of the static rotation.
* @note if you want use eilor angles then use the QQuaternion::fromEulerAngles method.
* @note See the staticRotation method for get more information.
*/
void setStaticRotation(const QQuaternion &newStaticRotation);
protected:
/**
* @brief renderRotation This method recalc raration for an @a object. The Default do nothing.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
virtual void renderRotation(GuiObject* object, unsigned int tbfMsec) = 0;
/**
* @brief renderRotation This method recalc position for an @a object.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
virtual void renderPosition(GuiObject* object, unsigned int tbfMsec) = 0;
private:
QQuaternion _staticRotation = QQuaternion::fromEulerAngles(0,0,0);
};
}
#endif // BASEMOTION_H

View File

@ -0,0 +1,77 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "circularmotion.h"
#include <Crawl/guiobject.h>
#include "cmath"
namespace CRAWL {
CircularMotion::CircularMotion(const QVector3D *center) {
_center = center;
}
void CircularMotion::render(unsigned int tbfMsec) {
if (auto _this = checkminimumRequariedType<GuiObject>()) {
renderPosition(_this, tbfMsec);
renderRotation(_this, tbfMsec);
}
}
float CircularMotion::angularVelocity() const {
return _angularVelocity;
}
void CircularMotion::setAngularVelocity(float newAngularVelocity) {
_angularVelocity = newAngularVelocity;
}
const QVector3D &CircularMotion::axis() const {
return _axis;
}
void CircularMotion::setAxis(const QVector3D &newAxis) {
_axis = newAxis;
}
float CircularMotion::radius() const {
return _radius;
}
void CircularMotion::setRadius(float newRadius) {
_radius = newRadius;
}
double CircularMotion::anglePosition() const {
return _angle;
}
void CircularMotion::setAnglePosition(double newAngle) {
_angle = newAngle;
}
void CircularMotion::renderRotation(GuiObject *object,
unsigned int ) {
object->setRotation(QQuaternion::rotationTo({1.0f, 0.0, 0.0}, *_center) * staticRotation());
}
void CircularMotion::renderPosition(GuiObject *object,
unsigned int tbfMsec) {
if (!_center)
return;
double motionCoef = 360 / (2 * M_PI * radius());
_angle += motionCoef * angularVelocity() * (tbfMsec / 1000.f);
auto normal = (QQuaternion::fromAxisAndAngle(_axis, _angle) * QVector3D{0,0,1}).normalized();
object->setposition(*_center + normal * radius());
}
}

View File

@ -0,0 +1,106 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef CIRCULARMOTION_H
#define CIRCULARMOTION_H
#include <Extensions/basemotion.h>
#include <QVector3D>
namespace CRAWL {
class GuiObject;
/**
* @brief The CircularMotion class. This class contains render function for the moving guiobject by round.
* @note For motion set motion asix and angular velocity
*/
class CRAWL_EXPORT CircularMotion: public BaseMotion
{
public:
CircularMotion(const QVector3D* center);
// IRender interface
public:
void render(unsigned int tbfMsec) override;
/**
* @brief angularVelocity This is property are speed of motion.
* @return current speed of the motion object.
*/
float angularVelocity() const;
/**
* @brief setAngularVelocity This method sets new value of the current speed of the object.
* @param newAngularVelocity This is new value of the motion speed
*/
void setAngularVelocity(float newAngularVelocity);
/**
* @brief axis This method are asix of motion. This object will moving around this axis.
* @return curretn asix value.
*/
const QVector3D &axis() const;
/**
* @brief setAxis This method sets new value of the motion axis.
* @param newAxis This is new value of the motion asix.
*/
void setAxis(const QVector3D &newAxis);
/**
* @brief radius This method return current radius of the circular motion
* @return current radius
*/
float radius() const;
/**
* @brief setRadius This method sets new value of the circular motion radius.
* @param newRadius This is new value of the circular motion radius.
*/
void setRadius(float newRadius);
/**
* @brief anglePosition This method return current angel of the item position arountd center.
* @return current angle position around center.
*/
double anglePosition() const;
/**
* @brief setAnglePosition This method sets new angel of the item position arountd center.
* @return newAngle angle position around center.
*/
void setAnglePosition(double newAngle);
protected:
/**
* @brief renderRotation This method recalc raration for an @a object. The Default implementation rotate object to center.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
void renderRotation(GuiObject* object, unsigned int) override;
/**
* @brief renderRotation This method recalc position for an @a object. The Default implementation move the current object around center.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
void renderPosition(GuiObject* object, unsigned int tbfMsec) override;
private:
float _angularVelocity = 0;
QVector3D _axis;
const QVector3D *_center = nullptr;
float _radius;
double _angle = 0;
};
}
#endif // CIRCULARMOTION_H

View File

@ -0,0 +1,41 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "claster.h"
#include "Crawl/singleclasterworlditem.h"
namespace CRAWL {
Claster::Claster() {}
Claster::~Claster() {
for (auto child : qAsConst(_objects)) {
if (auto obj = dynamic_cast<ClasterItem*>(child))
obj->removeClaster(this);
}
}
void Claster::add(ClasterItem *object) {
_objects.insert(object->guiId(), object);
if (auto singlClasterObject = dynamic_cast<ClasterItem*>(object)) {
singlClasterObject->setClaster(this);
}
}
void Claster::remove(ClasterItem *object) {
_objects.remove(object->guiId());
}
void Claster::remove(int id) {
_objects.remove(id);
}
const QHash<int, ClasterItem *> &Claster::objects() const {
return _objects;
}
}

View File

@ -0,0 +1,61 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef CLASTER_H
#define CLASTER_H
#include "Crawl/iworlditem.h"
namespace CRAWL {
class ClasterItem;
/**
* @brief The Claster class are object with support multiple objects render.
* For example snake with 20 points of the snake blocks.
* @note The claster object is extansion for the IWorldItems objects.
*/
class CRAWL_EXPORT Claster
{
public:
Claster();
virtual ~Claster();
/**
* @brief add This method added new object to claster.
* @param object This is model of added object
* @note if you want you can override this methods for extend functionality of this class.
*/
virtual void add(ClasterItem* object);
/**
* @brief remove This method remove object from claster
* @param object poiter of removed object
*/
virtual void remove(ClasterItem* object);
/**
* @brief remove some as a Claster::remove(IWorldItem* object) but by id.
* @param id of the remved object.
*/
virtual void remove(int id);
/**
* @brief objects This method return list of collected objects.
* @return return const reference to objects list .
*/
const QHash<int, ClasterItem*> &objects() const;
private:
QHash<int, ClasterItem*> _objects;
};
}
#endif // CLASTER_H

View File

@ -0,0 +1,94 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "movableobject.h"
#include <math.h>
#include <Crawl/guiobject.h>
namespace CRAWL {
MovableObject::MovableObject() {
}
void MovableObject::render(unsigned int tbfMsec) {
if (auto _this = checkminimumRequariedType<GuiObject>()) {
renderPosition(_this, tbfMsec);
renderRotation(_this, tbfMsec);
}
}
const QVector3D &MovableObject::movableVector() const {
return _movableVector;
}
void MovableObject::setMovableVector(const QVector3D &newMovableVector) {
_movableVector = newMovableVector;
}
float MovableObject::angularVelocity() const {
return _angularVelocity;
}
void MovableObject::setAngularVelocity(float newAngularVelocity) {
_angularVelocity = newAngularVelocity;
}
float MovableObject::breakingForce() const {
return _breakingForce;
}
void MovableObject::setBreakingForce(float newBreakingForce) {
_breakingForce = newBreakingForce;
}
void MovableObject::renderRotation(GuiObject *object, unsigned int) {
if (_currentMovableVector.length() > 0) {
object->setRotation(QQuaternion::rotationTo({1.0f, 0.0, 0.0}, _currentMovableVector) * staticRotation());
}
}
void MovableObject::renderPosition(GuiObject *object, unsigned int tbfMsec) {
// get object center position
QVector3D currentPosition = object->position();
// move object to vector
currentPosition += (_currentMovableVector * (tbfMsec / 1000.0));
object->setposition(currentPosition);
// calc temp vector betvin user moveble vector and real moveble vector
QVector3D tempVector = _movableVector - _currentMovableVector ;
// calc change on this iteration for new moveble vector
float delta = 0.0;
if (_angularVelocity <= 0) {
delta = tempVector.length();
} else {
delta = std::min(_angularVelocity * (tbfMsec / 1000.0), static_cast<double>(tempVector.length()));
}
// resize temp vector for calc changes of the movableVector
tempVector = tempVector.normalized() * delta;
// recalc new currentMovable vector (applay changes)
_currentMovableVector += tempVector;
float newMovableVectorLength = std::max(_movableVector.length() - (_breakingForce * (tbfMsec / 1000.0)), 0.0);
// update movable vector
_movableVector = _movableVector.normalized() * newMovableVectorLength;
}
const QVector3D &MovableObject::currentMovableVector() const {
return _currentMovableVector;
}
}

View File

@ -0,0 +1,116 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef MOVABLEOBJECT_H
#define MOVABLEOBJECT_H
#include "Extensions/basemotion.h"
#include <QQuaternion>
#include <QVector3D>
namespace CRAWL {
class GuiObject;
/**
* @brief The MovableObject class contains functions for moving object on the world.
* All moving separate to next properties:
*
* * **Movable vector** This property sets direction of move
* * **Movable vector force** This is force of the movable vector.
* * **Angular velocity** This property sets spead of the angle moving.
* * **Braking force** This property are delta decriment the Power of the movable vector on time.
*/
class CRAWL_EXPORT MovableObject: public BaseMotion
{
public:
MovableObject();
/**
* @brief render This impplementation of the render method add simulation of the physics in the vacuum space.
* @param tbfMsec This is time betwin frames argument.
*/
void render(unsigned int tbfMsec) override;
/**
* @brief movableVector This method return current mvable vector.
* The movable vector it is second point of line betwin object center and movableVector point.
* The movableVector base on own releative asix system wher the object center is vector {0 0 0}
* @note So movableVector are 3d angle of the moving of this object.
* @return movable vector of object
*/
const QVector3D &movableVector() const;
/**
* @brief setMovableVector This method sets new value of the mvable vector.
* @param newMovableVector this is a new value ofthe movable vector
* @note The movable vector will be changed in time if you set the MovableObject::breakingForce property to non 0 value.
*/
void setMovableVector(const QVector3D &newMovableVector);
/**
* @brief angularVelocity This method return current angular veloscity.
* @return angular velosity
* @note This property contains speed on angle per second (a/s)
*/
float angularVelocity() const;
/**
* @brief setAngularVelocity This method sets new value of the angular velacity in angele per second
* @param newAngularVelocity This is new value of the angular velacity
*/
void setAngularVelocity(float newAngularVelocity);
/**
* @brief breakingForce This method return current value of the breaking force.
* @return urrent value of the breaking force
*/
float breakingForce() const;
/**
* @brief setBreakingForce This method sets new value of the breaking force.
* @param newBreakingForce This is new value of the breaking force
*/
void setBreakingForce(float newBreakingForce);
/**
* @brief currentMovableVector This method return current movable vector.
* @return current movable vector.
*/
const QVector3D &currentMovableVector() const;
protected:
/**
* @brief renderRotation This method recalc raration for an @a object. The Default implementation converts movableVector to rotation of an @a object.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
void renderRotation(GuiObject* object, unsigned int tbfMsec) override;
/**
* @brief renderRotation This method recalc position for an @a object. The Default implementation move the current movable vector to setts movable vector. For example if you invoke the MovableObject::setMovableVector method then object change current movable vector with spead MovableObject::angularVelocity. If you sets
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
void renderPosition(GuiObject* object, unsigned int tbfMsec) override;
private:
QVector3D _movableVector;
QVector3D _currentMovableVector;
QQuaternion _staticRotation = QQuaternion::fromEulerAngles(0,0,0);
float _angularVelocity = 0;
float _breakingForce = 0;
};
}
#endif // MOVABLEOBJECT_H

View File

@ -0,0 +1,28 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "rotationaroundaxis.h"
#include <Crawl/guiobject.h>
namespace CRAWL {
RotationAroundAxis::RotationAroundAxis(): CircularMotion(nullptr) {
}
void RotationAroundAxis::renderRotation(GuiObject *object, unsigned int tbfMsec) {
setAnglePosition(anglePosition() + angularVelocity() * (tbfMsec / 1000.0f));
object->setRotation(QQuaternion::fromAxisAndAngle(axis(), angularVelocity()));
}
void RotationAroundAxis::renderPosition(GuiObject *, unsigned int ) {
}
}

View File

@ -0,0 +1,34 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef ROTATIONAROUNDAXIS_H
#define ROTATIONAROUNDAXIS_H
#include "circularmotion.h"
namespace CRAWL {
/**
* @brief The RotationAroundAxis class This class provide the rotation of our axis
*/
class RotationAroundAxis: public CircularMotion
{
public:
RotationAroundAxis();
// BaseMotion interface
protected:
void renderRotation(GuiObject *object, unsigned int tbfMsec) override;
void renderPosition(GuiObject *object, unsigned int tbfMsec) override;
};
}
#endif // ROTATIONAROUNDAXIS_H

View File

@ -0,0 +1,32 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "affector.h"
namespace CRAWL {
Affector::Affector(const QString &name,
const QString &viewTempalte,
QObject *ptr) :
IWorldItem(name, viewTempalte, ptr)
{
}
bool Affector::enabled() const {
return _enabled;
}
void Affector::setEnabled(bool newEnabled) {
if (_enabled == newEnabled)
return;
_enabled = newEnabled;
emit enabledChanged();
}
}

View File

@ -0,0 +1,79 @@
#ifndef AFFECTOR_H
#define AFFECTOR_H
#include "iworlditem.h"
namespace CRAWL {
/**
* @brief The Affector class is an abstract base class of affectors like Gravity3D, Wander3D, and PointRotator3D. By default affectors affect all particles in the system,
* but this can be limited by defining the particles list.
* If the system has multiple affectors, the order of affectors may result in different outcome, as affectors are applied one after another.
*
* For custumisation your own Affectors you need to change the templateView qml file for your own class.
* @note For get more inforamtion about available qml affectors see the qt documentation [page](https://doc.qt.io/qt-6.1/qml-qtquick3d-particles3d-affector3d.html)
**Example of qml view file**
@code
Attractor3D {
property var model: null
property int guiId: (model) ? model.guiId : -1;
rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
scale: (model)? model.size: Qt.vector3d(0, 0, 0);
position: (model) ? model.position: Qt.vector3d(0,0,0);
visible: (model)? model.visible: false
enabled: (model)? model.enabled: false
positionVariation: Qt.vector3d(50, 50, 50)
duration: 3000
durationVariation: 1000
}
@endcode
*/
class CRAWL_EXPORT Affector : public IWorldItem
{
Q_OBJECT
/**
* @brief enabled if enabled is set to false, this affector will not alter any particles. Usually this is used to conditionally turn an affector on or off.
The default value is true.
*/
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
Affector(const QString& name,
const QString& viewTempalte = DEFAULT_VIEW_TEMPLATE,
QObject *ptr = nullptr);
/**
* @brief enabled if enabled is set to false, this affector will not alter any particles. Usually this is used to conditionally turn an affector on or off.
The default value is true.
* @return true if the Affector is enabled else false.
*/
bool enabled() const;
/**
* @brief setEnabled This method enable or disable the affector object.
* @param newEnabled new value.
*/
void setEnabled(bool newEnabled);
signals:
/**
* @brief enabledChanged This signal emited when the object change own enabled status.
*/
void enabledChanged();
private:
bool _enabled = true;
};
}
#endif // AFFECTOR_H

View File

@ -0,0 +1,43 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "Extensions/claster.h"
#include "clasteritem.h"
namespace CRAWL {
ClasterItem::ClasterItem(const QString &name,
const QString &viewTempalte,
QObject *ptr):
IWorldItem(name, viewTempalte, ptr) {
}
ClasterItem::~ClasterItem() {
for (auto claster : qAsConst(_parentClasters)) {
claster->remove(this);
}
}
int ClasterItem::parentClastersCount() const {
return _parentClasters.size();
}
void ClasterItem::setClaster(Claster *claster) {
_parentClasters += claster;
}
void ClasterItem::removeClaster(Claster *claster) {
_parentClasters -= claster;
}
const QSet<Claster *> &ClasterItem::parentClasters() const {
return _parentClasters;
}
}

View File

@ -0,0 +1,65 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "iworlditem.h"
#include <QSet>
#ifndef CLASTERITEM_H
#define CLASTERITEM_H
namespace CRAWL {
class Claster;
/**
* @brief The ClasterItem class This is item of the claster object. Thi class can be used as a one element of the claster class.
* @note This object invoke the Claster::remove method in destructor.
*/
class CRAWL_EXPORT ClasterItem: public IWorldItem
{
Q_OBJECT
public:
ClasterItem(const QString& name,
const QString& viewTempalte = DEFAULT_VIEW_TEMPLATE,
QObject *ptr = nullptr);
~ClasterItem();
/**
* @brief parentClastersCount This method return count of the parent clasters.
* @return parent clasters count
*/
int parentClastersCount() const;
protected:
/**
* @brief setClaster invoked when object added to new claster.
* @param claster pointer to invoker claster object.
*/
virtual void setClaster(Claster *claster);
/**
* @brief removeClaster
* @param claster
*/
virtual void removeClaster(Claster *claster);
/**
* @brief parentClasters return current parent clasters list;
* @return
*/
const QSet<Claster *> &parentClasters() const;
private:
QSet<Claster*> _parentClasters;
friend class Claster;
};
}
#endif // CLASTERITEM_H

View File

@ -0,0 +1,95 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "clientapp.h"
#include "imageprovider.h"
#include "iworld.h"
#include "mainmenumodel.h"
#include <QCoreApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <quasarapp.h>
#include <store.h>
#include <engine.h>
#include <qmlnotifyservice.h>
#include <QStandardPaths>
#include <QDir>
#include "pluginloader.h"
#include <viewsolutions.h>
#include "worldstatus.h"
#include "user.h"
namespace CRAWL {
QByteArray ClientApp::initTheme() {
int themeIndex = Settings::instance()->getValue(THEME, THEME_DEFAULT).toInt();
switch (themeIndex) {
case 1: return "Dark";
default: return "Light";
}
}
ClientApp::ClientApp() {
_engine = new Engine();
}
ClientApp::~ClientApp() {
delete _engine;
}
bool ClientApp::init(QQmlApplicationEngine *engine) {
qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", initTheme());
qputenv("QT_QUICK_CONTROLS_STYLE", "Material");
auto root = engine->rootContext();
if (!root)
return false;
engine->addImageProvider(QLatin1String("userItems"), new ImageProvider());
root->setContextProperty("engine", QVariant::fromValue(_engine));
qmlRegisterUncreatableMetaObject(
WorldStatus::staticMetaObject,
"engine.worldstatus",
1, 0,
"WorldStatus",
"Error: only enums");
initCrawlResources();
engine->addImportPath(":/CrawlModule/");
if (!QmlNotificationService::init(engine)) {
return false;
}
if (!ViewSolutions::init(engine)) {
return false;
}
engine->load("qrc:/CrawlModule/Crawl.qml");
if (engine->rootObjects().isEmpty())
return false;
_engine->init();
return true;
}
void ClientApp::addLvl(ILevel *levelWordl) {
_engine->addLvl(levelWordl);
}
}

View File

@ -0,0 +1,74 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef CLIENTAPP_H
#define CLIENTAPP_H
#include <QByteArray>
#include <QFileInfo>
#include <QStringList>
#include "global.h"
#include "ilevel.h"
class QQmlApplicationEngine;
inline void initCrawlResources() { Q_INIT_RESOURCE(Crawl); }
namespace CRAWL {
class Engine;
class IWorld;
class MainMenuModel;
class IControl;
class Store;
/**
* @brief The ClientApp class This is main class of the Game engine.
*/
class CRAWL_EXPORT ClientApp : public QObject
{
Q_OBJECT
public:
ClientApp();
~ClientApp() override;
/**
* @brief init This method initialize engine on application.
* @param engine This is qml engine instance object.
* @return true if all initialize successful
*/
bool init(QQmlApplicationEngine* engine);
template<class LevelType>
/**
* @brief registerLevel This method register new levels in game.
*/
void registerLevel() {
static_assert(std::is_base_of_v<ILevel, LevelType>,
"Plrease use the child classes of the ILevel interface for tegistering new levels in the crawl game.");
addLvl(new LevelType());
}
private:
QByteArray initTheme();
/**
* @brief addLvl This method should be add level to game.
* @param levelWordl This is world instance
*/
void addLvl(ILevel* levelWordl);
Engine *_engine = nullptr;
};
}
#endif // CLIENTAPP_H

View File

@ -0,0 +1,10 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "day.h"

View File

@ -0,0 +1,189 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DAY_H
#define DAY_H
#include "Extensions/claster.h"
#include "dayitem.h"
#include "iworlditem.h"
#include "math.h"
namespace CRAWL {
template <class Sun, class Moon>
/**
* @brief The Day class is template wrapper for the moon and sun objects.
* The moon and sun objects moving around world center for imitation of the day.
*
* ### Integration on the world.
* You need to add one object of this class in the IWorld::initWorldRules method.
* **Example:**
*
* ```cpp
* CRAWL::WorldRule *World::initWorldRules() {
using Day = CRAWL::Day<CRAWL::Sun, CRAWL::Moon>;
return new CRAWL::WorldRule {
{0, {
{registerObject<Day>(), 1},
}
},
{1000, {
{registerObject<Day>(), 1},
}
},
};
}
* ```
* @note All objects will be moving around this objects with radius. The Radius by default is 1000.
* @note This class automaticly sets ligth force for the light objects.
*
*
*/
class Day: public IWorldItem, public Claster
{
public:
Day(): IWorldItem(AUTO_CLASS_NAME) {
static_assert(std::is_base_of_v<DayItem, Sun>,
"The Day class can be works only with DayItem child classes");
DayItem* sun = new Sun(&position());
DayItem* moon = new Moon(&position());
sun->setAnglePosition(0);
moon->setAnglePosition(180);
add(sun);
add(moon);
}
void render(unsigned int ) override {
setposition(getPlayer()->position() + QVector3D{0, 0, 0});
}
void add(ClasterItem *object) override {
if (auto item = dynamic_cast<DayItem*>(object)) {
item->setRadius(radius());
item->setAxis(_axis);
item->setAngularVelocity(lengthToSpeed(_dayLengthSec));
item->setLightForce(lengthForce());
Claster::add(item);
} else {
QuasarAppUtils::Params::log("The Day class can works only with "
" Child classes of the DayItem",
QuasarAppUtils::Error);
}
};
void remove(ClasterItem *object) override {
Claster::remove(object);
};
/**
* @brief radius This method return radius of the motion day objects.
* @return radius of the motions
*/
int radius() const {
return _radius;
}
/**
* @brief setRadius This method sets new value of the motions radius.
* @param newRadius This is new value o fthe motion.
*/
void setRadius(int newRadius) {
if (newRadius == _radius)
return;
_radius = newRadius;
for (auto object: objects()) {
reinterpret_cast<DayItem*>(object)->setLightForce(lengthForce());
reinterpret_cast<DayItem*>(object)->setRadius(_radius);
}
}
/**
* @brief axis This is sxis of rotation. all objects will be moving around this axis. The axis is general 3d vector object.
* @return rotation axis.
* @note By default it is y axis
*/
const QVector3D &axis() const {
return _axis;
}
/**
* @brief setAxis This method sets new value of the rotation axis. For get more information see the axis method.
* @param newAxis This is new value of the rotation axis.
*/
void setAxis(const QVector3D &newAxis) {
if (newAxis == _axis)
return;
_axis = newAxis;
for (auto object: objects()) {
reinterpret_cast<DayItem*>(object)->setAxis(_axis);
}
}
/**
* @brief dayLengthSec This method return length of the game day in real secs.
* @note by default this value is 360 sec
* @return length of the game day in real secs.
*/
float dayLengthSec() const {
return _dayLengthSec;
}
/**
* @brief setDayLengthSec This method sets new value of the day length.
* @param newDayLongSec This is new value of the day length.
* @note For get more information see the dayLengthSec method.
*/
void setDayLengthSec(float newDayLengthSec) {
if (newDayLengthSec == _dayLengthSec)
return;
_dayLengthSec = newDayLengthSec;
for (auto object: objects()) {
reinterpret_cast<DayItem*>(object)->setAngularVelocity(lengthToSpeed(_dayLengthSec));
}
}
private:
float lengthToSpeed(float length) const {
return (2 * M_PI * radius()) / length;
}
float lengthForce() const {
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
return _radius * 0.1;
#else
return _radius * 15;
#endif
}
int _radius = 1000;
float _dayLengthSec = 360;
QVector3D _axis = {1,0,0};
};
}
#endif // DAY_H

View File

@ -0,0 +1,29 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "dayitem.h"
namespace CRAWL {
DayItem::DayItem(
const QVector3D* center,
const QString &name,
const QString &viewTempalte,
QObject *ptr):
IWorldLight(name, viewTempalte, ptr),
CircularMotion(center) {
}
void DayItem::render(unsigned int tbfMsec) {
CircularMotion::render(tbfMsec);
setVisible(position().z() > 0);
}
}

View File

@ -0,0 +1,29 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DAYITEM_H
#define DAYITEM_H
#include "iworldlight.h"
#include "Extensions/circularmotion.h"
namespace CRAWL {
/**
* @brief The DayItem class This is base class of the sun of moon of anther movable around center objects.
*/
class DayItem: public IWorldLight, public CircularMotion {
Q_OBJECT
public:
DayItem(const QVector3D* center,
const QString& name,
const QString& viewTempalte = "qrc:/CrawlModule/DayLight.qml",
QObject *ptr = nullptr);
void render(unsigned int tbfMsec);
};
}
#endif // DAYITEM_H

View File

@ -0,0 +1,19 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "defaultcontrol.h"
namespace CRAWL {
DefaultControl::DefaultControl() {
}
QString DefaultControl::initQmlView() const {
return "qrc:/CrawlModule/DefaultMenu.qml";
}
}

View File

@ -0,0 +1,44 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DEFAULTCONTROL_H
#define DEFAULTCONTROL_H
#include "player.h"
namespace CRAWL {
/**
* @brief The DefaultControl class This class contains default implementation of the game menu.
*/
class CRAWL_EXPORT DefaultControl : public Player {
Q_OBJECT
public:
DefaultControl();
/**
* @brief initQmlView This implementation use the DefaultMenu.qml file.
* @return qrc:/CrawlModule/DefaultMenu.qml
*/
QString initQmlView() const;
signals:
/**
* @brief backToMenu Emit when user click the return to main menu button.
*/
void backToMenu();
/**
* @brief userTap Emit when user tap to screen on any position.
*/
void userTap();
};
}
#endif // DEFAULTCONTROL_H

View File

@ -0,0 +1,27 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "defaultlight.h"
namespace CRAWL {
DefaultLight::DefaultLight(): IWorldLight(AUTO_CLASS_NAME) {
setColor("#fff8e7");
setposition({10000, 0, 10000});
setRotation(QQuaternion::fromEulerAngles({-90,0,0}));
setLightForce(110);
}
void DefaultLight::render(unsigned int) {
}
void DefaultLight::init() {
}
}

View File

@ -0,0 +1,32 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DEFAULTLIGHT_H
#define DEFAULTLIGHT_H
#include "iworldlight.h"
namespace CRAWL {
/**
* @brief The DefaultLight class This is default implementation of the world light.
* This object create uniform illumination for all world.
* For integration This object yo worl see the IWorld::initWorldRules method
*/
class DefaultLight final: public IWorldLight
{
Q_OBJECT
public:
DefaultLight();
void render(unsigned int tbfMsec) override;
void init() override;
};
}
#endif // DEFAULTLIGHT_H

View File

@ -0,0 +1,21 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "diff.h"
namespace CRAWL {
QList<int> Diff::getAddedIds() const {
return addedIds;
}
QList<int> Diff::getRemoveIds() const {
return removeIds;
}
}

View File

@ -0,0 +1,35 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DIFF_H
#define DIFF_H
#include <QList>
#include <QObject>
namespace CRAWL {
class GuiObject;
/**
* @brief The Diff class contains list of the last changes on a game world.
*/
class Diff {
Q_GADGET
public:
Q_INVOKABLE QList<int> getRemoveIds() const;
Q_INVOKABLE QList<int> getAddedIds() const;
QList<int> removeIds;
QList<int> addedIds;
};
}
Q_DECLARE_METATYPE(CRAWL::Diff)
#endif // DIFF_H

View File

@ -0,0 +1,60 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "dynamicwint.h"
namespace CRAWL {
DynamicWint::DynamicWint() {
}
void DynamicWint::render(unsigned int tbfMsec) {
_time += tbfMsec;
if (_time > _nextWintChange) {
setMagnitude(_baseMagnitude + (rand() % _magnitudeVariation) - _magnitudeVariation / 2 );
setDirection(QVector3D{static_cast<float>(rand()) - rand(), static_cast<float>(rand()) - rand(), static_cast<float>(rand()) - rand()} * _directionChangeMask);
_nextWintChange += ((rand() % 100) / 100.0f) * dayLengthSec() * 1000;
}
}
int DynamicWint::dayLengthSec() const {
return _dayLengthSec;
}
void DynamicWint::setDayLengthSec(int newDayLengthSec) {
_dayLengthSec = newDayLengthSec;
}
unsigned int DynamicWint::magnitudeVariation() const {
return _magnitudeVariation;
}
void DynamicWint::setMagnitudeVariation(unsigned int newMagnitudeVariation) {
_magnitudeVariation = newMagnitudeVariation;
}
unsigned int DynamicWint::baseMagnitude() const {
return _baseMagnitude;
}
void DynamicWint::setBaseMagnitude(unsigned int newBaseMagnitude) {
_baseMagnitude = newBaseMagnitude;
}
const QVector3D &DynamicWint::directionChangeMask() const {
return _directionChangeMask;
}
void DynamicWint::setDirectionChangeMask(const QVector3D &newDirectionChangeMask) {
_directionChangeMask = newDirectionChangeMask;
}
}

View File

@ -0,0 +1,90 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef DYNAMICWINT_H
#define DYNAMICWINT_H
#include "wint.h"
namespace CRAWL {
/**
* @brief The DynamicWint class This implementation dynamicly change wint direction and magnituede per day.
*/
class CRAWL_EXPORT DynamicWint : public Wint
{
Q_OBJECT
public:
DynamicWint();
// IRender interface
public:
void render(unsigned int tbfMsec) override;
/**
* @brief dayLengthSec This method return length of the game day in real secs.
* @note by default this value is 360 sec
* @return length of the game day in real secs.
*/
int dayLengthSec() const;
/**
* @brief setDayLengthSec This method sets new value of the day length.
* @param newDayLongSec This is new value of the day length.
* @note For get more information see the dayLengthSec method.
*/
void setDayLengthSec(int newDayLengthSec);
/**
* @brief magnitudeVariation This method return curerent value of the magnitude variation.
* @return curerent value of the magnitude variation.
*/
unsigned int magnitudeVariation() const;
/**
* @brief setMagnitudeVariation This method sets magnitude variation; by default it is 10
* @param newMagnitudeVariation This is new value of the magitude
*/
void setMagnitudeVariation(unsigned int newMagnitudeVariation);
/**
* @brief baseMagnitude This method return current base magnitude of the wint. The wint will be changed dynamicly one time per day length to the magnitudeVariation
* @return curretn value of the base magnitude
*/
unsigned int baseMagnitude() const;
/**
* @brief setBaseMagnitude This method sets new value of the base magnitude of the wint.
* @param newBaseMagnitude this is new value of the base magnitude of the wint.
*/
void setBaseMagnitude(unsigned int newBaseMagnitude);
/**
* @brief directionChangeMask This method return current value of mask of the direction variation. By default the wint will be changed by x and y axis.
* @return curertn value of the directionChangeMask
*/
const QVector3D &directionChangeMask() const;
/**
* @brief setDirectionChangeMask This method sets mask of the direction variation. By default the wint will be changed by x and y axis.
* @param newDirectionChangeMask This is new value of the directionChangeMask
*/
void setDirectionChangeMask(const QVector3D &newDirectionChangeMask);
private:
int _dayLengthSec = 360;
unsigned int _nextWintChange = 0;
unsigned int _time = 0;
unsigned int _magnitudeVariation = 50;
unsigned int _baseMagnitude = 50;
QVector3D _directionChangeMask = {1, 1, 0};
};
}
#endif // DYNAMICWINT_H

View File

@ -0,0 +1,54 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "fire.h"
#include "vectordirection.h"
namespace CRAWL {
Fire::Fire(): ParticleEffect(AUTO_CLASS_NAME, "qrc:/CrawlModule/particles/Fire.qml") {
useDirectionVelosity({0, 0 , 10}, {10, 10, 0});
setParticleScale(1);
setParticleEndScale(3);
setParticleScaleVariation(3);
setLifeSpanVariation(500);
setColor("#ffaf2c");
setposition({0,0,1});
setEnabled(true);
setParticleDelegate("qrc:/CrawlModule/particles/FireParticel.qml");
setFireStrength(100);
}
void CRAWL::Fire::onIntersects(const IWorldItem *) {
}
float Fire::fireStrength() const {
return _fireStrength;
}
void Fire::setFireStrength(float newFireStrength) {
if (qFuzzyCompare(_fireStrength, newFireStrength))
return;
_fireStrength = newFireStrength;
setEmitRate(10 + _fireStrength);
setLifeSpan(1000 + _fireStrength);
auto vel = static_cast<VectorDirection*>(velocity());
vel->setVelosityDirection({0, 0 , _fireStrength / 4});
vel->setVelosityDirectionValatility({10, 10, 0});
emit fireStrengthChanged();
}
}

Some files were not shown because too many files have changed in this diff Show More