Fix samegame example to use QML modules

In this case it really makes no sense to use a shared directory because
we want to show the progressive changes between the different versions.
It's actually important to note that we're adding the pictures one by
one. Therefore, the shared directory is dissolved and the pictures added
duplicated into the respective versions of samegame.

Furthermore, moving the code into a "content" directory is a bad idea
because it complicates the import logic. We don't want to make the
"content" directory its own QML module. We might move samegame.qml into
the "content" directory, too, and apply some path wrangling to make it
work, but it's really not worth it here.

Pick-to: 6.2
Change-Id: Ifc45f48832596377c21bc6ef55e918ef487bc94e
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2021-08-30 15:46:39 +02:00
parent ea5911adbb
commit a3ea7a9938
48 changed files with 287 additions and 77 deletions

View File

@ -1,2 +1 @@
# Generated from tutorials.pro.
add_subdirectory(samegame)

View File

@ -0,0 +1,4 @@
add_subdirectory(samegame1)
add_subdirectory(samegame2)
add_subdirectory(samegame3)
add_subdirectory(samegame4)

View File

@ -57,7 +57,7 @@ Item {
Image {
id: img
anchors.fill: parent
source: "../shared/pics/redStone.png"
source: "pics/redStone.png"
}
}
//![0]

View File

@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.16)
project(samegame1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame1")
find_package(Qt6 COMPONENTS Core)
find_package(Qt6 COMPONENTS Gui)
find_package(Qt6 COMPONENTS Quick)
find_package(Qt6 COMPONENTS Qml)
qt_add_executable(samegame1
main.cpp
)
set_target_properties(samegame1 PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
qt_add_qml_module(samegame1
URI samegame
VERSION 1.0
QML_FILES
"Block.qml"
"Button.qml"
"samegame.qml"
RESOURCES
"pics/background.jpg"
"pics/redStone.png"
)
target_link_libraries(samegame1 PRIVATE
Qt::Core
Qt::Gui
Qt::Qml
Qt::Quick
)
install(TARGETS samegame1
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -48,4 +48,4 @@
**
****************************************************************************/
#include "../../../shared/shared.h"
DECLARATIVE_EXAMPLE_MAIN(samegame)
DECLARATIVE_EXAMPLE_MAIN(samegame/samegame)

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -65,7 +65,7 @@ Rectangle {
Image {
id: background
anchors.fill: parent
source: "../shared/pics/background.jpg"
source: "pics/background.jpg"
fillMode: Image.PreserveAspectCrop
}
}

View File

@ -2,10 +2,7 @@ TEMPLATE = app
QT += quick qml
SOURCES += main.cpp
RESOURCES += \
samegame1.qrc \
../shared/pics/shared.qrc
RESOURCES += samegame1.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame1
INSTALLS += target

View File

@ -1,7 +1,9 @@
<RCC>
<qresource prefix="/">
<qresource prefix="/samegame">
<file>Button.qml</file>
<file>Block.qml</file>
<file>samegame.qml</file>
<file>pics/background.jpg</file>
<file>pics/redStone.png</file>
</qresource>
</RCC>

View File

@ -56,6 +56,6 @@ Item {
Image {
id: img
anchors.fill: parent
source: "../shared/pics/redStone.png"
source: "pics/redStone.png"
}
}

View File

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.16)
project(samegame2 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame2")
find_package(Qt6 COMPONENTS Core)
find_package(Qt6 COMPONENTS Gui)
find_package(Qt6 COMPONENTS Quick)
find_package(Qt6 COMPONENTS Qml)
qt_add_executable(samegame2
main.cpp
)
set_target_properties(samegame2 PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
qt_add_qml_module(samegame2
URI samegame
VERSION 1.0
QML_FILES
"Block.qml"
"Button.qml"
"samegame.qml"
"samegame.js"
RESOURCES
"pics/background.jpg"
"pics/redStone.png"
)
target_link_libraries(samegame2 PRIVATE
Qt::Core
Qt::Gui
Qt::Qml
Qt::Quick
)
install(TARGETS samegame2
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -48,4 +48,4 @@
**
****************************************************************************/
#include "../../../shared/shared.h"
DECLARATIVE_EXAMPLE_MAIN(samegame)
DECLARATIVE_EXAMPLE_MAIN(samegame/samegame)

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -67,7 +67,7 @@ Rectangle {
Image {
id: background
anchors.fill: parent
source: "../shared/pics/background.jpg"
source: "pics/background.jpg"
fillMode: Image.PreserveAspectCrop
}
}

View File

@ -2,10 +2,7 @@ TEMPLATE = app
QT += quick qml
SOURCES += main.cpp
RESOURCES += \
samegame2.qrc \
../shared/pics/shared.qrc
RESOURCES += samegame2.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame2
INSTALLS += target

View File

@ -1,8 +1,10 @@
<RCC>
<qresource prefix="/">
<qresource prefix="/samegame">
<file>Button.qml</file>
<file>Block.qml</file>
<file>samegame.qml</file>
<file>samegame.js</file>
<file>pics/background.jpg</file>
<file>pics/redStone.png</file>
</qresource>
</RCC>

View File

@ -62,11 +62,11 @@ Item {
anchors.fill: parent
source: {
if (type == 0)
return "../shared/pics/redStone.png";
return "pics/redStone.png";
else if (type == 1)
return "../shared/pics/blueStone.png";
return "pics/blueStone.png";
else
return "../shared/pics/greenStone.png";
return "pics/greenStone.png";
}
}
}

View File

@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 3.16)
project(samegame3 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame3")
find_package(Qt6 COMPONENTS Core)
find_package(Qt6 COMPONENTS Gui)
find_package(Qt6 COMPONENTS Quick)
find_package(Qt6 COMPONENTS Qml)
qt_add_executable(samegame3
main.cpp
)
set_target_properties(samegame3 PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
qt_add_qml_module(samegame3
URI samegame
VERSION 1.0
QML_FILES
"Block.qml"
"Button.qml"
"Dialog.qml"
"samegame.qml"
"samegame.js"
RESOURCES
"pics/background.jpg"
"pics/blueStone.png"
"pics/greenStone.png"
"pics/redStone.png"
)
target_link_libraries(samegame3 PRIVATE
Qt::Core
Qt::Gui
Qt::Qml
Qt::Quick
)
install(TARGETS samegame3
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -48,4 +48,4 @@
**
****************************************************************************/
#include "../../../shared/shared.h"
DECLARATIVE_EXAMPLE_MAIN(samegame)
DECLARATIVE_EXAMPLE_MAIN(samegame/samegame)

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -66,7 +66,7 @@ Rectangle {
Image {
id: background
anchors.fill: parent
source: "../shared/pics/background.jpg"
source: "pics/background.jpg"
fillMode: Image.PreserveAspectCrop
}

View File

@ -2,10 +2,7 @@ TEMPLATE = app
QT += quick qml
SOURCES += main.cpp
RESOURCES += \
samegame3.qrc \
../shared/pics/shared.qrc
RESOURCES += samegame3.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame3
INSTALLS += target

View File

@ -1,8 +1,13 @@
<RCC>
<qresource prefix="/">
<qresource prefix="/samegame">
<file>Button.qml</file>
<file>Block.qml</file>
<file>Dialog.qml</file>
<file>samegame.qml</file>
<file>samegame.js</file>
<file>pics/background.jpg</file>
<file>pics/blueStone.png</file>
<file>pics/greenStone.png</file>
<file>pics/redStone.png</file>
</qresource>
</RCC>

View File

@ -76,11 +76,11 @@ Item {
anchors.fill: parent
source: {
if (block.type == 0)
return "../../shared/pics/redStone.png";
return "pics/redStone.png";
else if (block.type == 1)
return "../../shared/pics/blueStone.png";
return "pics/blueStone.png";
else
return "../../shared/pics/greenStone.png";
return "pics/greenStone.png";
}
opacity: 0
@ -98,11 +98,11 @@ Item {
// ![0]
source: {
if (block.type == 0)
return "../../shared/pics/redStar.png";
return "pics/redStar.png";
else if (block.type == 1)
return "../../shared/pics/blueStar.png";
return "pics/blueStar.png";
else
return "../../shared/pics/greenStar.png";
return "pics/greenStar.png";
}
rotationVelocityVariation: 360
// ![0]

View File

@ -0,0 +1,62 @@
cmake_minimum_required(VERSION 3.16)
project(samegame4 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame4")
find_package(Qt6 COMPONENTS Core)
find_package(Qt6 COMPONENTS Gui)
find_package(Qt6 COMPONENTS Quick)
find_package(Qt6 COMPONENTS Qml)
qt_add_executable(samegame4
main.cpp
)
set_target_properties(samegame4 PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
qt_add_qml_module(samegame4
URI samegame
VERSION 1.0
QML_FILES
"BoomBlock.qml"
"Button.qml"
"Dialog.qml"
"samegame.qml"
"samegame.js"
RESOURCES
"highscores/README"
"highscores/score_data.xml"
"highscores/score_style.xsl"
"highscores/scores.php"
"pics/background.jpg"
"pics/blueStar.png"
"pics/blueStone.png"
"pics/greenStar.png"
"pics/greenStone.png"
"pics/redStar.png"
"pics/redStone.png"
)
target_link_libraries(samegame4 PRIVATE
Qt::Core
Qt::Gui
Qt::Qml
Qt::Quick
)
install(TARGETS samegame4
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -48,4 +48,4 @@
**
****************************************************************************/
#include "../../../shared/shared.h"
DECLARATIVE_EXAMPLE_MAIN(samegame)
DECLARATIVE_EXAMPLE_MAIN(samegame/samegame)

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -49,8 +49,7 @@
****************************************************************************/
import QtQuick 2.0
import "content"
import "content/samegame.js" as SameGame
import "samegame.js" as SameGame
Rectangle {
id: screen
@ -66,7 +65,7 @@ Rectangle {
Image {
id: background
anchors.fill: parent
source: "../shared/pics/background.jpg"
source: "pics/background.jpg"
fillMode: Image.PreserveAspectCrop
}

View File

@ -2,10 +2,7 @@ TEMPLATE = app
QT += quick qml
SOURCES += main.cpp
RESOURCES += \
samegame4.qrc \
../shared/pics/shared.qrc
RESOURCES += samegame4.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame4
INSTALLS += target

View File

@ -1,13 +1,20 @@
<RCC>
<qresource prefix="/">
<qresource prefix="/samegame">
<file>samegame.qml</file>
<file>content/BoomBlock.qml</file>
<file>content/Button.qml</file>
<file>content/Dialog.qml</file>
<file>content/samegame.js</file>
<file>BoomBlock.qml</file>
<file>Button.qml</file>
<file>Dialog.qml</file>
<file>samegame.js</file>
<file>highscores/README</file>
<file>highscores/score_data.xml</file>
<file>highscores/score_style.xsl</file>
<file>highscores/scores.php</file>
<file>pics/background.jpg</file>
<file>pics/blueStar.png</file>
<file>pics/blueStone.png</file>
<file>pics/greenStar.png</file>
<file>pics/greenStone.png</file>
<file>pics/redStar.png</file>
<file>pics/redStone.png</file>
</qresource>
</RCC>

View File

@ -1,13 +0,0 @@
<RCC>
<qresource prefix="/shared/pics">
<file>background.jpg</file>
<file>blueStar.png</file>
<file>blueStone.png</file>
<file>greenStar.png</file>
<file>greenStone.png</file>
<file>redStar.png</file>
<file>redStone.png</file>
<file>star.png</file>
<file>yellowStone.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -298,9 +298,6 @@ until the next chapter - where your application becomes alive!
Now we're going to do two things to liven up the game: animate the blocks and add a High Score system.
We've also cleaned up the directory structure for our application files. We now have a lot of files, so all the
JavaScript and QML files outside of \c samegame.qml have been moved into a new sub-directory named "content".
In anticipation of the new block animations, \c Block.qml file is now renamed to \c BoomBlock.qml.
\section3 Animating Block Movement
@ -311,7 +308,7 @@ In \c BoomBlock.qml, we apply a \l SpringAnimation behavior to the \c x and \c y
block will follow and animate its movement in a spring-like fashion towards the specified position (whose
values will be set by \c samegame.js).Here is the code added to \c BoomBlock.qml:
\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 1
\snippet tutorials/samegame/samegame4/BoomBlock.qml 1
The \c spring and \c damping values can be changed to modify the spring-like effect of the animation.
@ -328,7 +325,7 @@ animate the opacity value so that it gradually fades in and out, instead of abru
visible and invisible. To do this, we'll apply a \l Behavior on the \c opacity property of the \c Image
type in \c BoomBlock.qml:
\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 2
\snippet tutorials/samegame/samegame4/BoomBlock.qml 2
Note the \c{opacity: 0} which means the block is transparent when it is first created. We could set the opacity
in \c samegame.js when we create and destroy the blocks,
@ -354,14 +351,14 @@ To fade out, we set \c dying to true instead of setting opacity to 0 when a bloc
Finally, we'll add a cool-looking particle effect to the blocks when they are destroyed. To do this, we first add a \l ParticleSystem in
\c BoomBlock.qml, like so:
\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 3
\snippet tutorials/samegame/samegame4/BoomBlock.qml 3
To fully understand this you should read \l {Using the Qt Quick Particle System}, but it's important to note that \c emitRate is set
to zero so that particles are not emitted normally.
Also, we extend the \c dying State, which creates a burst of particles by calling the \c burst() method on the particles type. The code for the states now look
like this:
\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 4
\snippet tutorials/samegame/samegame4/BoomBlock.qml 4
Now the game is beautifully animated, with subtle (or not-so-subtle) animations added for all of the
player's actions. The end result is shown below, with a different set of images to demonstrate basic theming:
@ -378,20 +375,20 @@ To do this, we will show a dialog when the game is over to request the player's
This requires a few changes to \c Dialog.qml. In addition to a \c Text type, it now has a
\c TextInput child item for receiving keyboard text input:
\snippet tutorials/samegame/samegame4/content/Dialog.qml 0
\snippet tutorials/samegame/samegame4/Dialog.qml 0
\dots 4
\snippet tutorials/samegame/samegame4/content/Dialog.qml 2
\snippet tutorials/samegame/samegame4/Dialog.qml 2
\dots 4
\snippet tutorials/samegame/samegame4/content/Dialog.qml 3
\snippet tutorials/samegame/samegame4/Dialog.qml 3
We'll also add a \c showWithInput() function. The text input will only be visible if this function
is called instead of \c show(). When the dialog is closed, it emits a \c closed() signal, and
other types can retrieve the text entered by the user through an \c inputText property:
\snippet tutorials/samegame/samegame4/content/Dialog.qml 0
\snippet tutorials/samegame/samegame4/content/Dialog.qml 1
\snippet tutorials/samegame/samegame4/Dialog.qml 0
\snippet tutorials/samegame/samegame4/Dialog.qml 1
\dots 4
\snippet tutorials/samegame/samegame4/content/Dialog.qml 3
\snippet tutorials/samegame/samegame4/Dialog.qml 3
Now the dialog can be used in \c samegame.qml:
@ -401,9 +398,9 @@ When the dialog emits the \c closed signal, we call the new \c saveHighScore() f
The \c nameInputDialog is activated in the \c victoryCheck() function in \c samegame.js:
\snippet tutorials/samegame/samegame4/content/samegame.js 3
\snippet tutorials/samegame/samegame4/samegame.js 3
\dots 4
\snippet tutorials/samegame/samegame4/content/samegame.js 4
\snippet tutorials/samegame/samegame4/samegame.js 4
\section3 Storing High Scores Offline
@ -411,7 +408,7 @@ Now we need to implement the functionality to actually save the High Scores tabl
Here is the \c saveHighScore() function in \c samegame.js:
\snippet tutorials/samegame/samegame4/content/samegame.js 2
\snippet tutorials/samegame/samegame4/samegame.js 2
First we call \c sendHighScore() (explained in the section below) if it is possible to send the high scores to an online database.
@ -430,7 +427,7 @@ If the player entered their name we can send the data to the web service us
If the player enters a name, we send the data to the service using this code in \c samegame.js:
\snippet tutorials/samegame/samegame4/content/samegame.js 1
\snippet tutorials/samegame/samegame4/samegame.js 1
The \l XMLHttpRequest in this code is the same as the \c XMLHttpRequest() as you'll find in standard browser JavaScript, and can be used in the same way to dynamically get XML
or QML from the web service to display the high scores. We don't worry about the response in this case - we just post the high