Merge lp:~ahayzen/volleyball2d/bacon2d-10 into lp:volleyball2d/utopic

Proposed by Andrew Hayzen
Status: Merged
Approved by: Andrew Hayzen
Approved revision: 41
Merged at revision: 38
Proposed branch: lp:~ahayzen/volleyball2d/bacon2d-10
Merge into: lp:volleyball2d/utopic
Diff against target: 3206 lines (+1431/-908)
47 files modified
.bzrignore (+1/-0)
Bacon2D/qmldir (+0/-3)
Makefile (+0/-22)
deployment.pri (+9/-0)
manifest.json (+0/-15)
manifest/manifest.json.in (+15/-0)
manifest/manifest.pro (+28/-0)
scenes/FinishScene.qml (+0/-93)
scenes/MenuScene.qml (+0/-208)
tests/autopilot/run (+5/-0)
tests/autopilot/volleyball2d/__init__.py (+47/-29)
tests/autopilot/volleyball2d/test_game.py (+3/-3)
tests/autopilot/volleyball2d/test_high_score.py (+2/-2)
tests/autopilot/volleyball2d/test_main.py (+1/-1)
tests/autopilot/volleyball2d/test_menu.py (+5/-5)
tests/autopilot/volleyball2d/test_settings.py (+10/-10)
tests/unit/tst_ai_prediction.qml (+7/-8)
tests/unit/tst_game_ball.qml (+9/-9)
volleyball2d.pro (+8/-0)
volleyball2d.qmlproject (+0/-63)
volleyball2d/components/AIDebug.qml (+1/-1)
volleyball2d/components/AIPrediction.qml (+10/-8)
volleyball2d/components/Ball.qml (+13/-15)
volleyball2d/components/Character.qml (+2/-2)
volleyball2d/components/CharacterBarrier.qml (+12/-12)
volleyball2d/components/GameHeader.qml (+3/-3)
volleyball2d/components/PauseOverlay.qml (+12/-7)
volleyball2d/components/PointOverlay.qml (+13/-6)
volleyball2d/components/ScaleItem.qml (+37/-0)
volleyball2d/components/ScalePage.qml (+37/-0)
volleyball2d/components/Scoring.qml (+1/-1)
volleyball2d/components/SemiCircleEntity.qml (+23/-23)
volleyball2d/components/Wall.qml (+15/-14)
volleyball2d/fullscreen.cpp (+47/-0)
volleyball2d/fullscreen.h (+43/-0)
volleyball2d/main.cpp (+98/-0)
volleyball2d/main.qml (+73/-74)
volleyball2d/pages/FinishPage.qml (+93/-0)
volleyball2d/pages/GamePage.qml (+161/-67)
volleyball2d/pages/HighScorePage.qml (+79/-45)
volleyball2d/pages/MenuPage.qml (+210/-0)
volleyball2d/pages/RotateScreenPage.qml (+9/-2)
volleyball2d/pages/SettingsPage.qml (+194/-86)
volleyball2d/scenes/GameScene.qml (+29/-69)
volleyball2d/volleyball2d.desktop (+2/-2)
volleyball2d/volleyball2d.pro (+34/-0)
volleyball2d/volleyball2d.qrc (+30/-0)
To merge this branch: bzr merge lp:~ahayzen/volleyball2d/bacon2d-10
Reviewer Review Type Date Requested Status
Andrew Hayzen Approve
Review via email: mp+302491@code.launchpad.net

Commit message

* Bump to UC1.3
* Always enable keyboard controls
* Use bacon2d 1.0

Description of the change

* Bump to UC1.3
* Always enable keyboard controls
* Use bacon2d 1.0

To post a comment you must log in.
lp:~ahayzen/volleyball2d/bacon2d-10 updated
41. By Andrew Hayzen

* Merge of trunk

