qt

Description: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#55by dyvniy » Mon, 6 Mar 2017, 14:36:36

Image

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#56by dyvniy » Tue, 7 Mar 2017, 17:57:12

Image

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#57by dyvniy » Sun, 12 Mar 2017, 21:58:43

Создание мобильного приложения
https://habrahabr.ru/post/220877/
Spoiler
Qt 5.2, от желания до Google Play из песочницы
Разработка под Android*, Qt*, Разработка мобильных приложений*
Здравствуйте, коллеги.

Случилось так, что мне рассказали о Qt5.2 и его новой возможности быстро и легко создавать кроссплатформенные приложения под Android и iOS. С Qt я знаком был уже давно, но в последнее время работа была связана с другими технологиями и я немного запустил его развитие. Узнав это, я отправился на сайт Qt, посмотрел красивое видео, где за 10 минут HelloWorld приложение создается сразу под android и ios. Впечатления были очень положительные.

Было принято решиение заняться мобильной разработкой. Появился план пройти путь от желания сделать приложение до его публикации в Google Play. Но на первом этапе хотелось пройти это с тем что не жалко и в чем можно делать ошибки. И все это на новом Qt5.2.


Примерно в это же время я услышал про всем известную Flappy Bird и то что ее автор решил удалить свое приложение. Ну и тут уже понятно, что следующее решение было сделать очередную копию этой игры, но основная цель, это кончно опробовать новые возможности Qt.

Выбор с++ или javascript

Я конечно люблю c++, но писать на нем такую мелочь я не решился. C++ заставляет разработчика писать вдумчиво и быть очень внимательным чтобы не «отстрелить себе ногу», мне же хотелось сделать проект в стиле XP, быстро и главное чтобы работало. Выбор пал на QML и javascript, заодно возможность разобраться с этими так продвигаемыми Digia технологиями.

Первый набросок

Быстро поставив Qt, почитав документацию на qml и рассмотрев игровую механику Flappy Bird (до этого я о ней не слышал) был сделан первый набросок игры. Были использованы простые NumberAnimation для имитации полета птицы и передвижения столбов. Все работало отлично, но появились вопросы:
как сделать проверку столкновений
как масштабировать на разные разрешения графику и физику
как быть с дизайном
что делать со звуками игры
как встроить монетизацию


Физика

Единственно правильным решением, для 2-х выше указанных проблем, я посчитал использовать всем известный Box2D. Плагин для qml нашелся быстро — github.com/qml-box2d/qml-box2d. Пара дней экспериментов, чтения документации box2d и все переписано и прекрасно работает. Но проблемы еще ждали впереди.

Звук

От фоновой музыки я отказался так как сам ее не люблю да и не смог бы ни подобрать хороший вариант ни тем более сделать самостоятельно. Так на www.freesound.org были подобраны 3 звука: взмах крыльями, столкновение и новое очко.
Для воспроизведения был использован хороший пример создания Flappy Bird из V-play с AudioManager-ом. Но без напильника не обошлось.
import QtQuick 2.2

Item {
id : audioManager

property QtObject effect1: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{}", audioManager);
property QtObject effect2: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{}", audioManager);

property int hit: 22
property int point: 33
property int silence: 44
property int wing: 55

property bool effectSwitcher: false;

function play( sound) {

var effect;

if( !effectSwitcher){
effect = effect1;
effectSwitcher = true;
}else if( effectSwitcher){
effect = effect2;
effectSwitcher = false;
}

if(effect == null)
return;

switch(sound) {
case hit:
effect.source = "audio/sfx_hit.wav"
break
case point:
effect.source = "audio/sfx_point.wav"
break
case silence:
effect.source = "audio/sfx_silence.wav"
break
case wing:
effect.source = "audio/sfx_wing.wav"
break
}

effect.play();
}
}


воспроизведение:
audioManager.play( audioManager.wing);


Все заработало на desktop машине, на телефоне же приложение падало. Причина оказалась банальна, надо было в .pro файл добавить следующее:
QT += multimedia

Зачем здесь два SoundEffect и для чего sfx_silence станет понятно ниже в описании встретившихся багов.

Масштабирование

