Initial commit2
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Use target-compatible line endings as the safe default for cross compilation.
|
||||||
|
* text=auto eol=lf
|
20
harbour-tetrafish.desktop
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
X-Nemo-Application-Type=silica-qt5
|
||||||
|
Icon=harbour-tetrafish
|
||||||
|
Exec=harbour-tetrafish
|
||||||
|
Name=harbour-tetrafish
|
||||||
|
# translation example:
|
||||||
|
# your app name in German locale (de)
|
||||||
|
#
|
||||||
|
# Remember to comment out the following line, if you do not want to use
|
||||||
|
# a different app name in German locale (de).
|
||||||
|
Name[de]=harbour-tetrafish
|
||||||
|
|
||||||
|
[X-Sailjail]
|
||||||
|
# Replace with your organization as a reverse domain name
|
||||||
|
OrganizationName=org.myorg
|
||||||
|
# ApplicationName does not have to be identical to Name
|
||||||
|
ApplicationName=tetrafish
|
||||||
|
# Add the required permissions here
|
||||||
|
Permissions=
|
39
harbour-tetrafish.pro
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# NOTICE:
|
||||||
|
#
|
||||||
|
# Application name defined in TARGET has a corresponding QML filename.
|
||||||
|
# If name defined in TARGET is changed, the following needs to be done
|
||||||
|
# to match new name:
|
||||||
|
# - corresponding QML filename must be changed
|
||||||
|
# - desktop icon filename must be changed
|
||||||
|
# - desktop filename must be changed
|
||||||
|
# - icon definition filename in desktop file must be changed
|
||||||
|
# - translation filenames have to be changed
|
||||||
|
|
||||||
|
# The name of your application
|
||||||
|
TARGET = harbour-tetrafish
|
||||||
|
|
||||||
|
CONFIG += sailfishapp
|
||||||
|
|
||||||
|
SOURCES += src/harbour-tetrafish.cpp
|
||||||
|
|
||||||
|
DISTFILES += qml/harbour-tetrafish.qml \
|
||||||
|
qml/cover/CoverPage.qml \
|
||||||
|
qml/pages/FirstPage.qml \
|
||||||
|
qml/pages/SecondPage.qml \
|
||||||
|
rpm/harbour-tetrafish.changes.in \
|
||||||
|
rpm/harbour-tetrafish.changes.run.in \
|
||||||
|
rpm/harbour-tetrafish.spec \
|
||||||
|
translations/*.ts \
|
||||||
|
harbour-tetrafish.desktop
|
||||||
|
|
||||||
|
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
|
||||||
|
|
||||||
|
# to disable building translations every time, comment out the
|
||||||
|
# following CONFIG line
|
||||||
|
CONFIG += sailfishapp_i18n
|
||||||
|
|
||||||
|
# German translation is enabled as an example. If you aren't
|
||||||
|
# planning to localize your app, remember to comment out the
|
||||||
|
# following TRANSLATIONS line. And also do not forget to
|
||||||
|
# modify the localized app name in the the .desktop file.
|
||||||
|
TRANSLATIONS += translations/harbour-tetrafish-de.ts
|
BIN
icons/108x108/harbour-tetrafish.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
icons/128x128/harbour-tetrafish.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
icons/172x172/harbour-tetrafish.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
icons/86x86/harbour-tetrafish.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
65
qml/cover/CoverPage.qml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2013 Jolla Ltd.
|
||||||
|
Contact: Thomas Perl <thomas.perl@jollamobile.com>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
You may use this file under the terms of BSD license as follows:
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Jolla Ltd nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
CoverBackground {
|
||||||
|
Image {
|
||||||
|
id: tetimg
|
||||||
|
source: "../data/tetris.png"
|
||||||
|
fillMode: Image.Stretch
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
opacity: 0.2
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: tetraimg
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
source: "../data/tetrafish.png"
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
width: parent.width
|
||||||
|
height: parent.width
|
||||||
|
// opacity: 0.1
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "TetraFish"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
font.pixelSize: Theme.fontSizeExtraLarge
|
||||||
|
color: Theme.highlightColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
BIN
qml/data/Kraku - Tetris part 1.ogg
Normal file
BIN
qml/data/back2back.wav
Normal file
BIN
qml/data/bonus.wav
Normal file
BIN
qml/data/dot.png
Normal file
After Width: | Height: | Size: 341 B |
BIN
qml/data/down.wav
Normal file
BIN
qml/data/gravity.wav
Normal file
BIN
qml/data/harbour-tetrafish.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
qml/data/harddrop.wav
Normal file
BIN
qml/data/levelup.wav
Normal file
BIN
qml/data/move.wav
Normal file
BIN
qml/data/nobonus.wav
Normal file
BIN
qml/data/rotate.wav
Normal file
BIN
qml/data/softdrop.wav
Normal file
BIN
qml/data/tetrafish.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
qml/data/tetris.png
Normal file
After Width: | Height: | Size: 196 KiB |
BIN
qml/data/tetris.wav
Normal file
32
qml/game/Dot.qml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
GlassItem {
|
||||||
|
property int active: 0 // 0 = empty; 1 = active; 2 = inactive
|
||||||
|
property bool ghost: false
|
||||||
|
property bool glowing: false
|
||||||
|
id: dot
|
||||||
|
width: Theme.paddingLarge
|
||||||
|
height: width
|
||||||
|
radius: dots === 0 ? 0.3 : 0 // 0 ? 0.2 : 0
|
||||||
|
falloffRadius: dots === 0 ? 0.40 : 2 // 0 ? 0.25 : 2
|
||||||
|
color: Theme.highlightColor
|
||||||
|
Timer {
|
||||||
|
property bool up
|
||||||
|
id: glowingTimer
|
||||||
|
running: glowing
|
||||||
|
repeat: true
|
||||||
|
interval: 30
|
||||||
|
onTriggered: {
|
||||||
|
if (opacity === 1){
|
||||||
|
up = false
|
||||||
|
} else if (opacity < 0.5) {
|
||||||
|
up = true
|
||||||
|
}
|
||||||
|
if (up)
|
||||||
|
opacity += 0.05
|
||||||
|
else
|
||||||
|
opacity -= 0.05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1175
qml/game/Functions.qml
Normal file
167
qml/game/HighScoreModel.qml
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the QtDeclarative module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.LocalStorage 2.0
|
||||||
|
|
||||||
|
// 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 place: 0
|
||||||
|
property int maxScores: 10
|
||||||
|
property bool newScore: false
|
||||||
|
|
||||||
|
onGameChanged: fillModel()
|
||||||
|
|
||||||
|
function __db()
|
||||||
|
{
|
||||||
|
return LocalStorage.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 compareScore(point) {
|
||||||
|
__db().transaction( function(tx) {
|
||||||
|
__ensureTables(tx);
|
||||||
|
var rs = tx.executeSql("SELECT score,player FROM HighScores WHERE game=? ORDER BY score ASC", [game]);
|
||||||
|
if (rs.rows.length >= 10) {
|
||||||
|
if (point > rs.rows.item(0).score) newScore = true; else newScore = false;//return true; else return false;
|
||||||
|
} else newScore = true
|
||||||
|
var length = rs.rows.length
|
||||||
|
if (newScore){
|
||||||
|
var i=0
|
||||||
|
try {
|
||||||
|
while (point>rs.rows.item(i).score) i++;
|
||||||
|
place = (lenght-i)-1
|
||||||
|
} catch (e) {place = (length-i)+1}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
// console.log('ts 0: '+rs.rows.item(0).score)
|
||||||
|
//console.log('ts 9: '+rs.rows.item(0).score)
|
||||||
|
for (var i=0; i<rs.rows.length; ++i) {
|
||||||
|
if (i < maxScores) {
|
||||||
|
//place = i+1
|
||||||
|
model.append(rs.rows.item(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (rs.rows.length > maxScores)
|
||||||
|
tx.executeSql("DELETE FROM HighScores WHERE game=? AND score <= ?",
|
||||||
|
[game, 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() }
|
||||||
|
}
|
5
qml/game/OnlineHighScoreModel.qml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
|
||||||
|
}
|
33
qml/game/Square.qml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
GlassItem {
|
||||||
|
property int active: 0 // 0 = empty; 1 = active; 2 = inactive
|
||||||
|
property bool ghost: false
|
||||||
|
property bool glowing: false
|
||||||
|
id: square
|
||||||
|
width: Theme.paddingLarge*2
|
||||||
|
height: width
|
||||||
|
radius: dots === 0 ? 0.4 : 0 // 0 ? 0.2 : 0
|
||||||
|
falloffRadius: dots === 0 ? 0.25 : 2 // 0 ? 0.25 : 2
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
opacity: 0.1
|
||||||
|
Timer {
|
||||||
|
property bool up
|
||||||
|
id: glowingTimer
|
||||||
|
running: glowing
|
||||||
|
repeat: true
|
||||||
|
interval: 30
|
||||||
|
onTriggered: {
|
||||||
|
if (opacity === 1){
|
||||||
|
up = false
|
||||||
|
} else if (opacity < 0.5) {
|
||||||
|
up = true
|
||||||
|
}
|
||||||
|
if (up)
|
||||||
|
opacity += 0.05
|
||||||
|
else
|
||||||
|
opacity -= 0.05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
qml/harbour-tetrafish.qml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2013 Jolla Ltd.
|
||||||
|
Contact: Thomas Perl <thomas.perl@jollamobile.com>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
You may use this file under the terms of BSD license as follows:
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Jolla Ltd nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import "pages"
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
initialPage: Component { GamePage { } }
|
||||||
|
cover: Qt.resolvedUrl("cover/CoverPage.qml")
|
||||||
|
allowedOrientations: defaultAllowedOrientations
|
||||||
|
}
|
||||||
|
|
76
qml/js/settings.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
var db = undefined;
|
||||||
|
function settings_db_open() {
|
||||||
|
if (db == undefined)
|
||||||
|
db = LocalStorage.openDatabaseSync("harbour-tetrafish", "1.0", "StorageDatabase", 100000);
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
/// GAME SETTINGS
|
||||||
|
function getValue(setting,def) {
|
||||||
|
var db = settings_db_open();
|
||||||
|
var res=def;
|
||||||
|
try {
|
||||||
|
db.transaction(function(tx) {
|
||||||
|
var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
|
||||||
|
if (rs.rows.length > 0) {
|
||||||
|
res = rs.rows.item(0).value;
|
||||||
|
} else {
|
||||||
|
res = def;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
res = def
|
||||||
|
};
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValue(setting, value) {
|
||||||
|
var db = settings_db_open();
|
||||||
|
var res = "";
|
||||||
|
db.transaction(function(tx) {
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
|
||||||
|
var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]);
|
||||||
|
if (rs.rowsAffected > 0) {
|
||||||
|
res = "OK";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res = "Error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/// LOAD/SAVE GAME
|
||||||
|
function getSave(setting,def) {
|
||||||
|
var db = settings_db_open();
|
||||||
|
var res=def;
|
||||||
|
try {
|
||||||
|
db.transaction(function(tx) {
|
||||||
|
var rs = tx.executeSql('SELECT value FROM savegame WHERE setting=?;', [setting]);
|
||||||
|
if (rs.rows.length > 0) {
|
||||||
|
res = rs.rows.item(0).value;
|
||||||
|
} else {
|
||||||
|
res = def;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
res = def
|
||||||
|
};
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSave(setting, value) {
|
||||||
|
var db = settings_db_open();
|
||||||
|
var res = "";
|
||||||
|
db.transaction(function(tx) {
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(savegame TEXT UNIQUE, value TEXT)');
|
||||||
|
var rs = tx.executeSql('INSERT OR REPLACE INTO savegame VALUES (?,?);', [setting,value]);
|
||||||
|
if (rs.rowsAffected > 0) {
|
||||||
|
res = "OK";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res = "Error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
97
qml/pages/About.qml
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: page
|
||||||
|
SilicaFlickable {
|
||||||
|
id: flickable
|
||||||
|
anchors.fill: page
|
||||||
|
contentHeight: column.height
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
width: parent.width - Theme.paddingLarge*2
|
||||||
|
spacing: 20
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
PageHeader { title: qsTr("TetraFish") }
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("A remake of SailTris which is a remake of Tetris\n")
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignJustify
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("TetraFish is a remake of the game SailTris by Billy Halley, available on OpenRepos. I wanted to contribute to SailTris with some changes and fixes but Billy Halley had stopped he's development on Sailfish and SailTris and so was TetraFish with the kind approval of Billy Halley born. \n\nTetra fish is a common fish in a lot of aquariums and the original game Tetris got it's name from the greek numerical prefix tetra (4) symbolising the 4 segments making up every block in a Tetris game.")
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignJustify
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Controls")
|
||||||
|
color: Theme.highlightColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.paddingLarge
|
||||||
|
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("TetraFish i controlled by multitouch\n\nUse one finger to swipe left, right and down (tap with second finger to rotate while moving)\n\nUse two fingers to swipe down without the ability to swipe left or right (handy to avoid mistakes :-)...)\n\nSwipe down with three fingers to make an instant down\n\nSwipe up with two fingers to pause the game")
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Scoring")
|
||||||
|
color: Theme.highlightColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.paddingLarge
|
||||||
|
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Block soft down = 1 x level\nBlock hard down = 2 x level\nBlock instant down = 3 x level\nSingle line clear = 100 x level\ntwo line clear = 300 x level\nthree line clear = 500 x level\nfour line clear (Tetris) = 800 x level\nBack to back Tetris (2 four line clear in a row) = 1200 x level\ncombo bonus = 50 x combo x level\n")
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Credits")
|
||||||
|
color: Theme.highlightColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.paddingLarge
|
||||||
|
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Music by kraku\n\nSounds from different sources (should be public domain according to the same sources!)\n\nSailTris by Billy Halley\n\nTetris by Alexey Pajitnov\n\nHighscoreModel by Nokia\n\nPut together and modified with added functions by me (nesnomis)\n\nAll copyrights belong to their respective owners\n\n")
|
||||||
|
color: Theme.primaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalScrollDecorator { flickable: flickable }
|
||||||
|
}
|
||||||
|
}
|
43
qml/pages/FirstPage.qml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: page
|
||||||
|
|
||||||
|
// The effective value will be restricted by ApplicationWindow.allowedOrientations
|
||||||
|
allowedOrientations: Orientation.All
|
||||||
|
|
||||||
|
// To enable PullDownMenu, place our content in a SilicaFlickable
|
||||||
|
SilicaFlickable {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
|
||||||
|
PullDownMenu {
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Show Page 2")
|
||||||
|
onClicked: pageStack.animatorPush(Qt.resolvedUrl("SecondPage.qml"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell SilicaFlickable the height of its content.
|
||||||
|
contentHeight: column.height
|
||||||
|
|
||||||
|
// Place our content in a Column. The PageHeader is always placed at the top
|
||||||
|
// of the page, followed by our content.
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
|
||||||
|
width: page.width
|
||||||
|
spacing: Theme.paddingLarge
|
||||||
|
PageHeader {
|
||||||
|
title: qsTr("UI Template")
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
x: Theme.horizontalPageMargin
|
||||||
|
text: qsTr("Hello Sailors")
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeExtraLarge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
728
qml/pages/GamePage.qml
Normal file
@ -0,0 +1,728 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Created by Antonio Mancini **
|
||||||
|
** Contact: <ziobilly94@gmail.com> **
|
||||||
|
** This is a version of classic Tetris game for SailfishOS developed **
|
||||||
|
** entirely by me, no copyright infringement intended. **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import QtQuick.LocalStorage 2.0
|
||||||
|
import QtQuick.Particles 2.0
|
||||||
|
import "../js/settings.js" as Settings
|
||||||
|
import "../game"
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: page
|
||||||
|
|
||||||
|
|
||||||
|
HighScoreModel {
|
||||||
|
id: highScoreModel
|
||||||
|
game: hsdb
|
||||||
|
}
|
||||||
|
|
||||||
|
Functions {
|
||||||
|
id: functions
|
||||||
|
}
|
||||||
|
property bool onlineEnabled: Settings.getValue("onlineEnabled",0)
|
||||||
|
property string hsdb: onlineEnabled ? "online" : "local"
|
||||||
|
property int dots: Settings.getValue("dots",1)
|
||||||
|
property int ghostEnabled: Settings.getValue("ghostEnabled",1)
|
||||||
|
property int musicEnabled: Settings.getValue("musicEnabled",1)
|
||||||
|
property int sfxEnabled: Settings.getValue("sfxEnabled",1)
|
||||||
|
property string musicScore: "../data/Kraku - Tetris part 1.ogg" //: Settings.getValue("musicScore","")
|
||||||
|
property int scoreValue
|
||||||
|
property int speedValue
|
||||||
|
property int linesValue
|
||||||
|
property int level: 1
|
||||||
|
property int linesTotal: 0
|
||||||
|
property int activeBlock
|
||||||
|
property int futureBlock: -1
|
||||||
|
property int combo: 1
|
||||||
|
property int gravityBreak: 1
|
||||||
|
property bool pauseVal
|
||||||
|
property int downSpeed: 2500
|
||||||
|
property int comboSpeed: 10000
|
||||||
|
|
||||||
|
// 0 = l_normal; 1 = l_reverse;
|
||||||
|
// 2 = s_normal; 3 = s_reverse;
|
||||||
|
// 4 = t_normal; 5 = square;
|
||||||
|
// 6 = line
|
||||||
|
|
||||||
|
property variant activeColor
|
||||||
|
property variant futureColor
|
||||||
|
|
||||||
|
property real centerX
|
||||||
|
property real centerY
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: gameOverTimer
|
||||||
|
property int i: 15
|
||||||
|
property int j: 10
|
||||||
|
property bool clear: true
|
||||||
|
property bool done: false
|
||||||
|
interval: 10
|
||||||
|
repeat: true
|
||||||
|
onTriggered : {
|
||||||
|
if (clear) {
|
||||||
|
if ( j === 0) {
|
||||||
|
i--
|
||||||
|
j = 10
|
||||||
|
} else {
|
||||||
|
if ( i === 0) {
|
||||||
|
clear = false
|
||||||
|
done = true
|
||||||
|
j = 10
|
||||||
|
i = 15
|
||||||
|
} else {
|
||||||
|
var index = i*12+j
|
||||||
|
repeater.itemAt(index).color = Theme.secondaryHighlightColor//"black"//"transparent"//Theme.secondaryColor
|
||||||
|
repeater.itemAt(index).opacity = 0.5//0.5
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( j === 0) {
|
||||||
|
i--
|
||||||
|
j = 10
|
||||||
|
} else {
|
||||||
|
if ( i === 0) {
|
||||||
|
running = false
|
||||||
|
clear = true
|
||||||
|
if (highScoreModel.newScore) {
|
||||||
|
highScoreModel.newScore = false
|
||||||
|
getName.visible = true ;
|
||||||
|
} else {
|
||||||
|
pullDownMenu.enabled = true
|
||||||
|
splash.visible = true
|
||||||
|
}
|
||||||
|
i = 15
|
||||||
|
j = 10
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
done = false
|
||||||
|
index = i*12+j
|
||||||
|
repeater.itemAt(index).opacity = 0.1
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function downSpeedCalc(level) {
|
||||||
|
if (level>1){
|
||||||
|
for ( var i = 1; i < level; i++) {
|
||||||
|
var ds = downSpeed/15
|
||||||
|
downSpeed -= ds
|
||||||
|
}
|
||||||
|
return downSpeed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function comboSpeedCalc(level) {
|
||||||
|
for ( var i = 1; i < level; i++) {
|
||||||
|
comboSpeed = comboSpeed/30
|
||||||
|
}
|
||||||
|
return comboSpeed+200
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: downTimer
|
||||||
|
interval: downSpeed+150//interval-(interval/20)+150 //difficulty*(1338*Math.pow(Math.E,-0.07*level)+150) //difficulty*(1338*Math.pow(Math.E,-0.26*level)+150)
|
||||||
|
repeat: true
|
||||||
|
running: false
|
||||||
|
onTriggered: {
|
||||||
|
functions.flow()
|
||||||
|
speedValue += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SilicaFlickable {
|
||||||
|
id: root
|
||||||
|
anchors.fill: page
|
||||||
|
contentHeight : height
|
||||||
|
|
||||||
|
PushUpMenu {
|
||||||
|
id:pushUpMenu
|
||||||
|
enabled: false
|
||||||
|
visible: false
|
||||||
|
MenuItem {
|
||||||
|
id: pauseMenuItem
|
||||||
|
text: qsTr("Resume")
|
||||||
|
onClicked: functions.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PullDownMenu {
|
||||||
|
id: pullDownMenu
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("About")
|
||||||
|
onClicked: pageStack.push("About.qml")
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Settings")
|
||||||
|
onClicked: {
|
||||||
|
var dialog = pageStack.push("SettingsDialog.qml", {"dots": dots, "ghostEnabled": ghostEnabled, "musicEnabled": musicEnabled, "sfxEnabled": sfxEnabled, "musicScore": musicScore, "onlineEnabled": onlineEnabled})
|
||||||
|
dialog.accepted.connect(function() {
|
||||||
|
|
||||||
|
dots = dialog.dots
|
||||||
|
ghostEnabled = dialog.ghostEnabled
|
||||||
|
musicEnabled = dialog.musicEnabled
|
||||||
|
sfxEnabled = dialog.sfxEnabled
|
||||||
|
onlineEnabled = dialog.onlineEnabled
|
||||||
|
highScoreModel.place = 0
|
||||||
|
Settings.setValue("dots",dots)
|
||||||
|
Settings.setValue("ghostEnabled",ghostEnabled)
|
||||||
|
Settings.setValue("musicEnabled",musicEnabled)
|
||||||
|
Settings.setValue("sfxEnabled",sfxEnabled)
|
||||||
|
Settings.setValue("onlineEnabled",onlineEnabled)
|
||||||
|
// highScoreModel.game = "local"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: functions.garunning ? functions.gapaused ? qsTr("Resume") : qsTr("Pause") : qsTr("New Game")
|
||||||
|
onClicked: {
|
||||||
|
if (functions.garunning) {
|
||||||
|
functions.pause()
|
||||||
|
} else {
|
||||||
|
|
||||||
|
splash.visible = false
|
||||||
|
highscores.visible = false
|
||||||
|
functions.newGame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: score
|
||||||
|
text: qsTr("LEVEL ") + "\n" + qsTr("SCORE ") + "\n" + qsTr("LINES ")
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
font.family: Theme.fontFamilyHeading
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: Theme.paddingMedium
|
||||||
|
bottom: futureGrid.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: scoreValues
|
||||||
|
text: level + "\n" + scoreValue + "\n" + linesTotal
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.family: Theme.fontFamilyHeading
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
anchors {
|
||||||
|
right: bonusPanel.left
|
||||||
|
rightMargin: Theme.paddingLarge
|
||||||
|
bottom: futureGrid.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bonusPanel
|
||||||
|
radius: height / 2
|
||||||
|
height: futureGrid.height
|
||||||
|
width: height
|
||||||
|
color: Theme.highlightDimmerColor
|
||||||
|
|
||||||
|
opacity: bonusLabel.opacity > 0 ? 0.8 : 0//bonusLabel.opacity
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
top: futureGrid.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: bonusLabel
|
||||||
|
text: ""///functions.garunning ? "" : "PLAY"
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.pixelSize: functions.garunning ? bonusPanel.height - (Theme.paddingMedium * 2) : Theme.fontSizeLarge
|
||||||
|
font.bold: true
|
||||||
|
anchors.verticalCenter: bonusPanel.verticalCenter
|
||||||
|
anchors.horizontalCenter: bonusPanel.horizontalCenter
|
||||||
|
opacity: 0//functions.garunning ? 0 : 1//infoTimer.running ? 1 : 0
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
id: futureGrid
|
||||||
|
y: (parent.height-rect.height-height)/2
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
columns: 4
|
||||||
|
rows: 3
|
||||||
|
Repeater {
|
||||||
|
id: futureRepeater
|
||||||
|
model: 12
|
||||||
|
delegate: Dot {width: Theme.paddingLarge*5/3 ;color: Theme.highlightBackgroundColor; opacity: 0.1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer { // EXPERIMENT
|
||||||
|
id: hssplachTimer
|
||||||
|
running: splash.visible || highscores.visible && Qt.application.active && !contextMenu.visible? true : false//!functions.garunning && !gameOverTimer.running ? true : false
|
||||||
|
interval: 8000
|
||||||
|
repeat: true
|
||||||
|
onTriggered: if (highscores.visible) {highscores.visible=false;splash.visible = true;} else {highscores.visible=true;splash.visible=false}//highscores.visible ? splash.visible = true : high.visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
width: grid.width
|
||||||
|
height: grid.height
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
border.color: "transparent"
|
||||||
|
color: "black"
|
||||||
|
opacity: 0.8//0.8
|
||||||
|
Grid {
|
||||||
|
id: grid
|
||||||
|
columns: 12
|
||||||
|
rows: 17
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
model: 204
|
||||||
|
delegate: Dot {width: page.width/12 ;color: Theme.highlightBackgroundColor; opacity: 0.1}
|
||||||
|
onItemAdded: { // Bordi "muro"... seriamente, si può fare di meglio, 576 caratteri per una linea è più brutto di questo commento, da aggiungere a newGame() magari
|
||||||
|
if (index < 12 || index > 191 || index === 0 || index === 12 ||
|
||||||
|
index === 24 || index === 36 || index === 48 || index === 60 ||
|
||||||
|
index === 72 || index === 84 || index === 96 || index === 108 ||
|
||||||
|
index === 120 || index === 132 || index === 144 || index === 156 ||
|
||||||
|
index === 168 || index === 180 || index === 23 || index === 35 ||
|
||||||
|
index === 47 || index === 59 || index === 71 || index === 83 ||
|
||||||
|
index === 95 || index === 107 || index === 119 || index === 131 ||
|
||||||
|
index === 143 || index === 155 || index === 167 || index === 179 || index === 191)
|
||||||
|
{
|
||||||
|
itemAt(index).active = 3
|
||||||
|
itemAt(index).color = Theme.highlightBackgroundColor
|
||||||
|
itemAt(index).opacity = 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ParticleSystem {
|
||||||
|
id: sys
|
||||||
|
}
|
||||||
|
|
||||||
|
Emitter {
|
||||||
|
anchors.fill: parent
|
||||||
|
system: sys
|
||||||
|
ImageParticle {
|
||||||
|
anchors.fill: parent
|
||||||
|
system: sys
|
||||||
|
source: "../data/dot.png"
|
||||||
|
clip: true
|
||||||
|
id: redblip
|
||||||
|
}
|
||||||
|
velocity: PointDirection {yVariation: 16; xVariation: 5}
|
||||||
|
acceleration: PointDirection {y: -16}
|
||||||
|
lifeSpan: Emitter.InfiniteLife
|
||||||
|
maximumEmitted: 1000
|
||||||
|
} */
|
||||||
|
|
||||||
|
MultiPointTouchArea {
|
||||||
|
id: mouseArea
|
||||||
|
property int offsetX: grid.width/14
|
||||||
|
property int offsetY: (grid.height/19)
|
||||||
|
property int blahX: (parent.width - (grid.width-point1.x))/offsetX
|
||||||
|
property int blahY: (parent.height - (grid.height-point1.y))/offsetY
|
||||||
|
property int prevX
|
||||||
|
property int prevY
|
||||||
|
property int initX
|
||||||
|
property int initY
|
||||||
|
property int inter: 85
|
||||||
|
property int plus: 0
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
|
||||||
|
anchors.fill: grid
|
||||||
|
anchors.margins: offsetX
|
||||||
|
mouseEnabled: true
|
||||||
|
|
||||||
|
touchPoints: [
|
||||||
|
TouchPoint { id: point1 },
|
||||||
|
TouchPoint { id: point2 },
|
||||||
|
TouchPoint { id: point3 }
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
onTouchUpdated: {
|
||||||
|
if (functions.maenabled){
|
||||||
|
if (point1.pressed && point2.pressed && point3.pressed){
|
||||||
|
if (blahY > prevY+2){
|
||||||
|
prevY=blahY
|
||||||
|
functions.instantDown()
|
||||||
|
}
|
||||||
|
} else if (point1.pressed && point2.pressed && !point3.pressed){
|
||||||
|
if (blahY > prevY){
|
||||||
|
prevY=blahY
|
||||||
|
functions.down()
|
||||||
|
}
|
||||||
|
if (blahY < prevY-2){
|
||||||
|
prevY=blahY
|
||||||
|
functions.pause()
|
||||||
|
}
|
||||||
|
} else if (point1.pressed && !point2.pressed && !point3.pressed){
|
||||||
|
//if (blahY==prevY) var plus = 0; else plus = 1;
|
||||||
|
if (blahY > prevY){
|
||||||
|
plus = 1;
|
||||||
|
functions.down()
|
||||||
|
prevY=blahY
|
||||||
|
} else {
|
||||||
|
if (blahX < prevX-plus) {
|
||||||
|
functions.left()
|
||||||
|
prevX=blahX
|
||||||
|
plus = 0
|
||||||
|
}
|
||||||
|
if (blahX > prevX+plus){
|
||||||
|
functions.right()
|
||||||
|
prevX=blahX
|
||||||
|
plus = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if (blahY > prevY){
|
||||||
|
prevY=blahY
|
||||||
|
functions.down()
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
// console.log(blahX + " - " + prevX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (blahY == initY && blahX == initX && !point1.pressed && !point2.pressed || point1.pressed && !point2.pressed){
|
||||||
|
functions.rotate()
|
||||||
|
}
|
||||||
|
|
||||||
|
functions.maenabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
prevX = blahX
|
||||||
|
initX = blahX
|
||||||
|
prevY = blahY
|
||||||
|
initY = blahY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: gameOverLabel
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: rect.horizontalCenter
|
||||||
|
verticalCenter: rect.verticalCenter
|
||||||
|
}
|
||||||
|
style: Text.Outline; styleColor: Theme.secondaryHighlightColor
|
||||||
|
text: "GAME OVER"
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeHuge
|
||||||
|
font.bold: true
|
||||||
|
visible: !functions.garunning && opacity > 0 ? true : false
|
||||||
|
opacity: gameOverTimer.running ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: pauseLabel
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: rect.horizontalCenter
|
||||||
|
verticalCenter: rect.verticalCenter
|
||||||
|
}
|
||||||
|
style: Text.Outline; styleColor: Theme.secondaryHighlightColor
|
||||||
|
text: "PAUSED"
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeHuge
|
||||||
|
font.bold: true
|
||||||
|
visible: false
|
||||||
|
states: [
|
||||||
|
State { when: stateVisible;
|
||||||
|
PropertyChanges { target: myRect; opacity: 1.0 }
|
||||||
|
},
|
||||||
|
State { when: !stateVisible;
|
||||||
|
PropertyChanges { target: myRect; opacity: 0.0 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
transitions: Transition {
|
||||||
|
NumberAnimation { property: "opacity"; duration: 300}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: infoLabel
|
||||||
|
anchors {
|
||||||
|
verticalCenter: rect.verticalCenter
|
||||||
|
horizontalCenter: rect.horizontalCenter
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
style: Text.Outline; styleColor: Theme.secondaryHighlightColor;
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeLarge*2
|
||||||
|
font.bold: true
|
||||||
|
opacity: infoTimer.running ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: infoTimer
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
interval: 1100
|
||||||
|
onTriggered: {
|
||||||
|
infoLabel.opacity = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: highscores
|
||||||
|
anchors.verticalCenter: rect.verticalCenter
|
||||||
|
anchors.horizontalCenter: rect.horizontalCenter
|
||||||
|
width: rect.width - (rect.width/6)
|
||||||
|
height: rect.height - (rect.height/8)+Theme.paddingSmall
|
||||||
|
visible: splash.visible || functions.garunning || getName.visible && opacity === 0 ? false : true //!splash.visible && !getName.visible && !functions.garunning
|
||||||
|
color: "transparent"//Theme.highlightBackgroundColor
|
||||||
|
opacity: !visible ? 0 : 0.8
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {onStopped: console.log("highscores fade animation klar")}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: hs1
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: Theme.paddingLarge
|
||||||
|
text: "HIGHSCORES ["+highScoreModel.game+"]"
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.bold: true
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: hs1
|
||||||
|
onClicked: {
|
||||||
|
!onlineEnabled ? onlineEnabled=true : onlineEnabled=false
|
||||||
|
console.log("ONLINE: "+highScoreModel.game)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
width: parent.width; height: parent.height - hs1.height
|
||||||
|
enabled: true
|
||||||
|
anchors.top: hs1.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: Theme.paddingLarge
|
||||||
|
model: highScoreModel
|
||||||
|
delegate: ListItem {
|
||||||
|
id: showDelegate
|
||||||
|
// menu: contextMenu
|
||||||
|
highlighted: index == highScoreModel.place-1 ? true : false
|
||||||
|
width: ListView.view.width
|
||||||
|
height: menuOpen ? contextMenu.height + pn.height + Theme.paddingSmall : pn.height + Theme.paddingSmall//contextMenu.height + contentItem.height + Theme.paddingMedium : contentItem.height + Theme.paddingMedium
|
||||||
|
contentHeight: pn.height + Theme.paddingSmall
|
||||||
|
Text {
|
||||||
|
id: pn
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.paddingMedium
|
||||||
|
color: Theme.highlightColor
|
||||||
|
text: index+(1)+"."
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: pnm
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
anchors.left: pn.right
|
||||||
|
anchors.leftMargin: Theme.paddingMedium
|
||||||
|
anchors.top: pn.top
|
||||||
|
color: Theme.highlightColor
|
||||||
|
text: player
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.paddingMedium
|
||||||
|
anchors.top: pn.top
|
||||||
|
color: Theme.highlightColor
|
||||||
|
text: score
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextMenu {
|
||||||
|
id: contextMenu
|
||||||
|
width: rect.width - (rect.width/6)
|
||||||
|
anchors.horizontalCenter: highscores.horizontalCenter
|
||||||
|
MenuItem {
|
||||||
|
id:onlineMenu
|
||||||
|
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Share score online")
|
||||||
|
onClicked: {
|
||||||
|
var uuid = generateUUID()
|
||||||
|
console.log("UUID: "+uuid)
|
||||||
|
/* internal ? ps(source) : model.id == 0 ? ps(source) : cps(model.id)
|
||||||
|
radioStation = title
|
||||||
|
if (icon == "0") picon = "../allradio-data/images/allradio.png"
|
||||||
|
else if (icon.search(".png")>0) picon = icon.toLowerCase(); // The old save in database
|
||||||
|
else picon = "../allradio-data/images/"+icon+".png";
|
||||||
|
website = (Qt.resolvedUrl(site)) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: splash
|
||||||
|
anchors.verticalCenter: rect.verticalCenter
|
||||||
|
anchors.horizontalCenter: rect.horizontalCenter
|
||||||
|
width: rect.width - (rect.width/6)
|
||||||
|
height: rect.height - (rect.height/8) + Theme.paddingSmall
|
||||||
|
|
||||||
|
visible: functions.garunning || getName.visible || highscores.visible && opacity === 0 ? false : true//true && !functions.garunning//!functions.garunning && !getName.visible && !highscores.visible//&& !gameOverTimer.done ? true : false //&& gameOverTimer.running ? done :
|
||||||
|
color: "transparent"//Theme.highlightBackgroundColor
|
||||||
|
opacity: !visible ? 0 : 0.8
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {}
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
spacing: Theme.paddingLarge
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: splash.horizontalCenter
|
||||||
|
verticalCenter: splash.verticalCenter
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: name
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: "TetraFish"
|
||||||
|
color: Theme.highlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeHuge
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
id: tetraFish
|
||||||
|
width: name.width
|
||||||
|
height: width
|
||||||
|
source: "../data/tetrafish.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: info1
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: "A TETRIS clone"
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: info2
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: "Presented by NESNOMIS"
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: getName
|
||||||
|
anchors.fill: rect
|
||||||
|
anchors.left: rect.left
|
||||||
|
anchors.top: rect.top
|
||||||
|
width: rect.width
|
||||||
|
height: rect.height
|
||||||
|
|
||||||
|
visible: false//!functions.garunning && !gameOverTimer.done ? true : false //&& gameOverTimer.running ? done :
|
||||||
|
color: "black"//Theme.highlightBackgroundColor
|
||||||
|
opacity: !visible ? 0 : 0.8
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
FadeAnimator {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: congrat
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: "CONGRATULATIONS"//+highScoreModel.place
|
||||||
|
color: Theme.highlightColor
|
||||||
|
anchors.bottom: namn.top
|
||||||
|
font.pixelSize: Theme.fontSizeExtraLarge
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: namn
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: "You placed No. "+highScoreModel.place
|
||||||
|
color: Theme.primaryColor
|
||||||
|
anchors.bottom: textField.top
|
||||||
|
anchors.bottomMargin: Theme.paddingLarge * 3
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: textField
|
||||||
|
enabled: parent.visible
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
width: parent.width
|
||||||
|
maximumLength: 8
|
||||||
|
focus: true
|
||||||
|
placeholderText: "ENTER YOUR NAME"
|
||||||
|
inputMethodHints: Qt.ImhUppercaseOnly | Qt.ImhPreferUppercase | Qt.ImhNoPredictiveText
|
||||||
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Theme.fontSizeHuge
|
||||||
|
font.capitalization: Font.AllUppercase
|
||||||
|
EnterKey.iconSource: "image://theme/icon-m-enter" //"image://theme/icon-m-enter-close"
|
||||||
|
EnterKey.onClicked: {
|
||||||
|
|
||||||
|
getName.visible = false
|
||||||
|
splash.visible = false
|
||||||
|
highscores.visible = true
|
||||||
|
pullDownMenu.enabled = true
|
||||||
|
root.interactive = true
|
||||||
|
functions.saveHighscore(text.toUpperCase(),scoreValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function generateUUID(){
|
||||||
|
var d = new Date().getTime();
|
||||||
|
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||||
|
var r = (d + Math.random()*16)%16 | 0;
|
||||||
|
d = Math.floor(d/16);
|
||||||
|
return (c === 'x' ? r : (r&0x3|0x8)).toString(16);
|
||||||
|
});
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: splash.visible = true
|
||||||
|
}
|
||||||
|
|
30
qml/pages/SecondPage.qml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: page
|
||||||
|
|
||||||
|
// The effective value will be restricted by ApplicationWindow.allowedOrientations
|
||||||
|
allowedOrientations: Orientation.All
|
||||||
|
|
||||||
|
SilicaListView {
|
||||||
|
id: listView
|
||||||
|
model: 20
|
||||||
|
anchors.fill: parent
|
||||||
|
header: PageHeader {
|
||||||
|
title: qsTr("Nested Page")
|
||||||
|
}
|
||||||
|
delegate: BackgroundItem {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
Label {
|
||||||
|
x: Theme.horizontalPageMargin
|
||||||
|
text: qsTr("Item") + " " + index
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
|
||||||
|
}
|
||||||
|
onClicked: console.log("Clicked " + index)
|
||||||
|
}
|
||||||
|
VerticalScrollDecorator {}
|
||||||
|
}
|
||||||
|
}
|
105
qml/pages/SettingsDialog.qml
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: page
|
||||||
|
property int dots
|
||||||
|
property int ghostEnabled
|
||||||
|
property int musicEnabled
|
||||||
|
property int sfxEnabled
|
||||||
|
property int highscoreValue
|
||||||
|
property int onlineEnabled
|
||||||
|
|
||||||
|
SilicaFlickable {
|
||||||
|
id: flickable
|
||||||
|
anchors.fill: parent
|
||||||
|
contentHeight: column.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
width: page.width
|
||||||
|
spacing: Theme.paddingLarge
|
||||||
|
DialogHeader {
|
||||||
|
title: qsTr("Settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSwitch {
|
||||||
|
id: dotSwitch
|
||||||
|
automaticCheck: false
|
||||||
|
checked: dots ? true : false
|
||||||
|
text: checked ? qsTr("Squares") : qsTr("Dots")
|
||||||
|
description: qsTr("Changes the shape of the blocks")
|
||||||
|
onClicked: {
|
||||||
|
if (dots === 0) {
|
||||||
|
dots = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dots = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextSwitch {
|
||||||
|
id: ghostSwitch
|
||||||
|
automaticCheck: false
|
||||||
|
checked: ghostEnabled ? true : false
|
||||||
|
text: checked ? qsTr("Ghost Enabled") : qsTr("Ghost Disabled")
|
||||||
|
description: qsTr("Display a hint of where the block will fall")
|
||||||
|
onClicked: {
|
||||||
|
if (ghostEnabled === 0) {
|
||||||
|
ghostEnabled = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ghostEnabled = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextSwitch {
|
||||||
|
id: sfxSwitch
|
||||||
|
automaticCheck: false
|
||||||
|
checked: sfxEnabled ? true : false
|
||||||
|
text: checked ? qsTr("SoundFX Enabled") : qsTr("SoundFX Disabled")
|
||||||
|
description: qsTr("Play sound effects in game")
|
||||||
|
onClicked: {
|
||||||
|
if (sfxEnabled === 0) {
|
||||||
|
sfxEnabled = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sfxEnabled = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextSwitch {
|
||||||
|
id: musicSwitch
|
||||||
|
automaticCheck: false
|
||||||
|
checked: musicEnabled ? true : false
|
||||||
|
text: checked ? qsTr("Music Enabled") : qsTr("Music Disabled")
|
||||||
|
description: qsTr("Play music in game")
|
||||||
|
enabled: true /// enable if music should be included?!
|
||||||
|
onClicked: {
|
||||||
|
if (musicEnabled === 0) {
|
||||||
|
musicEnabled = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
musicEnabled = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TextSwitch {
|
||||||
|
id: onlineSwitch
|
||||||
|
automaticCheck: false
|
||||||
|
checked: onlineEnabled ? true : false
|
||||||
|
text: checked ? qsTr("Online highscores Enabled") : qsTr("Online highscores Disabled")
|
||||||
|
description: qsTr("Save scores online to compare scores with other players")
|
||||||
|
enabled: true /// enable if music should be included?!
|
||||||
|
onClicked: {
|
||||||
|
if (onlineEnabled === 0) {
|
||||||
|
onlineEnabled = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
onlineEnabled = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
rpm/harbour-tetrafish.changes.in
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Rename this file as harbour-tetrafish.changes to include changelog
|
||||||
|
# entries in your RPM file.
|
||||||
|
#
|
||||||
|
# Add new changelog entries following the format below.
|
||||||
|
# Add newest entries to the top of the list.
|
||||||
|
# Separate entries from eachother with a blank line.
|
||||||
|
#
|
||||||
|
# Alternatively, if your changelog is automatically generated (e.g. with
|
||||||
|
# the git-change-log command provided with Sailfish OS SDK), create a
|
||||||
|
# harbour-tetrafish.changes.run script to let mb2 run the required commands for you.
|
||||||
|
|
||||||
|
# * date Author's Name <author's email> version-release
|
||||||
|
# - Summary of changes
|
||||||
|
|
||||||
|
* Sun Apr 13 2014 Jack Tar <jack.tar@example.com> 0.0.1-1
|
||||||
|
- Scrubbed the deck
|
||||||
|
- Hoisted the sails
|
||||||
|
|
24
rpm/harbour-tetrafish.changes.run.in
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Rename this file as harbour-tetrafish.changes.run to let sfdk automatically
|
||||||
|
# generate changelog from well formatted Git commit messages and tag
|
||||||
|
# annotations. Note that 'sfdk changelog' must be invoked as 'sfdk-changelog' here.
|
||||||
|
|
||||||
|
sfdk-changelog
|
||||||
|
|
||||||
|
# Here are some basic examples how to change from the default behavior. Run
|
||||||
|
# 'sfdk --help-maintaining' to learn more.
|
||||||
|
|
||||||
|
# Use a subset of tags
|
||||||
|
#sfdk-changelog --tags refs/tags/my-prefix/*
|
||||||
|
|
||||||
|
# Group entries by minor revision, suppress headlines for patch-level revisions
|
||||||
|
#sfdk-changelog --dense '/[0-9]+.[0-9+$'
|
||||||
|
|
||||||
|
# Trim very old changes
|
||||||
|
#sfdk-changelog --since 2014-04-01
|
||||||
|
#echo '[ Some changelog entries trimmed for brevity ]'
|
||||||
|
|
||||||
|
# Use the subjects (first lines) of tag annotations when no entry would be
|
||||||
|
# included for a revision otherwise
|
||||||
|
#sfdk-changelog --auto-add-annotations
|
41
rpm/harbour-tetrafish.spec
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Name: harbour-tetrafish
|
||||||
|
|
||||||
|
Summary: TetraFish
|
||||||
|
Version: 0.0.1
|
||||||
|
Release: 1
|
||||||
|
License: LICENSE
|
||||||
|
URL: http://example.org/
|
||||||
|
Source0: %{name}-%{version}.tar.bz2
|
||||||
|
Requires: sailfishsilica-qt5 >= 0.10.9
|
||||||
|
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
|
||||||
|
BuildRequires: pkgconfig(Qt5Core)
|
||||||
|
BuildRequires: pkgconfig(Qt5Qml)
|
||||||
|
BuildRequires: pkgconfig(Qt5Quick)
|
||||||
|
BuildRequires: desktop-file-utils
|
||||||
|
|
||||||
|
%description
|
||||||
|
Tetris clone
|
||||||
|
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q -n %{name}-%{version}
|
||||||
|
|
||||||
|
%build
|
||||||
|
|
||||||
|
%qmake5
|
||||||
|
|
||||||
|
%make_build
|
||||||
|
|
||||||
|
|
||||||
|
%install
|
||||||
|
%qmake5_install
|
||||||
|
|
||||||
|
|
||||||
|
desktop-file-install --delete-original --dir %{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/*.desktop
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_bindir}/%{name}
|
||||||
|
%{_datadir}/%{name}
|
||||||
|
%{_datadir}/applications/%{name}.desktop
|
||||||
|
%{_datadir}/icons/hicolor/*/apps/%{name}.png
|
20
src/harbour-tetrafish.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifdef QT_QML_DEBUG
|
||||||
|
#include <QtQuick>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sailfishapp.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// SailfishApp::main() will display "qml/harbour-tetrafish.qml", if you need more
|
||||||
|
// control over initialization, you can use:
|
||||||
|
//
|
||||||
|
// - SailfishApp::application(int, char *[]) to get the QGuiApplication *
|
||||||
|
// - SailfishApp::createView() to get a new QQuickView * instance
|
||||||
|
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
|
||||||
|
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
|
||||||
|
//
|
||||||
|
// To display the view, call "show()" (will show fullscreen on device).
|
||||||
|
|
||||||
|
return SailfishApp::main(argc, argv);
|
||||||
|
}
|
197
translations/harbour-tetrafish-de.ts
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1">
|
||||||
|
<context>
|
||||||
|
<name>About</name>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>A remake of SailTris which is a remake of Tetris
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish is a remake of the game SailTris by Billy Halley, available on OpenRepos. I wanted to contribute to SailTris with some changes and fixes but Billy Halley had stopped he's development on Sailfish and SailTris and so was TetraFish with the kind approval of Billy Halley born.
|
||||||
|
|
||||||
|
Tetra fish is a common fish in a lot of aquariums and the original game Tetris got it's name from the greek numerical prefix tetra (4) symbolising the 4 segments making up every block in a Tetris game.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Controls</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish i controlled by multitouch
|
||||||
|
|
||||||
|
Use one finger to swipe left, right and down (tap with second finger to rotate while moving)
|
||||||
|
|
||||||
|
Use two fingers to swipe down without the ability to swipe left or right (handy to avoid mistakes :-)...)
|
||||||
|
|
||||||
|
Swipe down with three fingers to make an instant down
|
||||||
|
|
||||||
|
Swipe up with two fingers to pause the game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scoring</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Block soft down = 1 x level
|
||||||
|
Block hard down = 2 x level
|
||||||
|
Block instant down = 3 x level
|
||||||
|
Single line clear = 100 x level
|
||||||
|
two line clear = 300 x level
|
||||||
|
three line clear = 500 x level
|
||||||
|
four line clear (Tetris) = 800 x level
|
||||||
|
Back to back Tetris (2 four line clear in a row) = 1200 x level
|
||||||
|
combo bonus = 50 x combo x level
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Credits</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music by kraku
|
||||||
|
|
||||||
|
Sounds from different sources (should be public domain according to the same sources!)
|
||||||
|
|
||||||
|
SailTris by Billy Halley
|
||||||
|
|
||||||
|
Tetris by Alexey Pajitnov
|
||||||
|
|
||||||
|
HighscoreModel by Nokia
|
||||||
|
|
||||||
|
Put together and modified with added functions by me (nesnomis)
|
||||||
|
|
||||||
|
All copyrights belong to their respective owners
|
||||||
|
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>FirstPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Show Page 2</source>
|
||||||
|
<translation>Zur Seite 2</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>UI Template</source>
|
||||||
|
<translation>UI-Vorlage</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hello Sailors</source>
|
||||||
|
<translation>Hallo Matrosen</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>GamePage</name>
|
||||||
|
<message>
|
||||||
|
<source>Resume</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pause</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>New Game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>LEVEL </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SCORE </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>LINES </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Share score online</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SecondPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Nested Page</source>
|
||||||
|
<translation>Unterseite</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Item</source>
|
||||||
|
<translation>Element</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SettingsDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Squares</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Changes the shape of the blocks</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ghost Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ghost Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Display a hint of where the block will fall</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SoundFX Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SoundFX Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Play sound effects in game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Play music in game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
197
translations/harbour-tetrafish.ts
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1">
|
||||||
|
<context>
|
||||||
|
<name>About</name>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>A remake of SailTris which is a remake of Tetris
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish is a remake of the game SailTris by Billy Halley, available on OpenRepos. I wanted to contribute to SailTris with some changes and fixes but Billy Halley had stopped he's development on Sailfish and SailTris and so was TetraFish with the kind approval of Billy Halley born.
|
||||||
|
|
||||||
|
Tetra fish is a common fish in a lot of aquariums and the original game Tetris got it's name from the greek numerical prefix tetra (4) symbolising the 4 segments making up every block in a Tetris game.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Controls</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TetraFish i controlled by multitouch
|
||||||
|
|
||||||
|
Use one finger to swipe left, right and down (tap with second finger to rotate while moving)
|
||||||
|
|
||||||
|
Use two fingers to swipe down without the ability to swipe left or right (handy to avoid mistakes :-)...)
|
||||||
|
|
||||||
|
Swipe down with three fingers to make an instant down
|
||||||
|
|
||||||
|
Swipe up with two fingers to pause the game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scoring</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Block soft down = 1 x level
|
||||||
|
Block hard down = 2 x level
|
||||||
|
Block instant down = 3 x level
|
||||||
|
Single line clear = 100 x level
|
||||||
|
two line clear = 300 x level
|
||||||
|
three line clear = 500 x level
|
||||||
|
four line clear (Tetris) = 800 x level
|
||||||
|
Back to back Tetris (2 four line clear in a row) = 1200 x level
|
||||||
|
combo bonus = 50 x combo x level
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Credits</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music by kraku
|
||||||
|
|
||||||
|
Sounds from different sources (should be public domain according to the same sources!)
|
||||||
|
|
||||||
|
SailTris by Billy Halley
|
||||||
|
|
||||||
|
Tetris by Alexey Pajitnov
|
||||||
|
|
||||||
|
HighscoreModel by Nokia
|
||||||
|
|
||||||
|
Put together and modified with added functions by me (nesnomis)
|
||||||
|
|
||||||
|
All copyrights belong to their respective owners
|
||||||
|
|
||||||
|
</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>FirstPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Show Page 2</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>UI Template</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hello Sailors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>GamePage</name>
|
||||||
|
<message>
|
||||||
|
<source>Resume</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pause</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>New Game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>LEVEL </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SCORE </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>LINES </source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Share score online</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SecondPage</name>
|
||||||
|
<message>
|
||||||
|
<source>Nested Page</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Item</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SettingsDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Squares</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Changes the shape of the blocks</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ghost Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ghost Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Display a hint of where the block will fall</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SoundFX Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SoundFX Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Play sound effects in game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music Enabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Music Disabled</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Play music in game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|