pax_global_header 0000666 0000000 0000000 00000000064 12577170675 0014533 g ustar 00root root 0000000 0000000 52 comment=c2e57c4ba7e0af23f4b950e43b06c2f29e5e1fb1 2048-Qt-0.1.6/ 0000775 0000000 0000000 00000000000 12577170675 0012516 5 ustar 00root root 0000000 0000000 2048-Qt-0.1.6/.gitignore 0000664 0000000 0000000 00000000034 12577170675 0014503 0 ustar 00root root 0000000 0000000 2048-qt.pro.user .directory 2048-Qt-0.1.6/2048-qt.pro 0000664 0000000 0000000 00000001372 12577170675 0014262 0 ustar 00root root 0000000 0000000 TEMPLATE = app QT += qml quick widgets SOURCES += \ src/main.cpp \ src/myclass.cpp \ src/settings.cpp lupdate_only { SOURCES += qml/main.qml \ qml/Tile.qml \ qml/2048.js } RESOURCES += \ resources.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) # Setting the application icon win32: RC_ICONS = res/icons/2048-qt.ico # On Windows macx: ICON = res/icons/2048-qt.ico # On Mac OSX HEADERS += \ src/settings.h \ src/myclass.h TRANSLATIONS = ts/2048-qt_de_DE.ts ts/2048-qt_fr_FR.ts ts/2048-qt_pl_PL.ts ts/2048-qt_ru_RU.ts ts/2048-qt_zh_CN.ts VERSION = 0.1.6 DEFINES += APP_VERSION=\\\"$${VERSION}\\\" 2048-Qt-0.1.6/Changelog.md 0000664 0000000 0000000 00000002535 12577170675 0014734 0 ustar 00root root 0000000 0000000 # Changelog ## 2015-09-19 0.1.6 * added French, German, Polish translation * put config file in `~/.config/2048-qt/` instead of `~/.config/xiaoyong/` ## 2014-05-29 0.1.5 * fixed the VERSION issue for Visual Studio * do not translate the language names * Merge branch 'SBasalaev-master' * avoided trying to load English translation file * added Russian translation * Russian translation * added the Debian package in README ## 2014-05-03 0.1.4 * updated the version number * added man page and Changelog files * typo fix * added the AUR package to README.md ## 2014-04-26 0.1.3 * updated the version * added desktop file * added new icons ## 2014-04-26 0.1.2 * fixed a locale display bug ## 2014-04-26 0.1.1 * added language setting, version variable etc. * line break in README.md * updated README.md ## 2014-04-22 0.1.0 * embeded Droid Sans Fallback font * save label setting * added more variants of 2048 and selection of them * improved the out of focus issue * specified font family and figured out an translation file issue * added Settings function. The best score is saved on disk * added Chinese translation and the adding score animation * added fluid animation * added application icon and menubar * added binary file on 64-bit Linux * setup the Github repo * Initial commit * handle window resize * simplified the UI structure * integrated Qml within C++ 2048-Qt-0.1.6/LICENSE 0000664 0000000 0000000 00000002071 12577170675 0013523 0 ustar 00root root 0000000 0000000 The MIT License (MIT) Copyright (c) 2015 Qiaoyong Zhong Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2048-Qt-0.1.6/README.md 0000664 0000000 0000000 00000003547 12577170675 0014006 0 ustar 00root root 0000000 0000000 # 2048-Qt A clone of [2048](https://github.com/gabrielecirulli/2048), implemented in Qt. ## Features - Cross platform Currently tested on Windows and Linux. Should be able to run on Mac OS X or even Android and iOS. - Shipped with multiple variants - 2048 - Degree (学位) - Military Rank (军衔) - PRC (天朝) - Multi-language support, currently - English - French (by [Rémi Verschelde](https://github.com/akien-mga)) - German (by [Jens John](https://github.com/2ion)) - Polish (by [Michał Radwański](https://github.com/enedil)) - Russian (by [Sergey Basalaev](https://github.com/SBasalaev)) - Simplified Chinese ## Screenshots - Classical 2048  - 2048 Degree  ## Downloads Check https://github.com/xiaoyong/2048-Qt/releases for compiled binary executable files. ### Windows All required Qt libraries have been packed into one .exe file. So it should work out of the box. ### Linux The Qt libraries (version >= 5.2.1) are required. Make sure that they are installed on your system. ### Arch Linux Install the AUR package [2048-qt](https://aur.archlinux.org/packages/2048-qt/) through: ``` yaourt 2048-qt ``` And please vote it if you like it. ### Debian [Alejandro Garrido Mota](https://github.com/mogaal) has packaged it for Debian. On Debian unstable, install it through: ``` sudo apt-get install 2048-qt ``` ### Gentoo 2048-Qt is available from the overlay maintained by [Jorge Pizarro Callejas](https://github.com/jorgicio): ``` layman -a jorgicio emerge 2048-qt ``` ### Ubuntu From Ubuntu 14.10 on, install it through: ``` sudo apt-get install 2048-qt ``` ## Todo - Allow the user to add his own label systems - AI support 2048-Qt-0.1.6/deployment.pri 0000664 0000000 0000000 00000000743 12577170675 0015416 0 ustar 00root root 0000000 0000000 android-no-sdk { target.path = /data/user/qt export(target.path) INSTALLS += target } else:android { x86 { target.path = /libs/x86 } else: armeabi-v7a { target.path = /libs/armeabi-v7a } else { target.path = /libs/armeabi } export(target.path) INSTALLS += target } else:unix { isEmpty(target.path) { target.path = /opt/$${TARGET}/bin export(target.path) } INSTALLS += target } export(INSTALLS) 2048-Qt-0.1.6/qml/ 0000775 0000000 0000000 00000000000 12577170675 0013307 5 ustar 00root root 0000000 0000000 2048-Qt-0.1.6/qml/2048.js 0000664 0000000 0000000 00000032551 12577170675 0014250 0 ustar 00root root 0000000 0000000 var score = 0; var bestScore = settings.value("bestScore", 0); var gridSize = 4; var cellValues; var tileItems = []; var availableCells; var targetLevel = 11; var checkTargetFlag = true; var tileComponent = Qt.createComponent("Tile.qml"); var label = settings.value("label", "2048"); var labelOptions = ["2048", "Degree", "Military Rank", "PRC"]; var labelFunc = { "2048": function(n) { return Math.pow(2, n).toString(); }, "PRC": function(n) { var arr = ["商", "周", "秦", "汉", "唐", "宋", "元", "明", "清", "民国", "天朝", "天庭"]; if (n > 0 && n < arr.length) return arr[n-1]; else return ""; }, "Military Rank": function(n) { var arr = ["少尉", "中尉", "上尉", "少校", "中校", "上校", "大校", "少将", "中将", "上将", "元帅", "大元帅"]; if (n > 0 && n < arr.length) return arr[n-1]; else return ""; }, "Degree": function(n) { var arr = ["幼儿园", "小学", "初中", "高中", "学士", "硕士", "博士", "博士后", "勇士", "壮士", "烈士", "圣斗士"]; if (n > 0 && n < arr.length) return arr[n-1]; else return ""; } } function startupFunction() { // Initialize variables score = 0; checkTargetFlag = true; var i; var j; cellValues = new Array(gridSize); for (i = 0; i < gridSize; i++) { cellValues[i] = new Array(gridSize); for (j = 0; j < gridSize; j++) cellValues[i][j] = 0; } for (i = 0; i < Math.pow(gridSize, 2); i++) { try { tileItems[i].destroy(); } catch(e) { } tileItems[i] = null; } updateAvailableCells(); createNewTileItems(true); updateScore(0); addScoreText.parent = scoreBoard.itemAt(0); // Save the currently achieved best score if (bestScore > settings.value("bestScore", 0)) { console.log("Updating new high score..."); settings.setValue("bestScore", bestScore); } if (label !== settings.value("label", "2048")) settings.setValue("label", label); console.log("Started a new game"); } function moveKey(event) { var isMoved = false; var i, j; var v, v2, mrg, indices; var oldScore = score; switch (event.key) { case Qt.Key_Left: for (i = 0; i < gridSize; i++) { v = cellValues[i]; mrg = mergeVector(v); v2 = mrg[0]; indices = mrg[1]; if (! arraysIdentical(v,v2)) { isMoved = true; moveMergeTilesLeftRight(i, v, v2, indices, true); cellValues[i] = v2; } } event.accepted = true; break; case Qt.Key_Right: for (i = 0; i < gridSize; i++) { v = cellValues[i].slice(); v.reverse(); mrg = mergeVector(v); v2 = mrg[0]; indices = mrg[1]; if (! arraysIdentical(v,v2)) { isMoved = true; v.reverse(); v2.reverse(); indices.reverse(); for (j = 0; j < indices.length; j++) indices[j] = gridSize - 1 - indices[j]; moveMergeTilesLeftRight(i, v, v2, indices, false); cellValues[i] = v2; } } event.accepted = true; break; case Qt.Key_Up: for (i = 0; i < gridSize; i++) { v = cellValues.map(function(row) {return row[i];}); mrg = mergeVector(v); v2 = mrg[0]; indices = mrg[1]; if (! arraysIdentical(v,v2)) { isMoved = true; moveMergeTilesUpDown(i, v, v2, indices, true); for (j = 0; j < gridSize; j++) { cellValues[j][i] = v2[j]; } } } event.accepted = true; break; case Qt.Key_Down: for (i = 0; i < gridSize; i++) { v = cellValues.map(function(row) {return row[i];}); v.reverse(); mrg = mergeVector(v); v2 = mrg[0]; indices = mrg[1]; if (! arraysIdentical(v,v2)) { isMoved = true; v.reverse(); v2.reverse(); indices.reverse(); for (j = 0; j < gridSize; j++) { indices[j] = gridSize - 1 - indices[j]; cellValues[j][i] = v2[j]; } moveMergeTilesUpDown(i, v, v2, indices, false); } } event.accepted = true; break; } if (isMoved) { updateAvailableCells(); createNewTileItems(false); if (oldScore !== score) { if (bestScore < score) { bestScore = score; } updateScore(oldScore); if (checkTargetFlag && maxTileValue() >= targetLevel) { winMessage.open(); } } } else { if (isDead()) { deadMessage.open(); } } } function ind2sub(ind) { var sub = [0, 0]; sub[0] = Math.floor(ind / gridSize); sub[1] = ind % gridSize; return sub; } function mergeVector(v0) { var i, j; var vlen = v0.length; var indices = []; // Pass 1: remove zero elements var v = []; for (i = 0; i < vlen; i++) { indices[i] = v.length; if (v0[i] > 0) { v.push(v0[i]); } } // Pass 2: merge same elements var v2 = []; for (i = 0; i < v.length; i++) { if (i === v.length - 1) { // The last element v2.push(v[i]); } else { if (v[i] === v[i+1]) { // move all right-side elements to left by 1 for (j = 0; j < vlen; j++) { if (indices[j] > v2.length) indices[j] -= 1; } // Merge i-1 and i v2.push(v[i] + 1); score += Math.pow(2, v[i] + 1); i++; } else { v2.push(v[i]); } } } // Fill the gaps with zeros for (i = v2.length; i < vlen; i++) v2[i] = 0; return [v2, indices]; } function removeElementsWithValue(arr, val) { var i = arr.length; while (i--) { if (arr[i] === val) { arr.splice(i, 1); } } return arr; } function arraysIdentical(a, b) { var i = a.length; if (i !== b.length) return false; while (i--) { if (a[i] !== b[i]) return false; } return true; }; function updateAvailableCells() { availableCells = []; for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (cellValues[i][j] === 0) { availableCells.push(i * gridSize + j); } } } } function createNewTileItems(isStartup) { var i, sub, nTiles; if (isStartup) { nTiles = 2; } else { nTiles = 1; } // Popup a new number for (i = 0; i < nTiles; i++) { var oneOrTwo = Math.random() < 0.9 ? 1: 2; var randomCellId = availableCells[Math.floor(Math.random() * availableCells.length)]; sub = ind2sub(randomCellId); cellValues[sub[0]][sub[1]] = oneOrTwo; tileItems[randomCellId] = createTileObject(randomCellId, oneOrTwo, isStartup); // Mark this cell as unavailable var idx = availableCells.indexOf(randomCellId); availableCells.splice(idx, 1); } } function updateScore(oldScore) { if (score > oldScore) { addScoreText.text = "+" + (score-oldScore).toString(); addScoreAnim.running = true; } scoreBoard.itemAt(0).scoreText = MyScript.score.toString(); scoreBoard.itemAt(1).scoreText = MyScript.bestScore.toString(); } function isDead() { var dead = true; for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (cellValues[i][j] === 0) { dead = false; } if (i > 0) { if (cellValues[i-1][j] === cellValues[i][j]) { dead = false; } } if (j > 0) { if (cellValues[i][j-1] === cellValues[i][j]) { dead = false; } } } } return dead; } function computeTileStyle(n, tileText) { var fgColors = ["#776E62", "#F9F6F2"]; var bgColors = ["#EEE4DA", "#EDE0C8", "#F2B179", "#F59563", "#F67C5F", "#F65E3B", "#EDCF72", "#EDCC61", "#EDC850", "#EDC53F", "#EDC22E", "#3C3A32"]; var sty = {bgColor: helper.myColors.bggray, fgColor: fgColors[0], fontSize: 55 }; if (n > 0) { if (n > 2) sty.fgColor = fgColors[1]; if (n <= bgColors.length) sty.bgColor = bgColors[n-1]; else sty.bgColor = bgColors[bgColors.length-1]; } /* Adjust font size according to the length of the text <= 2: 55 {3, 4}: 45 {5, 6}: 35 > 6: 30 */ var tlen = getLengthInBytes(tileText); if (tlen <= 2) sty.fontSize = 50; else if (tlen <= 4) sty.fontSize = 40; else if (tlen <= 6) sty.fontSize = 30; else sty.fontSize = 20; return sty; } function getLengthInBytes(str) { // getLengthInBytes("一二三") = 6 // getLengthInBytes("123") = 3 var b = str.match(/[^\x00-\xff]/g); // Multi-byte characters (Chinese) occupy twice more space return (str.length + (!b ? 0: b.length)); } function maxTileValue() { var mv = 0; for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { var cv = cellValues[i][j]; if ( mv < cv) { mv = cv; } } } return mv; } function createTileObject(ind, n, isStartup) { var tile; var tileText = labelFunc[label](n); var sty = computeTileStyle(n, tileText); tile = tileComponent.createObject(tileGrid, {"x": cells.itemAt(ind).x, "y": cells.itemAt(ind).y, "color": sty.bgColor, "tileColor": sty.fgColor, "tileFontSize": sty.fontSize, "tileText": tileText}); if (! isStartup) { tile.runNewTileAnim = true; } if (tile === null) { // Error Handling console.log("Error creating a new tile"); } return tile; } function moveMergeTilesLeftRight(i, v, v2, indices, left) { var j0, j; for (j0 = 0; j0 < v.length; j0++) { if (left) { j = j0; } else { j = v.length - 1 - j0; } if (v[j] > 0 && indices[j] !== j) { if (v2[indices[j]] > v[j] && tileItems[gridSize*i+indices[j]] !== null) { // Move and merge tileItems[gridSize*i+j].destroyFlag = true; tileItems[gridSize*i+j].z = -1; tileItems[gridSize*i+j].opacity = 0; tileItems[gridSize*i+j].x = cells.itemAt(gridSize*i+indices[j]).x; // tileItems[gridSize*i+j].destroy(); var tileText = labelFunc[label](v2[indices[j]]); var sty = computeTileStyle(v2[indices[j]], tileText); tileItems[gridSize*i+indices[j]].tileText = tileText; tileItems[gridSize*i+indices[j]].color = sty.bgColor; tileItems[gridSize*i+indices[j]].tileColor = sty.fgColor; tileItems[gridSize*i+indices[j]].tileFontSize = sty.fontSize; } else { // Move only tileItems[gridSize*i+j].x = cells.itemAt(gridSize*i+indices[j]).x; tileItems[gridSize*i+indices[j]] = tileItems[gridSize*i+j]; } tileItems[gridSize*i+j] = null; } } } function moveMergeTilesUpDown(i, v, v2, indices, up) { var j0, j; for (j0 = 0; j0 < v.length; j0++) { if (up) { j = j0; } else { j = v.length - 1 - j0; } if (v[j] > 0 && indices[j] !== j) { if (v2[indices[j]] > v[j] && tileItems[gridSize*indices[j]+i] !== null) { // Move and merge tileItems[gridSize*j+i].destroyFlag = true; tileItems[gridSize*j+i].z = -1; tileItems[gridSize*j+i].opacity = 0; tileItems[gridSize*j+i].y = cells.itemAt(gridSize*indices[j]+i).y; // tileItems[gridSize*j+i].destroy(); var tileText = labelFunc[label](v2[indices[j]]); var sty = computeTileStyle(v2[indices[j]], tileText); tileItems[gridSize*indices[j]+i].tileText = tileText; tileItems[gridSize*indices[j]+i].color = sty.bgColor; tileItems[gridSize*indices[j]+i].tileColor = sty.fgColor; tileItems[gridSize*indices[j]+i].tileFontSize = sty.fontSize; } else { // Move only tileItems[gridSize*j+i].y = cells.itemAt(gridSize*indices[j]+i).y; tileItems[gridSize*indices[j]+i] = tileItems[gridSize*j+i]; } tileItems[gridSize*j+i] = null; } } } function cleanUpAndQuit() { if (bestScore > settings.value("bestScore", 0)) { console.log("Updating new high score..."); settings.setValue("bestScore", bestScore); } if (label !== settings.value("label", "2048")) settings.setValue("label", label); Qt.quit(); } 2048-Qt-0.1.6/qml/Tile.qml 0000664 0000000 0000000 00000003640 12577170675 0014722 0 ustar 00root root 0000000 0000000 import QtQuick 2.2 Rectangle { id: tileContainer width: 425/4 height: 425/4 radius: 3 color: "white" property string tileText: "" property int tileFontSize: 55 property color tileColor: "black" property int moveAnimTime: 100 property int newTileAnimTime: 200 property bool runNewTileAnim: false property bool destroyFlag: false FontLoader { id: localFont; source: "qrc:///res/fonts/DroidSansFallback.ttf" } Text { id: tileLabel text: tileText color: tileColor font.family: localFont.name font.pixelSize: tileFontSize font.bold: true anchors.centerIn: parent Behavior on text { PropertyAnimation { target: tileContainer property: "opacity" from: 0.5 to: 1 duration: moveAnimTime } } } ParallelAnimation { running: runNewTileAnim NumberAnimation { target: tileContainer property: "opacity" from: 0.0 to: 1.0 duration: newTileAnimTime } ScaleAnimator { target: tileContainer from: 0 to: 1 duration: newTileAnimTime easing.type: Easing.OutQuad } } Behavior on color { ColorAnimation { duration: moveAnimTime } } Behavior on y { NumberAnimation { duration: moveAnimTime onRunningChanged: { if ((!running) && destroyFlag) { tileContainer.destroy(); } } } } Behavior on x { NumberAnimation { duration: moveAnimTime onRunningChanged: { if ((!running) && destroyFlag) { tileContainer.destroy(); } } } } } 2048-Qt-0.1.6/qml/main.qml 0000664 0000000 0000000 00000032744 12577170675 0014760 0 ustar 00root root 0000000 0000000 import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.1 import "2048.js" as MyScript ApplicationWindow { id: mainWindow visible: true width: 550 height: 740 title: qsTr("2048 Game"); // flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint x: (Screen.width - width) / 2 y: (Screen.height - height) / 2 ExclusiveGroup { id: labelSettingsGroup } ExclusiveGroup { id: languageSettingsGroup } menuBar: MenuBar { Menu { title: qsTr("File") MenuItem { text: qsTr("New Game") shortcut: "Ctrl+N" onTriggered: MyScript.startupFunction(); } MenuItem { text: qsTr("Exit") shortcut: "Ctrl+Q" onTriggered: MyScript.cleanUpAndQuit(); } } Menu { title: qsTr("Settings") Menu { title: qsTr("Labeling") MenuItem { text: qsTr("2048") checkable: true exclusiveGroup: labelSettingsGroup checked: MyScript.label === MyScript.labelOptions[0] ? true : false onTriggered: { if (MyScript.label !== MyScript.labelOptions[0]) { MyScript.label = MyScript.labelOptions[0]; MyScript.startupFunction(); } } } MenuItem { text: qsTr("Degree") checkable: true exclusiveGroup: labelSettingsGroup checked: MyScript.label === MyScript.labelOptions[1] ? true : false onTriggered: { if (MyScript.label !== MyScript.labelOptions[1]) { MyScript.label = MyScript.labelOptions[1]; MyScript.startupFunction(); } } } MenuItem { text: qsTr("Military Rank") checkable: true exclusiveGroup: labelSettingsGroup checked: MyScript.label === MyScript.labelOptions[2] ? true : false onTriggered: { if (MyScript.label !== MyScript.labelOptions[2]) { MyScript.label = MyScript.labelOptions[2]; MyScript.startupFunction(); } } } MenuItem { text: qsTr("PRC") checkable: true exclusiveGroup: labelSettingsGroup checked: MyScript.label === MyScript.labelOptions[3] ? true : false onTriggered: { if (MyScript.label !== MyScript.labelOptions[3]) { MyScript.label = MyScript.labelOptions[3]; MyScript.startupFunction(); } } } } Menu { title: qsTr("Language") MenuItem { text: "English" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") === "en_US" ? true : false onTriggered: { if (settings.value("language") !== "en_US") { settings.setValue("language", "en_US"); changeLanguageDialog.open(); } } } MenuItem { text: "Français" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") === "fr_FR" ? true : false onTriggered: { if (settings.value("language") !== "fr_FR") { settings.setValue("language", "fr_FR"); changeLanguageDialog.open(); } } } MenuItem { text: "简体中文" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") === "zh_CN" ? true : false onTriggered: { if (settings.value("language") !== "zh_CN") { settings.setValue("language", "zh_CN"); changeLanguageDialog.open(); } } } MenuItem { text: "Polski" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") === "pl_PL" ? true : false onTriggered: { if (settings.value("language") !== "pl_PL") { settings.setValue("language", "pl_PL"); changeLanguageDialog.open(); } } } MenuItem { text: "Русский" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") === "ru_RU" ? true : false onTriggered: { if (settings.value("language") !== "ru_RU") { settings.setValue("language", "ru_RU"); changeLanguageDialog.open(); } } } MenuItem { text: "German" checkable: true exclusiveGroup: languageSettingsGroup checked: settings.value("language") == "de_DE" ? true : false onTriggered: { if (settings.value("language") != "de_DE") { settings.setValue("language", "de_DE"); changeLanguageDialog.open(); } } } } } Menu { id: helpMenu title: qsTr("Help") MenuItem { text: qsTr("About") onTriggered: aboutDialog.open(); } MenuItem { text: qsTr("About Qt") onTriggered: myClass.aboutQt(); } } } Item { id: helper focus: false property var myColors: {"bglight": "#FAF8EF", "bggray": Qt.rgba(238/255, 228/255, 218/255, 0.35), "bgdark": "#BBADA0", "fglight": "#EEE4DA", "fgdark": "#776E62", "bgbutton": "#8F7A66", // Background color for the "New Game" button "fgbutton": "#F9F6F2" // Foreground color for the "New Game" button } } color: helper.myColors.bglight Item { width: 500 height: 670 anchors.centerIn: parent focus: true Keys.onPressed: MyScript.moveKey(event) MouseArea { anchors.fill: parent onClicked: parent.forceActiveFocus() } FontLoader { id: localFont; source: "qrc:///res/fonts/DroidSansFallback.ttf" } Text { id: gameName font.family: localFont.name font.pixelSize: 55 font.bold: true text: "2048" color: helper.myColors.fgdark } Row { anchors.right: parent.right spacing: 5 Repeater { id: scoreBoard model: 2 Rectangle { width: (index == 0) ? 95 : 125 height: 55 radius: 3 color: helper.myColors.bgdark property string scoreText: (index === 0) ? MyScript.score.toString() : MyScript.bestScore.toString() Text { text: (index == 0) ? qsTr("SCORE") : qsTr("BEST") anchors.horizontalCenter: parent.horizontalCenter y: 6 font.family: localFont.name font.pixelSize: 13 color: helper.myColors.fglight } Text { text: scoreText anchors.horizontalCenter: parent.horizontalCenter y: 22 font.family: localFont.name font.pixelSize: 25 font.bold: true color: "white" } } } Text { id: addScoreText font.family: localFont.name font.pixelSize: 25 font.bold: true color: Qt.rgba(119/255, 110/255, 101/255, 0.9); // parent: scoreBoard.itemAt(0) anchors.horizontalCenter: parent.horizontalCenter property bool runAddScore: false property real yfrom: 0 property real yto: -(parent.y + parent.height) property int addScoreAnimTime: 600 ParallelAnimation { id: addScoreAnim running: false NumberAnimation { target: addScoreText property: "y" from: addScoreText.yfrom to: addScoreText.yto duration: addScoreText.addScoreAnimTime } NumberAnimation { target: addScoreText property: "opacity" from: 1 to: 0 duration: addScoreText.addScoreAnimTime } } } } Text { id: banner y: 90 height: 40 text: qsTr("Join the numbers and get to the 2048 tile!") color: helper.myColors.fgdark font.family: localFont.name font.pixelSize: 16 verticalAlignment: Text.AlignVCenter } Button { width: 129 height: 40 y: 90 anchors.right: parent.right style: ButtonStyle { background: Rectangle { color: helper.myColors.bgbutton radius: 3 Text{ anchors.centerIn: parent text: qsTr("New Game") color: helper.myColors.fgbutton font.family: localFont.name font.pixelSize: 18 font.bold: true } } } onClicked: MyScript.startupFunction() } Rectangle { y: 170 width: 500 height: 500 color: helper.myColors.bgdark radius: 6 Grid { id: tileGrid x: 15; y: 15; rows: 4; columns: 4; spacing: 15 Repeater { id: cells model: 16 Rectangle { width: 425/4; height: 425/4 radius: 3 color: helper.myColors.bggray } } } } MessageDialog { id: changeLanguageDialog title: qsTr("Language Setting Hint") text: qsTr("Please restart the program to make the language setting take effect.") standardButtons: StandardButton.Ok } MessageDialog { id: aboutDialog title: qsTr("About 2048-Qt") text: qsTr("
2048-Qt
Version " + settings.getVersion() + "
2015 Qiaoyong Zhong <solary.sh@gmail.com>
") standardButtons: StandardButton.Ok } MessageDialog { id: deadMessage title: qsTr("Game Over") text: qsTr("Game Over!") standardButtons: StandardButton.Retry | StandardButton.Abort onAccepted: { MyScript.startupFunction(); } onRejected: MyScript.cleanUpAndQuit(); } MessageDialog { id: winMessage title: qsTr("You Win") text: qsTr("You win! Continue playing?") standardButtons: StandardButton.Yes | StandardButton.No onYes: { MyScript.checkTargetFlag = false; close() } onNo: MyScript.startupFunction() onRejected: { MyScript.checkTargetFlag = false; close() } } } Component.onCompleted: MyScript.startupFunction(); } 2048-Qt-0.1.6/res/ 0000775 0000000 0000000 00000000000 12577170675 0013307 5 ustar 00root root 0000000 0000000 2048-Qt-0.1.6/res/2048-qt.desktop 0000664 0000000 0000000 00000000375 12577170675 0015726 0 ustar 00root root 0000000 0000000 #!/usr/bin/env xdg-open [Desktop Entry] Name=2048-Qt GenericName=2048-Qt Comment=The 2048 number game implemented in Qt Comment[fr]=Jeu de réflexion et de mathématique Exec=2048-qt Icon=2048-qt Terminal=false Type=Application Categories=Game;Math;Qt; 2048-Qt-0.1.6/res/fonts/ 0000775 0000000 0000000 00000000000 12577170675 0014440 5 ustar 00root root 0000000 0000000 2048-Qt-0.1.6/res/fonts/DroidSansFallback.ttf 0000664 0000000 0000000 00016511350 12577170675 0020501 0 ustar 00root root 0000000 0000000 @GDEF &| 8 GPOSp 8 ZGSUB; 9 OS/2]Z `cmap~f d Lcvt ? fpgm!Y ? gasp 8t glyf>x ] 2head L 6hheaǀ $hmtxO (