Масштабирование было сделано стандартно. За основу было взято разрешение 480x800 (маленькое но наверно самое распространенное на данный момент). Относительно него были жестко заданы размеры птицы, и столбов. Дальше просто было сделано вычисление коэффициента масштабирования для текущего разрешения относительно эталонного, и затем все размеры требующие масштабирования просто на него умножались. Со всем этим сильно помог вот этот пример bitbucket.org/wearyinside/cute-plane, но как обычно множество проблем там решено не было.
width: Screen.width
height: Screen.height
property int defaultWidth: 480
property int defaultHeight: 800
property double measure: Math.min(Math.min(width, height) / defaultWidth, Math.max(width, height) / defaultHeight)
property double textScale: Math.sqrt( measure)

Все физические объекты мастабируются линейно, а вот текст при таком мастабировании на высоких разрешениях разрывал все рамки. Для него пришлось сделать масштабироваие по квадратному корню от основного коэффициента масштабирования.

Дизайн

Так как я программист, дизайн был для меня дремучий лес, но интернет наше все и через день чтения различных статей на эту тему была выбрана векторная графика и редактор Inkscape. Для того чтоб нарисовать мультяшную птицу тоже понадобился всего 1-2 дня. Первоначально был сделан набросок на бумаге и нарисовано несколько возможных вариантов. Затем самый лучший был перенесен в svg. Далее и все остальные изображения были сделаны в векторном формате. Для того чтобы использовать svg фаилы в qml в .pro файл надо добавить следующее:
QT += xml svg
QTPLUGIN += qsvg


Монетизация

Основная часть была написана и встал вопрос монетизации. Данный проект хоть и тестовый, но хотелось в нем уже разобраться и с монетизацией. Выбрана была монетизация рекламой admob. И тут начались первые серьезные проблемы. Оказалось что для qt/qml нет никаких плагинов для встраивания admob. Была найдена устаревшая реализация qadmob и закрытая реализация V-play AdMob plugin. Тучи сгустились и начали появляться мысли оставить Qt до лучших времен. Перерыв весь интернет стало понятно что надо перерыть исходники Qt и разобраться как он сделан под Android. И через 4 дня раскопок, тестовый рекламный баннер отобразился в игре. Вот пример как это делается github.com/AlexMarlo/AdMob-Qt5.2-Example. На отображение баннера в общем ушла неделя.

Баги

Далее стало ясно что все основные части сделаны и надо поправить мелкие, отложенные на потом, баги.

Утечка памяти

Память утекала по 100 MB за минуту игры. После переодического комментирования qml кода и проверки результатов, проблема была найдена. Оказалось что память утекала при таком присвоении:
linearVelocity.x = 220;
linearVelocity.y = -420;

поменяв этот вариант на
var flyImpulseVelosityY = -420 * measure;
var flyImpulseVelosityX = 220 * measure;
var impulse;
impulse = Qt.point( flyImpulseVelosityX, flyImpulseVelosityY);
applyLinearImpulse( impulse, getWorldCenter());

утечки прекратились. Здесь похоже на проблему с qml-box2d, но копать глубже я не стал.

Пропадание звука

При очень частом тапанье и следовательно очень частом воспроизведении, звук стабильно пропадал до проигрывания другого звукового файла. Тут и появилось два SoundEffect. Причем это проявлялось только на андроидах. Для того чтоб этого пропадания не было SoundEffect-ы проигрываются поочередно. К такому решению пришел просто опытным путем. Судя по всему это какая-то проблема в самом Qt.

Приложение завершалось на assert в Box2D при включенном масштабировании

width: Screen.width
height: Screen.height
property int defaultWidth: 480
property int defaultHeight: 800
property double measure: Math.min(Math.min(width, height) / defaultWidth, Math.max(width, height) / defaultHeight)

Проблема кроется в первых 2-х строчках. Как оказалось пока не сконструирован qml элемент в котором вызывается Screen, Screen.width и Screen.height будут равны 0. Получается что коэффициент масштабирования первоначально равен 0 и здесь box2d завершает приложение на assert, так как физические объекты не могут быть нулевого размера.
Это удалось исправить только динамически создавая объекты в тот момент, когда коэффициент масштабирования примет не нулевое значение.

Не работающее управление громкостью

Как оказалось, в текущей версии Qt под андроид, кнопки управления громкостью не работают. Все советы на форумах того же Qt предлогали перехватывать нажатия кнопок в Activity, что и было сделано.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ( keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) + 1;
if( index <= am.getStreamMaxVolume( AudioManager.STREAM_MUSIC))
am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0);
}
if( keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) - 1;
if( index >= 0)
am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0);
}
return super.onKeyDown(keyCode, event);
}


Тестирование на разных устройствах и снова баги

