From 75dc9f4475f93e149376c680cc23655b16774174 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 25 Nov 2009 17:48:49 +1000 Subject: Doc --- doc/src/declarative/declarativeui.qdoc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 7df87c5..b383836 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -46,11 +46,12 @@ \brief The Qt Declarative module provides a declarative framework for building highly dynamic, custom user interfaces. -Qt Declarative aids programmers and designers in building the animation rich, -highly fluid user interfaces that are becoming common in portable consumer -electronics devices, such as mobile phones, media players, set-top boxes and -netbooks. The Qt Declarative module provides an engine for interpreting the -declarative QML language, and a rich set of \l {QML Elements}{QML elements} that can be used +Qt Declarative UI provides a declarative framework for building highly dynamic, custom +user interfaces. Declarative UI helps programmers and designers collaborate to build +the animation rich, fluid user interfaces that are becoming common in portable +consumer devices, such as mobile phones, media players, set-top boxes and netbooks. +The Qt Declarative module provides an engine for interpreting the declarative QML +language, and a rich set of \l {QML Elements}{QML elements} that can be used from QML. QML is an extension to \l {http://www.ecma-international.org/publications/standards/Ecma-262.htm} @@ -85,12 +86,12 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \o \l {ECMAScript Blocks} \o \l {QML Scope} \o \l {Network Transparency} -\o \l {qmlmodels}{Data Models} -\o \l {anchor-layout}{Anchor-based Layout} -\o \l {qmlstates}{States} +\o \l {Data Models} +\o \l {anchor-layout.html}{Anchor-based Layout} +\o \l {qmlstates.html}{States} \o \l {qmlanimation.html}{Animation} \o \l {qmlmodules.html}{Modules} -\o \l {qmlfocus}{Keyboard Focus} +\o \l {qmlfocus.html}{Keyboard Focus} \o \l {Extending types from QML} \endlist -- cgit v0.12 From 10d689d226d5d221e8c6bc34ce0e0af4ed5b73d6 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 25 Nov 2009 12:04:25 +0100 Subject: added a snake demo --- demos/declarative/snake/Button.qml | 25 +++ demos/declarative/snake/Cookie.qml | 48 +++++ demos/declarative/snake/HighScoreModel.qml | 100 +++++++++ demos/declarative/snake/Link.qml | 75 +++++++ demos/declarative/snake/Skull.qml | 21 ++ demos/declarative/snake/Snake.qml | 189 ++++++++++++++++ demos/declarative/snake/pics/README | 1 + demos/declarative/snake/pics/background.png | Bin 0 -> 144508 bytes demos/declarative/snake/pics/blueStar.png | Bin 0 -> 272 bytes demos/declarative/snake/pics/blueStone.png | Bin 0 -> 3139 bytes demos/declarative/snake/pics/cookie.png | Bin 0 -> 2729 bytes demos/declarative/snake/pics/eyes.svg | 118 ++++++++++ demos/declarative/snake/pics/head.png | Bin 0 -> 3473 bytes demos/declarative/snake/pics/head.svg | 134 ++++++++++++ demos/declarative/snake/pics/redStar.png | Bin 0 -> 273 bytes demos/declarative/snake/pics/redStone.png | Bin 0 -> 3456 bytes demos/declarative/snake/pics/skull.png | Bin 0 -> 2543 bytes demos/declarative/snake/pics/snake.jpg | Bin 0 -> 663901 bytes demos/declarative/snake/pics/star.png | Bin 0 -> 262 bytes demos/declarative/snake/pics/stoneShadow.png | Bin 0 -> 1699 bytes demos/declarative/snake/pics/yellowStone.png | Bin 0 -> 2667 bytes demos/declarative/snake/snake.js | 308 +++++++++++++++++++++++++++ 22 files changed, 1019 insertions(+) create mode 100644 demos/declarative/snake/Button.qml create mode 100644 demos/declarative/snake/Cookie.qml create mode 100644 demos/declarative/snake/HighScoreModel.qml create mode 100644 demos/declarative/snake/Link.qml create mode 100644 demos/declarative/snake/Skull.qml create mode 100644 demos/declarative/snake/Snake.qml create mode 100644 demos/declarative/snake/pics/README create mode 100644 demos/declarative/snake/pics/background.png create mode 100644 demos/declarative/snake/pics/blueStar.png create mode 100644 demos/declarative/snake/pics/blueStone.png create mode 100644 demos/declarative/snake/pics/cookie.png create mode 100644 demos/declarative/snake/pics/eyes.svg create mode 100644 demos/declarative/snake/pics/head.png create mode 100644 demos/declarative/snake/pics/head.svg create mode 100644 demos/declarative/snake/pics/redStar.png create mode 100644 demos/declarative/snake/pics/redStone.png create mode 100644 demos/declarative/snake/pics/skull.png create mode 100644 demos/declarative/snake/pics/snake.jpg create mode 100644 demos/declarative/snake/pics/star.png create mode 100644 demos/declarative/snake/pics/stoneShadow.png create mode 100644 demos/declarative/snake/pics/yellowStone.png create mode 100644 demos/declarative/snake/snake.js diff --git a/demos/declarative/snake/Button.qml b/demos/declarative/snake/Button.qml new file mode 100644 index 0000000..63cd555 --- /dev/null +++ b/demos/declarative/snake/Button.qml @@ -0,0 +1,25 @@ +import Qt 4.6 + +Rectangle { + id: container + + signal clicked + property string text: "Button" + + color: activePalette.button; smooth: true + width: txtItem.width + 20; height: txtItem.height + 6 + border.width: 1; border.color: Qt.darker(activePalette.button); radius: 8; + + gradient: Gradient { + GradientStop { + id: topGrad; position: 0.0 + color: if (mr.pressed) { activePalette.dark } else { activePalette.light } } + GradientStop { position: 1.0; color: activePalette.button } + } + + MouseRegion { id: mr; anchors.fill: parent; onClicked: container.clicked() } + + Text { + id: txtItem; text: container.text; anchors.centerIn: container; color: activePalette.buttonText + } +} diff --git a/demos/declarative/snake/Cookie.qml b/demos/declarative/snake/Cookie.qml new file mode 100644 index 0000000..d1577ca --- /dev/null +++ b/demos/declarative/snake/Cookie.qml @@ -0,0 +1,48 @@ +import Qt 4.6 + +Item { + id: root + property bool dying: false + property int row; + property int column; + x: margin + column * gridSize + y: margin + row * gridSize + + width: gridSize + height: gridSize + property int value : 1; + + Image { + id: img + anchors.fill: parent + source: "pics/cookie.png" + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 100 } } + Text { + font.bold: true + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + text: value + } + } + + + Particles { id: particles + width:1; height:1; anchors.centerIn: parent; + emissionRate: 0; + lifeSpan: 700; lifeSpanDeviation: 600; + angle: 0; angleDeviation: 360; + velocity: 100; velocityDeviation:30; + source: "pics/greenStar.png"; + } + + states: [ + State{ name: "AliveState"; when: dying == false + PropertyChanges { target: img; opacity: 1 } + }, + State{ name: "DeathState"; when: dying == true + StateChangeScript { script: particles.burst(50); } + PropertyChanges { target: img; opacity: 0 } + } + ] +} diff --git a/demos/declarative/snake/HighScoreModel.qml b/demos/declarative/snake/HighScoreModel.qml new file mode 100644 index 0000000..f585ce8 --- /dev/null +++ b/demos/declarative/snake/HighScoreModel.qml @@ -0,0 +1,100 @@ +import Qt 4.6 + +// Models a high score table. +// +// Use this component like this: +// +// HighScoreModel { +// id: highScores +// game: "MyCoolGame" +// } +// +// Then use either use the top-score properties: +// +// Text { text: "HI: " + highScores.topScore } +// +// or, use the model in a view: +// +// ListView { +// model: highScore +// delegate: Component { +// ... player ... score ... +// } +// } +// +// Add new scores via: +// +// saveScore(newScore) +// +// or: +// +// savePlayerScore(playerName,newScore) +// +// The best maxScore scores added by this method will be retained in an SQL database, +// and presented in the model and in the topScore/topPlayer properties. +// + +ListModel { + id: model + property string game: "" + property int topScore: 0 + property string topPlayer: "" + property int maxScores: 10 + + Script { + function db() + { + return openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000); + } + function ensureTables(tx) + { + tx.executeSql('CREATE TABLE IF NOT EXISTS HighScores(game TEXT, score INT, player TEXT)', []); + } + } + + function fillModel() { + db().transaction( + function(tx) { + ensureTables(tx); + var rs = tx.executeSql("SELECT score,player FROM HighScores WHERE game=? ORDER BY score DESC", [game]); + model.clear(); + if (rs.rows.length > 0) { + topScore = rs.rows.item(0).score + topPlayer = rs.rows.item(0).player + for (var i=0; i maxScores) + tx.executeSql("DELETE FROM HighScores WHERE game=? AND score <= ?", + [rs.rows.item(maxScores).score]); + } + } + ) + } + + function savePlayerScore(player,score) { + db().transaction( + function(tx) { + ensureTables(tx); + tx.executeSql("INSERT INTO HighScores VALUES(?,?,?)", [game,score,player]); + fillModel(); + } + ) + } + + function saveScore(score) { + savePlayerScore("player",score); + } + + function clearScores() { + db().transaction( + function(tx) { + tx.executeSql("DELETE FROM HighScores WHERE game=?", [game]); + fillModel(); + } + ) + } + + Component.onCompleted: { fillModel() } +} diff --git a/demos/declarative/snake/Link.qml b/demos/declarative/snake/Link.qml new file mode 100644 index 0000000..1b3f7bf --- /dev/null +++ b/demos/declarative/snake/Link.qml @@ -0,0 +1,75 @@ +import Qt 4.6 + +Item { id:link + property bool dying: false + property bool spawned: false + property int type: 0 + property int row: 0 + property int column: 0 + property int rotation; + + width: 40; + height: 40 + + x: margin - 3 + gridSize * column + y: margin - 3 + gridSize * row + x: Behavior { NumberAnimation { duration: spawned ? heartbeatInterval : 0} } + y: Behavior { NumberAnimation { duration: spawned ? heartbeatInterval : 0 } } + + + Item { + id: img + anchors.fill: parent + Image { + source: { + if(type == 1) { + "pics/blueStone.png"; + } else if (type == 2) { + "pics/head.png"; + } else { + "pics/redStone.png"; + } + } + + transform: Rotation { + id: actualImageRotation + origin.x: width/2; origin.y: height/2; + angle: rotation * 90 + angle: Behavior{ NumberAnimation { duration: spawned ? 200 : 0} } + } + } + + Image { + source: "pics/stoneShadow.png" + } + + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + } + + + Particles { id: particles + width:1; height:1; anchors.centerIn: parent; + emissionRate: 0; + lifeSpan: 700; lifeSpanDeviation: 600; + angle: 0; angleDeviation: 360; + velocity: 100; velocityDeviation:30; + source: { + if(type == 1){ + "pics/blueStar.png"; + } else { + "pics/redStar.png"; + } + } + } + + states: [ + State{ name: "AliveState"; when: spawned == true && dying == false + PropertyChanges { target: img; opacity: 1 } + }, + State{ name: "DeathState"; when: dying == true + StateChangeScript { script: particles.burst(50); } + PropertyChanges { target: img; opacity: 0 } + } + ] +} diff --git a/demos/declarative/snake/Skull.qml b/demos/declarative/snake/Skull.qml new file mode 100644 index 0000000..585e7d3 --- /dev/null +++ b/demos/declarative/snake/Skull.qml @@ -0,0 +1,21 @@ +import Qt 4.6 + +Image { + property bool spawned: false + property int row; + property int column; + property int verticalMovement; + property int horizontalMovement; + + x: margin + column * gridSize + 2 + y: margin + row * gridSize - 3 + x: Behavior { NumberAnimation { duration: spawned ? halfbeatInterval : 0} } + y: Behavior { NumberAnimation { duration: spawned ? halfbeatInterval : 0 } } + + opacity: spawned ? 1 : 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + + source: "pics/skull.png" + width: 24 + height: 40 +} diff --git a/demos/declarative/snake/Snake.qml b/demos/declarative/snake/Snake.qml new file mode 100644 index 0000000..a9835d4 --- /dev/null +++ b/demos/declarative/snake/Snake.qml @@ -0,0 +1,189 @@ +import Qt 4.6 + +Rectangle { + id: screen; + SystemPalette { id: activePalette } + color: activePalette.window + + Script { source: "snake.js" } + + property int gridSize : 34 + property int margin: 4 + property int numRowsAvailable: Math.floor((height-32-2*margin)/gridSize) + property int numColumnsAvailable: Math.floor((width-2*margin)/gridSize) + + property int lastScore : 0 + + property int score: 0; + property int heartbeatInterval: 200 + property int halfbeatInterval: 160 + + width: 480 + height: 750 + + property int direction + property int headDirection + + property var head; + + HighScoreModel { + id: highScores + game: "Snake" + } + + Timer { + id: heartbeat; + interval: heartbeatInterval; + repeat: true + onTriggered: { move() } + } + Timer { + id: halfbeat; + interval: halfbeatInterval; + repeat: true + running: heartbeat.running + onTriggered: { moveSkull() } + } + Timer { + id: startNewGameTimer; + interval: 700; + onTriggered: {startNewGame(); } + } + + Timer { + id: startHeartbeatTimer; + interval: 1000 ; + } + + + Image { + Image { + id: title + source: "pics/snake.jpg" + fillMode: "PreserveAspectCrop" + anchors.fill: parent + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + opacity: Behavior { NumberAnimation { duration: 500 } } + + Text { + color: "white" + font.pointSize: 24 + horizontalAlignment: "AlignHCenter" + text: "Last Score:\t" + lastScore + "\nHighscore:\t" + highScores.topScore; + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: gridSize + } + } + + source: "pics/background.png" + fillMode: "PreserveAspectCrop" + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: toolbar.top + + Rectangle { + id: playfield + border.width: 1 + border.color: "white" + color: "transparent" + anchors.horizontalCenter: parent.horizontalCenter + y: (screen.height - 32 - height)/2; + width: numColumnsAvailable * gridSize + 2*margin + height: numRowsAvailable * gridSize + 2*margin + + + Skull { + id: skull + } + + MouseRegion { + anchors.fill: parent + onPressed: { + if (!head || !heartbeat.running) { + startNewGame(); + return; + } + if (direction == 0 || direction == 2) + scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); + else + scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); + } + } + } + + } + + Rectangle { + id: progressBar + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + color: "transparent" + border.width: 2 + border.color: "#221edd" + x: 50 + y: 50 + width: 200 + height: 30 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: 40 + + Rectangle { + id: progressIndicator + color: "#221edd"; + width: 0; + width: Behavior { NumberAnimation { duration: startHeartbeatTimer.running ? 1000 : 0}} + height: 30; + } + } + + Rectangle { + id: toolbar + color: activePalette.window + height: 32; width: parent.width + anchors.bottom: screen.bottom + + Button { + id: btnA; text: "New Game"; onClicked: {startNewGame();} + anchors.left: parent.left; anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + color: activePalette.text + text: "Score: " + score; font.bold: true + anchors.right: parent.right; anchors.rightMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } + } + + focus: true + Keys.onSpacePressed: startNewGame(); + Keys.onLeftPressed: if (state == "starting" || direction != 1) scheduleDirection(3); + Keys.onRightPressed: if (state == "starting" || direction != 3) scheduleDirection(1); + Keys.onUpPressed: if (state == "starting" || direction != 2) scheduleDirection(0); + Keys.onDownPressed: if (state == "starting" || direction != 0) scheduleDirection(2); + + states: [ + State { + name: "starting" + when: startHeartbeatTimer.running; + PropertyChanges {target: progressIndicator; width: 200} + PropertyChanges {target: title; opacity: 0} + PropertyChanges {target: progressBar; opacity: 1} + }, + State { + name: "running" + when: heartbeat.running + PropertyChanges {target: progressIndicator; width: 200} + PropertyChanges {target: title; opacity: 0} + PropertyChanges {target: skull; row: 0; column: 0; } + PropertyChanges {target: skull; spawned: 1} + } + ] + +} diff --git a/demos/declarative/snake/pics/README b/demos/declarative/snake/pics/README new file mode 100644 index 0000000..0215132 --- /dev/null +++ b/demos/declarative/snake/pics/README @@ -0,0 +1 @@ +snake.jpg: This image is based on the picture "Eastern Green Mamba.jpg" from the free media databse Wikimedia Commons and is published under the terms of the GNU Free Documentation License. The original picture was taken by Danleo. diff --git a/demos/declarative/snake/pics/background.png b/demos/declarative/snake/pics/background.png new file mode 100644 index 0000000..72dffaa Binary files /dev/null and b/demos/declarative/snake/pics/background.png differ diff --git a/demos/declarative/snake/pics/blueStar.png b/demos/declarative/snake/pics/blueStar.png new file mode 100644 index 0000000..ba7acab Binary files /dev/null and b/demos/declarative/snake/pics/blueStar.png differ diff --git a/demos/declarative/snake/pics/blueStone.png b/demos/declarative/snake/pics/blueStone.png new file mode 100644 index 0000000..356affd Binary files /dev/null and b/demos/declarative/snake/pics/blueStone.png differ diff --git a/demos/declarative/snake/pics/cookie.png b/demos/declarative/snake/pics/cookie.png new file mode 100644 index 0000000..aec2957 Binary files /dev/null and b/demos/declarative/snake/pics/cookie.png differ diff --git a/demos/declarative/snake/pics/eyes.svg b/demos/declarative/snake/pics/eyes.svg new file mode 100644 index 0000000..1078692 --- /dev/null +++ b/demos/declarative/snake/pics/eyes.svg @@ -0,0 +1,118 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/demos/declarative/snake/pics/head.png b/demos/declarative/snake/pics/head.png new file mode 100644 index 0000000..550e002 Binary files /dev/null and b/demos/declarative/snake/pics/head.png differ diff --git a/demos/declarative/snake/pics/head.svg b/demos/declarative/snake/pics/head.svg new file mode 100644 index 0000000..3bf0bd2 --- /dev/null +++ b/demos/declarative/snake/pics/head.svg @@ -0,0 +1,134 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/demos/declarative/snake/pics/redStar.png b/demos/declarative/snake/pics/redStar.png new file mode 100644 index 0000000..cd06854 Binary files /dev/null and b/demos/declarative/snake/pics/redStar.png differ diff --git a/demos/declarative/snake/pics/redStone.png b/demos/declarative/snake/pics/redStone.png new file mode 100644 index 0000000..9bb7fe4 Binary files /dev/null and b/demos/declarative/snake/pics/redStone.png differ diff --git a/demos/declarative/snake/pics/skull.png b/demos/declarative/snake/pics/skull.png new file mode 100644 index 0000000..6318616 Binary files /dev/null and b/demos/declarative/snake/pics/skull.png differ diff --git a/demos/declarative/snake/pics/snake.jpg b/demos/declarative/snake/pics/snake.jpg new file mode 100644 index 0000000..e91a784 Binary files /dev/null and b/demos/declarative/snake/pics/snake.jpg differ diff --git a/demos/declarative/snake/pics/star.png b/demos/declarative/snake/pics/star.png new file mode 100644 index 0000000..defbde5 Binary files /dev/null and b/demos/declarative/snake/pics/star.png differ diff --git a/demos/declarative/snake/pics/stoneShadow.png b/demos/declarative/snake/pics/stoneShadow.png new file mode 100644 index 0000000..1bd56af Binary files /dev/null and b/demos/declarative/snake/pics/stoneShadow.png differ diff --git a/demos/declarative/snake/pics/yellowStone.png b/demos/declarative/snake/pics/yellowStone.png new file mode 100644 index 0000000..c56124a Binary files /dev/null and b/demos/declarative/snake/pics/yellowStone.png differ diff --git a/demos/declarative/snake/snake.js b/demos/declarative/snake/snake.js new file mode 100644 index 0000000..1cea8b7 --- /dev/null +++ b/demos/declarative/snake/snake.js @@ -0,0 +1,308 @@ + +var snake = new Array; +var board = new Array; +var links = new Array; +var scheduledDirections = new Array; +var numRows = 1; +var numColumns = 1; +var linkComponent = createComponent("Link.qml"); +var cookieComponent = createComponent("Cookie.qml"); +var cookie; +var linksToGrow = 0; +var linksToDie = 0; +var waitForCookie = 0; +var growType = 0; +var skullMovementsBeforeDirectionChange = 0; + + +function rand(n) +{ + return (Math.floor(Math.random() * n)); +} + +function scheduleDirection(dir) +{ + direction = dir; + if(scheduledDirections[scheduledDirections.length-1]!=direction) + scheduledDirections.push(direction); +} + +function startNewGame() +{ + if (state == "starting") + return; + + if (heartbeat.running) { + endGame(); + startNewGameTimer.running = true; + return; + } + numRows = numRowsAvailable; + numColumns = numColumnsAvailable; + board = new Array(numRows * numColumns); + snake = new Array; + scheduledDirections = new Array; + growType = 0; + + skull.z = numRows * numColumns + 1; + + for (var i = 0; i < numRows * numColumns; ++i) { + if (i < links.length) { + var link = links[i]; + link.spawned = false; + link.dying = false; + } else { + if(linkComponent.isReady == false){ + if(linkComponent.isError == true) + print(linkComponent.errorString()); + else + print("Still loading linkComponent"); + continue;//TODO: Better error handling? + } + var link = linkComponent.createObject(); + link.parent = playfield; + link.z = numRows * numColumns + 1 - i; + link.type = i == 0 ? 2 : 0; + link.spawned = false; + link.dying = false; + links.push(link); + } + } + + head = links[0]; + snake.push(head); + head.row = numRows/2 -1; + head.column = numColumns/2 -1; + head.spawned = true; + + linksToGrow = 5; + linksToDie = 0; + waitForCookie = 5; + score = 0; + startHeartbeatTimer.running = true; + heartbeat.running = true; +} + +function endGame() +{ + heartbeat.running = false; + for(var i in snake) + snake[i].dying = true; + if (cookie) { + cookie.dying = true; + cookie = 0; + } + lastScore = score; + highScores.saveScore(lastScore); +} + +function move() { + + if (!head) + return; + + var dir = direction; + + if (scheduledDirections.length) { + dir = scheduledDirections.shift(); + } + + if (state == "starting") { + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + return; + } + + var row = head.row; + var column = head.column; + + if (dir == 0) { + row = row - 1; + } else if (dir == 1) { + column = column + 1 + } else if (dir == 2) { + row = row + 1; + } else if (dir == 3) { + column = column - 1; + } + + //validate the new position + if (row < 0 || row >= numRows + || column < 0 || column >= numColumns + || (row == skull.row && column == skull.column) + || !isFree(row, column)) { + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + endGame(); + return; + } + + var newLink; + if (linksToGrow > 0) { + --linksToGrow; + newLink = links[snake.length]; + newLink.spawned = false; + newLink.rotation = snake[snake.length-1].rotation; + newLink.type = growType; + newLink.dying = false; + snake.push(newLink); + } else { + var lastLink = snake[snake.length-1]; + board[lastLink.row * numColumns + lastLink.column] = Undefined; + } + + if (waitForCookie > 0) { + if (--waitForCookie == 0) + createCookie(cookie? (cookie.value+1) : 1); + } + + for (var i = snake.length-1; i > 0; --i) { + snake[i].row = snake[i-1].row; + snake[i].column = snake[i-1].column; + snake[i].rotation = snake[i-1].rotation; + } + + if (newLink) { + newLink.spawned = true; + } + + // move the head + head.row = row; + head.column = column; + board[row * numColumns + column] = head; + + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + + var value = testCookie(row, column); + if (value > 0) { + linksToGrow += value; + score += value; + } +} + +function isFree(row, column) +{ + return board[row * numColumns + column] == Undefined; +} + +function isHead(row, column) +{ + return head.column == column && head.row == row; +} + +function testCookie(row, column) +{ + if (cookie && !cookie.dying && cookie.row == row && cookie.column == column) { + var value = cookie.value; + waitForCookie = value; + growType = snake[snake.length-1].type == 1 ? 0 : 1; + cookie.dying = true; + cookie.z = numRows * numColumns + 2; + return value; + } + return 0; +} + +function moveSkull() +{ + + if (linksToDie > 0) { + --linksToDie; + var link = snake.pop(); + link.dying = true; + board[link.row * numColumns + link.column] = Undefined; + if (score > 0) + --score; + if (snake.length == 0) { + endGame(); + return; + } + } + + var row = skull.row; + var column = skull.column; + if (isHead(row, column)) { + endGame(); + return; + } + row += skull.verticalMovement; + column += skull.horizontalMovement; + + var attempts = 4; + + while (skullMovementsBeforeDirectionChange == 0 || row < 0 || row >= numRows + || column < 0 || column >= numColumns + || (!isFree(row, column) && !isHead(row, column))) { + var d = rand(8); + skull.verticalMovement = 0; + skull.horizontalMovement = 0; + skullMovementsBeforeDirectionChange = rand(20)+1; + if (d == 0) { + skull.verticalMovement = -1 + } else if (d == 1) { + skull.horizontalMovement = -1; + } else if (d == 2) { + skull.verticalMovement = 1 + } else if (d == 3){ + skull.horizontalMovement = 1; + } else if (cookie) { + var rd = cookie.row - skull.row; + var rc = cookie.column - skull.column; + if (Math.abs(rd) > Math.abs(rc)) { + skull.verticalMovement = rd > 0 ? 1 : -1; + skullMovementsBeforeDirectionChange = Math.abs(rd); + } else { + skull.horizontalMovement= rc > 0 ? 1 : -1; + skullMovementsBeforeDirectionChange = Math.abs(rc); + } + } + row = skull.row + skull.verticalMovement; + column = skull.column + skull.horizontalMovement; + if (--attempts == 0) + return; + } + + skull.row = row; + skull.column = column; + --skullMovementsBeforeDirectionChange; + var value = testCookie(row, column); + if (value > 0) + linksToDie += value/2; + + if (isHead(row, column)) + endGame(); +} + +function createCookie(value) { + if (numRows * numColumns - snake.length < 10) + return; + + var column = rand(numColumns); + var row = rand(numRows); + while (!isFree(row, column)) { + column++; + if (column == numColumns) { + column = 0; + row++; + if (row == numRows) + row = 0; + } + } + + if(cookieComponent.isReady == false){ + if(cookieComponent.isError == true) + print(cookieComponent.errorString()); + else + print("Still loading cookieComponent"); + return;//TODO: Better error handling? + } + cookie = cookieComponent.createObject(); + cookie.parent = head.parent; + cookie.value = value; + cookie.row = row; + cookie.column = column; +} -- cgit v0.12 From 59a0002b1eaedd1961136b364a595c376755e085 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 25 Nov 2009 16:04:00 +0100 Subject: Treat emissionRate=0 like emitting=false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including stopping the timer because we arenæt emitting anything. Because emissionRate=0 is exactly the same as emitting=false, the emitting property has been removed. Task-number: QTBUG-6209 --- .../graphicsitems/qmlgraphicsparticles.cpp | 54 ++++------------------ .../graphicsitems/qmlgraphicsparticles_p.h | 4 -- .../tst_qmlgraphicsparticles.cpp | 3 -- .../visual/qmlgraphicsparticles/particles.qml | 7 ++- 4 files changed, 16 insertions(+), 52 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp index a0b41e8..f15d9f6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp @@ -372,7 +372,7 @@ public: , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) , addParticleTime(0), addParticleCount(0), lastAdvTime(0) - , emitting(true), motion(0), pendingPixmapCache(false), clock(this) + , motion(0), pendingPixmapCache(false), clock(this) { } @@ -407,7 +407,6 @@ public: int addParticleTime; int addParticleCount; int lastAdvTime; - bool emitting; QmlGraphicsParticleMotion *motion; QmlGraphicsParticlesPainter *paintItem; @@ -443,14 +442,14 @@ void QmlGraphicsParticlesPrivate::tick(int time) } if(emissionRate == -1)//Otherwise leave emission to the emission rate - while(removed-- && ((count == -1) || particles.count() < count) && emitting) + while(removed-- && ((count == -1) || particles.count() < count)) createParticle(time); if (!addParticleTime) addParticleTime = time; //Possibly emit new particles - if (((count == -1) || particles.count() < count) && emitting + if (((count == -1) || particles.count() < count) && emissionRate && !(count==-1 && emissionRate==-1)) { int emissionCount = -1; if (emissionRate != -1){ @@ -497,7 +496,7 @@ void QmlGraphicsParticlesPrivate::tick(int time) lastAdvTime = time; paintItem->updateSize(); paintItem->update(); - if (!(oldCount || particles.count()) && (!count || !emitting) && bursts.isEmpty()) { + if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) { lastAdvTime = 0; clock.stop(); } @@ -733,7 +732,7 @@ void QmlGraphicsParticles::setCount(int cnt) d->count = cnt; d->addParticleTime = 0; d->addParticleCount = d->particles.count(); - if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emitting) { + if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { d->clock.start(); } d->paintItem->updateSize(); @@ -774,6 +773,9 @@ void QmlGraphicsParticles::setEmissionRate(int er) if(er == d->emissionRate) return; d->emissionRate = er; + if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { + d->clock.start(); + } emit emissionRateChanged(); } @@ -1100,42 +1102,6 @@ void QmlGraphicsParticles::setVelocityDeviation(qreal velocity) } /*! - \qmlproperty bool Particles::emitting - This property determines whether new particles are created - - If emitting is set to false no new particles will be created. This means that - when a particle reaches the end of its lifespan it is not replaced. This - property can be used to turn particles on and off with a more natural look. - - The default setting is true. Note that if it initialized to false no particles - will be produced until it is set to true. -*/ -/*! - \property QmlGraphicsParticles::emitting - If emitting is set to false no new particles will be created. This means that - when a particle reaches the end of its lifespan it is not replaced. This - property can be used to turn particles on and off with a more natural look. - - The default setting is true. Note that if it initialized to false no particles - will be produced until it is set to true. -*/ -bool QmlGraphicsParticles::emitting() const -{ - Q_D(const QmlGraphicsParticles); - return d->emitting; -} - -void QmlGraphicsParticles::setEmitting(bool r) -{ - Q_D(QmlGraphicsParticles); - if(d->emitting == r) - return; - d->emitting = r; - if (d->count && r) - d->clock.start(); - emit emittingChanged(); -} -/*! \qmlproperty ParticleMotion Particles::motion This property sets the type of motion to apply to the particles. @@ -1178,7 +1144,7 @@ void QmlGraphicsParticles::setMotion(QmlGraphicsParticleMotion *motion) burst. If the second argument is omitted, it is treated as -1. The burst of particles has a separate emissionRate and count to the normal emission of particles. The burst uses the same values as normal emission for all other - properties, including emissionVariance and emitting. + properties, including emissionVariance. The normal emission of particles will continue during the burst, however the particles created by the burst count towards the maximum number used by @@ -1189,7 +1155,7 @@ void QmlGraphicsParticles::burst(int count, int emissionRate) { Q_D(QmlGraphicsParticles); d->bursts << qMakePair(count, emissionRate); - if (d->clock.state() != QAbstractAnimation::Running && d->emitting) + if (d->clock.state() != QAbstractAnimation::Running) d->clock.start(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h index 02c4e6d..3cb3ff6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h @@ -157,7 +157,6 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsParticles : public QmlGraphicsItem Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged) Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged) - Q_PROPERTY(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged) Q_PROPERTY(QmlGraphicsParticleMotion *motion READ motion WRITE setMotion) Q_CLASSINFO("DefaultProperty", "motion") @@ -201,9 +200,6 @@ public: qreal velocityDeviation() const; void setVelocityDeviation(qreal); - bool emitting() const; - void setEmitting(bool); - QmlGraphicsParticleMotion *motion() const; void setMotion(QmlGraphicsParticleMotion *); diff --git a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp index c8d181b..ed68eaf 100644 --- a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp +++ b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp @@ -96,9 +96,6 @@ void tst_QmlGraphicsParticles::properties() particles->setEmissionRate(12); QCOMPARE(particles->emissionRate(), 12); - - particles->setEmitting(false); - QCOMPARE(particles->emitting(), false); } void tst_QmlGraphicsParticles::runs() diff --git a/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml b/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml index a7a8143..2d481c9 100644 --- a/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml +++ b/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml @@ -3,7 +3,12 @@ import Qt 4.6 Rectangle { width: 640; height: 480; color: "black" - Particles { emitting: false } + Particles { id:particlesAnotEmitting + y:60; width: 260; height:30; source: "star.png"; + lifeSpan:1000; count: 50; angle:70; angleDeviation:36; + velocity:30; velocityDeviation:10; emissionRate: 0 + ParticleMotionWander { yvariance:5; xvariance:30; pace:100 } + } Particles { id:particlesA y:0; width: 260; height:30; source: "star.png"; lifeSpan:1000; count: 50; angle:70; angleDeviation:36; -- cgit v0.12