summaryrefslogtreecommitdiffstats
path: root/doc/src/declarative/advtutorial2.qdoc
blob: 2aa68f3a6234a147cc36a060fd907816d40c1cb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\page advtutorial2.html
\title Advanced Tutorial 2 - Populating the Game Canvas

Now that we've written some basic elements, let's start writing the game. The
first thing to do is to generate all of the blocks. Now we need to dynamically
generate all of these blocks, because you have a new, random set of blocks
every time. As they are dynamically generated every time the new game button is
clicked, as opposed to on startup, we will be dynamically generating the blocks
in the JavaScript, as opposed to using a \l Repeater.

This adds enough script to justify a new file, \c{samegame.js}, the intial version
of which is shown below

\snippet declarative/tutorials/samegame/samegame2/samegame.js 0

The gist of this code is that we create the blocks dynamically, as many as will fit, and then store them in an array for future reference.
The \c initBoard function will be hooked up to the new game button soon, and should be fairly straight forward.

The \c createBlock function is a lot bigger, and I'll explain it block by block.
First we ensure that the component has been constructed. QML elements, including composite ones like the \c Block.qml
that we've written, are never created directly in script. While there is a function to parse and create an arbitrary QML string,
in the case where you are repeatedly creating the same item you will want to use the \c createComponent function. \c createComponent is
a built-in function in the declarative JavaScript, and returns a component object.
A component object prepares and stores a QML element (usually a composite element) for easy and efficient use.
When the component is ready, you can create a new instance of the loaded QML with the \c createObject method.
If the component is loaded remotely (over HTTP for example) then you will have to wait for the component to finish loading
before calling \c createObject. Since we don't wait here (the waiting is asyncronous, the component object will send a signal to tell
you when it's done) this code will only work if the block QML is a local file.

As we aren't waiting for the component, the next block of code creates a game block with \c{component.createObject}.
Since there could be an error in the QML file you are trying to load, success is not guaranteed.
The first bit of error checkign code comes right after \c{createObject()}, to ensure that the object loaded correctly.
If it did not load correctly the function returns false, but we don't have that hooked up to the main UI to indicate
that something has gone wrong. Instead we print out error messages to the console, because an error here means an invalid
QML file and should only happen while you are developing and testing the UI.

Next we start to set up our dynamically created block.
Because the \c{Block.qml} file is generic it needs to be placed in the main scene, and in the right place.
This is why \c parent, \c x, \c y, \c width and \c height are set. We then store it in the board array for later use.

Finally, we have some more error handling. You can only call \c{createObject} if the component has loaded.
If it has not loaded, either it is still loading or there was an error loading (such as a missing file).
Since we don't request remote files the problem is likely to be a missing or misplaced file.
Again we print this to the console to aid debugging.

You now have the code to create a field of blocks dynamically, like below:

\image declarative-adv-tutorial2.png

To hook this code up to the \e{New Game} button, you alter it as below:

\snippet declarative/tutorials/samegame/samegame2/samegame.qml 1

We have just replaced the \c{onClicked: console.log("Implement me!")} with \c{onClicked: initBoard()}.
Note that in order to have the function available, you'll need to include the script in the main file,
by adding a script element to it.

\snippet declarative/tutorials/samegame/samegame2/samegame.qml 2

With those two changes, and the script file, you are now dynamically creating a field of blocks you can play with.
They don't do anything now though; the next chapter will add the game mechanics.

[Previous: \l {Advanced Tutorial 1 - Creating the Game canvas and block}] [\l {advtutorial.html}{Advanced Tutorial}] [Next: \l {Advanced Tutorial 3 - Implementing the Game Logic}]

*/