Revision history for this message
Andrew Hayzen (ahayzen) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2014-12-14 21:57:20 +0000
3+++ .bzrignore 2016-08-09 23:30:40 +0000
4@@ -1,1 +1,2 @@
5 volleyball2d.qmlproject.user
6+*.user
7
8=== removed directory 'Bacon2D'
9=== removed file 'Bacon2D/CMakeLists.txt'
10=== removed file 'Bacon2D/libbacon2dplugin.so'
11Binary files Bacon2D/libbacon2dplugin.so 2014-12-18 17:45:01 +0000 and Bacon2D/libbacon2dplugin.so 1970-01-01 00:00:00 +0000 differ
12=== removed file 'Bacon2D/qmldir'
13--- Bacon2D/qmldir 2014-12-04 00:00:55 +0000
14+++ Bacon2D/qmldir 1970-01-01 00:00:00 +0000
15@@ -1,3 +0,0 @@
16-module Bacon2D
17-plugin bacon2dplugin
18-typeinfo plugins.qmltypes
19
20=== removed file 'Makefile'
21--- Makefile 2014-12-14 21:57:20 +0000
22+++ Makefile 1970-01-01 00:00:00 +0000
23@@ -1,22 +0,0 @@
24-# More information: https://wiki.ubuntu.com/Touch/Testing
25-#
26-# Notes for autopilot tests:
27-# -----------------------------------------------------------
28-# In order to run autopilot tests:
29-# sudo apt-add-repository ppa:autopilot/ppa
30-# sudo apt-get update
31-# sudo apt-get install python-autopilot autopilot-qt
32-#############################################################
33-
34-all:
35-
36-autopilot:
37- chmod +x tests/autopilot/run
38- tests/autopilot/run
39-
40-check:
41- qmltestrunner -input tests/unit
42-
43-run:
44- /usr/bin/qmlscene $@ volleyball2d.qml
45-
46
47=== added file 'deployment.pri'
48--- deployment.pri 1970-01-01 00:00:00 +0000
49+++ deployment.pri 2016-08-09 23:30:40 +0000
50@@ -0,0 +1,9 @@
51+qt_install_libs = $$[QT_INSTALL_LIBS]
52+target.path = /lib/$$basename(qt_install_libs)/bin
53+export(target.path)
54+INSTALLS += target
55+
56+lib_copy.path = /lib/$$basename(qt_install_libs)/Bacon2D
57+lib_copy.files = /usr/lib/$$basename(qt_install_libs)/qt5/qml/Bacon2D.1.0/*
58+INSTALLS += lib_copy
59+
60
61=== added directory 'manifest'
62=== removed file 'manifest.json'
63--- manifest.json 2015-03-31 23:29:42 +0000
64+++ manifest.json 1970-01-01 00:00:00 +0000
65@@ -1,15 +0,0 @@
66-{
67- "architecture": "armhf",
68- "description": "A basic 2d volleyball game using semi-circular characters, inspired by 'Slime Volleyball'",
69- "framework": "ubuntu-sdk-14.10",
70- "hooks": {
71- "volleyball2d": {
72- "apparmor": "volleyball2d.apparmor",
73- "desktop": "volleyball2d.desktop"
74- }
75- },
76- "maintainer": "Andrew Hayzen <ahayzen@gmail.com>",
77- "name": "com.ubuntu.developer.andrew-hayzen.volleyball2d",
78- "title": "Volleyball 2D",
79- "version": "0.3.1"
80-}
81
82=== added file 'manifest/manifest.json.in'
83--- manifest/manifest.json.in 1970-01-01 00:00:00 +0000
84+++ manifest/manifest.json.in 2016-08-09 23:30:40 +0000
85@@ -0,0 +1,15 @@
86+{
87+ "architecture": "@CLICK_ARCH@",
88+ "description": "A basic 2d volleyball game using semi-circular characters, inspired by 'Slime Volleyball'",
89+ "framework": "ubuntu-sdk-15.04.5-qml",
90+ "hooks": {
91+ "volleyball2d": {
92+ "apparmor": "volleyball2d/volleyball2d.apparmor",
93+ "desktop": "volleyball2d/volleyball2d.desktop"
94+ }
95+ },
96+ "maintainer": "Andrew Hayzen <ahayzen@gmail.com>",
97+ "name": "com.ubuntu.developer.andrew-hayzen.volleyball2d",
98+ "title": "Volleyball 2D",
99+ "version": "0.4"
100+}
101
102=== added file 'manifest/manifest.pro'
103--- manifest/manifest.pro 1970-01-01 00:00:00 +0000
104+++ manifest/manifest.pro 2016-08-09 23:30:40 +0000
105@@ -0,0 +1,28 @@
106+#This creates the manifest.json file, it is the description file for the
107+#click package.
108+
109+TEMPLATE = aux
110+
111+#figure out the current build architecture
112+CLICK_ARCH=$$system(dpkg-architecture -qDEB_HOST_ARCH)
113+
114+
115+# substitute the architecture in the manifest file
116+manifest_file.output = manifest.json
117+manifest_file.CONFIG += no_link \
118+ add_inputs_as_makefile_deps\
119+ target_predeps
120+manifest_file.commands = sed s/@CLICK_ARCH@/$$CLICK_ARCH/g ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT}
121+manifest_file.input = UBUNTU_MANIFEST_FILE
122+QMAKE_EXTRA_COMPILERS += manifest_file
123+
124+#do not remove this line, it is required by the IDE even if you do
125+#not substitute variables in the manifest file
126+UBUNTU_MANIFEST_FILE = $$PWD/manifest.json.in
127+
128+#installation path of the manifest file
129+mfile.path = /
130+mfile.CONFIG += no_check_exist
131+mfile.files += $$OUT_PWD/manifest.json
132+INSTALLS+=mfile
133+
134
135=== removed file 'scenes/FinishScene.qml'
136--- scenes/FinishScene.qml 2014-12-18 14:27:43 +0000
137+++ scenes/FinishScene.qml 1970-01-01 00:00:00 +0000
138@@ -1,93 +0,0 @@
139-/*
140- * Copyright (C) 2014
141- * Andrew Hayzen <ahayzen@gmail.com>
142- *
143- * This program is free software; you can redistribute it and/or modify
144- * it under the terms of the GNU General Public License as published by
145- * the Free Software Foundation; version 3.
146- *
147- * This program is distributed in the hope that it will be useful,
148- * but WITHOUT ANY WARRANTY; without even the implied warranty of
149- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
150- * GNU General Public License for more details.
151- *
152- * You should have received a copy of the GNU General Public License
153- * along with this program. If not, see <http://www.gnu.org/licenses/>.
154- */
155-
156-import Bacon2D 1.0
157-import Ubuntu.Components 1.1
158-import QtQuick 2.3
159-
160-Scene {
161- height: parent.height
162- physics: false
163- running: false
164- viewport: Viewport {
165- }
166- width: parent.width
167-
168- property int computerScore: 0
169- property int humanScore: 0
170- property bool newHighScore: false
171- property int time: 0
172- property bool timeBased: false
173-
174- signal finishedComplete()
175-
176- MouseArea {
177- id: finishedMouseArea
178- anchors {
179- fill: parent
180- }
181- onClicked: finishedComplete()
182-
183- Rectangle {
184- anchors {
185- fill: parent
186- }
187- color: "#000"
188- opacity: .2
189- }
190-
191- Column {
192- anchors {
193- centerIn: parent
194- }
195- spacing: units.gu(2)
196-
197- Label {
198- anchors {
199- horizontalCenter: parent.horizontalCenter
200- }
201- fontSize: "x-large"
202- text: timeBased ? i18n.tr("New fastest time") + ": " + time : i18n.tr("New highest score") + ": " + humanScore
203- visible: newHighScore
204- }
205-
206- Label {
207- anchors {
208- horizontalCenter: parent.horizontalCenter
209- }
210- fontSize: "x-large"
211- text: i18n.tr("Final Score")
212- }
213-
214- Label {
215- anchors {
216- horizontalCenter: parent.horizontalCenter
217- }
218- fontSize: "large"
219- text: i18n.tr("You") + ": " + humanScore +
220- (timeBased ? " " + i18n.tr("Computer") + ": " + computerScore + " " + i18n.tr("Time") + ": " + time : "")
221- }
222-
223- Label {
224- anchors {
225- horizontalCenter: parent.horizontalCenter
226- }
227- text: i18n.tr("Tap to return to the menu")
228- }
229- }
230- }
231-}
232
233=== removed file 'scenes/MenuScene.qml'
234--- scenes/MenuScene.qml 2015-01-04 18:52:43 +0000
235+++ scenes/MenuScene.qml 1970-01-01 00:00:00 +0000
236@@ -1,208 +0,0 @@
237-/*
238- * Copyright (C) 2014
239- * Andrew Hayzen <ahayzen@gmail.com>
240- *
241- * This program is free software; you can redistribute it and/or modify
242- * it under the terms of the GNU General Public License as published by
243- * the Free Software Foundation; version 3.
244- *
245- * This program is distributed in the hope that it will be useful,
246- * but WITHOUT ANY WARRANTY; without even the implied warranty of
247- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
248- * GNU General Public License for more details.
249- *
250- * You should have received a copy of the GNU General Public License
251- * along with this program. If not, see <http://www.gnu.org/licenses/>.
252- */
253-
254-import Bacon2D 1.0
255-import Ubuntu.Components 1.1
256-import QtQuick 2.3
257-
258-
259-Scene {
260- height: parent.height
261- physics: false
262- running: false
263- viewport: Viewport {
264- }
265- width: parent.width
266-
267- signal startGame()
268-
269- Rectangle {
270- anchors {
271- fill: parent
272- }
273- color: "#000"
274- opacity: .2
275- }
276-
277- Column {
278- anchors {
279- centerIn: parent
280- }
281- spacing: units.gu(1)
282-
283- Label {
284- anchors {
285- left: mainLabel.right
286- }
287- color: "#F00"
288- fontSize: "large"
289- rotation: -20
290- text: i18n.tr("Beta") + "!"
291- }
292-
293- Label {
294- id: mainLabel
295- anchors {
296- horizontalCenter: parent.horizontalCenter
297- }
298- color: "#111"
299- fontSize: "x-large"
300- objectName: "mainLabel"
301- text: i18n.tr("Volleyball 2D")
302- }
303-
304- Row {
305- anchors {
306- horizontalCenter: parent.horizontalCenter
307- }
308- spacing: units.gu(1)
309-
310- Repeater {
311- id: modeRepeater
312- model: [
313- i18n.tr("First to") + " " + settings.targetScore,
314- i18n.tr("Highest Score"),
315- i18n.tr("Survival")
316- ]
317- objectName: "modeRepeater"
318-
319- property var secondaryText: [
320- "",
321- i18n.tr("Within a certain amount of time"),
322- i18n.tr("Highest score without losing a point")
323- ]
324- property int selectedIndex: settings.gameMode
325-
326- delegate: Button {
327- color: selected ? UbuntuColors.darkGrey : UbuntuColors.coolGrey
328- height: units.gu(10)
329- width: selected ? units.gu(20) : units.gu(10)
330-
331- property bool selected: index === settings.gameMode
332-
333- onClicked: settings.gameMode = index
334-
335- Behavior on color {
336- ColorAnimation { duration: 200 }
337- }
338-
339- Behavior on width {
340- NumberAnimation {
341- id: delegateAnimation
342- duration: 200
343- }
344- }
345-
346- Column {
347- anchors {
348- left: parent.left
349- leftMargin: units.gu(1)
350- right: parent.right
351- rightMargin: units.gu(1)
352- verticalCenter: parent.verticalCenter
353- }
354-
355- Label {
356- anchors {
357- left: parent.left
358- right: parent.right
359- }
360- color: selected ? "#FFF" : UbuntuColors.darkGrey
361- horizontalAlignment: Text.AlignHCenter
362- text: modelData
363- verticalAlignment: Text.AlignVCenter
364- wrapMode: Text.WordWrap
365-
366- Behavior on color {
367- ColorAnimation { duration: 200 }
368- }
369- }
370-
371- Label {
372- anchors {
373- left: parent.left
374- right: parent.right
375- }
376- color: "#FFF"
377- horizontalAlignment: Text.AlignHCenter
378- text: modeRepeater.secondaryText[index]
379- verticalAlignment: Text.AlignVCenter
380- opacity: visible ? 1 : 0
381- visible: selected && modeRepeater.secondaryText[index] && !delegateAnimation.running
382- wrapMode: Text.WordWrap
383-
384- Behavior on opacity {
385- NumberAnimation { duration: 200 }
386- }
387- }
388- }
389- }
390- }
391- }
392-
393- Label {
394- anchors {
395- horizontalCenter: parent.horizontalCenter
396- }
397- horizontalAlignment: Text.AlignHCenter
398- fontSize: "small"
399- objectName: "instructionLabel"
400- text: settings.useMotion ?
401- i18n.tr("Rotate your device to move your player") + "\n"
402- + i18n.tr("Tap to jump")
403- :
404- i18n.tr("Press on the left or right of the screen to move") + "\n"
405- + i18n.tr("Tap in the center or a two finger press to jump")
406- }
407-
408- Button {
409- anchors {
410- horizontalCenter: parent.horizontalCenter
411- }
412- objectName: "playButton"
413- text: i18n.tr("Play")
414-
415- onClicked: startGame()
416- }
417- }
418-
419- Row {
420- anchors {
421- bottom: parent.bottom
422- bottomMargin: units.gu(2)
423- right: parent.right
424- rightMargin: units.gu(2)
425- }
426- spacing: units.gu(1)
427-
428- Button {
429- iconName: "favorite-selected"
430- objectName: "highScoreButton"
431- height: units.gu(5)
432- width: height
433- onClicked: mainPageStack.pushPage("pages/HighScorePage.qml", {"objectName": "highScorePage"})
434- }
435-
436- Button {
437- iconName: "settings"
438- objectName: "settingsButton"
439- height: units.gu(5)
440- width: height
441- onClicked: mainPageStack.pushPage("pages/SettingsPage.qml", {"objectName": "settingsPage"})
442- }
443- }
444-}
445
446=== modified file 'tests/autopilot/run'
447--- tests/autopilot/run 2014-12-14 21:57:20 +0000
448+++ tests/autopilot/run 2016-08-09 23:30:40 +0000
449@@ -5,6 +5,11 @@
450 exit
451 fi
452
453+pushd ../../
454+qmake
455+make
456+popd
457+
458 SCRIPTPATH=`dirname $0`
459 pushd ${SCRIPTPATH}
460 autopilot3 run volleyball2d
461
462=== modified file 'tests/autopilot/volleyball2d/__init__.py'
463--- tests/autopilot/volleyball2d/__init__.py 2015-01-04 18:52:43 +0000
464+++ tests/autopilot/volleyball2d/__init__.py 2016-08-09 23:30:40 +0000
465@@ -126,18 +126,16 @@
466 app_qml_source_location = self._get_app_qml_source_path()
467 if os.path.exists(app_qml_source_location):
468 self.app = self.launch_test_application(
469- get_qmlscene_launch_command(),
470- '-I' + _get_module_include_path(),
471- app_qml_source_location,
472- app_type='qt',
473- emulator_base=UbuntuUIToolkitCustomProxyObjectBase)
474+ "../../volleyball2d/volleyball2d",
475+ app_type='qt',
476+ emulator_base=UbuntuUIToolkitCustomProxyObjectBase)
477 else:
478 raise NotImplementedError(
479 "On desktop we can't install click packages yet, so we can "
480 "only run from source.")
481
482 def _get_app_qml_source_path(self):
483- qml_file_name = 'main.qml'
484+ qml_file_name = 'volleyball2d/main.qml'
485 return os.path.join(self._get_path_to_app_source(), qml_file_name)
486
487 def _get_path_to_app_source(self):
488@@ -170,7 +168,8 @@
489
490 @property
491 def high_score(self):
492- return self.app.wait_select_single(Page11, objectName="highScorePage",
493+ return self.app.wait_select_single(HighScorePage,
494+ objectName="highScorePage",
495 visible=True)
496
497 @property
498@@ -178,25 +177,32 @@
499 return self.app.wait_select_single(MainView)
500
501 @property
502- def menu_scene(self):
503- return self.app.select_single(MenuScene, objectName="menuScene")
504+ def menu_page(self):
505+ return self.app.select_single(MenuPage, objectName="menuPage")
506
507 @property
508 def settings(self):
509- return self.app.wait_select_single(Page11, objectName="settingsPage",
510+ return self.app.wait_select_single(SettingsPage,
511+ objectName="settingsPage",
512 visible=True)
513
514 @property
515 def window(self):
516- return self.app.select_single(QQuickWindowQmlImpl, objectName="window")
517+ return self.app.select_single(QQuickView, objectName="window")
518
519
520 class GameScene(UbuntuUIToolkitCustomProxyObjectBase):
521 def __init__(self, *args):
522 super(GameScene, self).__init__(*args)
523
524+ self.main_view = self.get_root_instance().select_single(MainView)
525+
526 @click_object
527 def click_pause_button(self):
528+ self.point_overlay.visible.wait_for(True)
529+ self.point_overlay.click_continue()
530+ self.point_overlay.visible.wait_for(False)
531+
532 return self.get_pause_button()
533
534 @property
535@@ -212,7 +218,13 @@
536
537 @property
538 def pause_overlay(self):
539- return self.wait_select_single(PauseOverlay, objectName="pauseOverlay")
540+ return self.main_view.wait_select_single(PauseOverlay,
541+ objectName="pauseOverlay")
542+
543+ @property
544+ def point_overlay(self):
545+ return self.main_view.wait_select_single(PointOverlay,
546+ objectName="pointOverlay")
547
548
549 class HighScorePage(UbuntuUIToolkitCustomProxyObjectBase):
550@@ -244,9 +256,14 @@
551 super(MainView, self).__init__(*args)
552
553
554-class MenuScene(UbuntuUIToolkitCustomProxyObjectBase):
555- def __init__(self, *args):
556- super(MenuScene, self).__init__(*args)
557+class ScalePage(UbuntuUIToolkitCustomProxyObjectBase):
558+ def __init__(self, *args):
559+ super(ScalePage, self).__init__(*args)
560+
561+
562+class MenuPage(ScalePage):
563+ def __init__(self, *args):
564+ super(MenuPage, self).__init__(*args)
565
566 @click_object
567 def click_high_score_button(self):
568@@ -301,6 +318,18 @@
569 return self.select_single("Button", objectName="continue")
570
571
572+class PointOverlay(UbuntuUIToolkitCustomProxyObjectBase):
573+ def __init__(self, *args):
574+ super(PointOverlay, self).__init__(*args)
575+
576+ @click_object
577+ def click_continue(self):
578+ return self.get_continue_label()
579+
580+ def get_continue_label(self):
581+ return self.select_single("Label", objectName="continue")
582+
583+
584 class SettingsPage(UbuntuUIToolkitCustomProxyObjectBase):
585 def __init__(self, *args):
586 super(SettingsPage, self).__init__(*args)
587@@ -372,20 +401,9 @@
588 self.click_motion_switch()
589
590
591-class Page11(HighScorePage, SettingsPage):
592- """
593- FIXME: Represents HighScorePage, SettingsPage
594- due to bug 1341671 and bug 1337004 they all appear as Page11
595- Therefore this class 'contains' all of them for now
596- Once the bugs are fixed Page11 should be swapped for SettingsPage etc
597- """
598- def __init__(self, *args):
599- super(Page11, self).__init__(*args)
600-
601-
602-class QQuickWindowQmlImpl(UbuntuUIToolkitCustomProxyObjectBase):
603- def __init__(self, *args):
604- super(QQuickWindowQmlImpl, self).__init__(*args)
605+class QQuickView(UbuntuUIToolkitCustomProxyObjectBase):
606+ def __init__(self, *args):
607+ super(QQuickView, self).__init__(*args)
608
609 def is_fullscreen(self):
610 return self.visibility == 5
611
612=== modified file 'tests/autopilot/volleyball2d/test_game.py'
613--- tests/autopilot/volleyball2d/test_game.py 2014-12-18 18:28:17 +0000
614+++ tests/autopilot/volleyball2d/test_game.py 2016-08-09 23:30:40 +0000
615@@ -29,10 +29,10 @@
616 """Test the game starts after clicking the menu"""
617
618 # Test menu is visible at start
619- self.assertThat(self.menu_scene.visible, Eventually(Equals(True)))
620+ self.assertThat(self.menu_page.visible, Eventually(Equals(True)))
621
622 # Click menu to start game
623- self.menu_scene.click_play_button()
624+ self.menu_page.click_play_button()
625
626 # Test game is visible and running
627 self.assertThat(self.game_scene.visible, Eventually(Equals(True)))
628@@ -68,7 +68,7 @@
629 # Check that the game has stopped, game hidden and menu shown
630 self.assertThat(self.game_scene.running, Eventually(Equals(False)))
631 self.assertThat(self.game_scene.visible, Eventually(Equals(False)))
632- self.assertThat(self.menu_scene.visible, Eventually(Equals(True)))
633+ self.assertThat(self.menu_page.visible, Eventually(Equals(True)))
634
635 def test_resume_game(self):
636 """Test that the game resumes after pausing"""
637
638=== modified file 'tests/autopilot/volleyball2d/test_high_score.py'
639--- tests/autopilot/volleyball2d/test_high_score.py 2014-12-18 14:27:43 +0000
640+++ tests/autopilot/volleyball2d/test_high_score.py 2016-08-09 23:30:40 +0000
641@@ -26,8 +26,8 @@
642 """Wrapper which switches to the settings page"""
643 def func_wrapper(self, *args, **kwargs):
644 # Switch to settings page
645- self.menu_scene.visible.wait_for(True)
646- self.menu_scene.click_high_score_button()
647+ self.menu_page.visible.wait_for(True)
648+ self.menu_page.click_high_score_button()
649 self.high_score.visible.wait_for(True)
650
651 return func(self, *args, **kwargs)
652
653=== modified file 'tests/autopilot/volleyball2d/test_main.py'
654--- tests/autopilot/volleyball2d/test_main.py 2015-01-04 18:52:43 +0000
655+++ tests/autopilot/volleyball2d/test_main.py 2016-08-09 23:30:40 +0000
656@@ -27,4 +27,4 @@
657
658 def test_app_starts_on_menu(self):
659 self.assertThat(self.main_view.visible, Eventually(Equals(True)))
660- self.assertThat(self.menu_scene.visible, Eventually(Equals(True)))
661+ self.assertThat(self.menu_page.visible, Eventually(Equals(True)))
662
663=== modified file 'tests/autopilot/volleyball2d/test_menu.py'
664--- tests/autopilot/volleyball2d/test_menu.py 2014-12-18 18:28:17 +0000
665+++ tests/autopilot/volleyball2d/test_menu.py 2016-08-09 23:30:40 +0000
666@@ -33,15 +33,15 @@
667 def test_inital_labels(self):
668 """Test inital states of labels are correct"""
669
670- self.assertThat(self.menu_scene.visible, Eventually(Equals(True)))
671+ self.assertThat(self.menu_page.visible, Eventually(Equals(True)))
672
673 # Ensure labels are correct
674- self.assertThat(self.menu_scene.get_main_label().text,
675+ self.assertThat(self.menu_page.get_main_label().text,
676 Equals("Volleyball 2D"))
677- self.assertThat(self.menu_scene.get_play_button().text,
678+ self.assertThat(self.menu_page.get_play_button().text,
679 Equals("Play"))
680
681- self.assertThat(self.menu_scene.get_instruction_label().text,
682+ self.assertThat(self.menu_page.get_instruction_label().text,
683 Equals(INSTRUCTION_MOTION_STR))
684- self.assertThat(self.menu_scene.get_mode_repeater_value(),
685+ self.assertThat(self.menu_page.get_mode_repeater_value(),
686 Equals(0))
687
688=== modified file 'tests/autopilot/volleyball2d/test_settings.py'
689--- tests/autopilot/volleyball2d/test_settings.py 2014-12-19 14:49:30 +0000
690+++ tests/autopilot/volleyball2d/test_settings.py 2016-08-09 23:30:40 +0000
691@@ -28,8 +28,8 @@
692 """Wrapper which switches to the settings page"""
693 def func_wrapper(self, *args, **kwargs):
694 # Switch to settings page
695- self.menu_scene.visible.wait_for(True)
696- self.menu_scene.click_settings_button()
697+ self.menu_page.visible.wait_for(True)
698+ self.menu_page.click_settings_button()
699 self.settings.visible.wait_for(True)
700
701 return func(self, *args, **kwargs)
702@@ -94,12 +94,12 @@
703
704 # Check labels on menu scene
705 self.main_view.go_back()
706- self.menu_scene.visible.wait_for(True)
707+ self.menu_page.visible.wait_for(True)
708
709- self.assertThat(self.menu_scene.get_instruction_label().text,
710+ self.assertThat(self.menu_page.get_instruction_label().text,
711 Eventually(Equals(INSTRUCTION_MOTION_STR)))
712
713- self.menu_scene.click_settings_button()
714+ self.menu_page.click_settings_button()
715 self.settings.visible.wait_for(True)
716
717 # Disable motion - check the switch and labels
718@@ -109,11 +109,11 @@
719
720 # Check labels on menu scene
721 self.main_view.go_back()
722- self.menu_scene.visible.wait_for(True)
723- self.assertThat(self.menu_scene.get_instruction_label().text,
724+ self.menu_page.visible.wait_for(True)
725+ self.assertThat(self.menu_page.get_instruction_label().text,
726 Eventually(Equals(INSTRUCTION_NO_MOTION_STR)))
727
728- self.menu_scene.click_settings_button()
729+ self.menu_page.click_settings_button()
730 self.settings.visible.wait_for(True)
731
732 # Enable motion - check the switch and labels
733@@ -123,9 +123,9 @@
734
735 # Check labels on menu scene
736 self.main_view.go_back()
737- self.menu_scene.visible.wait_for(True)
738+ self.menu_page.visible.wait_for(True)
739
740- self.assertThat(self.menu_scene.get_instruction_label().text,
741+ self.assertThat(self.menu_page.get_instruction_label().text,
742 Eventually(Equals(INSTRUCTION_MOTION_STR)))
743
744 @switch_to_settings_page
745
746=== modified file 'tests/unit/tst_ai_prediction.qml'
747--- tests/unit/tst_ai_prediction.qml 2015-01-04 15:30:20 +0000
748+++ tests/unit/tst_ai_prediction.qml 2016-08-09 23:30:40 +0000
749@@ -1,5 +1,5 @@
750 /*
751- * Copyright (C) 2014
752+ * Copyright (C) 2014, 2015
753 * Andrew Hayzen <ahayzen@gmail.com>
754 *
755 * This program is free software; you can redistribute it and/or modify
756@@ -19,7 +19,7 @@
757 import QtQuick 2.3
758 import QtTest 1.0
759 import Ubuntu.Components 1.1
760-import "../../components"
761+import "../../volleyball2d/components"
762
763 // See more details @ http://doc.qt.io/qt-5/qml-qttest-testcase.html
764 // Ensure qml-module-qttest is installed
765@@ -36,7 +36,9 @@
766 visible: true
767 width: units.gu(70)
768 */
769-Item {
770+Game {
771+ id: game
772+ currentScene: gameScene
773 /*
774 * Basic game scene with a ball, ground and AI
775 */
776@@ -46,9 +48,6 @@
777 gravity: Qt.point(0, 20)
778 pixelsPerMeter: units.gu(3)
779 physics: true
780- running: false
781- viewport: Viewport {
782- }
783 width: units.gu(70)
784 visible: true
785 x: 0
786@@ -150,7 +149,7 @@
787 computer.x = gameScene.width - (gameScene.width / 4) - computer.radius;
788 computer.y = gameScene.height - computer.radius;
789
790- gameScene.running = true
791+ game.gameState = Bacon2D.Running
792
793 if (!silent) {
794 console.debug("<< init");
795@@ -167,7 +166,7 @@
796 console.debug(">> cleanup");
797 }
798
799- gameScene.running = false
800+ game.gameState = Bacon2D.Paused
801
802 if (!silent) {
803 console.debug("<< cleanup");
804
805=== modified file 'tests/unit/tst_game_ball.qml'
806--- tests/unit/tst_game_ball.qml 2014-12-14 18:49:37 +0000
807+++ tests/unit/tst_game_ball.qml 2016-08-09 23:30:40 +0000
808@@ -1,5 +1,5 @@
809 /*
810- * Copyright (C) 2014
811+ * Copyright (C) 2014, 2015
812 * Andrew Hayzen <ahayzen@gmail.com>
813 *
814 * This program is free software; you can redistribute it and/or modify
815@@ -19,14 +19,17 @@
816 import QtQuick 2.3
817 import QtTest 1.0
818 import Ubuntu.Components 1.1
819-import "../../components"
820+import "../../volleyball2d/components"
821
822 // See more details @ http://doc.qt.io/qt-5/qml-qttest-testcase.html
823 // Ensure qml-module-qttest is installed
824 // Execute tests with:
825 // qmltestrunner
826
827-Item {
828+Game {
829+ id: game
830+ currentScene: scene
831+ gameState: Bacon2D.Paused
832 /*
833 * Basic game scene with a ball in the air and ground underneath
834 * If the ball collides with anything it will store that in the
835@@ -38,9 +41,6 @@
836 gravity: Qt.point(0, 20)
837 pixelsPerMeter: units.gu(3)
838 physics: true
839- running: false
840- viewport: Viewport {
841- }
842 width: units.gu(20)
843
844 Ball {
845@@ -77,7 +77,7 @@
846 function cleanup() {
847 // Reset the ball position and any game states
848 console.debug(">> cleanup");
849- scene.running = false
850+ game.gameState = Bacon2D.Paused
851 ball.y = 100
852 console.debug("<< cleanup");
853 }
854@@ -94,7 +94,7 @@
855
856 function test_ball_collides_with_ground() {
857 // When the game is running, test the ball collides with the ground
858- scene.running = true;
859+ game.gameState = Bacon2D.Running;
860
861 tryCompare(ball, "collidedWith", ground, 2000,
862 "Ball did not collided with wall")
863@@ -102,7 +102,7 @@
864
865 function test_ball_falls() {
866 // When the game is running, test the ball falls
867- scene.running = true;
868+ game.gameState = Bacon2D.Running;
869
870 wait(100); // wait for the ball to fall
871
872
873=== added directory 'volleyball2d'
874=== added file 'volleyball2d.pro'
875--- volleyball2d.pro 1970-01-01 00:00:00 +0000
876+++ volleyball2d.pro 2016-08-09 23:30:40 +0000
877@@ -0,0 +1,8 @@
878+#This is the basic qmake template for the Ubuntu-SDK
879+#Now if you want to get started right click the project
880+#and add the subproject you like (app,scope,helper,backend)
881+
882+TEMPLATE = subdirs
883+
884+SUBDIRS += volleyball2d \
885+ manifest
886
887=== removed file 'volleyball2d.qmlproject'
888--- volleyball2d.qmlproject 2014-12-14 21:57:20 +0000
889+++ volleyball2d.qmlproject 1970-01-01 00:00:00 +0000
890@@ -1,63 +0,0 @@
891-import QmlProject 1.1
892-
893-Project {
894- mainFile: "main.qml"
895-
896- /* Include .qml, .js, and image files from current directory and subdirectories */
897- QmlFiles {
898- directory: "."
899- }
900- JavaScriptFiles {
901- directory: "."
902- }
903- ImageFiles {
904- directory: "."
905- }
906- Files {
907- filter: "*.desktop"
908- }
909- Files {
910- filter: "www/*.html"
911- }
912- Files {
913- filter: "Makefile"
914- }
915- Files {
916- filter: "*.apparmor"
917- }
918- Files {
919- directory: "."
920- paths: ["manifest.json",".excludes", "tests/autopilot/run"]
921- }
922- Files {
923- directory: "www"
924- filter: "*"
925- }
926- Files {
927- directory: "www/img/"
928- filter: "*"
929- }
930- Files {
931- directory: "www/css/"
932- filter: "*"
933- }
934- Files {
935- directory: "www/js/"
936- filter: "*"
937- }
938- Files {
939- directory: "Bacon2D/"
940- filter: "*"
941- }
942- Files {
943- directory: "tests/"
944- filter: "*.py"
945- }
946- Files {
947- directory: "debian"
948- filter: "*"
949- }
950- /* List of plugin directories passed to QML runtime */
951- importPaths: [ "." ,"/usr/bin","/usr/lib/x86_64-linux-gnu/qt5/qml" ]
952-}
953-
954
955=== renamed directory 'components' => 'volleyball2d/components'
956=== modified file 'volleyball2d/components/AIDebug.qml'
957--- components/AIDebug.qml 2014-12-27 23:22:04 +0000
958+++ volleyball2d/components/AIDebug.qml 2016-08-09 23:30:40 +0000
959@@ -16,7 +16,7 @@
960 */
961
962 import QtQuick 2.3
963-import Ubuntu.Components 1.1
964+import Ubuntu.Components 1.3
965
966 Item {
967 anchors {
968
969=== modified file 'volleyball2d/components/AIPrediction.qml'
970--- components/AIPrediction.qml 2015-01-04 15:30:20 +0000
971+++ volleyball2d/components/AIPrediction.qml 2016-08-09 23:30:40 +0000
972@@ -1,5 +1,5 @@
973 /*
974- * Copyright (C) 2014
975+ * Copyright (C) 2014, 2015
976 * Andrew Hayzen <ahayzen@gmail.com>
977 *
978 * This program is free software; you can redistribute it and/or modify
979@@ -185,7 +185,9 @@
980
981 function iter() {
982 // Convert to Y=0 is baseline and Vy is positive when going up for easier calculation
983- var ballPoint = Qt.point(ball.x, (ball.y <= 0) ? -ball.y + gameScene.height : gameScene.height - ball.y)
984+ var ballWorldPoint = ball.getWorldCenter()
985+
986+ var ballPoint = Qt.point(ballWorldPoint.x, (ballWorldPoint.y <= 0) ? -ballWorldPoint.y + gameScene.height : gameScene.height - ballWorldPoint.y)
987 var ballU = Qt.point(ball.linearVelocity.x, -ball.linearVelocity.y)
988
989 // Get the top, land points and the angle
990@@ -216,20 +218,20 @@
991 var target = character.center;
992 var weight = 0;
993
994- if (Math.abs(ball.x - character.center) < character.radius &&
995- character.y + character.radius > ball.y &&
996- character.y - ball.y < units.gu(10)) {
997+ if (Math.abs(ballWorldPoint.x - character.center) < character.radius &&
998+ character.y + character.radius > ballWorldPoint.y &&
999+ character.y - ballWorldPoint.y < units.gu(10)) {
1000 // Ball is within the radius of the character and less that X units above the char
1001- if (ball.x >= character.center - units.gu(.5)) {
1002+ if (ballWorldPoint.x >= character.center - units.gu(.5)) {
1003 // Ball is to the right of the center
1004 weight = character.radius / 2
1005- } else if (ball.x <= character + units.gu(.5)) {
1006+ } else if (ballWorldPoint.x <= character + units.gu(.5)) {
1007 // Ball is to the left of the center
1008 weight = -character.radius / 2
1009 }
1010
1011 character.jump()
1012- } else if (pred.x < minX && ball.x < minX) {
1013+ } else if (pred.x < minX && ballWorldPoint.x < minX) {
1014 // Ball is out of court and predicted to land there
1015 // Attempt to return to center-front
1016 target = minX + (maxX - minX) / 2;
1017
1018=== modified file 'volleyball2d/components/Ball.qml'
1019--- components/Ball.qml 2015-01-04 15:30:20 +0000
1020+++ volleyball2d/components/Ball.qml 2016-08-09 23:30:40 +0000
1021@@ -1,5 +1,5 @@
1022 /*
1023- * Copyright (C) 2014
1024+ * Copyright (C) 2014, 2015
1025 * Andrew Hayzen <ahayzen@gmail.com>
1026 *
1027 * This program is free software; you can redistribute it and/or modify
1028@@ -19,10 +19,10 @@
1029 import Bacon2D 1.0
1030
1031
1032-Entity {
1033+PhysicsEntity {
1034 id: entity
1035 angularDamping: 0.5
1036- bodyType: Entity.Dynamic
1037+ bodyType: Body.Dynamic
1038 sleepingAllowed: false
1039 linearDamping: 0.5
1040
1041@@ -34,22 +34,20 @@
1042 fixtures: [
1043 Circle {
1044 id: circle
1045- anchors {
1046- centerIn: parent
1047- }
1048 density: 1.0
1049 friction: 1.0
1050 radius: units.gu(2)
1051 restitution: 0.8
1052- Rectangle {
1053- id: fill
1054- anchors {
1055- fill: parent
1056- }
1057- radius: width
1058- color: "#000"
1059- }
1060- onBeginContact: contact(other.parent)
1061+
1062+ onBeginContact: contact(other.getBody().target)
1063 }
1064 ]
1065+
1066+ Rectangle {
1067+ id: fill
1068+ color: "#000"
1069+ height: target.radius * 2
1070+ radius: width
1071+ width: target.radius * 2
1072+ }
1073 }
1074
1075=== modified file 'volleyball2d/components/Character.qml'
1076--- components/Character.qml 2014-12-16 23:46:08 +0000
1077+++ volleyball2d/components/Character.qml 2016-08-09 23:30:40 +0000
1078@@ -1,5 +1,5 @@
1079 /*
1080- * Copyright (C) 2014
1081+ * Copyright (C) 2014, 2015
1082 * Andrew Hayzen <ahayzen@gmail.com>
1083 *
1084 * This program is free software; you can redistribute it and/or modify
1085@@ -21,7 +21,7 @@
1086
1087 SemiCircleEntity {
1088 // Entity settings
1089- bodyType: Entity.Dynamic
1090+ bodyType: Body.Dynamic
1091 fixedRotation: true
1092 gravityScale: 1.5
1093 linearDamping: 0.8
1094
1095=== modified file 'volleyball2d/components/CharacterBarrier.qml'
1096--- components/CharacterBarrier.qml 2014-12-04 00:00:55 +0000
1097+++ volleyball2d/components/CharacterBarrier.qml 2016-08-09 23:30:40 +0000
1098@@ -1,5 +1,5 @@
1099 /*
1100- * Copyright (C) 2014
1101+ * Copyright (C) 2014, 2015
1102 * Andrew Hayzen <ahayzen@gmail.com>
1103 *
1104 * This program is free software; you can redistribute it and/or modify
1105@@ -19,23 +19,23 @@
1106 import Bacon2D 1.0
1107
1108
1109-Entity {
1110- bodyType: Entity.Static
1111+PhysicsEntity {
1112+ bodyType: Body.Static
1113 onHeightChanged: box.height = height
1114 onWidthChanged: box.width = width
1115 fixtures: Box {
1116 id: box
1117 collidesWith: Fixture.Category2 // collide with other objects in cat2
1118 friction: 0
1119+ }
1120
1121- Rectangle {
1122- id: rect
1123- color: "#555"
1124- height: parent.height
1125- opacity: .1
1126- width: parent.width
1127- x: 0
1128- y: 0
1129- }
1130+ Rectangle {
1131+ id: rect
1132+ color: "#555"
1133+ height: parent.height
1134+ opacity: .1
1135+ width: parent.width
1136+ x: 0
1137+ y: 0
1138 }
1139 }
1140
1141=== modified file 'volleyball2d/components/GameHeader.qml'
1142--- components/GameHeader.qml 2014-12-18 14:27:43 +0000
1143+++ volleyball2d/components/GameHeader.qml 2016-08-09 23:30:40 +0000
1144@@ -1,5 +1,5 @@
1145 /*
1146- * Copyright (C) 2014
1147+ * Copyright (C) 2014, 2015
1148 * Andrew Hayzen <ahayzen@gmail.com>
1149 *
1150 * This program is free software; you can redistribute it and/or modify
1151@@ -16,7 +16,7 @@
1152 */
1153
1154 import QtQuick 2.3
1155-import Ubuntu.Components 1.1
1156+import Ubuntu.Components 1.3
1157
1158
1159 Item {
1160@@ -57,7 +57,7 @@
1161 if ((mouse.x > x + radius && mouse.x < x + width - radius)
1162 || inCircle(Qt.point(x + radius, y + height / 2), radius, mouse)
1163 || inCircle(Qt.point(x + width - radius, y + height / 2), radius, mouse)) {
1164- pauseOverlay.pause()
1165+ pause()
1166 }
1167 }
1168 }
1169
1170=== modified file 'volleyball2d/components/PauseOverlay.qml'
1171--- components/PauseOverlay.qml 2014-12-16 23:46:08 +0000
1172+++ volleyball2d/components/PauseOverlay.qml 2016-08-09 23:30:40 +0000
1173@@ -1,5 +1,5 @@
1174 /*
1175- * Copyright (C) 2014
1176+ * Copyright (C) 2014, 2015
1177 * Andrew Hayzen <ahayzen@gmail.com>
1178 *
1179 * This program is free software; you can redistribute it and/or modify
1180@@ -16,15 +16,20 @@
1181 */
1182
1183 import QtQuick 2.3
1184-import Ubuntu.Components 1.1
1185-
1186-Item {
1187+import Ubuntu.Components 1.3
1188+
1189+ScaleItem {
1190+ objectName: "pauseOverlay"
1191+
1192+ // Hack for autopilot otherwise PointOverlay appears as ScaleItem
1193+ // due to bug 1341671 it is required that there is a property so that
1194+ // qml doesn't optimise using the parent type
1195+ property bool bug1341671workaround: true
1196+
1197+ signal endGame()
1198 signal pause()
1199 signal resume()
1200
1201- onPause: visible = true
1202- onResume: visible = false
1203-
1204 Rectangle {
1205 anchors {
1206 fill: parent
1207
1208=== modified file 'volleyball2d/components/PointOverlay.qml'
1209--- components/PointOverlay.qml 2014-12-04 00:00:55 +0000
1210+++ volleyball2d/components/PointOverlay.qml 2016-08-09 23:30:40 +0000
1211@@ -1,5 +1,5 @@
1212 /*
1213- * Copyright (C) 2014
1214+ * Copyright (C) 2014, 2015
1215 * Andrew Hayzen <ahayzen@gmail.com>
1216 *
1217 * This program is free software; you can redistribute it and/or modify
1218@@ -16,9 +16,15 @@
1219 */
1220
1221 import QtQuick 2.3
1222-import Ubuntu.Components 1.1
1223-
1224-Item {
1225+import Ubuntu.Components 1.3
1226+
1227+ScaleItem {
1228+ objectName: "pointOverlay"
1229+
1230+ property bool userWon: false
1231+
1232+ signal close()
1233+
1234 Rectangle {
1235 anchors {
1236 fill: parent
1237@@ -39,7 +45,7 @@
1238 }
1239 color: "#FFF"
1240 fontSize: "x-large"
1241- text: lastWinner === human ? i18n.tr("You won this round") : i18n.tr("You lost this round")
1242+ text: userWon ? i18n.tr("You won this round") : i18n.tr("You lost this round")
1243 }
1244
1245 Label {
1246@@ -48,6 +54,7 @@
1247 }
1248 color: "#FFF"
1249 fontSize: "large"
1250+ objectName: "continue"
1251 text: i18n.tr("Tap to continue")
1252 }
1253 }
1254@@ -56,6 +63,6 @@
1255 anchors {
1256 fill: parent
1257 }
1258- onClicked: gameScene.reset()
1259+ onClicked: close()
1260 }
1261 }
1262
1263=== added file 'volleyball2d/components/ScaleItem.qml'
1264--- volleyball2d/components/ScaleItem.qml 1970-01-01 00:00:00 +0000
1265+++ volleyball2d/components/ScaleItem.qml 2016-08-09 23:30:40 +0000
1266@@ -0,0 +1,37 @@
1267+/*
1268+ * Copyright (C) 2015
1269+ * Andrew Hayzen <ahayzen@gmail.com>
1270+ *
1271+ * This program is free software; you can redistribute it and/or modify
1272+ * it under the terms of the GNU General Public License as published by
1273+ * the Free Software Foundation; version 3.
1274+ *
1275+ * This program is distributed in the hope that it will be useful,
1276+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1277+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1278+ * GNU General Public License for more details.
1279+ *
1280+ * You should have received a copy of the GNU General Public License
1281+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1282+ */
1283+
1284+import Ubuntu.Components 1.3
1285+import QtQuick 2.3
1286+
1287+
1288+Item {
1289+ anchors {
1290+ fill: parent
1291+ }
1292+
1293+ default property alias childrenDefault: scalable.children
1294+ property int scalar: units.gu(70)
1295+
1296+ Item {
1297+ id: scalable
1298+ height: parent.height / scale
1299+ scale: parent.width / scalar
1300+ transformOrigin: Qt.TopLeftCorner
1301+ width: scalar
1302+ }
1303+}
1304
1305=== added file 'volleyball2d/components/ScalePage.qml'
1306--- volleyball2d/components/ScalePage.qml 1970-01-01 00:00:00 +0000
1307+++ volleyball2d/components/ScalePage.qml 2016-08-09 23:30:40 +0000
1308@@ -0,0 +1,37 @@
1309+/*
1310+ * Copyright (C) 2014, 2015
1311+ * Andrew Hayzen <ahayzen@gmail.com>
1312+ *
1313+ * This program is free software; you can redistribute it and/or modify
1314+ * it under the terms of the GNU General Public License as published by
1315+ * the Free Software Foundation; version 3.
1316+ *
1317+ * This program is distributed in the hope that it will be useful,
1318+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1319+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1320+ * GNU General Public License for more details.
1321+ *
1322+ * You should have received a copy of the GNU General Public License
1323+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1324+ */
1325+
1326+import Ubuntu.Components 1.3
1327+import QtQuick 2.3
1328+
1329+
1330+Page {
1331+ anchors {
1332+ fill: parent
1333+ }
1334+
1335+ default property alias childrenDefault: scalable.children
1336+ property int scalar: units.gu(70)
1337+
1338+ Item {
1339+ id: scalable
1340+ height: parent.height / scale
1341+ scale: parent.width / scalar
1342+ transformOrigin: Qt.TopLeftCorner
1343+ width: scalar
1344+ }
1345+}
1346
1347=== modified file 'volleyball2d/components/Scoring.qml'
1348--- components/Scoring.qml 2014-12-27 23:22:04 +0000
1349+++ volleyball2d/components/Scoring.qml 2016-08-09 23:30:40 +0000
1350@@ -16,7 +16,7 @@
1351 */
1352
1353 import QtQuick 2.3
1354-import Ubuntu.Components 1.1
1355+import Ubuntu.Components 1.3
1356
1357 Item {
1358 anchors {
1359
1360=== modified file 'volleyball2d/components/SemiCircleEntity.qml'
1361--- components/SemiCircleEntity.qml 2014-12-16 23:46:08 +0000
1362+++ volleyball2d/components/SemiCircleEntity.qml 2016-08-09 23:30:40 +0000
1363@@ -1,5 +1,5 @@
1364 /*
1365- * Copyright (C) 2014
1366+ * Copyright (C) 2014, 2015
1367 * Andrew Hayzen <ahayzen@gmail.com>
1368 *
1369 * This program is free software; you can redistribute it and/or modify
1370@@ -19,7 +19,7 @@
1371 import Bacon2D 1.0
1372
1373
1374-Entity {
1375+PhysicsEntity {
1376 id: entity
1377 property alias categories: polygon.categories
1378 property alias color: circularRect.color
1379@@ -66,27 +66,27 @@
1380 entity.endContact(other.parent)
1381 }
1382 }
1383-
1384- Item {
1385- id: rectContainer
1386- clip: true
1387- height: radius
1388- width: radius * 2
1389- x: 0
1390- y: 0
1391-
1392- Rectangle {
1393- id: circularRect
1394- anchors {
1395- left: parent.left
1396- top: parent.top
1397- right: parent.right
1398- }
1399- color: "#F00"
1400- height: width
1401- radius: width * 2
1402- }
1403- }
1404 }
1405 ]
1406+
1407+ Item {
1408+ id: rectContainer
1409+ clip: true
1410+ height: radius
1411+ width: radius * 2
1412+ x: 0
1413+ y: 0
1414+
1415+ Rectangle {
1416+ id: circularRect
1417+ anchors {
1418+ left: parent.left
1419+ top: parent.top
1420+ right: parent.right
1421+ }
1422+ color: "#F00"
1423+ height: width
1424+ radius: width * 2
1425+ }
1426+ }
1427 }
1428
1429=== modified file 'volleyball2d/components/Wall.qml'
1430--- components/Wall.qml 2014-12-04 00:00:55 +0000
1431+++ volleyball2d/components/Wall.qml 2016-08-09 23:30:40 +0000
1432@@ -1,5 +1,5 @@
1433 /*
1434- * Copyright (C) 2014
1435+ * Copyright (C) 2014, 2015
1436 * Andrew Hayzen <ahayzen@gmail.com>
1437 *
1438 * This program is free software; you can redistribute it and/or modify
1439@@ -19,21 +19,22 @@
1440 import Bacon2D 1.0
1441
1442
1443-Entity {
1444- bodyType: Entity.Static
1445+PhysicsEntity {
1446+ bodyType: Body.Static
1447
1448 property alias friction: box.friction
1449
1450- fixtures: Box {
1451- id: box
1452- anchors {
1453- fill: parent
1454- }
1455- Rectangle {
1456- anchors {
1457- fill: parent
1458- }
1459- color: "#000"
1460- }
1461+ fixtures: [
1462+ Box {
1463+ id: box
1464+ height: target.height
1465+ width: target.width
1466+ }
1467+ ]
1468+
1469+ Rectangle {
1470+ color: "#000"
1471+ height: target.height
1472+ width: target.width
1473 }
1474 }
1475
1476=== added file 'volleyball2d/fullscreen.cpp'
1477--- volleyball2d/fullscreen.cpp 1970-01-01 00:00:00 +0000
1478+++ volleyball2d/fullscreen.cpp 2016-08-09 23:30:40 +0000
1479@@ -0,0 +1,47 @@
1480+/*
1481+ * Copyright (C) 2015
1482+ * Andrew Hayzen <ahayzen@gmail.com>
1483+ *
1484+ * This program is free software; you can redistribute it and/or modify
1485+ * it under the terms of the GNU General Public License as published by
1486+ * the Free Software Foundation; version 3.
1487+ *
1488+ * This program is distributed in the hope that it will be useful,
1489+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1490+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1491+ * GNU General Public License for more details.
1492+ *
1493+ * You should have received a copy of the GNU General Public License
1494+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1495+ */
1496+
1497+
1498+#include "fullscreen.h"
1499+
1500+#include <QDebug>
1501+#include <QQuickView>
1502+
1503+Fullscreen::Fullscreen(QObject *parent) :
1504+ QObject(parent)
1505+{
1506+}
1507+
1508+void Fullscreen::setFullscreen(bool state)
1509+{
1510+ qDebug() << "setFullscreen" << state;
1511+
1512+ if (state) {
1513+ m_view->showFullScreen();
1514+ } else {
1515+ m_view->showNormal();
1516+ }
1517+
1518+ emit fullscreenChanged(state);
1519+}
1520+
1521+void Fullscreen::setView(QQuickView *newView)
1522+{
1523+ this->m_view = newView;
1524+
1525+ emit viewChanged(newView);
1526+}
1527
1528=== added file 'volleyball2d/fullscreen.h'
1529--- volleyball2d/fullscreen.h 1970-01-01 00:00:00 +0000
1530+++ volleyball2d/fullscreen.h 2016-08-09 23:30:40 +0000
1531@@ -0,0 +1,43 @@
1532+/*
1533+ * Copyright (C) 2015
1534+ * Andrew Hayzen <ahayzen@gmail.com>
1535+ *
1536+ * This program is free software; you can redistribute it and/or modify
1537+ * it under the terms of the GNU General Public License as published by
1538+ * the Free Software Foundation; version 3.
1539+ *
1540+ * This program is distributed in the hope that it will be useful,
1541+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1542+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1543+ * GNU General Public License for more details.
1544+ *
1545+ * You should have received a copy of the GNU General Public License
1546+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1547+ */
1548+
1549+
1550+#ifndef FULLSCREEN_H
1551+#define FULLSCREEN_H
1552+
1553+#include <QObject>
1554+#include <QQuickView>
1555+
1556+class Fullscreen : public QObject
1557+{
1558+ Q_OBJECT
1559+public:
1560+ explicit Fullscreen(QObject *parent = 0);
1561+
1562+ QQuickView *view() const { return m_view; }
1563+
1564+public slots:
1565+ void setFullscreen(bool state);
1566+ void setView(QQuickView *newView);
1567+signals:
1568+ void fullscreenChanged(bool state);
1569+ void viewChanged(QQuickView *newView);
1570+private:
1571+ QQuickView *m_view;
1572+};
1573+
1574+#endif // FULLSCREEN_H
1575
1576=== added file 'volleyball2d/main.cpp'
1577--- volleyball2d/main.cpp 1970-01-01 00:00:00 +0000
1578+++ volleyball2d/main.cpp 2016-08-09 23:30:40 +0000
1579@@ -0,0 +1,98 @@
1580+/*
1581+ * Copyright (C) 2015
1582+ * Andrew Hayzen <ahayzen@gmail.com>
1583+ *
1584+ * This program is free software; you can redistribute it and/or modify
1585+ * it under the terms of the GNU General Public License as published by
1586+ * the Free Software Foundation; version 3.
1587+ *
1588+ * This program is distributed in the hope that it will be useful,
1589+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1590+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1591+ * GNU General Public License for more details.
1592+ *
1593+ * You should have received a copy of the GNU General Public License
1594+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1595+ */
1596+
1597+#include <QtCore/QLibrary>
1598+#include <QDebug>
1599+#include <QGuiApplication>
1600+#include <QProcessEnvironment>
1601+#include <QQmlApplicationEngine>
1602+#include <QQuickView>
1603+#include <QSettings>
1604+#include <QQmlProperty>
1605+#include <QQuickItem>
1606+
1607+#include "fullscreen.h"
1608+
1609+#define WINDOW_HEIGHT 40
1610+#define WINDOW_WIDTH 70
1611+
1612+
1613+int main(int argc, char *argv[])
1614+{
1615+ QGuiApplication app(argc, argv);
1616+ QGuiApplication::setApplicationName("com.ubuntu.developer.andrew-hayzen.volleyball2d");
1617+
1618+ // Necessary for Qt.labs.settings to work
1619+ // Ref.: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1354321
1620+ QCoreApplication::setOrganizationDomain(QGuiApplication::applicationName());
1621+
1622+ // The testability driver is only loaded by QApplication but not by QGuiApplication.
1623+ // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
1624+ if (QGuiApplication::arguments().contains(QLatin1String("-testability")) ||
1625+ qgetenv("QT_LOAD_TESTABILITY") == "1") {
1626+ QLibrary testLib(QLatin1String("qttestability"));
1627+ if (testLib.load()) {
1628+ typedef void (*TasInitialize)(void);
1629+ TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
1630+ if (initFunction) {
1631+ initFunction();
1632+ } else {
1633+ qCritical("Library qttestability resolve failed!");
1634+ }
1635+ } else {
1636+ qCritical("Library qttestability load failed!");
1637+ }
1638+ }
1639+
1640+ // Get GU for application
1641+ int gu = QProcessEnvironment::systemEnvironment().value("GRID_UNIT_PX", "8").toInt();
1642+
1643+ if (gu <= 0) {
1644+ gu = 8;
1645+ }
1646+
1647+ // Load main.qml file
1648+ QQuickView view;
1649+ view.setSource(QUrl(QStringLiteral("qrc:///main.qml")));
1650+ view.setObjectName("window");
1651+ view.setResizeMode(QQuickView::SizeRootObjectToView);
1652+ view.setHeight(WINDOW_HEIGHT * gu);
1653+ view.setWidth(WINDOW_WIDTH * gu);
1654+
1655+ // Connect to signal MainView::fullscreen(bool) to change QQuickView fullscreen state
1656+ Fullscreen fullscreenToggle;
1657+ fullscreenToggle.setView(&view);
1658+
1659+ if (view.status() == QQuickView::Ready) {
1660+ QObject *childObject = dynamic_cast<QObject *>(view.rootObject());
1661+
1662+ QObject::connect(childObject, SIGNAL(fullscreen(bool)), &fullscreenToggle, SLOT(setFullscreen(bool)));
1663+ } else {
1664+ qDebug() << "Could not open qml file";
1665+ }
1666+
1667+ // Load the app in windowed/fullscreen depending on settings
1668+ QSettings settings;
1669+
1670+ settings.beginGroup(QString("settings"));
1671+
1672+ fullscreenToggle.setFullscreen(settings.value(QString("fullscreen"), QVariant(true)).toBool());
1673+
1674+ settings.endGroup();
1675+
1676+ return app.exec();
1677+}
1678
1679=== renamed file 'main.qml' => 'volleyball2d/main.qml'
1680--- main.qml 2015-01-04 21:41:13 +0000
1681+++ volleyball2d/main.qml 2016-08-09 23:30:40 +0000
1682@@ -1,5 +1,5 @@
1683 /*
1684- * Copyright (C) 2014
1685+ * Copyright (C) 2014, 2015
1686 * Andrew Hayzen <ahayzen@gmail.com>
1687 *
1688 * This program is free software; you can redistribute it and/or modify
1689@@ -16,84 +16,83 @@
1690 */
1691
1692 import QtQuick 2.3
1693-import QtQuick.Window 2.1
1694-import Ubuntu.Components 1.1
1695+import Ubuntu.Components 1.3
1696 import Qt.labs.settings 1.0
1697
1698-Window {
1699- id: window
1700+MainView {
1701+ id: mainView
1702+ anchors {
1703+ fill: parent
1704+ }
1705+ applicationName: "com.ubuntu.developer.andrew-hayzen.volleyball2d"
1706+ automaticOrientation: true
1707+ objectName: "mainView"
1708+
1709 height: units.gu(40)
1710- objectName: "window"
1711- visibility: settings !== undefined && !settings.fullscreen ? Window.Windowed : Window.FullScreen
1712- visible: true
1713+ //objectName: "window"
1714+ //visibility: settings !== undefined && !settings.fullscreen ? Window.Windowed : Window.FullScreen
1715 width: units.gu(70)
1716
1717- MainView {
1718- id: mainView
1719- anchors {
1720- fill: parent
1721- }
1722- applicationName: "com.ubuntu.developer.andrew-hayzen.volleyball2d"
1723- automaticOrientation: true
1724- objectName: "mainView"
1725- useDeprecatedToolbar: false
1726-
1727- Settings {
1728- id: settings
1729- category: "settings"
1730-
1731- property bool aiDebugLayer: false
1732- property int gameMode: 0
1733- property int firstToXScore: -1
1734- property bool fullscreen: true
1735- property int highestScore: -1
1736- property int highestScoreTime: 120
1737- property int motionDeadZone: 3
1738- property double motionSensitivity: 0.75
1739- property int survivalScore: -1
1740- property int targetScore: 5
1741- property bool useMotion: true
1742- }
1743-
1744- PageStack {
1745- id: mainPageStack
1746-
1747- property bool landscape: width > height
1748-
1749- onLandscapeChanged: {
1750- if (landscape && (mainPageStack.currentPage === null || (mainPageStack.currentPage !== null && mainPageStack.currentPage.objectName === "rotateScreenPage"))) {
1751- if (mainPageStack.depth > 0) {
1752- mainPageStack.pop()
1753- }
1754-
1755- if (mainPageStack.depth === 0) {
1756- mainPageStack.pushPage("pages/GamePage.qml", {"objectName": "gamePage"})
1757- }
1758- } else if (!landscape && (mainPageStack.currentPage === null ||
1759- mainPageStack.currentPage.objectName !== "rotateScreenPage")) {
1760- mainPageStack.pushPage("pages/RotateScreenPage.qml", {objectName: "rotateScreenPage"});
1761- }
1762- }
1763-
1764- function pushPage(pageUrl, properties) {
1765- if (properties === undefined) {
1766- properties = {}
1767- }
1768-
1769- var comp = Qt.createComponent(pageUrl)
1770- var sprite = comp.createObject(mainPageStack, properties)
1771-
1772- if (sprite == null) { // Error Handling
1773- console.log("Error creating object");
1774- }
1775-
1776- mainPageStack.push(sprite);
1777- }
1778-
1779- Component.onCompleted: {
1780- if (landscape) {
1781- mainPageStack.pushPage("pages/GamePage.qml", {"objectName": "gamePage"})
1782- }
1783+ signal fullscreen(bool state)
1784+
1785+ Settings {
1786+ id: settings
1787+ category: "settings"
1788+
1789+ property bool aiDebugLayer: false
1790+ property int gameMode: 0
1791+ property int firstToXScore: -1
1792+ property bool fullscreen: true
1793+ property int highestScore: -1
1794+ property int highestScoreTime: 120
1795+ property int motionDeadZone: 3
1796+ property double motionSensitivity: 0.75
1797+ property int survivalScore: -1
1798+ property int targetScore: 5
1799+ property bool useMotion: true
1800+
1801+ // Call signal that cpp listens to
1802+ onFullscreenChanged: mainView.fullscreen(fullscreen);
1803+ }
1804+
1805+ PageStack {
1806+ id: mainPageStack
1807+
1808+ property bool landscape: width > height
1809+
1810+ onLandscapeChanged: {
1811+ if (landscape && (mainPageStack.currentPage === null || (mainPageStack.currentPage !== null && mainPageStack.currentPage.objectName === "rotateScreenPage"))) {
1812+ if (mainPageStack.depth > 0) {
1813+ mainPageStack.pop()
1814+ }
1815+
1816+ if (mainPageStack.depth === 0) {
1817+ mainPageStack.pushPage("qrc:///pages/MenuPage.qml", {"objectName": "menuPage"})
1818+ }
1819+ } else if (!landscape && (mainPageStack.currentPage === null ||
1820+ mainPageStack.currentPage.objectName !== "rotateScreenPage")) {
1821+ mainPageStack.pushPage("qrc:///pages/RotateScreenPage.qml", {objectName: "rotateScreenPage"});
1822+ }
1823+ }
1824+
1825+ function pushPage(pageUrl, properties) {
1826+ if (properties === undefined) {
1827+ properties = {}
1828+ }
1829+
1830+ var comp = Qt.createComponent(pageUrl)
1831+ var sprite = comp.createObject(mainPageStack, properties)
1832+
1833+ if (sprite == null) { // Error Handling
1834+ console.log("Error creating object");
1835+ }
1836+
1837+ mainPageStack.push(sprite);
1838+ }
1839+
1840+ Component.onCompleted: {
1841+ if (landscape && mainPageStack.depth === 0) {
1842+ mainPageStack.pushPage("qrc:///pages/MenuPage.qml", {"objectName": "menuPage"})
1843 }
1844 }
1845 }
1846
1847=== renamed directory 'pages' => 'volleyball2d/pages'
1848=== added file 'volleyball2d/pages/FinishPage.qml'
1849--- volleyball2d/pages/FinishPage.qml 1970-01-01 00:00:00 +0000
1850+++ volleyball2d/pages/FinishPage.qml 2016-08-09 23:30:40 +0000
1851@@ -0,0 +1,93 @@
1852+/*
1853+ * Copyright (C) 2014, 2015
1854+ * Andrew Hayzen <ahayzen@gmail.com>
1855+ *
1856+ * This program is free software; you can redistribute it and/or modify
1857+ * it under the terms of the GNU General Public License as published by
1858+ * the Free Software Foundation; version 3.
1859+ *
1860+ * This program is distributed in the hope that it will be useful,
1861+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1862+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1863+ * GNU General Public License for more details.
1864+ *
1865+ * You should have received a copy of the GNU General Public License
1866+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1867+ */
1868+
1869+import Ubuntu.Components 1.3
1870+import QtQuick 2.3
1871+import "../components"
1872+
1873+
1874+ScalePage {
1875+ header: PageHeader {
1876+ visible: false
1877+ }
1878+ objectName: "finishPage"
1879+
1880+ property int computerScore: 0
1881+ property int humanScore: 0
1882+ property bool newHighScore: false
1883+ property int time: 0
1884+ property bool timeBased: false
1885+
1886+ MouseArea {
1887+ id: finishedMouseArea
1888+ anchors {
1889+ fill: parent
1890+ }
1891+ onClicked: {
1892+ mainPageStack.pop()
1893+ mainPageStack.pop()
1894+ }
1895+
1896+ Rectangle {
1897+ anchors {
1898+ fill: parent
1899+ }
1900+ color: "#000"
1901+ opacity: .2
1902+ }
1903+
1904+ Column {
1905+ anchors {
1906+ centerIn: parent
1907+ }
1908+ spacing: units.gu(2)
1909+
1910+ Label {
1911+ anchors {
1912+ horizontalCenter: parent.horizontalCenter
1913+ }
1914+ fontSize: "x-large"
1915+ text: timeBased ? i18n.tr("New fastest time") + ": " + time : i18n.tr("New highest score") + ": " + humanScore
1916+ visible: newHighScore
1917+ }
1918+
1919+ Label {
1920+ anchors {
1921+ horizontalCenter: parent.horizontalCenter
1922+ }
1923+ fontSize: "x-large"
1924+ text: i18n.tr("Final Score")
1925+ }
1926+
1927+ Label {
1928+ anchors {
1929+ horizontalCenter: parent.horizontalCenter
1930+ }
1931+ fontSize: "large"
1932+ text: i18n.tr("You") + ": " + humanScore +
1933+ (timeBased ? " " + i18n.tr("Computer") + ": " + computerScore + " " + i18n.tr("Time") + ": " + time : "")
1934+ }
1935+
1936+ Label {
1937+ anchors {
1938+ horizontalCenter: parent.horizontalCenter
1939+ }
1940+ text: i18n.tr("Tap to return to the menu")
1941+ }
1942+ }
1943+ }
1944+}
1945
1946=== modified file 'volleyball2d/pages/GamePage.qml'
1947--- pages/GamePage.qml 2015-01-04 21:41:13 +0000
1948+++ volleyball2d/pages/GamePage.qml 2016-08-09 23:30:40 +0000
1949@@ -1,5 +1,5 @@
1950 /*
1951- * Copyright (C) 2014
1952+ * Copyright (C) 2014, 2015
1953 * Andrew Hayzen <ahayzen@gmail.com>
1954 *
1955 * This program is free software; you can redistribute it and/or modify
1956@@ -16,84 +16,178 @@
1957 */
1958
1959 import QtQuick 2.3
1960-import Ubuntu.Components 1.1
1961+import Ubuntu.Components 1.3
1962 import Bacon2D 1.0
1963-import "../scenes"
1964
1965 Page {
1966- onVisibleChanged: {
1967- if (!visible && game.currentScene === gameScene) {
1968- gameScene.pause()
1969+ header: PageHeader {
1970+ visible: false
1971+ }
1972+
1973+ visible: true
1974+
1975+ onVisibleChanged: { // User rotate device so RotateScreenPage is pushed
1976+ if (!visible && mainPageStack.currentPage.objectName === "rotateScreenPage" && gameSceneLoader.status === Loader.Ready) {
1977+ gameSceneLoader.item.pause()
1978 }
1979 }
1980
1981 Game {
1982 id: game
1983- currentScene: menuScene
1984+ anchors {
1985+ left: parent.left
1986+ top: parent.top
1987+ }
1988+
1989+ currentScene: gameSceneLoader.item
1990 height: parent.height / scale
1991 scale: parent.width / width // scale the scenes to meet the width
1992 transformOrigin: Qt.TopLeftCorner
1993 width: units.gu(70)
1994- x: 0
1995- y: 0
1996-
1997- MenuScene {
1998- id: menuScene
1999- objectName: "menuScene"
2000- onStartGame: {
2001- game.currentScene = gameScene
2002- gameScene.restart()
2003- }
2004- }
2005-
2006- FinishScene {
2007- id: finishScene
2008- objectName: "finishScene"
2009- onFinishedComplete: game.currentScene = menuScene
2010- }
2011-
2012- GameScene {
2013- id: gameScene
2014- objectName: "gameScene"
2015-
2016- onEndGame: game.currentScene = menuScene
2017-
2018- onGameFinished: {
2019- // Tell finish scene about the scores
2020- finishScene.computerScore = computer.score
2021- finishScene.humanScore = human.score
2022- finishScene.time = time
2023- finishScene.timeBased = settings.gameMode === modeFirstToX
2024-
2025- if (settings.gameMode === modeFirstToX) {
2026- // Save new time if it is faster
2027- if (human.score > computer.score &&
2028- (time < settings.firstToXScore || settings.firstToXScore === -1)) {
2029- settings.firstToXScore = time
2030- finishScene.newHighScore = true
2031- } else {
2032- finishScene.newHighScore = false
2033- }
2034- } else if (settings.gameMode === modeHighestScore) {
2035- // Save the new highest
2036- if (human.score > settings.highestScore || settings.highestScore === -1) {
2037- settings.highestScore = human.score
2038- finishScene.newHighScore = true
2039- } else {
2040- finishScene.newHighScore = false
2041- }
2042- } else if (settings.gameMode === modeSurvival) {
2043- // Save new longest survival
2044- if (human.score > settings.survivalScore || settings.survivalScore === -1) {
2045- settings.survivalScore = human.score
2046- finishScene.newHighScore = true
2047- } else {
2048- finishScene.newHighScore = false
2049- }
2050- }
2051-
2052- // Switch to the finish scene
2053- game.currentScene = finishScene;
2054+
2055+ property bool pageLoaded: false
2056+
2057+ // Scenes loaded once the page has loaded otherwise height is infinity
2058+ Loader {
2059+ id: gameSceneLoader
2060+ active: parent.pageLoaded
2061+ asynchronous: true
2062+ source: "qrc:///scenes/GameScene.qml"
2063+
2064+ onStatusChanged: {
2065+ if (status === Loader.Ready) {
2066+ gameSceneLoader.item.restart()
2067+ }
2068+ }
2069+
2070+ Connections {
2071+ target: gameSceneLoader.item
2072+ onEndGame: {
2073+ game.gameState = Bacon2D.Paused
2074+ mainPageStack.pop()
2075+ }
2076+ onGameFinished: {
2077+ var newHighScore = false;
2078+
2079+ if (settings.gameMode === gameSceneLoader.item.modeFirstToX) {
2080+ // Save new time if it is faster
2081+ if (human.score > computer.score &&
2082+ (time < settings.firstToXScore || settings.firstToXScore === -1)) {
2083+ settings.firstToXScore = time
2084+ newHighScore = true
2085+ } else {
2086+ newHighScore = false
2087+ }
2088+ } else if (settings.gameMode === gameSceneLoader.item.modeHighestScore) {
2089+ // Save the new highest
2090+ if (human.score > settings.highestScore || settings.highestScore === -1) {
2091+ settings.highestScore = human.score
2092+ newHighScore = true
2093+ } else {
2094+ newHighScore = false
2095+ }
2096+ } else if (settings.gameMode === gameSceneLoader.item.modeSurvival) {
2097+ // Save new longest survival
2098+ if (human.score > settings.survivalScore || settings.survivalScore === -1) {
2099+ settings.survivalScore = human.score
2100+ newHighScore = true
2101+ } else {
2102+ newHighScore = false
2103+ }
2104+ } else {
2105+ console.debug("Unknown gameMode to save!")
2106+ }
2107+
2108+ // Switch to the finish page and tell it about the scores
2109+ mainPageStack.push("qrc:///pages/FinishPage.qml", {
2110+ "objectName": "finishPage",
2111+ "computerScore": computer.score,
2112+ "humanScore": human.score,
2113+ "time": time,
2114+ "timeBased": settings.gameMode === gameSceneLoader.item.modeFirstToX,
2115+ "newHighScore": newHighScore
2116+ })
2117+
2118+ game.gameState = Bacon2D.Paused
2119+ }
2120+ onPause: {
2121+ // don't show pauseOverlay if pointOverlay is shown
2122+ if (!pointOverlayLoader.visible && pointOverlayLoader.status === Loader.Ready) {
2123+ pauseOverlayLoader.visible = true
2124+ }
2125+
2126+ game.gameState = Bacon2D.Paused
2127+ }
2128+ onResume: {
2129+ if (pauseOverlayLoader.status === Loader.Ready) {
2130+ pauseOverlayLoader.item.resume()
2131+ }
2132+ }
2133+ onRoundWon: {
2134+ // Increment score and store last winner
2135+ winner.score++;
2136+ gameSceneLoader.item.lastWinner = winner;
2137+
2138+ // Check if the game has finished
2139+ if (settings.gameMode === gameSceneLoader.item.modeFirstToX &&
2140+ winner.score >= settings.targetScore) {
2141+ gameSceneLoader.item.gameFinished(human, computer, time);
2142+ } else if (settings.gameMode === gameSceneLoader.item.modeSurvival && winner === computer) {
2143+ gameSceneLoader.item.gameFinished(human, computer, time);
2144+ } else {
2145+ pointOverlayLoader.visible = true;
2146+ pointOverlayLoader.item.userWon = winner === human;
2147+ }
2148+ }
2149+ }
2150+ }
2151+
2152+ Component.onCompleted: pageLoaded = true
2153+ }
2154+
2155+ Loader {
2156+ id: pauseOverlayLoader
2157+ anchors {
2158+ fill: parent
2159+ }
2160+ asynchronous: true
2161+ source: "qrc:///components/PauseOverlay.qml"
2162+ visible: false
2163+
2164+ Connections {
2165+ target: pauseOverlayLoader.item
2166+ onEndGame: gameSceneLoader.item.endGame()
2167+ onResume: {
2168+ pauseOverlayLoader.visible = false;
2169+ game.gameState = Bacon2D.Running
2170+
2171+ // Ensure focus is correct
2172+ game.currentScene.forceActiveFocus()
2173+ }
2174+ }
2175+ }
2176+
2177+ // Point overlay at the end of a round
2178+ Loader {
2179+ id: pointOverlayLoader
2180+ anchors {
2181+ fill: parent
2182+ }
2183+ asynchronous: true
2184+ source: "qrc:///components/PointOverlay.qml"
2185+ visible: false
2186+
2187+ onVisibleChanged: {
2188+ if (visible) {
2189+ game.gameState = Bacon2D.Paused
2190+ }
2191+ }
2192+
2193+ Connections {
2194+ target: pointOverlayLoader.item
2195+ onClose: {
2196+ pointOverlayLoader.visible = false
2197+ gameSceneLoader.item.reset()
2198 }
2199 }
2200 }
2201
2202=== modified file 'volleyball2d/pages/HighScorePage.qml'
2203--- pages/HighScorePage.qml 2015-01-04 21:41:13 +0000
2204+++ volleyball2d/pages/HighScorePage.qml 2016-08-09 23:30:40 +0000
2205@@ -16,15 +16,34 @@
2206 */
2207
2208 import QtQuick 2.3
2209-import Ubuntu.Components 1.1
2210-import Ubuntu.Components.ListItems 0.1 as ListItem
2211+import Ubuntu.Components 1.3
2212
2213 Page {
2214- title: i18n.tr("High Scores")
2215+ header: PageHeader {
2216+ leadingActionBar {
2217+ actions: [
2218+ Action {
2219+ iconName: "back"
2220+ text: i18n.tr("Back")
2221+
2222+ onTriggered: mainPageStack.pop()
2223+ }
2224+ ]
2225+ }
2226+ title: i18n.tr("High Scores")
2227+ }
2228+
2229+ // Hack for autopilot otherwise HighScorePage appears as Page11
2230+ // due to bug 1341671 it is required that there is a property so that
2231+ // qml doesn't optimise using the parent type
2232+ property bool bug1341671workaround: true
2233
2234 Flickable {
2235 anchors {
2236- fill: parent
2237+ bottom: parent.bottom
2238+ left: parent.left
2239+ right: parent.right
2240+ top: parent.header.bottom
2241 }
2242 height: parent.height
2243 contentHeight: scoresColumn.childrenRect.height
2244@@ -35,47 +54,62 @@
2245 fill: parent
2246 }
2247
2248- ListItem.Header {
2249- text: i18n.tr("First to") + " " + settings.targetScore
2250- }
2251-
2252- ListItem.SingleValue {
2253- objectName: "firstToXScore"
2254- text: settings.firstToXScore < 0 ? i18n.tr("N/A") : settings.firstToXScore + " " + i18n.tr("seconds")
2255- }
2256-
2257- ListItem.Header {
2258- text: i18n.tr("Highest Score")
2259- }
2260-
2261- ListItem.SingleValue {
2262- objectName: "highestScore"
2263- text: settings.highestScore < 0 ? i18n.tr("N/A") : settings.highestScore + " " + i18n.tr("points") || i18n.tr("N/A")
2264- }
2265-
2266- ListItem.Header {
2267- text: i18n.tr("Survival")
2268- }
2269-
2270- ListItem.SingleValue {
2271- objectName: "survivalScore"
2272- text: settings.survivalScore < 0 ? i18n.tr("N/A") : settings.survivalScore + " " + i18n.tr("points") || i18n.tr("N/A")
2273- }
2274-
2275- ListItem.Empty {
2276- Button {
2277- anchors {
2278- centerIn: parent
2279- }
2280- text: i18n.tr("Reset")
2281-
2282- onClicked: { // TODO: add autopilot tests
2283- settings.firstToXScore = -1
2284- settings.highestScore = -1
2285- settings.survivalScore = -1
2286- }
2287- }
2288- showDivider: false
2289+ ListItem {
2290+ ListItemLayout {
2291+ subtitle {
2292+ objectName: "firstToXScore"
2293+ text: settings.firstToXScore < 0 ? i18n.tr("N/A") : settings.firstToXScore + " " + i18n.tr("seconds")
2294+ }
2295+ title {
2296+ text: i18n.tr("First to") + " " + settings.targetScore
2297+ }
2298+ }
2299+ }
2300+
2301+ ListItem {
2302+ ListItemLayout {
2303+ subtitle {
2304+ objectName: "highestScore"
2305+ text: settings.highestScore < 0 ? i18n.tr("N/A") : settings.highestScore + " " + i18n.tr("points") || i18n.tr("N/A")
2306+ }
2307+ title {
2308+ text: i18n.tr("Highest Score")
2309+ }
2310+ }
2311+ }
2312+
2313+ ListItem {
2314+ ListItemLayout {
2315+ subtitle {
2316+ objectName: "survivalScore"
2317+ text: settings.survivalScore < 0 ? i18n.tr("N/A") : settings.survivalScore + " " + i18n.tr("points") || i18n.tr("N/A")
2318+ }
2319+ title {
2320+ text: i18n.tr("Survival")
2321+ }
2322+ }
2323+ }
2324+
2325+ ListItem {
2326+ divider {
2327+ visible: false
2328+ }
2329+
2330+ ListItemLayout {
2331+ Button {
2332+ anchors {
2333+ centerIn: parent
2334+ }
2335+ SlotsLayout.position: SlotsLayout.Center
2336+ text: i18n.tr("Reset")
2337+
2338+ onClicked: { // TODO: add autopilot tests
2339+ settings.firstToXScore = -1
2340+ settings.highestScore = -1
2341+ settings.survivalScore = -1
2342+ }
2343+ }
2344+ }
2345 }
2346 }
2347 }
2348
2349=== added file 'volleyball2d/pages/MenuPage.qml'
2350--- volleyball2d/pages/MenuPage.qml 1970-01-01 00:00:00 +0000
2351+++ volleyball2d/pages/MenuPage.qml 2016-08-09 23:30:40 +0000
2352@@ -0,0 +1,210 @@
2353+/*
2354+ * Copyright (C) 2014, 2015
2355+ * Andrew Hayzen <ahayzen@gmail.com>
2356+ *
2357+ * This program is free software; you can redistribute it and/or modify
2358+ * it under the terms of the GNU General Public License as published by
2359+ * the Free Software Foundation; version 3.
2360+ *
2361+ * This program is distributed in the hope that it will be useful,
2362+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2363+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2364+ * GNU General Public License for more details.
2365+ *
2366+ * You should have received a copy of the GNU General Public License
2367+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2368+ */
2369+
2370+import Ubuntu.Components 1.3
2371+import QtQuick 2.3
2372+import "../components"
2373+
2374+
2375+ScalePage {
2376+ objectName: "menuPage"
2377+
2378+ header: PageHeader {
2379+ visible: false
2380+ }
2381+
2382+ // Hack for autopilot otherwise MenuPage appears as ScalePage
2383+ // due to bug 1341671 it is required that there is a property so that
2384+ // qml doesn't optimise using the parent type
2385+ property bool bug1341671workaround: true
2386+
2387+ Rectangle {
2388+ anchors {
2389+ fill: parent
2390+ }
2391+ color: "#000"
2392+ opacity: .2
2393+ }
2394+
2395+ Column {
2396+ anchors {
2397+ centerIn: parent
2398+ }
2399+ spacing: units.gu(1)
2400+
2401+ Label {
2402+ anchors {
2403+ left: mainLabel.right
2404+ }
2405+ color: "#F00"
2406+ fontSize: "large"
2407+ rotation: -20
2408+ text: i18n.tr("Beta") + "!"
2409+ }
2410+
2411+ Label {
2412+ id: mainLabel
2413+ anchors {
2414+ horizontalCenter: parent.horizontalCenter
2415+ }
2416+ color: "#111"
2417+ fontSize: "x-large"
2418+ objectName: "mainLabel"
2419+ text: i18n.tr("Volleyball 2D")
2420+ }
2421+
2422+ Row {
2423+ anchors {
2424+ horizontalCenter: parent.horizontalCenter
2425+ }
2426+ spacing: units.gu(1)
2427+
2428+ Repeater {
2429+ id: modeRepeater
2430+ model: [
2431+ i18n.tr("First to") + " " + settings.targetScore,
2432+ i18n.tr("Highest Score"),
2433+ i18n.tr("Survival")
2434+ ]
2435+ objectName: "modeRepeater"
2436+
2437+ property var secondaryText: [
2438+ "",
2439+ i18n.tr("Within a certain amount of time"),
2440+ i18n.tr("Highest score without losing a point")
2441+ ]
2442+ property int selectedIndex: settings.gameMode
2443+
2444+ delegate: Button {
2445+ color: selected ? UbuntuColors.darkGrey : UbuntuColors.coolGrey
2446+ height: units.gu(10)
2447+ width: selected ? units.gu(20) : units.gu(10)
2448+
2449+ property bool selected: index === settings.gameMode
2450+
2451+ onClicked: settings.gameMode = index
2452+
2453+ Behavior on color {
2454+ ColorAnimation { duration: 200 }
2455+ }
2456+
2457+ Behavior on width {
2458+ NumberAnimation {
2459+ id: delegateAnimation
2460+ duration: 200
2461+ }
2462+ }
2463+
2464+ Column {
2465+ anchors {
2466+ left: parent.left
2467+ leftMargin: units.gu(1)
2468+ right: parent.right
2469+ rightMargin: units.gu(1)
2470+ verticalCenter: parent.verticalCenter
2471+ }
2472+
2473+ Label {
2474+ anchors {
2475+ left: parent.left
2476+ right: parent.right
2477+ }
2478+ color: selected ? "#FFF" : UbuntuColors.darkGrey
2479+ horizontalAlignment: Text.AlignHCenter
2480+ text: modelData
2481+ verticalAlignment: Text.AlignVCenter
2482+ wrapMode: Text.WordWrap
2483+
2484+ Behavior on color {
2485+ ColorAnimation { duration: 200 }
2486+ }
2487+ }
2488+
2489+ Label {
2490+ anchors {
2491+ left: parent.left
2492+ right: parent.right
2493+ }
2494+ color: "#FFF"
2495+ horizontalAlignment: Text.AlignHCenter
2496+ text: modeRepeater.secondaryText[index]
2497+ verticalAlignment: Text.AlignVCenter
2498+ opacity: visible ? 1 : 0
2499+ visible: selected && modeRepeater.secondaryText[index] && !delegateAnimation.running
2500+ wrapMode: Text.WordWrap
2501+
2502+ Behavior on opacity {
2503+ NumberAnimation { duration: 200 }
2504+ }
2505+ }
2506+ }
2507+ }
2508+ }
2509+ }
2510+
2511+ Label {
2512+ anchors {
2513+ horizontalCenter: parent.horizontalCenter
2514+ }
2515+ horizontalAlignment: Text.AlignHCenter
2516+ fontSize: "small"
2517+ objectName: "instructionLabel"
2518+ text: settings.useMotion ?
2519+ i18n.tr("Rotate your device to move your player") + "\n"
2520+ + i18n.tr("Tap to jump")
2521+ :
2522+ i18n.tr("Press on the left or right of the screen to move") + "\n"
2523+ + i18n.tr("Tap in the center or a two finger press to jump")
2524+ }
2525+
2526+ Button {
2527+ anchors {
2528+ horizontalCenter: parent.horizontalCenter
2529+ }
2530+ objectName: "playButton"
2531+ text: i18n.tr("Play")
2532+
2533+ onClicked: mainPageStack.pushPage("qrc:///pages/GamePage.qml", {"objectName": "gamePage"})
2534+ }
2535+ }
2536+
2537+ Row {
2538+ anchors {
2539+ bottom: parent.bottom
2540+ bottomMargin: units.gu(2)
2541+ right: parent.right
2542+ rightMargin: units.gu(2)
2543+ }
2544+ spacing: units.gu(1)
2545+
2546+ Button {
2547+ iconName: "favorite-selected"
2548+ objectName: "highScoreButton"
2549+ height: units.gu(5)
2550+ width: height
2551+ onClicked: mainPageStack.pushPage("qrc:///pages/HighScorePage.qml", {"objectName": "highScorePage"})
2552+ }
2553+
2554+ Button {
2555+ iconName: "settings"
2556+ objectName: "settingsButton"
2557+ height: units.gu(5)
2558+ width: height
2559+ onClicked: mainPageStack.pushPage("qrc:///pages/SettingsPage.qml", {"objectName": "settingsPage"})
2560+ }
2561+ }
2562+}
2563
2564=== modified file 'volleyball2d/pages/RotateScreenPage.qml'
2565--- pages/RotateScreenPage.qml 2015-01-04 21:41:13 +0000
2566+++ volleyball2d/pages/RotateScreenPage.qml 2016-08-09 23:30:40 +0000
2567@@ -1,5 +1,5 @@
2568 /*
2569- * Copyright (C) 2014
2570+ * Copyright (C) 2014, 2015
2571 * Andrew Hayzen <ahayzen@gmail.com>
2572 *
2573 * This program is free software; you can redistribute it and/or modify
2574@@ -16,10 +16,15 @@
2575 */
2576
2577 import Bacon2D 1.0
2578-import Ubuntu.Components 1.1
2579+import Ubuntu.Components 1.3
2580 import QtQuick 2.3
2581
2582 Page {
2583+ header: PageHeader {
2584+ visible: false
2585+ }
2586+ objectName: "rotateScreenPage"
2587+
2588 Rectangle {
2589 anchors {
2590 fill: parent
2591@@ -34,5 +39,7 @@
2592 }
2593 fontSize: "x-large"
2594 text: i18n.tr("Please rotate your device")
2595+ width: parent.width
2596+ wrapMode: Text.WordWrap
2597 }
2598 }
2599
2600=== modified file 'volleyball2d/pages/SettingsPage.qml'
2601--- pages/SettingsPage.qml 2015-01-04 21:41:13 +0000
2602+++ volleyball2d/pages/SettingsPage.qml 2016-08-09 23:30:40 +0000
2603@@ -16,16 +16,26 @@
2604 */
2605
2606 import QtQuick 2.3
2607-import Ubuntu.Components 1.1
2608-import Ubuntu.Components.ListItems 0.1 as ListItem
2609+import Ubuntu.Components 1.3
2610
2611 Page {
2612 id: settingsPage
2613- title: i18n.tr("Settings")
2614+ header: PageHeader {
2615+ title: i18n.tr("Settings")
2616+ }
2617+
2618+
2619+ // Hack for autopilot otherwise SettingsPage appears as Page11
2620+ // due to bug 1341671 it is required that there is a property so that
2621+ // qml doesn't optimise using the parent type
2622+ property bool bug1341671workaround: true
2623
2624 Flickable {
2625 anchors {
2626- fill: parent
2627+ bottom: parent.bottom
2628+ left: parent.left
2629+ right: parent.right
2630+ top: parent.header.bottom
2631 }
2632 height: parent.height
2633 contentHeight: settingsColumn.childrenRect.height
2634@@ -37,94 +47,192 @@
2635 fill: parent
2636 }
2637
2638- ListItem.Header {
2639- text: i18n.tr("Controls")
2640- }
2641-
2642- ListItem.Standard {
2643- control: CheckBox {
2644- checked: settings.useMotion
2645- objectName: "motionCheckBox"
2646- onClicked: settings.useMotion = !settings.useMotion
2647- }
2648- text: i18n.tr("Use motion")
2649- }
2650-
2651- ListItem.Standard {
2652- control: Slider {
2653- live: true
2654- minimumValue: 0
2655- maximumValue: 5
2656- objectName: "motionDeadZoneSlider"
2657- value: settings.motionDeadZone
2658- width: settingsPage.width / 3
2659- onValueChanged: settings.motionDeadZone = value
2660- }
2661+ ListItem {
2662+ height: layoutControls.height + (divider.visible ? divider.height : 0)
2663+
2664+ ListItemLayout {
2665+ id: layoutControls
2666+ title {
2667+ font {
2668+ bold: true
2669+ }
2670+ text: i18n.tr("Controls")
2671+ }
2672+ }
2673+ }
2674+
2675+ ListItem {
2676+ height: layoutUseMotion.height + (divider.visible ? divider.height : 0)
2677+
2678+ ListItemLayout {
2679+ id: layoutUseMotion
2680+ title {
2681+ text: i18n.tr("Use motion")
2682+ }
2683+
2684+ CheckBox {
2685+ checked: settings.useMotion
2686+ objectName: "motionCheckBox"
2687+ onClicked: settings.useMotion = !settings.useMotion
2688+
2689+ SlotsLayout.position: SlotsLayout.Trailing
2690+ }
2691+ }
2692+ }
2693+
2694+ ListItem {
2695 enabled: settings.useMotion
2696 objectName: "motionDeadZoneListItem"
2697- text: i18n.tr("Motion deadzone")
2698+ height: layoutMotionDeadzone.height + (divider.visible ? divider.height : 0)
2699+
2700+ ListItemLayout {
2701+ id: layoutMotionDeadzone
2702+ title {
2703+ text: i18n.tr("Motion deadzone")
2704+ }
2705+
2706+ Slider {
2707+ live: true
2708+ minimumValue: 0
2709+ maximumValue: 5
2710+ objectName: "motionDeadZoneSlider"
2711+ stepSize: 1.0
2712+ value: settings.motionDeadZone
2713+ width: settingsPage.width / 3
2714+
2715+ SlotsLayout.position: SlotsLayout.Trailing
2716+
2717+ onValueChanged: settings.motionDeadZone = value
2718+ }
2719+
2720+ // FIXME: Hack to disable clipping Item parent of layout
2721+ Component.onCompleted: parent.clip = false
2722+ }
2723 }
2724
2725- ListItem.Standard {
2726- control: Slider {
2727- live: true
2728- function formatValue(v) { return v.toFixed(2) }
2729- minimumValue: 0.5
2730- maximumValue: 1.0
2731- objectName: "motionSensitivitySlider"
2732- value: settings.motionSensitivity
2733- width: settingsPage.width / 3
2734- onValueChanged: settings.motionSensitivity = value
2735- }
2736+ ListItem {
2737 enabled: settings.useMotion
2738 objectName: "motionSensitivityListItem"
2739- text: i18n.tr("Motion sensitivity")
2740- }
2741-
2742- ListItem.Header {
2743- text: i18n.tr("Game")
2744- }
2745-
2746- ListItem.Standard {
2747- control: CheckBox {
2748- checked: settings.fullscreen
2749- objectName: "fullscreenCheckBox"
2750- onClicked: settings.fullscreen = !settings.fullscreen
2751- }
2752- text: i18n.tr("Fullscreen")
2753- }
2754-
2755- ListItem.Header {
2756- text: i18n.tr("Debug")
2757- }
2758-
2759- ListItem.Standard {
2760- text: i18n.tr("AI Debug Layer")
2761- control: CheckBox {
2762- checked: settings.aiDebugLayer
2763- objectName: "aiDebugCheckBox"
2764- onClicked: settings.aiDebugLayer = !settings.aiDebugLayer
2765- }
2766- }
2767-
2768- ListItem.Empty {
2769- Button {
2770- anchors {
2771- centerIn: parent
2772- }
2773- text: i18n.tr("Reset")
2774-
2775- onClicked: { // TODO: add autopilot tests
2776- settings.useMotion = true
2777- settings.motionDeadZone = 3
2778- settings.motionSensitivity = 0.75
2779- settings.fullscreen = true
2780- settings.aiDebugLayer = false
2781-
2782- mainPageStack.pop() // return back to the menu
2783- }
2784- }
2785- showDivider: false
2786+ height: layoutMotionSensitivity.height + (divider.visible ? divider.height : 0)
2787+
2788+ ListItemLayout {
2789+ id: layoutMotionSensitivity
2790+ title {
2791+ text: i18n.tr("Motion sensitivity")
2792+ }
2793+
2794+ Slider {
2795+ live: true
2796+ function formatValue(v) { return v.toFixed(2) }
2797+ minimumValue: 0.5
2798+ maximumValue: 1.0
2799+ objectName: "motionSensitivitySlider"
2800+ value: settings.motionSensitivity
2801+ width: settingsPage.width / 3
2802+
2803+ SlotsLayout.position: SlotsLayout.Trailing
2804+
2805+ onValueChanged: settings.motionSensitivity = value
2806+ }
2807+
2808+ // FIXME: Hack to disable clipping Item parent of layout
2809+ Component.onCompleted: parent.clip = false
2810+ }
2811+ }
2812+
2813+ ListItem {
2814+ height: layoutGame.height + (divider.visible ? divider.height : 0)
2815+
2816+ ListItemLayout {
2817+ id: layoutGame
2818+ title {
2819+ font {
2820+ bold: true
2821+ }
2822+ text: i18n.tr("Game")
2823+ }
2824+ }
2825+ }
2826+
2827+ ListItem {
2828+ height: layoutFullscreen.height + (divider.visible ? divider.height : 0)
2829+
2830+ ListItemLayout {
2831+ id: layoutFullscreen
2832+ title {
2833+ text: i18n.tr("Fullscreen")
2834+ }
2835+
2836+ CheckBox {
2837+ checked: settings.fullscreen
2838+ objectName: "fullscreenCheckBox"
2839+
2840+ SlotsLayout.position: SlotsLayout.Trailing
2841+
2842+ onClicked: settings.fullscreen = !settings.fullscreen
2843+ }
2844+ }
2845+ }
2846+
2847+ ListItem {
2848+ height: layoutDebug.height + (divider.visible ? divider.height : 0)
2849+
2850+ ListItemLayout {
2851+ id: layoutDebug
2852+ title {
2853+ font {
2854+ bold: true
2855+ }
2856+ text: i18n.tr("Debug")
2857+ }
2858+ }
2859+ }
2860+
2861+ ListItem {
2862+ height: layoutAIDebugLayer.height + (divider.visible ? divider.height : 0)
2863+
2864+ ListItemLayout {
2865+ id: layoutAIDebugLayer
2866+ title {
2867+ text: i18n.tr("AI Debug Layer")
2868+ }
2869+
2870+ CheckBox {
2871+ checked: settings.aiDebugLayer
2872+ objectName: "aiDebugCheckBox"
2873+
2874+ SlotsLayout.position: SlotsLayout.Trailing
2875+
2876+ onClicked: settings.aiDebugLayer = !settings.aiDebugLayer
2877+ }
2878+ }
2879+ }
2880+
2881+ ListItem {
2882+ height: layoutReset.height + (divider.visible ? divider.height : 0)
2883+
2884+ ListItemLayout {
2885+ id: layoutReset
2886+
2887+ Button {
2888+ anchors {
2889+ centerIn: parent
2890+ }
2891+ text: i18n.tr("Reset")
2892+
2893+ SlotsLayout.position: SlotsLayout.Center
2894+
2895+ onClicked: { // TODO: add autopilot tests
2896+ settings.useMotion = true
2897+ settings.motionDeadZone = 3
2898+ settings.motionSensitivity = 0.75
2899+ settings.fullscreen = true
2900+ settings.aiDebugLayer = false
2901+
2902+ mainPageStack.pop() // return back to the menu
2903+ }
2904+ }
2905+ }
2906 }
2907 }
2908 }
2909
2910=== renamed directory 'scenes' => 'volleyball2d/scenes'
2911=== modified file 'volleyball2d/scenes/GameScene.qml'
2912--- scenes/GameScene.qml 2015-03-31 23:29:42 +0000
2913+++ volleyball2d/scenes/GameScene.qml 2016-08-09 23:30:40 +0000
2914@@ -1,5 +1,5 @@
2915 /*
2916- * Copyright (C) 2014
2917+ * Copyright (C) 2014, 2015
2918 * Andrew Hayzen <ahayzen@gmail.com>
2919 *
2920 * This program is free software; you can redistribute it and/or modify
2921@@ -16,21 +16,21 @@
2922 */
2923
2924 import Bacon2D 1.0
2925-import Ubuntu.Components 1.1
2926+import Ubuntu.Components 1.3
2927 import QtFeedback 5.0
2928 import QtQuick 2.3
2929 import QtSensors 5.3
2930 import "../components"
2931
2932 Scene {
2933- height: parent.height
2934+ id: gameScene
2935+ anchors {
2936+ fill: parent
2937+ }
2938 gravity: Qt.point(0, 20)
2939+ objectName: "gameScene"
2940 pixelsPerMeter: units.gu(3)
2941 physics: true
2942- running: false
2943- viewport: Viewport {
2944- }
2945- width: parent.width
2946
2947 property int netDepth: units.gu(1)
2948 property int wallDepth: units.gu(.5)
2949@@ -45,33 +45,9 @@
2950
2951 signal endGame()
2952 signal gameFinished(Character human, Character computer, int time)
2953- signal roundWon(Character winner)
2954-
2955- onEndGame: running = false
2956-
2957- onRoundWon: {
2958- // Increment score and store last winner
2959- winner.score++;
2960- gameScene.lastWinner = winner;
2961-
2962- // Check if the game has finished
2963- gameScene.running = false;
2964-
2965- if (settings.gameMode === modeFirstToX && winner.score >= settings.targetScore) {
2966- gameFinished(human, computer, gameHeader.time);
2967- } else if (settings.gameMode === modeSurvival && winner === computer) {
2968- gameFinished(human, computer, gameHeader.time);
2969- } else {
2970- pointOverlay.visible = true;
2971- }
2972- }
2973-
2974- function pause() {
2975- // don't show pauseOverlay if pointOverlay is shown
2976- if (!pointOverlay.visible) {
2977- pauseOverlay.pause()
2978- }
2979- }
2980+ signal pause()
2981+ signal resume()
2982+ signal roundWon(Character winner, Character human, Character computer, int time)
2983
2984 // Scoring for the players
2985 Scoring {
2986@@ -99,10 +75,11 @@
2987 rumbleEffect.start()
2988
2989 if (other === ground) {
2990- roundWon(x < parent.width / 2 ? computer : human)
2991+ roundWon(x < parent.width / 2 ? computer : human, human, computer, gameHeader.time)
2992 }
2993 }
2994 }
2995+ onXChanged: volleyBallHint.x = volleyball.getWorldCenter().x
2996
2997 HapticsEffect {
2998 id: rumbleEffect
2999@@ -119,7 +96,6 @@
3000 color: volleyball.color
3001 height: width / 2
3002 width: volleyball.radius
3003- x: volleyball.x - width / 2 // volleyball.x is actually centre
3004 visible: volleyball.y < y
3005 }
3006
3007@@ -271,49 +247,28 @@
3008 }
3009 }
3010
3011- // Point overlay at the end of a round
3012- PointOverlay {
3013- id: pointOverlay
3014- anchors {
3015- fill: parent
3016- }
3017- visible: false
3018- }
3019-
3020- PauseOverlay {
3021- id: pauseOverlay
3022- anchors {
3023- fill: parent
3024- }
3025- objectName: "pauseOverlay"
3026- visible: false
3027-
3028- onPause: gameScene.running = false
3029- onResume: gameScene.running = true
3030- }
3031-
3032 // Keyboard controls
3033 // TODO: add scaling
3034 Keys.onEscapePressed: {
3035- if (pointOverlay.visible) {
3036+ if (pointOverlayLoader.visible) {
3037 gameScene.reset();
3038 } else {
3039- if (pauseOverlay.visible) {
3040- pauseOverlay.resume()
3041- } else {
3042- pauseOverlay.pause()
3043+ if (pauseOverlayLoader.visible) {
3044+ resume()
3045+ } else {
3046+ pause()
3047 }
3048 }
3049 }
3050
3051 Keys.onReturnPressed: {
3052- if (pointOverlay.visible) {
3053+ if (pointOverlayLoader.visible) {
3054 gameScene.reset();
3055 }
3056 }
3057
3058 Keys.onPressed: {
3059- if (!event.isAutoRepeat && !settings.useMotion) {
3060+ if (!event.isAutoRepeat) {
3061 switch (event.key) {
3062 case Qt.Key_Left:
3063 human.leftPressed = 1;
3064@@ -321,6 +276,7 @@
3065 case Qt.Key_Right:
3066 human.rightPressed = 1;
3067 break;
3068+ case Qt.Key_Space:
3069 case Qt.Key_Up:
3070 human.upPressed = true;
3071 break;
3072@@ -329,7 +285,7 @@
3073 }
3074
3075 Keys.onReleased: {
3076- if (!event.isAutoRepeat && !settings.useMotion) {
3077+ if (!event.isAutoRepeat) {
3078 switch (event.key) {
3079 case Qt.Key_Left:
3080 human.leftPressed = false;
3081@@ -337,6 +293,7 @@
3082 case Qt.Key_Right:
3083 human.rightPressed = false;
3084 break;
3085+ case Qt.Key_Space:
3086 case Qt.Key_Up:
3087 human.upPressed = false;
3088 break;
3089@@ -358,12 +315,12 @@
3090
3091 // Reset the sprites between points
3092 function reset() {
3093- // Hide overlays
3094- pointOverlay.visible = false;
3095- pauseOverlay.visible = false;
3096+ pauseOverlayLoader.visible = false;
3097+ pointOverlayLoader.visible = false;
3098
3099 // Zero any velocities
3100 volleyball.angularVelocity = 0.0;
3101+ volleyball.rotation = 0;
3102 volleyball.linearVelocity = Qt.point(0, 0);
3103 human.linearVelocity = Qt.point(0, 0);
3104 computer.linearVelocity = Qt.point(0, 0);
3105@@ -391,6 +348,9 @@
3106 computer.y = gameScene.height - computer.radius;
3107
3108 // Restart the game
3109- gameScene.running = true;
3110+ resume()
3111+
3112+ // Ensure focus is correct
3113+ gameScene.forceActiveFocus()
3114 }
3115 }
3116
3117=== renamed file 'volleyball2d.apparmor' => 'volleyball2d/volleyball2d.apparmor'
3118=== renamed file 'volleyball2d.desktop' => 'volleyball2d/volleyball2d.desktop'
3119--- volleyball2d.desktop 2014-12-19 17:17:35 +0000
3120+++ volleyball2d/volleyball2d.desktop 2016-08-09 23:30:40 +0000
3121@@ -1,7 +1,7 @@
3122 [Desktop Entry]
3123 Name=Volleyball 2D
3124-Exec=qmlscene $@ main.qml
3125-Icon=volleyball2d.svg
3126+Exec=volleyball2d
3127+Icon=volleyball2d/volleyball2d.svg
3128 StartupNotify=true
3129 Terminal=false
3130 Type=Application
3131
3132=== added file 'volleyball2d/volleyball2d.pro'
3133--- volleyball2d/volleyball2d.pro 1970-01-01 00:00:00 +0000
3134+++ volleyball2d/volleyball2d.pro 2016-08-09 23:30:40 +0000
3135@@ -0,0 +1,34 @@
3136+TEMPLATE = app
3137+TARGET = volleyball2d
3138+
3139+QT += qml quick
3140+
3141+SOURCES += main.cpp \
3142+ fullscreen.cpp
3143+
3144+RESOURCES += volleyball2d.qrc
3145+
3146+OTHER_FILES += volleyball2d.apparmor \
3147+ volleyball2d.desktop \
3148+ volleyball2d.svg \
3149+
3150+TRANSLATIONS += ../po/*.pot \
3151+ ../po/*.po
3152+
3153+#specify where the config files are installed to
3154+config_files.path = /volleyball2d
3155+config_files.files += $${OTHER_FILES}
3156+message($$config_files.files)
3157+INSTALLS+=config_files
3158+
3159+translations.path = /po
3160+translations.files += $${TRANSLATIONS}
3161+message($$translations.files)
3162+INSTALLS += translations
3163+
3164+# Default rules for deployment.
3165+include(../deployment.pri)
3166+
3167+HEADERS += \
3168+ fullscreen.h
3169+
3170
3171=== added file 'volleyball2d/volleyball2d.qrc'
3172--- volleyball2d/volleyball2d.qrc 1970-01-01 00:00:00 +0000
3173+++ volleyball2d/volleyball2d.qrc 2016-08-09 23:30:40 +0000
3174@@ -0,0 +1,30 @@
3175+<RCC>
3176+ <qresource prefix="/">
3177+ <file>components/AIDebug.qml</file>
3178+ <file>components/AIPrediction.qml</file>
3179+ <file>components/Ball.qml</file>
3180+ <file>components/Boundaries.qml</file>
3181+ <file>components/Character.qml</file>
3182+ <file>components/CharacterBarrier.qml</file>
3183+ <file>components/Computer.qml</file>
3184+ <file>components/GameHeader.qml</file>
3185+ <file>components/Human.qml</file>
3186+ <file>components/LiveScore.qml</file>
3187+ <file>components/Net.qml</file>
3188+ <file>components/PauseOverlay.qml</file>
3189+ <file>components/PointOverlay.qml</file>
3190+ <file>components/ScaleItem.qml</file>
3191+ <file>components/ScalePage.qml</file>
3192+ <file>components/Scoring.qml</file>
3193+ <file>components/SemiCircleEntity.qml</file>
3194+ <file>components/Wall.qml</file>
3195+ <file>pages/FinishPage.qml</file>
3196+ <file>pages/GamePage.qml</file>
3197+ <file>pages/HighScorePage.qml</file>
3198+ <file>pages/MenuPage.qml</file>
3199+ <file>pages/RotateScreenPage.qml</file>
3200+ <file>pages/SettingsPage.qml</file>
3201+ <file>scenes/GameScene.qml</file>
3202+ <file>main.qml</file>
3203+ </qresource>
3204+</RCC>
3205
3206=== renamed file 'volleyball2d.svg' => 'volleyball2d/volleyball2d.svg'

Subscribers

People subscribed via source and target branches

to all changes: