标签:qt quick qml qt for android qt on android
使用 Qt Quick 写了个小游戏:疯狂算数。支持 Windows 和 Android 两个平台。
就差您这一票了亲:博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
游戏简单,但牵涉到下面你的 Qt Quick 主题:
其实所有这些内容,在我的书《Qt Quick核心编程》里都讲到了,感兴趣的朋友可以看我的书。
大概来看一下吧,先看效果。
下面是 Android 应用列表:
看到“疯狂算数”那个应用了吧,图标是我自己画的,名字是中文的。
再来看游戏进行中的效果:
界面中间,第一行是倒计时,数秒的。第二行是算术题。第三行是两个按钮,选择对错;判断正确的话,继续下一题,如果选错了,游戏就结束了,可以看到下面的图。
游戏结束时显示当前答对的题数、历史最好成绩。界面下方是两个按钮,点“再来”可以重玩,点“退出”就结束整个游戏。游戏结束的界面,使用了弹簧动画(SprintgAnimation),有一些动画效果。
源码我们走马观花,摘重要的讲一下。
这个简单的示例里,只有 qml 文档中有需要翻译的字符串。在 pro 文件里有一些改动:
TRANSLATIONS = madmath_zh_cn.ts
lupdate_only {
SOURCES = main.qml
}main.cpp 代码如下:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QFont>
#include <QQmlContext>
#include <QIcon>
#include <QLocale>
#include <QTranslator>
#include "sizeUtil.h"
#include "problem.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QFont f = app.font();
f.setPointSize(24);
app.setWindowIcon(QIcon(":/res/madmath_36.png"));
QLocale locale = QLocale::system();
if(locale.language() == QLocale::Chinese)
{
QTranslator *translator = new QTranslator(&app);
if(translator->load(":/madmath_zh_cn.qm"))
{
app.installTranslator(translator);
}
}
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("sizeUtil", new SizeUtil);
engine.rootContext()->setContextProperty("problems", new MathProblem);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}实现了一个简单的图片按钮—— ImageButton ,在 ImageButton.qml 文件内。所有源码:
import QtQuick 2.0
Rectangle {
id: btn;
property alias normalImage: normal.source;
property alias pressedImage: pressed.source;
signal clicked();
Image {
id: normal;
anchors.fill: parent;
}
Image {
id: pressed;
anchors.fill: parent;
visible: false;
}
implicitWidth: 64;
implicitHeight: 48;
MouseArea {
anchors.fill: parent;
onPressed: {
pressed.visible = true;
normal.visible = false;
}
onReleased: {
pressed.visible = false;
normal.visible = true;
btn.clicked();
}
}
}还定义了一个 clicked() 信号。暴露了属性别名 normalImage 和 pressedImage 用来设置按钮需要的图片。
ImageButton 用起来也很简单,下面是 main.qml 中的使用示例:
ImageButton {
id: wrong;
anchors.right: parent.horizontalCenter;
anchors.rightMargin: 12;
anchors.top: problem.bottom;
anchors.topMargin: 20;
normalImage: Qt.resolvedUrl("res/wrong_normal.png");
pressedImage: Qt.resolvedUrl("res/wrong_selected.png");
width: root.dpiFactor * 64;
height: root.dpiFactor * 48;
onClicked: root.check(false);
}算术题目的生成和结果判断,我放在了 C++ 中,在 MathProblem 里实现。另外还有 DPI 的一些信息,也在 C++ 中,在 SizeUtil 中实现。
有关 QML 与 C++ 混合编程的细节,请看我的博客或者我的书——《Qt Quick核心编程》,这里就不再细说了。我们只看一下题目是如何出的,部分源码:
QString MathProblem::next()
{
++m_index;
if(m_index == sizeof(g_answers)/sizeof(g_answers[0]))
{
m_index = 0;
}
int var = qrand() % 2;
if(var && (qrand() % 2)) var = -var;
m_currentAnswer = g_answers[m_index] + qrand() % 2;
m_currentRight = (g_answers[m_index] == m_currentAnswer);
return QString("%1%2").arg(g_problems[m_index]).arg(m_currentAnswer);
}
bool MathProblem::test(bool right)
{
return right == m_currentRight;
}test() 用来测试用户的选择与实际结果是否一致。
题目在全局数组 g_problems 中,答案在全局数组 g_answers 中。
当用户答错题时,会从应用顶部弹出一个提示界面。我使用了 SpringAnimation 为这个界面加入了一些动画效果。
gameOverUI 的代码如下:
Rectangle {
id: gameOverUI;
border.width: 2;
border.color: "white";
color: "lightsteelblue";
width: root.width * 0.75;
height: root.height * 0.75;
x: root.width * 0.125;
y: -height-1;
visible: false;
Text {
id: overTitle;
anchors.top: parent.top;
anchors.topMargin: sizeUtil.defaultFontHeight();
anchors.horizontalCenter: parent.horizontalCenter;
font.pointSize: 30;
text: qsTr("Game Over");
color: "red";
}
Text {
anchors.bottom: parent.verticalCenter;
anchors.bottomMargin: 10;
anchors.right: parent.horizontalCenter;
anchors.rightMargin: 8;
text: qsTr("New:");
horizontalAlignment: Text.AlignRight;
color: "black";
}
Text {
id: current;
anchors.bottom: parent.verticalCenter;
anchors.bottomMargin: 10;
anchors.left: parent.horizontalCenter;
anchors.leftMargin: 8;
horizontalAlignment: Text.AlignLeft;
color: "blue";
font.bold: true;
}
Text {
anchors.top: current.bottom;
anchors.topMargin: 20;
anchors.right: parent.horizontalCenter;
anchors.rightMargin: 8;
text: qsTr("Best:");
horizontalAlignment: Text.AlignRight;
color: "black";
}
Text {
id: best;
anchors.top: current.bottom;
anchors.topMargin: 20;
anchors.left: parent.horizontalCenter;
anchors.leftMargin: 8;
horizontalAlignment: Text.AlignLeft;
color: "blue";
font.bold: true;
}
Button {
anchors.bottom: parent.bottom;
anchors.bottomMargin: 40;
anchors.right: parent.horizontalCenter;
anchors.rightMargin: 16;
text: qsTr("Restart");
onClicked: {
gameOverUI.dismiss();
root.start();
}
}
Button {
anchors.bottom: parent.bottom;
anchors.bottomMargin: 40;
anchors.left: parent.horizontalCenter;
anchors.leftMargin: 16;
text: qsTr("Quit");
onClicked: Qt.quit();
}
SpringAnimation {
id: overAnimation;
target: gameOverUI;
from: -height - 1;
to: root.height * 0.125;
spring: 2;
damping: 0.2;
duration: 1000;
property: "y";
onStarted: {
gameOverUI.visible = true;
}
}
function dismiss() {
y = -height - 1;
visible = false;
}
function fire(currentRecord, bestRecord) {
current.text = currentRecord;
best.text = bestRecord;
overAnimation.start();
}
}fire() 方法会在游戏进行中被调用,它启动动画,讲游戏结果赋值给提示界面里的 Text 元素。
SpringAnimation 的具体用法,参考 Qt 帮助,或者《Qt Quick核心编程》一书,它对 Qt Quick 里的动画类库作了非常详尽的介绍。
给 Android 版本创建一个 AndroidManifest.xml ,在项目视图里双击就可以打开图形化编辑界面,可以选择你设计的图标。参考《Qt on Android核心编程》一书,或者“Qt on Android:图文详解Hello World全过程”。
我在“Qt on Android:创建可伸缩界面”一文中讲了 Qt on Android 如何适应 Android 手机多变的分辨率。这里就不再细说了。只看一下 QML 里如何根据 DPI 来设置图片按钮的大小,代码:
ImageButton {
id: right;
anchors.left: parent.horizontalCenter;
anchors.leftMargin: 12;
anchors.top: problem.bottom;
anchors.topMargin: 20;
normalImage: Qt.resolvedUrl("res/right_normal.png");
pressedImage: Qt.resolvedUrl("res/right_selected.png");
width: root.dpiFactor * 64;
height: root.dpiFactor * 48;
onClicked: root.check(true);
}qreal SizeUtil::dpiFactor()
{
QScreen *screen = qApp->primaryScreen();
return screen->logicalDotsPerInch() / 72;
}就差您这一票了亲:博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
好啦,到此结束了。完整的项目代码下载:点击下载。
--------
回顾一下我的Qt Quick系列文章:
标签:qt quick qml qt for android qt on android
原文地址:http://blog.csdn.net/foruok/article/details/42554321