Дальше наступил этап тестирования на разных андроидах, вот примерный список устройств:
Motorola Droid Razr
Nexus One
Samsung Galaxy S Duos
Nexus S
Nexus 7 1st gen
Nexus 7 2nd gen
Nexus 5
Sone Xperia Ray
Samsung Galaxy S3
Nexus 4
Acer Iconia Tab A510
Galaxy S Plus
Alcatel OneTouch M'POP 5020D
Samsung Galaxy Fame GT-S6810
ASUS Transformer Pad TF300TG


Samsung

И все проблемы вылезли на самсунгах, причем чем лучше телефон тем сильнее проявлялись баги, а судя по вот этой статистике www.appbrain.com/stats/top-android-phones оставлять баги на самсунгах просто нельзя.

Лаг при проигрывании первого звука

По непонятной причине первое проигрывание звука через SoundEffect подвисало и потом все работало нормально. Особенно сильно это проявлялось на Samsung Galaxy S3, на других самсунгах тоже было, но не так заметно. На устройствах других производителей данной проблемы не было. Тут и появился sfx_silence.wav. Это по сути пустой звукойвой файл который проигрывается при загрузке игры.

Лаг при динамическом создании Box2D объектов

Следующая проблема была по причине того что, Box2D объекты создавались динамически для корректного масштабирования и это создание очень тормозило на самсунгах, особенно на том же Samsung Galaxy S3.
Создание объектов земли:
Nexus One 97 ms
Samsung Galaxy S Duos 986 ms

Разница на порядок, но разбираться в нюансах реализации qml-box2d и самого Box2D я не стал, а просто перенес все создание на момент загрузки игры. Грузится дольше но зато во время игры никаких тормозов.

Выводы:

Qt под Android не смотря на множество непонятных багов и недоделок вполне пригоден для разработки. Особенно если вы уже знакомы с Qt. Но надо быть готовым к тому что вы встретите проблемы на которые еще нет ответов в сети.

Одним из минусов, который так и не удалось решить, стал большой размер приложения:
apk ~ 10 MB
установленное приложение ~38 MB

Самое печальное, что примерно 70% это библиотеки самого Qt и с этим придется мириться. С другой стороны для современных устройств такой размер уже не так критичен.
Image

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#58by dyvniy » Fri, 9 Jun 2017, 14:35:01

Installers
http://doc.qt.io/qtinstallerframework/ifw-offline-installers.html
Spoiler
Creating Offline Installers

Offline installers do not try to connect to an online repository at all during installation. However, the metadata configuration (config.xml) enables users to add and update components online.

Offline installers are especially useful in cases where a corporate firewall does not allow end users to connect to web servers. The network administrator can set up a local update service within the network.

To create offline installers, use the --offline-only option of the binarycreator tool.

To create an offline installer in Windows, enter the following command:

<location-of-ifw>\binarycreator.exe --offline-only -t <location-of-ifw>\installerbase.exe -p <package_directory> -c <config_directory>\<config_file> <installer_name>
Some options have default values, and therefore, you can omit them. For example, enter the following command to create an installer binary called SDKInstaller.exe that contains the packages identified by org.qt-project.sdk and their dependencies:

binarycreator.exe --offline-only -c installer-config -p installer-packes SDKInstaller.exe
Image

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#59by dyvniy » Sun, 2 Jul 2017, 06:58:34

Image

dyvniy M
Topic author, Администратор
Администратор
Avatar
dyvniy M
Topic author, Администратор
Администратор
Age: 36
Reputation: 1
Loyalty: 1
Posts: 3091
Joined: Wed, 10 Oct 2012
With us: 6 years 6 months
Профессия: Программист
Location: Россия, Москва
ICQ Website Skype VK

#60by dyvniy » Fri, 29 Dec 2017, 16:24:46

Добавить иконку в приложение windows
http://www.cyberforum.ru/qt/thread356540.html

1. создай файл file.rc с содержимым

Code: Select all

IDI_ICON1               ICON                    "Icon1.ico"

2. Файл Icon1.ico - это сама иконка, которая должна быть в папке этого проекта.
3. В файл проекта (*.pro) добавь:

Code: Select all

win32 {
    RC_FILE += file.rc
    OTHER_FILES 
+= file.rc
}
Image


Forum name: Программирование (под Desktop и Android)
Description: Разработка и отладка приложений. Упор на 3D-графику.

Quick reply


Enter the code exactly as it appears. All letters are case insensitive.
Confirmation code
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: View more smilies
   

Return to “Программирование (под Desktop и Android)”

Who is online (over the past 15 minutes)

Users browsing this forum: 1 guest