mirror of
https://github.com/QuasarApp/Snake.git
synced 2025-05-09 07:59:48 +00:00
ref #30 tmp commit
This commit is contained in:
parent
bd78303d02
commit
ee5a3be629
CMakeLists.txt
src/ClientLib
CMakeLists.txtSnakeProject.qrc
SnakeProject
ProfileViewItems
mainclient.cppmainclient.hmainmenumodel.cppmainmenumodel.hnetworkclient.cppnetworkclient.hnotificationdata.cppnotificationdata.hnotificationservice.cppnotificationservice.hplayerclientdata.cppplayerclientdata.hsettingsviewmodel.cppsettingsviewmodel.huserview.cppuserview.h
SnakeProject.cppSnakeProject.hSnakeProject_global.hasyncimageresponse.cppasyncimageresponse.hbackground.cppbackground.hbackgrounditem.cppbackgrounditem.hbaseclass.cppbaseclass.hbox.cppbox.hclientapp.cppclientapp.hcontroller.cppcontroller.hdiff.cppdiff.hguiobject.cppguiobject.hguiobjectfactory.cppguiobjectfactory.hhead.cpphead.himageprovider.cppimageprovider.hitemworld.cppitemworld.hlvls.cpplvls.hmain.cppqtquickcontrols2.confsettings.cppsettings.hsnake.cppsnake.hsnakeutils.cppsnakeutils.hworld.cppworld.hSnakeProjectModule
About.qmlAboutPage.qmlBasePopUp.qmlFrameView.qmlGraphicItem.qmlImageView.qmlLeftBoxSideBar.qmlLeftSideBar.qmlLoginView.qmlMainMenu.qmlMainMenuButton.qmlMetrix.qmlNotificationForm.qmlNotificationServiceView.qmlPagePopUp.qmlPropertyView.qmlScene.qmlSelectLevelScene.qmlSettingsView.qmlSideBar.qmlSnakeItem.qmlSnakeProject.qmlTextInput.qmlUserView.qml
android
languages
res
@ -20,8 +20,8 @@ set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test QUIET)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test QUIET)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test REQUIRED)
|
||||
|
||||
include(submodules/QuasarAppLib/CMake/QuasarApp.cmake)
|
||||
|
||||
|
@ -27,12 +27,13 @@ endif()
|
||||
set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(PRIVATE_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Private")
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick REQUIRED)
|
||||
|
||||
|
||||
add_library(${PROJECT_NAME} ${SOURCE_CPP} ${SOURCE_QRC})
|
||||
|
||||
if (${QT_VERSION_MAJOR})
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core)
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${PUBLIC_INCUDE_DIR})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PRIVATE_INCUDE_DIR})
|
||||
|
@ -2,5 +2,28 @@
|
||||
<qresource prefix="/">
|
||||
<file>SnakeProjectModule/qmldir</file>
|
||||
<file>SnakeProjectModule/SnakeProject.qml</file>
|
||||
<file>SnakeProjectModule/About.qml</file>
|
||||
<file>SnakeProjectModule/AboutPage.qml</file>
|
||||
<file>SnakeProjectModule/BasePopUp.qml</file>
|
||||
<file>SnakeProjectModule/FrameView.qml</file>
|
||||
<file>SnakeProjectModule/GraphicItem.qml</file>
|
||||
<file>SnakeProjectModule/ImageView.qml</file>
|
||||
<file>SnakeProjectModule/LeftBoxSideBar.qml</file>
|
||||
<file>SnakeProjectModule/LeftSideBar.qml</file>
|
||||
<file>SnakeProjectModule/LoginView.qml</file>
|
||||
<file>SnakeProjectModule/MainMenu.qml</file>
|
||||
<file>SnakeProjectModule/MainMenuButton.qml</file>
|
||||
<file>SnakeProjectModule/Metrix.qml</file>
|
||||
<file>SnakeProjectModule/NotificationForm.qml</file>
|
||||
<file>SnakeProjectModule/NotificationServiceView.qml</file>
|
||||
<file>SnakeProjectModule/PagePopUp.qml</file>
|
||||
<file>SnakeProjectModule/PropertyView.qml</file>
|
||||
<file>SnakeProjectModule/Scene.qml</file>
|
||||
<file>SnakeProjectModule/SelectLevelScene.qml</file>
|
||||
<file>SnakeProjectModule/SettingsView.qml</file>
|
||||
<file>SnakeProjectModule/SideBar.qml</file>
|
||||
<file>SnakeProjectModule/SnakeItem.qml</file>
|
||||
<file>SnakeProjectModule/TextInput.qml</file>
|
||||
<file>SnakeProjectModule/UserView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
180
src/ClientLib/SnakeProject/ProfileViewItems/mainclient.cpp
Normal file
180
src/ClientLib/SnakeProject/ProfileViewItems/mainclient.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
#include "mainclient.h"
|
||||
#include "notificationservice.h"
|
||||
#include "playerclientdata.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
OnlineStatus MainClient::onlineStatus() const {
|
||||
return _onlineStatus;
|
||||
}
|
||||
|
||||
void MainClient::setOnlineStatus(OnlineStatus onlineStatus) {
|
||||
if (_onlineStatus == onlineStatus)
|
||||
return;
|
||||
|
||||
emit sigOnlineStatusChanged(_onlineStatus = onlineStatus);
|
||||
pushNotify(onlineStatus);
|
||||
|
||||
}
|
||||
|
||||
void MainClient::clientStatusChanged() {
|
||||
auto status = OnlineStatus::ClientIsOffline;
|
||||
|
||||
if (isOnline()) {
|
||||
status = OnlineStatus::AuthorizationRequired;
|
||||
}
|
||||
|
||||
if (isLogin()) {
|
||||
status = OnlineStatus::Success;
|
||||
}
|
||||
|
||||
setOnlineStatus(status);
|
||||
}
|
||||
|
||||
void MainClient::pushNotify(OnlineStatus onlineStatus) {
|
||||
|
||||
|
||||
switch (onlineStatus) {
|
||||
|
||||
case OnlineStatus::Success: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login status"), tr("Success")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OnlineStatus::AuthorizationRequired: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login status"), tr("Authorization Required")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OnlineStatus::WaitForAnswer: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login status"), tr("Wait for answer")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OnlineStatus::AuthorizationFail: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login result"), tr("Authorization fail") , "", NotificationData::Error));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OnlineStatus::ClientIsOffline: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login result"), tr("Client is offline"), "", NotificationData::Warning));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OnlineStatus::OfflineMode: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Login result"), tr("Offline Mode")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MainClient::handleReceivePackage(ClientProtocol::Command cmd, const QByteArray &obj) {
|
||||
switch (cmd) {
|
||||
|
||||
case ClientProtocol::Command::Player: {
|
||||
auto playerData = QSharedPointer<PlayerClientData>::create();
|
||||
playerData->fromBytes(obj);
|
||||
|
||||
_users [playerData->id()] = playerData;
|
||||
|
||||
if (playerData->id() == _currentUserId) {
|
||||
emit currentUserDataChanged(_users [playerData->id()]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ClientProtocol::Command::BadRequest: {
|
||||
|
||||
NotificationService::getService()->setNotify(
|
||||
NotificationData(tr("Request"), tr("Bad Request"), "",
|
||||
NotificationData::Error));
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainClient::handleLoginChanged(bool logined) {
|
||||
this->setSubscribe(ClientProtocol::Command::Player, logined, _currentUserId);
|
||||
clientStatusChanged();
|
||||
|
||||
}
|
||||
|
||||
void MainClient::handleOnlineChanged(bool) {
|
||||
clientStatusChanged();
|
||||
}
|
||||
|
||||
MainClient::MainClient(const QString &addrress, unsigned short port, QObject *ptr):
|
||||
ClientProtocol::Client (addrress, port, ptr) {
|
||||
|
||||
connect(this, &MainClient::sigIncommingData,
|
||||
this, &MainClient::handleReceivePackage);
|
||||
|
||||
connect(this, &MainClient::onlineChanged,
|
||||
this, &MainClient::handleOnlineChanged);
|
||||
|
||||
connect(this, &MainClient::loginChanged,
|
||||
this, &MainClient::handleLoginChanged);
|
||||
}
|
||||
|
||||
bool MainClient::login(const QString &gmail, const QByteArray &pass, bool) {
|
||||
if (!ClientProtocol::Client::login(gmail, pass)) {
|
||||
setOnlineStatus(OnlineStatus::AuthorizationFail);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainClient::registration(const QString &gmail,
|
||||
const QByteArray &pass) {
|
||||
|
||||
if (!ClientProtocol::Client::registration(gmail, pass)) {
|
||||
setOnlineStatus(OnlineStatus::AuthorizationFail);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainClient::playOffline() {
|
||||
if (_onlineStatus == OnlineStatus::ClientIsOffline) {
|
||||
setOnlineStatus(OfflineMode);
|
||||
}
|
||||
}
|
||||
|
||||
void MainClient::tryConnect(const QString &addrress, unsigned short port) {
|
||||
setOnlineStatus(ClientIsOffline);
|
||||
connectToHost(addrress, port);
|
||||
}
|
||||
|
||||
MainClient::~MainClient() {
|
||||
for (auto &i: _users) {
|
||||
i.clear();
|
||||
}
|
||||
_users.clear();
|
||||
}
|
51
src/ClientLib/SnakeProject/ProfileViewItems/mainclient.h
Normal file
51
src/ClientLib/SnakeProject/ProfileViewItems/mainclient.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef MAINCLIENT_H
|
||||
#define MAINCLIENT_H
|
||||
#include <client.h>
|
||||
|
||||
class PlayerClientData;
|
||||
|
||||
enum OnlineStatus: int {
|
||||
Success = 0x0,
|
||||
AuthorizationRequired,
|
||||
WaitForAnswer,
|
||||
AuthorizationFail,
|
||||
ClientIsOffline,
|
||||
OfflineMode
|
||||
};
|
||||
|
||||
class MainClient: public ClientProtocol::Client
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QHash<int, QSharedPointer<PlayerClientData>> _users;
|
||||
OnlineStatus _onlineStatus = ClientIsOffline;
|
||||
|
||||
void setOnlineStatus(OnlineStatus onlineStatus);
|
||||
void clientStatusChanged();
|
||||
void pushNotify(OnlineStatus onlineStatus);
|
||||
|
||||
private slots:
|
||||
void handleReceivePackage(ClientProtocol::Command cmd, const QByteArray& obj);
|
||||
void handleLoginChanged(bool);
|
||||
void handleOnlineChanged(bool);
|
||||
|
||||
public:
|
||||
MainClient(const QString& addrress = LOCAL_SNAKE_SERVER,
|
||||
unsigned short port = DEFAULT_SNAKE_PORT,
|
||||
QObject * ptr = nullptr);
|
||||
bool login(const QString& gmail, const QByteArray &pass, bool registerNewUser = false) override;
|
||||
bool registration(const QString& gmail,
|
||||
const QByteArray &pass) override;
|
||||
void playOffline();
|
||||
void tryConnect(const QString &addrress, unsigned short port);
|
||||
|
||||
~MainClient() override;
|
||||
|
||||
OnlineStatus onlineStatus() const;
|
||||
|
||||
signals:
|
||||
void sigOnlineStatusChanged(OnlineStatus);
|
||||
void currentUserDataChanged(QSharedPointer<PlayerClientData>);
|
||||
};
|
||||
|
||||
#endif // MAINCLIENT_H
|
@ -0,0 +1,59 @@
|
||||
#include "mainmenumodel.h"
|
||||
#include "settingsviewmodel.h"
|
||||
#include "userview.h"
|
||||
|
||||
#include <back-end/settings.h>
|
||||
#include <quasarapp.h>
|
||||
#include "mainclient.h"
|
||||
|
||||
MainMenuModel::MainMenuModel(QObject *ptr): QObject (ptr) {
|
||||
|
||||
if(!ClientProtocol::initClientProtockol()) {
|
||||
QuasarAppUtils::Params::verboseLog("client protockol not inited", QuasarAppUtils::Error);
|
||||
}
|
||||
|
||||
_userViewModel = new UserView (this);
|
||||
_conf = Settings::get();
|
||||
_userSettingsModel = new SettingsViewModel(this);
|
||||
auto adderss = _conf->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
|
||||
auto port = _conf->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
|
||||
_client = new MainClient(adderss, static_cast<unsigned short>(port), this);
|
||||
|
||||
connect(_client, &MainClient::sigOnlineStatusChanged,
|
||||
this , &MainMenuModel::onlineStatusChanged);
|
||||
|
||||
connect(_client, &MainClient::currentUserDataChanged,
|
||||
_userViewModel , &UserView::setSource);
|
||||
}
|
||||
|
||||
QObject *MainMenuModel::userViewModel() const {
|
||||
return _userViewModel;
|
||||
}
|
||||
|
||||
int MainMenuModel::onlineStatus() const {
|
||||
return _client->onlineStatus();
|
||||
}
|
||||
|
||||
void MainMenuModel::playOffline() {
|
||||
_client->playOffline();
|
||||
_userViewModel->setOffline(true);
|
||||
}
|
||||
|
||||
void MainMenuModel::tryConnect() {
|
||||
auto adderss = _conf->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
|
||||
auto port = _conf->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
|
||||
_client->tryConnect(adderss, static_cast<unsigned short>(port));
|
||||
}
|
||||
|
||||
QObject *MainMenuModel::userSettingsModel() const {
|
||||
return _userSettingsModel;
|
||||
}
|
||||
|
||||
void MainMenuModel::login(const QString &email, const QString &pass) {
|
||||
_client->login(email, pass.toUtf8());
|
||||
}
|
||||
|
||||
void MainMenuModel::registerNewUser(const QString &email,
|
||||
const QString &pass) {
|
||||
_client->registration(email, pass.toUtf8());
|
||||
}
|
51
src/ClientLib/SnakeProject/ProfileViewItems/mainmenumodel.h
Normal file
51
src/ClientLib/SnakeProject/ProfileViewItems/mainmenumodel.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef NETWORKPROFILEMAINMODEL_H
|
||||
#define NETWORKPROFILEMAINMODEL_H
|
||||
|
||||
#include "mainclient.h"
|
||||
|
||||
#include <QObject>
|
||||
#include "./../settings.h"
|
||||
|
||||
class UserView;
|
||||
|
||||
class MainClient;
|
||||
class SettingsViewModel;
|
||||
|
||||
class MainMenuModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QObject* userViewModel READ userViewModel NOTIFY userViewModelChanged)
|
||||
Q_PROPERTY(QObject* userSettingsModel READ userSettingsModel NOTIFY userSettingsModelChanged)
|
||||
Q_PROPERTY(int onlineStatus READ onlineStatus NOTIFY onlineStatusChanged)
|
||||
|
||||
private:
|
||||
UserView* _userViewModel = nullptr;
|
||||
SettingsViewModel* _userSettingsModel = nullptr;
|
||||
MainClient *_client = nullptr;
|
||||
Settings *_conf = nullptr;
|
||||
|
||||
public:
|
||||
MainMenuModel(QObject *ptr = nullptr);
|
||||
|
||||
QObject* userViewModel() const;
|
||||
QObject* userSettingsModel() const;
|
||||
|
||||
int onlineStatus() const;
|
||||
Q_INVOKABLE void playOffline();
|
||||
Q_INVOKABLE void tryConnect();
|
||||
|
||||
public slots:
|
||||
void login(const QString& email, const QString& pass);
|
||||
void registerNewUser(const QString& email, const QString& pass);
|
||||
|
||||
signals:
|
||||
void userViewModelChanged(QObject* userViewModel);
|
||||
void newGame();
|
||||
void onlinelChanged(bool online);
|
||||
void loginChanged(bool login);
|
||||
void onlineStatusChanged();
|
||||
void userSettingsModelChanged(QObject* userSettingsModel);
|
||||
};
|
||||
|
||||
#endif // NETWORKPROFILEMAINMODEL_H
|
@ -0,0 +1,23 @@
|
||||
#include "networkclient.h"
|
||||
#include "playerclientdata.h"
|
||||
|
||||
#include <updateplayerdata.h>
|
||||
|
||||
int NetworkClient::loginedPlayer() const {
|
||||
return _loginedPlayer;
|
||||
}
|
||||
|
||||
void NetworkClient::handleReceiveData(ClientProtocol::Command cmd,
|
||||
const QByteArray &obj) {
|
||||
|
||||
if (cmd == ClientProtocol::Command::Player) {
|
||||
PlayerClientData data;
|
||||
data.fromBytes(obj);
|
||||
_playersDats[data.id()] = data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NetworkClient::NetworkClient() {
|
||||
|
||||
}
|
21
src/ClientLib/SnakeProject/ProfileViewItems/networkclient.h
Normal file
21
src/ClientLib/SnakeProject/ProfileViewItems/networkclient.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include "playerclientdata.h"
|
||||
|
||||
#include <client.h>
|
||||
|
||||
class NetworkClient : public ClientProtocol::Client
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QHash<int, PlayerClientData> _playersDats;
|
||||
int _loginedPlayer;
|
||||
private slots:
|
||||
void handleReceiveData(ClientProtocol::Command cmd, const QByteArray& obj);
|
||||
public:
|
||||
NetworkClient();
|
||||
int loginedPlayer() const;
|
||||
};
|
||||
|
||||
#endif // CLIENT_H
|
@ -0,0 +1,38 @@
|
||||
#include "notificationdata.h"
|
||||
|
||||
NotificationData::NotificationData(const QString &title,
|
||||
const QString &text,
|
||||
const QString &img, Type type) {
|
||||
|
||||
_text = text;
|
||||
_title = title;
|
||||
_img = img;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
QString NotificationData::text() const {
|
||||
return _text;
|
||||
}
|
||||
|
||||
QString NotificationData::img() const {
|
||||
return _img;
|
||||
}
|
||||
|
||||
QString NotificationData::title() const {
|
||||
return _title;
|
||||
}
|
||||
|
||||
bool NotificationData::operator ==(const NotificationData &righ) {
|
||||
return _title == righ._title &&
|
||||
_text == righ._text &&
|
||||
_img == righ._img &&
|
||||
_type == righ._type;
|
||||
}
|
||||
|
||||
bool NotificationData::operator !=(const NotificationData &righ) {
|
||||
return !operator==(righ);
|
||||
}
|
||||
|
||||
int NotificationData::type() const {
|
||||
return _type;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#ifndef NOTIFICATIONDATA_H
|
||||
#define NOTIFICATIONDATA_H
|
||||
#include <QObject>
|
||||
|
||||
class NotificationData
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QString text READ text)
|
||||
Q_PROPERTY(QString img READ img)
|
||||
Q_PROPERTY(QString title READ title)
|
||||
Q_PROPERTY(int type READ type)
|
||||
|
||||
QString _text;
|
||||
QString _img;
|
||||
QString _title;
|
||||
int _type;
|
||||
|
||||
public:
|
||||
|
||||
enum Type {
|
||||
Normal,
|
||||
Warning = 1,
|
||||
Error = 2,
|
||||
};
|
||||
|
||||
explicit NotificationData(const QString& title = "",
|
||||
const QString& text = "",
|
||||
const QString& img = "",
|
||||
Type type = Type::Normal);
|
||||
|
||||
Q_INVOKABLE QString text() const;
|
||||
Q_INVOKABLE QString img() const;
|
||||
Q_INVOKABLE QString title() const;
|
||||
Q_INVOKABLE int type() const;
|
||||
|
||||
bool operator ==(const NotificationData &righ);
|
||||
bool operator !=(const NotificationData &righ);
|
||||
|
||||
};
|
||||
|
||||
#endif // NOTIFICATIONDATA_H
|
@ -0,0 +1,38 @@
|
||||
#include "notificationservice.h"
|
||||
|
||||
NotificationService::NotificationService(QObject * ptr): QObject (ptr) {
|
||||
qRegisterMetaType<NotificationData>("NotificationData");
|
||||
qRegisterMetaType<QList<NotificationData>> ("QList<NotificationData>");
|
||||
|
||||
}
|
||||
|
||||
NotificationData NotificationService::notify() const {
|
||||
return _notify;
|
||||
}
|
||||
|
||||
void NotificationService::setNotify(const NotificationData& notify) {
|
||||
if (_notify != notify)
|
||||
_history.push_back(_notify);
|
||||
|
||||
_notify = notify;
|
||||
|
||||
emit notifyChanged();
|
||||
}
|
||||
|
||||
void NotificationService::setNotify(const QString &title,
|
||||
const QString &text,
|
||||
const QString &img,
|
||||
int type) {
|
||||
|
||||
setNotify(NotificationData(title, text, img,
|
||||
static_cast<NotificationData::Type>(type)));
|
||||
}
|
||||
|
||||
NotificationService *NotificationService::getService() {
|
||||
static auto service = new NotificationService;
|
||||
return service;
|
||||
}
|
||||
|
||||
const QList<NotificationData> &NotificationService::history() const {
|
||||
return _history;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef NOTIFICATIONSERVICE_H
|
||||
#define NOTIFICATIONSERVICE_H
|
||||
|
||||
#include "notificationdata.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class NotificationService: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(NotificationData notify READ notify NOTIFY notifyChanged)
|
||||
Q_PROPERTY(QList<NotificationData> history READ history NOTIFY notifyChanged)
|
||||
|
||||
private:
|
||||
explicit NotificationService(QObject *ptr = nullptr);
|
||||
|
||||
NotificationData _notify;
|
||||
QList<NotificationData> _history;
|
||||
|
||||
public:
|
||||
NotificationData notify() const;
|
||||
void setNotify(const NotificationData ¬ify);
|
||||
Q_INVOKABLE void setNotify(const QString& title = "",
|
||||
const QString& text = "",
|
||||
const QString& img = "",
|
||||
int type = NotificationData::Normal);
|
||||
|
||||
static NotificationService* getService();
|
||||
|
||||
const QList<NotificationData> & history() const;
|
||||
|
||||
signals:
|
||||
void notifyChanged();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // NOTIFICATIONSERVICE_H
|
@ -0,0 +1,6 @@
|
||||
#include "playerclientdata.h"
|
||||
|
||||
PlayerClientData::PlayerClientData()
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#ifndef PLAYERCLIENTDATA_H
|
||||
#define PLAYERCLIENTDATA_H
|
||||
#include <player.h>
|
||||
|
||||
class PlayerClientData: public ClientProtocol::Player
|
||||
{
|
||||
public:
|
||||
PlayerClientData();
|
||||
};
|
||||
|
||||
#endif // PLAYERCLIENTDATA_H
|
@ -0,0 +1,57 @@
|
||||
#include "settingsviewmodel.h"
|
||||
#include <QSettings>
|
||||
#include "settings.h"
|
||||
|
||||
void SettingsViewModel::handleValueChanged(QString key, QVariant value) {
|
||||
if (key == SERVER_ADDRESS) {
|
||||
emit hostChanged(value.toString());
|
||||
} else if (key == SERVER_ADDRESS_PORT) {
|
||||
emit portChanged(value.toInt());
|
||||
} else if (key == THEME) {
|
||||
emit themeChanged(value.toInt());
|
||||
}
|
||||
}
|
||||
|
||||
SettingsViewModel::SettingsViewModel(QObject *ptr):
|
||||
QObject (ptr) {
|
||||
_cfg = Settings::get();
|
||||
|
||||
connect(_cfg, &Settings::valueChanged, this , &SettingsViewModel::handleValueChanged);
|
||||
}
|
||||
|
||||
int SettingsViewModel::port() const {
|
||||
return _cfg->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
|
||||
}
|
||||
|
||||
QString SettingsViewModel::host() const {
|
||||
return _cfg->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
|
||||
}
|
||||
|
||||
int SettingsViewModel::theme() const {
|
||||
return _cfg->getValue(THEME, THEME_DEFAULT).toInt();
|
||||
}
|
||||
|
||||
void SettingsViewModel::forceUpdate() {
|
||||
emit hostChanged("");
|
||||
emit portChanged(0);
|
||||
emit themeChanged(0);
|
||||
|
||||
}
|
||||
|
||||
void SettingsViewModel::toDefault() {
|
||||
setPort(SERVER_ADDRESS_DEFAULT_PORT);
|
||||
setHost(SERVER_ADDRESS_DEFAULT);
|
||||
setTheme(THEME_DEFAULT);
|
||||
}
|
||||
|
||||
void SettingsViewModel::setPort(int port) {
|
||||
_cfg->setValue(SERVER_ADDRESS_PORT, port);
|
||||
}
|
||||
|
||||
void SettingsViewModel::setHost(const QString& host) {
|
||||
_cfg->setValue(SERVER_ADDRESS, host);
|
||||
}
|
||||
|
||||
void SettingsViewModel::setTheme(int theme) {
|
||||
_cfg->setValue(THEME, theme);
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#ifndef SETTINGSVIEWMODEL_H
|
||||
#define SETTINGSVIEWMODEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include "./../settings.h"
|
||||
|
||||
|
||||
class SettingsViewModel: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
|
||||
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
|
||||
Q_PROPERTY(int theme READ theme WRITE setTheme NOTIFY themeChanged)
|
||||
|
||||
private:
|
||||
Settings *_cfg = nullptr;
|
||||
|
||||
private slots:
|
||||
void handleValueChanged(QString key, QVariant value);
|
||||
|
||||
public:
|
||||
SettingsViewModel(QObject* ptr = nullptr);
|
||||
int port() const;
|
||||
QString host() const;
|
||||
int theme() const;
|
||||
|
||||
Q_INVOKABLE void forceUpdate();
|
||||
Q_INVOKABLE void toDefault();
|
||||
|
||||
|
||||
public slots:
|
||||
void setPort(int port);
|
||||
void setHost(const QString &host);
|
||||
void setTheme(int theme);
|
||||
|
||||
signals:
|
||||
void portChanged(int port);
|
||||
void hostChanged(const QString &host);
|
||||
void themeChanged(int theme);
|
||||
};
|
||||
|
||||
#endif // SETTINGSVIEWMODEL_H
|
78
src/ClientLib/SnakeProject/ProfileViewItems/userview.cpp
Normal file
78
src/ClientLib/SnakeProject/ProfileViewItems/userview.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "userview.h"
|
||||
|
||||
const PlayerClientData *UserView::getSource() const {
|
||||
return _source.data();
|
||||
}
|
||||
|
||||
void UserView::setSource(QSharedPointer<PlayerClientData> data) {
|
||||
|
||||
_offline = data == nullptr;
|
||||
|
||||
if (data->id() != _source->id()) {
|
||||
_source = data;
|
||||
emit sourceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool UserView::offline() const {
|
||||
return _offline;
|
||||
}
|
||||
|
||||
void UserView::setOffline(bool offline) {
|
||||
if (_offline != offline) {
|
||||
emit offlineChanged(_offline = offline);
|
||||
}
|
||||
}
|
||||
|
||||
UserView::UserView(QObject *parent) : QObject(parent) {
|
||||
|
||||
}
|
||||
|
||||
QString UserView::name() const {
|
||||
if (!_source) {
|
||||
return tr("Undefined name");
|
||||
}
|
||||
return _source->getName();
|
||||
}
|
||||
|
||||
QString UserView::gmail() const {
|
||||
if (!_source) {
|
||||
return tr("Undefined gmail");
|
||||
}
|
||||
return _source->getGmail();
|
||||
}
|
||||
|
||||
int UserView::money() const {
|
||||
if (!_source) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(_source->getMany());
|
||||
}
|
||||
|
||||
int UserView::record() const {
|
||||
if (!_source) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(_source->getRecord());
|
||||
}
|
||||
|
||||
int UserView::avgRecord() const {
|
||||
if (!_source) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(_source->getAvgRecord());
|
||||
}
|
||||
|
||||
int UserView::cureentSnake() const {
|
||||
if (!_source) {
|
||||
return -1;
|
||||
}
|
||||
return _source->getCureentSnake();
|
||||
}
|
||||
|
||||
int UserView::id() const {
|
||||
if (!_source) {
|
||||
return -1;
|
||||
}
|
||||
return _source->id();
|
||||
}
|
52
src/ClientLib/SnakeProject/ProfileViewItems/userview.h
Normal file
52
src/ClientLib/SnakeProject/ProfileViewItems/userview.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef USERVIEW_H
|
||||
#define USERVIEW_H
|
||||
|
||||
#include "playerclientdata.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class UserView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString name READ name NOTIFY sourceChanged)
|
||||
Q_PROPERTY(QString gmail READ gmail NOTIFY sourceChanged)
|
||||
Q_PROPERTY(int money READ money NOTIFY sourceChanged)
|
||||
Q_PROPERTY(int record READ record NOTIFY sourceChanged)
|
||||
Q_PROPERTY(int avgRecord READ avgRecord NOTIFY sourceChanged)
|
||||
Q_PROPERTY(int cureentSnake READ cureentSnake NOTIFY sourceChanged)
|
||||
Q_PROPERTY(int id READ id NOTIFY sourceChanged)
|
||||
Q_PROPERTY(bool offline READ offline NOTIFY offlineChanged)
|
||||
|
||||
private:
|
||||
QSharedPointer<PlayerClientData> _source = nullptr;
|
||||
|
||||
bool _offline = false;
|
||||
|
||||
public:
|
||||
explicit UserView(QObject *parent = nullptr);
|
||||
|
||||
QString name() const;
|
||||
QString gmail() const;
|
||||
int money() const;
|
||||
int record() const;
|
||||
int avgRecord() const;
|
||||
int cureentSnake() const;
|
||||
int id() const;
|
||||
|
||||
const PlayerClientData *getSource() const;
|
||||
bool offline() const;
|
||||
void setOffline(bool offline);
|
||||
|
||||
signals:
|
||||
|
||||
void sourceChanged();
|
||||
|
||||
void offlineChanged(bool offline);
|
||||
|
||||
public slots:
|
||||
void setSource(QSharedPointer<PlayerClientData> data);
|
||||
|
||||
};
|
||||
|
||||
#endif // USERVIEW_H
|
@ -1,19 +0,0 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2021 QuasarApp.
|
||||
//# Distributed under the lgplv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#include "SnakeProject.h"
|
||||
|
||||
|
||||
namespace SnakeProject {
|
||||
|
||||
bool init() {
|
||||
initSnakeProjectResources();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2021 QuasarApp.
|
||||
//# Distributed under the lgplv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#include "SnakeProject_global.h"
|
||||
|
||||
inline void initSnakeProjectResources() { Q_INIT_RESOURCE(SnakeProject); }
|
||||
|
||||
namespace SnakeProject {
|
||||
|
||||
bool SnakeProject_EXPORT init();
|
||||
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
//#
|
||||
//# Copyright (C) 2018-2021 QuasarApp.
|
||||
//# Distributed under the lgplv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#ifndef SnakeProject_GLOBAL_H
|
||||
#define SnakeProject_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(SnakeProject_LIBRARY)
|
||||
# define SnakeProject_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define SnakeProject_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif //SnakeProject_GLOBAL_H
|
||||
|
23
src/ClientLib/SnakeProject/asyncimageresponse.cpp
Normal file
23
src/ClientLib/SnakeProject/asyncimageresponse.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "asyncimageresponse.h"
|
||||
|
||||
AsyncImageResponse::AsyncImageResponse() = default;
|
||||
AsyncImageResponse::~AsyncImageResponse() = default;
|
||||
|
||||
QQuickTextureFactory *AsyncImageResponse::textureFactory() const {
|
||||
return _texture;
|
||||
}
|
||||
|
||||
// memory leak ?
|
||||
void AsyncImageResponse::setResult(const QImage& image) {
|
||||
_texture = QQuickTextureFactory::textureFactoryForImage(image);
|
||||
emit finished();
|
||||
// deleteLater();
|
||||
}
|
||||
|
||||
void AsyncImageResponse::error(const QString &err) {
|
||||
_errorString = " " + err;
|
||||
}
|
||||
|
||||
QString AsyncImageResponse::errorString() const {
|
||||
return QQuickImageResponse::errorString() + _errorString;
|
||||
}
|
24
src/ClientLib/SnakeProject/asyncimageresponse.h
Normal file
24
src/ClientLib/SnakeProject/asyncimageresponse.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef ASYNCIMAGERESPONSE_H
|
||||
#define ASYNCIMAGERESPONSE_H
|
||||
|
||||
#include <QQuickImageResponse>
|
||||
|
||||
|
||||
class AsyncImageResponse : public QQuickImageResponse {
|
||||
|
||||
private:
|
||||
QQuickTextureFactory *_texture = nullptr;
|
||||
QString _errorString;
|
||||
public:
|
||||
|
||||
AsyncImageResponse ();
|
||||
~AsyncImageResponse () override;
|
||||
|
||||
QQuickTextureFactory *textureFactory() const override;
|
||||
|
||||
void setResult(const QImage &image);
|
||||
void error(const QString &err);
|
||||
|
||||
QString errorString() const override;
|
||||
};
|
||||
#endif // ASYNCIMAGERESPONSE_H
|
20
src/ClientLib/SnakeProject/background.cpp
Normal file
20
src/ClientLib/SnakeProject/background.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "background.h"
|
||||
|
||||
BackGround::BackGround(double x, double y): ItemWorld (x, y) {
|
||||
this->setSize(200, 400);
|
||||
this->setTexture("qrc:/texture/asphalt");
|
||||
setBeckGroundObject(true);
|
||||
}
|
||||
|
||||
void BackGround::render() {
|
||||
auto wPart = w() / 2;
|
||||
|
||||
if (m_x + wPart < 200) {
|
||||
setX(wPart);
|
||||
}
|
||||
}
|
||||
|
||||
void BackGround::reset() {
|
||||
setX(0 - w());
|
||||
render();
|
||||
}
|
16
src/ClientLib/SnakeProject/background.h
Normal file
16
src/ClientLib/SnakeProject/background.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef BACKGROUND_H
|
||||
#define BACKGROUND_H
|
||||
|
||||
#include "itemworld.h"
|
||||
|
||||
|
||||
class BackGround : public ItemWorld
|
||||
{
|
||||
public:
|
||||
BackGround(double x, double y);
|
||||
|
||||
void render() override;
|
||||
void reset() override;
|
||||
};
|
||||
|
||||
#endif // BACKGROUND_H
|
19
src/ClientLib/SnakeProject/backgrounditem.cpp
Normal file
19
src/ClientLib/SnakeProject/backgrounditem.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "backgrounditem.h"
|
||||
|
||||
#include <QColor>
|
||||
|
||||
BackGroundItem::BackGroundItem(double x, double y):
|
||||
ItemWorld (x, y) {
|
||||
setBeckGroundObject(true);
|
||||
reset();
|
||||
}
|
||||
|
||||
void BackGroundItem::reset() {
|
||||
auto tempColor = QColor(rand() % 255, rand() % 255, rand() % 255, 10);
|
||||
setColor(tempColor.name(QColor::HexArgb));
|
||||
auto radius = rand() % 200;
|
||||
setSize(radius , radius);
|
||||
|
||||
setRadius(radius / 2);
|
||||
|
||||
}
|
15
src/ClientLib/SnakeProject/backgrounditem.h
Normal file
15
src/ClientLib/SnakeProject/backgrounditem.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef BACKGROUNDITEM_H
|
||||
#define BACKGROUNDITEM_H
|
||||
|
||||
#include "itemworld.h"
|
||||
|
||||
|
||||
class BackGroundItem : public ItemWorld
|
||||
{
|
||||
public:
|
||||
BackGroundItem(double x, double y);
|
||||
void reset() override;
|
||||
|
||||
};
|
||||
|
||||
#endif // BACKGROUNDITEM_H
|
17
src/ClientLib/SnakeProject/baseclass.cpp
Normal file
17
src/ClientLib/SnakeProject/baseclass.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "baseclass.h"
|
||||
|
||||
void BaseClass::setName(const QString &value) {
|
||||
name = value;
|
||||
}
|
||||
|
||||
BaseClass::BaseClass() :
|
||||
name("BaseClass") {
|
||||
}
|
||||
|
||||
BaseClass::~BaseClass() {
|
||||
|
||||
}
|
||||
|
||||
QString BaseClass::getName() const {
|
||||
return name;
|
||||
}
|
17
src/ClientLib/SnakeProject/baseclass.h
Normal file
17
src/ClientLib/SnakeProject/baseclass.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef BASECLASS_H
|
||||
#define BASECLASS_H
|
||||
#include <QString>
|
||||
|
||||
class BaseClass
|
||||
{
|
||||
private:
|
||||
QString name;
|
||||
public:
|
||||
BaseClass();
|
||||
virtual void render() = 0;
|
||||
virtual ~BaseClass();
|
||||
QString getName() const;
|
||||
void setName(const QString &value);
|
||||
};
|
||||
|
||||
#endif // BASECLASS_H
|
12
src/ClientLib/SnakeProject/box.cpp
Normal file
12
src/ClientLib/SnakeProject/box.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "box.h"
|
||||
|
||||
#include <QColor>
|
||||
|
||||
Box::Box(double x, double y):
|
||||
ItemWorld (x, y) {
|
||||
|
||||
this->setSize(10, 10);
|
||||
|
||||
setColor(QColor(100, 100, 100).name());
|
||||
}
|
||||
|
13
src/ClientLib/SnakeProject/box.h
Normal file
13
src/ClientLib/SnakeProject/box.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef BOX_H
|
||||
#define BOX_H
|
||||
|
||||
#include "itemworld.h"
|
||||
|
||||
class Box: public ItemWorld
|
||||
{
|
||||
public:
|
||||
Box(double x, double y);
|
||||
|
||||
};
|
||||
|
||||
#endif // BOX_H
|
50
src/ClientLib/SnakeProject/clientapp.cpp
Normal file
50
src/ClientLib/SnakeProject/clientapp.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "clientapp.h"
|
||||
#include "imageprovider.h"
|
||||
#include "ProfileViewItems/userview.h"
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
|
||||
#include <back-end/ProfileViewItems/mainmenumodel.h>
|
||||
#include <back-end/ProfileViewItems/notificationservice.h>
|
||||
|
||||
QByteArray ClientApp::initTheme() {
|
||||
int themeIndex = Settings::get()->getValue(THEME, THEME_DEFAULT).toInt();
|
||||
|
||||
switch (themeIndex) {
|
||||
case 1: return "Dark";
|
||||
default: return "Light";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ClientApp::ClientApp() {
|
||||
}
|
||||
|
||||
ClientApp::~ClientApp() {
|
||||
}
|
||||
|
||||
bool ClientApp::init(QQmlApplicationEngine *engine) {
|
||||
|
||||
qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", initTheme());
|
||||
|
||||
qmlRegisterType <GuiObject> ();
|
||||
qmlRegisterType <Diff> ();
|
||||
qmlRegisterType <MainMenuModel> ();
|
||||
qmlRegisterType <UserView> ();
|
||||
|
||||
auto root = engine->rootContext();
|
||||
if (!root)
|
||||
return false;
|
||||
|
||||
|
||||
engine->addImageProvider(QLatin1String("userItems"), new ImageProvider());
|
||||
|
||||
root->setContextProperty("contr", &contr);
|
||||
root->setContextProperty("notificationService", NotificationService::getService());
|
||||
|
||||
engine->load(QUrl(QStringLiteral("qrc:/front-end/main.qml")));
|
||||
if (engine->rootObjects().isEmpty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
22
src/ClientLib/SnakeProject/clientapp.h
Normal file
22
src/ClientLib/SnakeProject/clientapp.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef CLIENTAPP_H
|
||||
#define CLIENTAPP_H
|
||||
|
||||
#include "controller.h"
|
||||
#include "diff.h"
|
||||
|
||||
class QQmlApplicationEngine;
|
||||
|
||||
class ClientApp
|
||||
{
|
||||
private:
|
||||
Controller contr;
|
||||
|
||||
QByteArray initTheme();
|
||||
|
||||
public:
|
||||
ClientApp();
|
||||
~ClientApp();
|
||||
bool init(QQmlApplicationEngine* engine);
|
||||
};
|
||||
|
||||
#endif // CLIENTAPP_H
|
154
src/ClientLib/SnakeProject/controller.cpp
Normal file
154
src/ClientLib/SnakeProject/controller.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
#include "controller.h"
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include "diff.h"
|
||||
#include <lvls.h>
|
||||
#include "ProfileViewItems/mainmenumodel.h"
|
||||
#include <back-end/ProfileViewItems/notificationservice.h>
|
||||
|
||||
Controller::Controller() {
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
timer = new QTimer();
|
||||
timer->setInterval(1);
|
||||
|
||||
_networkModel = new MainMenuModel(this);
|
||||
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
connect(_networkModel, &MainMenuModel::newGame, this, &Controller::handleNewGame);
|
||||
|
||||
}
|
||||
|
||||
Controller::~Controller() {
|
||||
|
||||
}
|
||||
|
||||
bool Controller::nextLvl() {
|
||||
if (lvl + 1 >= lvls.size()) {
|
||||
return true;
|
||||
}
|
||||
m_generalLong += static_cast<int>(world.getCurrentLong());
|
||||
|
||||
generateDiff(world.init(lvls.value(++lvl)));
|
||||
startTimer();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Controller::generateDiff(const QMap<int, GuiObject *>& objs) {
|
||||
|
||||
auto removeIds = objectsContainer.keys();
|
||||
QList<int> addedIds;
|
||||
|
||||
for (auto i = objs.begin(); i != objs.end(); ++i) {
|
||||
if (objectsContainer.contains(i.key())) {
|
||||
removeIds.removeOne(i.key());
|
||||
} else {
|
||||
objectsContainer.insert(i.key(), i.value());
|
||||
addedIds.push_back(i.key());
|
||||
}
|
||||
}
|
||||
|
||||
if (removeIds.size() || addedIds.size()) {
|
||||
Diff diff;
|
||||
|
||||
diff.setRemoveIds(removeIds);
|
||||
diff.setAddedIds(addedIds);
|
||||
emit gameObjectsChanged(diff);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::update() {
|
||||
if (pause) {
|
||||
return;
|
||||
}
|
||||
|
||||
world.render();
|
||||
|
||||
if(world.isDefiat()) {
|
||||
stopTimer();
|
||||
if (!_showMenu) {
|
||||
setShowMenu(true);
|
||||
}
|
||||
handleNewGame();
|
||||
}
|
||||
|
||||
if (world.isEnd()) {
|
||||
stopTimer();
|
||||
|
||||
if (!_showMenu) {
|
||||
|
||||
NotificationData notify(tr(" Next Lvl!!!"),
|
||||
tr(" You anblock next lvl (%0)" ).arg(lvl),
|
||||
"qrc:/texture/up");
|
||||
|
||||
NotificationService::getService()->setNotify(notify);
|
||||
}
|
||||
|
||||
nextLvl();
|
||||
|
||||
}
|
||||
|
||||
long_changed(static_cast<int>(world.getCurrentLong()));
|
||||
generalLongchanged(generalLong());
|
||||
|
||||
}
|
||||
|
||||
void Controller::handleNewGame() {
|
||||
|
||||
world.resetPosition();
|
||||
|
||||
WorldRules newGameRules = lvls.first();
|
||||
lvl = 0;
|
||||
m_generalLong = 0;
|
||||
generateDiff(world.init(newGameRules));
|
||||
startTimer();
|
||||
}
|
||||
|
||||
QObject *Controller::getGameObject(int id) {
|
||||
return objectsContainer.value(id, nullptr);
|
||||
}
|
||||
|
||||
void Controller::startTimer() {
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void Controller::stopTimer() {
|
||||
timer->stop();
|
||||
}
|
||||
|
||||
int Controller::long_() const {
|
||||
return static_cast<int>(world.getCurrentLong());
|
||||
}
|
||||
|
||||
int Controller::generalLong() const {
|
||||
return m_generalLong + long_();
|
||||
}
|
||||
|
||||
QObject *Controller::mainMenuModel() const {
|
||||
return _networkModel;
|
||||
}
|
||||
|
||||
void Controller::buttonPress() {
|
||||
world.reversClick();
|
||||
}
|
||||
|
||||
void Controller::setPause(bool p){
|
||||
pause = p;
|
||||
if (!pause) {
|
||||
world.unPause();
|
||||
}
|
||||
}
|
||||
|
||||
bool Controller::showMenu() const {
|
||||
return _showMenu;
|
||||
}
|
||||
|
||||
void Controller::setShowMenu(bool showMenu) {
|
||||
if (_showMenu == showMenu)
|
||||
return;
|
||||
|
||||
_showMenu = showMenu;
|
||||
emit showMenuChanged(_showMenu);
|
||||
}
|
||||
|
88
src/ClientLib/SnakeProject/controller.h
Normal file
88
src/ClientLib/SnakeProject/controller.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef CONTROLLER_H
|
||||
#define CONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include "diff.h"
|
||||
#include "snake.h"
|
||||
#include "world.h"
|
||||
|
||||
class MainMenuModel;
|
||||
|
||||
class Controller : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int long_ READ long_ NOTIFY long_changed)
|
||||
Q_PROPERTY(int generalLong READ generalLong NOTIFY generalLongchanged)
|
||||
Q_PROPERTY(QObject* mainMenuModel READ mainMenuModel NOTIFY mainMenuModelchanged)
|
||||
Q_PROPERTY(bool showMenu READ showMenu WRITE setShowMenu NOTIFY showMenuChanged)
|
||||
|
||||
private:
|
||||
|
||||
World world;
|
||||
QMap<int, GuiObject *> objectsContainer;
|
||||
QTimer *timer = nullptr;
|
||||
|
||||
int lvl = 0;
|
||||
int m_generalLong = 0;
|
||||
bool pause = false;
|
||||
bool _showMenu = true;
|
||||
|
||||
void generateDiff(const QMap<int, GuiObject *> &);
|
||||
|
||||
MainMenuModel* _networkModel = nullptr;
|
||||
|
||||
public:
|
||||
Controller();
|
||||
~Controller();
|
||||
|
||||
void startTimer();
|
||||
void stopTimer();
|
||||
|
||||
int long_() const;
|
||||
int generalLong() const;
|
||||
bool showMenu() const;
|
||||
|
||||
QObject* mainMenuModel() const;
|
||||
|
||||
public slots:
|
||||
void buttonPress();
|
||||
void setPause(bool);
|
||||
void update();
|
||||
|
||||
/**
|
||||
* @brief nextLvl - switch to next lvl from array lvels
|
||||
* @return true if all levels are passed
|
||||
*/
|
||||
bool nextLvl();
|
||||
|
||||
/**
|
||||
* @brief newGame - start game from first lvl
|
||||
*/
|
||||
void handleNewGame();
|
||||
|
||||
/**
|
||||
* @brief getGameObject
|
||||
* @param id - id of guiObject;
|
||||
* @return guiObject if (id is not valid return nullptr)
|
||||
*/
|
||||
QObject* getGameObject(int id);
|
||||
|
||||
void setShowMenu(bool showMenu);
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* @brief gameObjectsChanged
|
||||
* @param dif
|
||||
*/
|
||||
void gameObjectsChanged(const Diff &dif);
|
||||
void long_changed(int m_long);
|
||||
void generalLongchanged(int generalLong);
|
||||
void mainMenuModelchanged(QObject* mainMenuModel);
|
||||
void showMenuChanged(bool showMenu);
|
||||
};
|
||||
|
||||
#endif // CONTROLLER_H
|
21
src/ClientLib/SnakeProject/diff.cpp
Normal file
21
src/ClientLib/SnakeProject/diff.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "diff.h"
|
||||
|
||||
QList<int> Diff::getRemoveIds() const {
|
||||
return removeIds;
|
||||
}
|
||||
|
||||
void Diff::setRemoveIds(const QList<int> &value) {
|
||||
removeIds = value;
|
||||
}
|
||||
|
||||
QList<int> Diff::getAddedIds() const {
|
||||
return addedIds;
|
||||
}
|
||||
|
||||
void Diff::setAddedIds(const QList<int> &value) {
|
||||
addedIds = value;
|
||||
}
|
||||
|
||||
Diff::Diff(){
|
||||
|
||||
}
|
23
src/ClientLib/SnakeProject/diff.h
Normal file
23
src/ClientLib/SnakeProject/diff.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef DIFF_H
|
||||
#define DIFF_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class Diff
|
||||
{
|
||||
Q_GADGET
|
||||
private:
|
||||
QList<int> removeIds;
|
||||
QList<int> addedIds;
|
||||
public:
|
||||
explicit Diff();
|
||||
|
||||
Q_INVOKABLE QList<int> getRemoveIds() const;
|
||||
void setRemoveIds(const QList<int> &value);
|
||||
Q_INVOKABLE QList<int> getAddedIds() const;
|
||||
void setAddedIds(const QList<int> &value);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Diff)
|
||||
|
||||
#endif // DIFF_H
|
116
src/ClientLib/SnakeProject/guiobject.cpp
Normal file
116
src/ClientLib/SnakeProject/guiobject.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "guiobject.h"
|
||||
|
||||
GuiObject::GuiObject(const QString &viewTempalte, QObject *ptr):
|
||||
QObject (ptr) {
|
||||
m_viewTemplate = viewTempalte;
|
||||
generateId();
|
||||
|
||||
}
|
||||
|
||||
double GuiObject::angle() const {
|
||||
return m_angle;
|
||||
}
|
||||
|
||||
QString GuiObject::texture() const {
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
void GuiObject::render() {
|
||||
}
|
||||
|
||||
QRectF GuiObject::rect() const {
|
||||
return QRectF(m_x - m_w / 2, m_y - m_h / 2, m_w, m_h);
|
||||
}
|
||||
|
||||
void GuiObject::setAngle(double angle) {
|
||||
m_angle = angle;
|
||||
emit angleChanged(m_angle);
|
||||
}
|
||||
|
||||
int GuiObject::guiId() const {
|
||||
return m_guiId;
|
||||
}
|
||||
|
||||
QString GuiObject::color() const {
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void GuiObject::setColor(QString color) {
|
||||
if (m_color == color)
|
||||
return;
|
||||
|
||||
m_color = color;
|
||||
emit colorChanged(m_color);
|
||||
}
|
||||
|
||||
double GuiObject::x() const {
|
||||
return m_x;
|
||||
}
|
||||
|
||||
double GuiObject::y() const {
|
||||
return m_y;
|
||||
}
|
||||
|
||||
double GuiObject::w() const {
|
||||
return m_w;
|
||||
}
|
||||
|
||||
double GuiObject::h() const {
|
||||
return m_h;
|
||||
}
|
||||
|
||||
void GuiObject::generateId() {
|
||||
static int id = 0;
|
||||
m_guiId = id++;
|
||||
}
|
||||
|
||||
void GuiObject::setH(double h) {
|
||||
m_h = h;
|
||||
emit hChanged(m_h);
|
||||
}
|
||||
|
||||
void GuiObject::reset() {
|
||||
setX(-1);
|
||||
setY(-1);
|
||||
}
|
||||
|
||||
int GuiObject::radius() const {
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
QString GuiObject::viewTemplate() const {
|
||||
return m_viewTemplate;
|
||||
}
|
||||
|
||||
void GuiObject::setRadius(int radius) {
|
||||
if (m_radius == radius)
|
||||
return;
|
||||
|
||||
m_radius = radius;
|
||||
emit radiusChanged(m_radius);
|
||||
}
|
||||
|
||||
void GuiObject::setW(double w) {
|
||||
m_w = w;
|
||||
emit wChanged(m_w);
|
||||
|
||||
}
|
||||
|
||||
void GuiObject::setY(double y) {
|
||||
m_y = y;
|
||||
emit yChanged(m_y);
|
||||
|
||||
}
|
||||
|
||||
void GuiObject::setX(double x) {
|
||||
m_x = x;
|
||||
emit xChanged(m_x);
|
||||
|
||||
}
|
||||
|
||||
void GuiObject::setTexture(const QString &texture) {
|
||||
m_texture = texture;
|
||||
emit textureChanged(m_texture);
|
||||
}
|
||||
|
||||
|
91
src/ClientLib/SnakeProject/guiobject.h
Normal file
91
src/ClientLib/SnakeProject/guiobject.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef GUIOBJECT_H
|
||||
#define GUIOBJECT_H
|
||||
|
||||
#include "baseclass.h"
|
||||
#include "QObject"
|
||||
|
||||
#include <QRectF>
|
||||
|
||||
class GuiObject:public QObject, public BaseClass
|
||||
{
|
||||
Q_OBJECT
|
||||
// @todo: add color
|
||||
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
|
||||
Q_PROPERTY(double angle READ angle NOTIFY angleChanged)
|
||||
Q_PROPERTY(QString texture READ texture NOTIFY textureChanged)
|
||||
Q_PROPERTY(int guiId READ guiId NOTIFY guiIdChanged)
|
||||
Q_PROPERTY(QString viewTemplate READ viewTemplate NOTIFY viewTemplateChanged)
|
||||
Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
|
||||
|
||||
Q_PROPERTY(double x READ x NOTIFY xChanged)
|
||||
Q_PROPERTY(double y READ y NOTIFY yChanged)
|
||||
Q_PROPERTY(double w READ w NOTIFY wChanged)
|
||||
Q_PROPERTY(double h READ h NOTIFY hChanged)
|
||||
|
||||
private:
|
||||
void generateId();
|
||||
QString m_viewTemplate;
|
||||
|
||||
protected:
|
||||
int m_guiId = -1;
|
||||
double m_angle = 0;
|
||||
QString m_texture = "";
|
||||
QString m_color = "";
|
||||
int m_radius = 0;
|
||||
|
||||
double m_x = 0;
|
||||
double m_y = 0;
|
||||
double m_w = 0;
|
||||
double m_h = 0;
|
||||
|
||||
void setTexture(const QString &texture);
|
||||
|
||||
|
||||
public:
|
||||
GuiObject(const QString& viewTempalte = "GraphicItem", QObject *ptr = nullptr);
|
||||
|
||||
double angle() const;
|
||||
QString texture() const;
|
||||
|
||||
void render() override;
|
||||
|
||||
QRectF rect() const;
|
||||
virtual void setAngle(double angle);
|
||||
int guiId() const;
|
||||
|
||||
QString color() const;
|
||||
|
||||
void setColor(QString color);
|
||||
|
||||
double x() const;
|
||||
double y() const;
|
||||
double w() const;
|
||||
double h() const;
|
||||
|
||||
void setX(double x);
|
||||
void setY(double y);
|
||||
void setW(double w);
|
||||
void setH(double h);
|
||||
|
||||
virtual void reset();
|
||||
int radius() const;
|
||||
QString viewTemplate() const;
|
||||
|
||||
public slots:
|
||||
|
||||
void setRadius(int radius);
|
||||
|
||||
signals:
|
||||
void angleChanged(double angle);
|
||||
void textureChanged(QString texture);
|
||||
void guiIdChanged(int guiId);
|
||||
void colorChanged(QString color);
|
||||
void xChanged(double x);
|
||||
void yChanged(double y);
|
||||
void wChanged(double w);
|
||||
void hChanged(double h);
|
||||
void radiusChanged(int radius);
|
||||
void viewTemplateChanged(QString viewTemplate);
|
||||
};
|
||||
|
||||
#endif // GUIOBJECT_H
|
23
src/ClientLib/SnakeProject/guiobjectfactory.cpp
Normal file
23
src/ClientLib/SnakeProject/guiobjectfactory.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "guiobjectfactory.h"
|
||||
#include "box.h"
|
||||
#include <snakeutils.h>
|
||||
#include "head.h"
|
||||
#include "background.h"
|
||||
#include "backgrounditem.h"
|
||||
|
||||
GuiObjectFactory::GuiObjectFactory() {}
|
||||
|
||||
ItemWorld *GuiObjectFactory::generate(const QString &name) {
|
||||
ItemWorld *obj = nullptr;
|
||||
if (name == "Box") {
|
||||
obj = new Box(rand() % 400, 0);
|
||||
}
|
||||
else if (name == "BackGround") {
|
||||
obj = new BackGround(0, 0);
|
||||
}
|
||||
else if (name == "BackGroundItem") {
|
||||
obj = new BackGroundItem(0, 0);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
27
src/ClientLib/SnakeProject/guiobjectfactory.h
Normal file
27
src/ClientLib/SnakeProject/guiobjectfactory.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef GUIOBJECTFACTORY_H
|
||||
#define GUIOBJECTFACTORY_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ItemWorld;
|
||||
|
||||
/**
|
||||
* @brief The GuiObjectFactory class
|
||||
* factory of gui ojects;
|
||||
*/
|
||||
class GuiObjectFactory
|
||||
{
|
||||
public:
|
||||
GuiObjectFactory();
|
||||
|
||||
/**
|
||||
* @brief generate - generate the child of GuiObject
|
||||
* by object name.
|
||||
* @param name - name of class of genereta object
|
||||
* @return pointer of generated object.
|
||||
* If method called with not valid name then return nullptr.
|
||||
*/
|
||||
static ItemWorld* generate(const QString& name);
|
||||
};
|
||||
|
||||
#endif // GUIOBJECTFACTORY_H
|
58
src/ClientLib/SnakeProject/head.cpp
Normal file
58
src/ClientLib/SnakeProject/head.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "head.h"
|
||||
#include <cmath>
|
||||
#include <QDateTime>
|
||||
|
||||
void Head::render() {
|
||||
|
||||
|
||||
qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time;
|
||||
time = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
double my = (m_y + (*speed * 0.55) * sin(m_angle * TO_RADIAN));
|
||||
m_y += (my - m_y) / 1000 * tempTime;
|
||||
|
||||
if (*speed < 1) {
|
||||
setColor(generalSpeadColor);
|
||||
setRadius(static_cast<int>(m_w * 0.4));
|
||||
|
||||
} else if (*speed < normSpead) {
|
||||
setColor(normSpeadColor);
|
||||
setRadius(static_cast<int>(m_w * 0.5));
|
||||
|
||||
} else if (*speed < fastSpead) {
|
||||
setColor(fastSpeadColor);
|
||||
setRadius(static_cast<int>(m_w * 0.5));
|
||||
|
||||
} else if (*speed < megaFastSpead) {
|
||||
setColor(megaFastSpeadColor);
|
||||
setRadius(static_cast<int>(m_w * 0.4));
|
||||
|
||||
}
|
||||
|
||||
emit yChanged(m_y);
|
||||
}
|
||||
|
||||
void Head::reset() {
|
||||
}
|
||||
|
||||
void Head::unPause() {
|
||||
time = QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
Head::Head(double x, double y, double h, double w, double *spead):
|
||||
GuiObject ("SnakeItem") {
|
||||
setX(x);
|
||||
setY(y);
|
||||
setW(w);
|
||||
setH(h);
|
||||
this->speed = spead;
|
||||
}
|
||||
|
||||
void Head::setAngle(double angle) {
|
||||
m_angle = angle;
|
||||
emit angleChanged(m_angle);
|
||||
}
|
||||
|
||||
Head::~Head() {
|
||||
|
||||
}
|
32
src/ClientLib/SnakeProject/head.h
Normal file
32
src/ClientLib/SnakeProject/head.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef HEAD_H
|
||||
#define HEAD_H
|
||||
#define TO_RADIAN 0.017453293
|
||||
|
||||
|
||||
#include "guiobject.h"
|
||||
#include <QString>
|
||||
|
||||
class Head : public GuiObject
|
||||
{
|
||||
private:
|
||||
qint64 time;
|
||||
double *speed;
|
||||
const int megaFastSpead = 200;
|
||||
const int fastSpead = 100;
|
||||
const int normSpead = 50;
|
||||
|
||||
const QString generalSpeadColor = "#616a6b";
|
||||
const QString normSpeadColor = "#5d6d7e";
|
||||
const QString fastSpeadColor = "#eb984e";
|
||||
const QString megaFastSpeadColor = "#ec7063";
|
||||
|
||||
public:
|
||||
Head(double x , double y, double h, double w, double *speed);
|
||||
void setAngle(double angle) override;
|
||||
void render() override;
|
||||
void reset() override;
|
||||
void unPause();
|
||||
~Head() override;
|
||||
};
|
||||
|
||||
#endif // HEAD_H
|
37
src/ClientLib/SnakeProject/imageprovider.cpp
Normal file
37
src/ClientLib/SnakeProject/imageprovider.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "asyncimageresponse.h"
|
||||
#include "imageprovider.h"
|
||||
#include <QQuickImageResponse>
|
||||
#include <QtConcurrent>
|
||||
|
||||
ImageProvider::ImageProvider() = default;
|
||||
ImageProvider::~ImageProvider() = default;
|
||||
|
||||
QQuickImageResponse *ImageProvider::requestImageResponse(const QString &id,
|
||||
const QSize &requestedSize) {
|
||||
|
||||
AsyncImageResponse* response = new AsyncImageResponse();
|
||||
auto readImage = [id, requestedSize, response]() mutable {
|
||||
Q_UNUSED(requestedSize);
|
||||
|
||||
auto params = id.split("/");
|
||||
|
||||
if (params.contains("player")) {
|
||||
response->setResult(QImage(":/img/defaultuser").
|
||||
scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
|
||||
|
||||
} else if (params.contains("item")) {
|
||||
response->setResult(QImage(":/img/defaultsnake").
|
||||
scaled(requestedSize, Qt::KeepAspectRatioByExpanding));
|
||||
} else {
|
||||
response->error("Wrong first parametr example 'first/last'");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
QtConcurrent::run(readImage);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
19
src/ClientLib/SnakeProject/imageprovider.h
Normal file
19
src/ClientLib/SnakeProject/imageprovider.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef IMAGEPROVIDER_H
|
||||
#define IMAGEPROVIDER_H
|
||||
|
||||
#include <QQuickAsyncImageProvider>
|
||||
#include <QPixmap>
|
||||
|
||||
class ImageProvider: public QQuickAsyncImageProvider
|
||||
{
|
||||
private:
|
||||
public:
|
||||
explicit ImageProvider();
|
||||
~ImageProvider() override;
|
||||
|
||||
QQuickImageResponse *requestImageResponse(const QString &id,
|
||||
const QSize &requestedSize) override;
|
||||
};
|
||||
|
||||
|
||||
#endif // IMAGEPROVIDER_H
|
48
src/ClientLib/SnakeProject/itemworld.cpp
Normal file
48
src/ClientLib/SnakeProject/itemworld.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "itemworld.h"
|
||||
#include "snakeutils.h"
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
#include <QRectF>
|
||||
|
||||
#define POINT 100
|
||||
|
||||
ItemWorld::ItemWorld(double x, double y, const QString& guiTemplate):
|
||||
GuiObject (guiTemplate) {
|
||||
setLoc(x, y);
|
||||
}
|
||||
|
||||
void ItemWorld::setBeckGroundObject(bool value) {
|
||||
beckGroundObject = value;
|
||||
}
|
||||
|
||||
void ItemWorld::setSize(double h, double w) {
|
||||
setH(h);
|
||||
setW(w);
|
||||
}
|
||||
|
||||
void ItemWorld::setLoc(double x, double y) {
|
||||
setX(x);
|
||||
setY(y);
|
||||
}
|
||||
|
||||
void ItemWorld::render() {
|
||||
if (m_x + w() < 0) {
|
||||
m_x = (rand() % 400) + 200;
|
||||
m_y = rand() % 100;
|
||||
emit xChanged(m_x);
|
||||
emit yChanged(m_y);
|
||||
}
|
||||
}
|
||||
|
||||
bool ItemWorld::move(const GuiObject *snakeRiger, double dx) {
|
||||
m_x -= dx;
|
||||
emit xChanged(m_x);
|
||||
|
||||
return snakeRiger->rect().intersects(rect()) && !beckGroundObject;
|
||||
}
|
||||
|
||||
bool ItemWorld::isBeckGroundObject() {
|
||||
return beckGroundObject;
|
||||
}
|
||||
|
||||
ItemWorld::~ItemWorld() {}
|
26
src/ClientLib/SnakeProject/itemworld.h
Normal file
26
src/ClientLib/SnakeProject/itemworld.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef ITEMWORLD_H
|
||||
#define ITEMWORLD_H
|
||||
|
||||
#include "guiobject.h"
|
||||
#include <QString>
|
||||
|
||||
class ItemWorld : public GuiObject
|
||||
{
|
||||
private:
|
||||
bool beckGroundObject = false;
|
||||
protected:
|
||||
virtual void setSize(double h, double w);
|
||||
virtual void setLoc(double x, double y);
|
||||
void setBeckGroundObject(bool value);
|
||||
|
||||
public:
|
||||
ItemWorld(double x, double y, const QString& GuiTemplate = "GraphicItem");
|
||||
|
||||
void render();
|
||||
virtual bool move(const GuiObject* snakeRiger, double dx);
|
||||
bool isBeckGroundObject();
|
||||
|
||||
~ItemWorld();
|
||||
};
|
||||
|
||||
#endif // ITEMWORLD_H
|
11
src/ClientLib/SnakeProject/lvls.cpp
Normal file
11
src/ClientLib/SnakeProject/lvls.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "lvls.h"
|
||||
|
||||
QList<WorldRules> lvls {
|
||||
WorldRules{{"Long", 500}, {"Box", 2}, {"Spead", 10}, {"BackGroundItem", 10}},
|
||||
WorldRules{{"Long", 1000}, {"Box", 4}, {"Spead", 10}, {"BackGroundItem", 10}},
|
||||
WorldRules{{"Long", 2000}, {"Box", 8}, {"Spead", 10}, {"BackGroundItem", 10}},
|
||||
WorldRules{{"Long", 4000}, {"Box", 16}, {"Spead", 10}, {"BackGroundItem", 10}},
|
||||
WorldRules{{"Long", 8000}, {"Box", 32}, {"Spead", 10}, {"BackGroundItem", 10}},
|
||||
WorldRules{{"Long", 16000}, {"Box", 64}, {"Spead", 10}, {"BackGroundItem", 10}}
|
||||
|
||||
};
|
9
src/ClientLib/SnakeProject/lvls.h
Normal file
9
src/ClientLib/SnakeProject/lvls.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef LVLS_H
|
||||
#define LVLS_H
|
||||
|
||||
#include <QList>
|
||||
#include "snakeutils.h"
|
||||
|
||||
extern QList<WorldRules> lvls;
|
||||
|
||||
#endif // LVLS_H
|
20
src/ClientLib/SnakeProject/main.cpp
Normal file
20
src/ClientLib/SnakeProject/main.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include "clientapp.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
|
||||
QGuiApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
ClientApp client;
|
||||
|
||||
if (!client.init(&engine)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
7
src/ClientLib/SnakeProject/qtquickcontrols2.conf
Normal file
7
src/ClientLib/SnakeProject/qtquickcontrols2.conf
Normal file
@ -0,0 +1,7 @@
|
||||
[Controls]
|
||||
Style=Material
|
||||
|
||||
[Material]
|
||||
Accent=Teal
|
||||
Primary=BlueGrey
|
||||
;Theme=Light
|
1
src/ClientLib/SnakeProject/settings.cpp
Normal file
1
src/ClientLib/SnakeProject/settings.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "settings.h"
|
17
src/ClientLib/SnakeProject/settings.h
Normal file
17
src/ClientLib/SnakeProject/settings.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef SNAKESETTINGS_H
|
||||
#define SNAKESETTINGS_H
|
||||
#include <config.h>
|
||||
#include <quasarapp.h>
|
||||
|
||||
#define SERVER_ADDRESS "SERVER_ADDRESS"
|
||||
#define SERVER_ADDRESS_PORT "SERVER_ADDRESS_PORT"
|
||||
#define THEME "THEME_GUI"
|
||||
|
||||
#define SERVER_ADDRESS_DEFAULT "quasarapp.ddns.net"
|
||||
//#define SERVER_ADDRESS_DEFAULT "127.0.0.1"
|
||||
#define SERVER_ADDRESS_DEFAULT_PORT DEFAULT_SNAKE_PORT
|
||||
#define THEME_DEFAULT 0
|
||||
|
||||
using Settings = QuasarAppUtils::Settings;
|
||||
|
||||
#endif // SNAKESETTINGS_H
|
200
src/ClientLib/SnakeProject/snake.cpp
Normal file
200
src/ClientLib/SnakeProject/snake.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
#include "snake.h"
|
||||
#include "guiobject.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QMap>
|
||||
#include <QRectF>
|
||||
#include <cmath>
|
||||
|
||||
Snake::Snake() {
|
||||
}
|
||||
|
||||
const QVector<Head *> &Snake::getItems() const {
|
||||
return items;
|
||||
}
|
||||
|
||||
void Snake::render() {
|
||||
|
||||
auto centerX = [](const Head* head) {
|
||||
return head->x()/* + (head->w() / 2)*/;
|
||||
};
|
||||
|
||||
auto centerY = [](const Head* head) {
|
||||
return head->y() /*+ (head->h() / 2)*/;
|
||||
};
|
||||
|
||||
for (int i = items.length() - 1; i >= 0; --i) {
|
||||
|
||||
if (dead) {
|
||||
items[i]->render();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (isClick) {
|
||||
if (countClick & 1){
|
||||
items[i]->setAngle(45);
|
||||
} else {
|
||||
items[i]->setAngle(315);
|
||||
}
|
||||
isClick = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
double _atan2 = atan2(centerY(items[i - 1]) - centerY(items[i]),
|
||||
centerX(items[i - 1]) - centerX(items[i])) * 90;
|
||||
|
||||
items[i]->setAngle(_atan2);
|
||||
}
|
||||
|
||||
items[i]->render();
|
||||
}
|
||||
}
|
||||
|
||||
double Snake::checDistance(int i) {
|
||||
|
||||
auto result = (items[i]->rect().y() -
|
||||
items[i - 1]->rect().y()) / rataticonDistance;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
double Snake::getRataticonDistance() const {
|
||||
return rataticonDistance;
|
||||
}
|
||||
|
||||
void Snake::setRataticonDistance(double value) {
|
||||
rataticonDistance = value;
|
||||
}
|
||||
|
||||
void Snake::unPause() {
|
||||
for ( int i = 0; i < items.size(); ++i ) {
|
||||
items[i]->unPause();
|
||||
}
|
||||
}
|
||||
|
||||
double Snake::sizeByLvl(double lvl , int count) const {
|
||||
double maxSize = 9;
|
||||
double minSize = 5;
|
||||
|
||||
double pos = (1 - (lvl / count));
|
||||
|
||||
QList<QPair<double, double>> snakeGradientSize {
|
||||
{1, 4},
|
||||
{0.99, 7},
|
||||
{0.8, 5},
|
||||
{0.6, 6},
|
||||
{0.0, 3}
|
||||
};
|
||||
|
||||
double local = 0;
|
||||
int index = 0;
|
||||
|
||||
while (index + 1 < snakeGradientSize.size()
|
||||
&& pos <= snakeGradientSize[index].first) {
|
||||
|
||||
maxSize = snakeGradientSize[index].second;
|
||||
minSize = snakeGradientSize[index + 1].second;
|
||||
|
||||
auto range = snakeGradientSize[index].first -
|
||||
snakeGradientSize[index + 1].first;
|
||||
|
||||
local = ( range - (snakeGradientSize[index].first - pos)) /
|
||||
range;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return local * (maxSize - minSize) + minSize;
|
||||
}
|
||||
|
||||
void Snake::changeCountObjects(int count) {
|
||||
if (count > 0) {
|
||||
double margin = 60.0 / count;
|
||||
for ( int i = 0; i < count; ++i ) {
|
||||
|
||||
auto size = sizeByLvl(i, count);
|
||||
auto obj = new Head(margin * (count - i),
|
||||
50, size , size,
|
||||
this->speed);
|
||||
|
||||
obj->setY(50 + obj->h() / 2);
|
||||
|
||||
items.push_back(obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( int i = count; i < 0; ++i ) {
|
||||
auto obj = items.first();
|
||||
items.removeFirst();
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMap<int, GuiObject*> Snake::init(int size, double *speed) {
|
||||
|
||||
QMap<int, GuiObject*> res;
|
||||
|
||||
if (size <= 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
this->speed = speed;
|
||||
|
||||
changeCountObjects(size - items.size());
|
||||
|
||||
for (auto i : items) {
|
||||
res[i->guiId()] = i;
|
||||
}
|
||||
|
||||
dead = false;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Snake::isInited() const {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
void Snake::clearItems() {
|
||||
for (auto i : items) {
|
||||
delete i;
|
||||
}
|
||||
items.clear();
|
||||
}
|
||||
|
||||
void Snake::resetPosotion() {
|
||||
double margin = 60.0 / items.size();
|
||||
|
||||
for ( int i = 0; i < items.size(); ++i ) {
|
||||
items[i]->setX(margin * (items.size() - i));
|
||||
items[i]->setY(50 + items[i]->h() / 2);
|
||||
items[i]->setAngle(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Snake::kill() {
|
||||
dead = true;
|
||||
}
|
||||
|
||||
bool Snake::isDead() const {
|
||||
return dead;
|
||||
}
|
||||
|
||||
Snake::~Snake() {
|
||||
clearItems();
|
||||
}
|
||||
|
||||
void Snake::clear() {
|
||||
clearItems();
|
||||
}
|
||||
|
||||
void Snake::reverse() {
|
||||
if (isClick) {
|
||||
return;
|
||||
}
|
||||
isClick = true;
|
||||
countClick++;
|
||||
}
|
52
src/ClientLib/SnakeProject/snake.h
Normal file
52
src/ClientLib/SnakeProject/snake.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef SNAKE_H
|
||||
#define SNAKE_H
|
||||
|
||||
#define SPEEDSNAKE 10
|
||||
|
||||
#include <QVector>
|
||||
#include "head.h"
|
||||
#include "baseclass.h"
|
||||
|
||||
class GuiObject;
|
||||
|
||||
|
||||
|
||||
class Snake : public BaseClass
|
||||
{
|
||||
private:
|
||||
double rataticonDistance = 1;
|
||||
QVector<Head*> items;
|
||||
double *speed = nullptr;
|
||||
bool isClick = false;
|
||||
int countClick = 0;
|
||||
bool dead = false;
|
||||
double sizeByLvl(double lvl, int count) const;
|
||||
void changeCountObjects(int count);
|
||||
|
||||
double checDistance(int i);
|
||||
void clearItems();
|
||||
|
||||
|
||||
public:
|
||||
Snake();
|
||||
~Snake() override;
|
||||
void clear();
|
||||
void resetPosotion();
|
||||
|
||||
void kill();
|
||||
bool isDead() const;
|
||||
|
||||
void reverse();
|
||||
void render() override;
|
||||
QMap<int, GuiObject *> init(int size, double *speed);
|
||||
bool isInited() const;
|
||||
const QVector<Head*>& getItems() const;
|
||||
double getMovedLong() const;
|
||||
double getRataticonDistance() const;
|
||||
void setRataticonDistance(double value);
|
||||
int getDeadTimer() const;
|
||||
void setDeadTimer(int value);
|
||||
void unPause();
|
||||
};
|
||||
|
||||
#endif // SNAKE_H
|
3
src/ClientLib/SnakeProject/snakeutils.cpp
Normal file
3
src/ClientLib/SnakeProject/snakeutils.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "snakeutils.h"
|
||||
|
||||
|
20
src/ClientLib/SnakeProject/snakeutils.h
Normal file
20
src/ClientLib/SnakeProject/snakeutils.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef SNAKEUTILS_H
|
||||
#define SNAKEUTILS_H
|
||||
|
||||
|
||||
#include <QMap>
|
||||
#include <QPoint>
|
||||
#include <QVariant>
|
||||
|
||||
/**
|
||||
* @brief WorldRules
|
||||
* this map conteins:
|
||||
* 1. list of generated objects and they count.
|
||||
* 2. long of world (Long),
|
||||
* 3. spead of world (Spead),
|
||||
* !!!Note: all object show on map alltime.
|
||||
*/
|
||||
typedef QMap<QString, int> WorldRules;
|
||||
|
||||
|
||||
#endif // SNAKEUTILS_H
|
173
src/ClientLib/SnakeProject/world.cpp
Normal file
173
src/ClientLib/SnakeProject/world.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
#include "background.h"
|
||||
#include "world.h"
|
||||
|
||||
#include <QMap>
|
||||
#include "guiobject.h"
|
||||
#include "guiobjectfactory.h"
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
|
||||
World::World() {
|
||||
currentLong = 0;
|
||||
endLong = 0;
|
||||
background = "";
|
||||
}
|
||||
|
||||
void World::clear() {
|
||||
clearItems();
|
||||
snake.clear();
|
||||
}
|
||||
|
||||
double World::getCurrentLong() const {
|
||||
return currentLong;
|
||||
}
|
||||
|
||||
QMultiMap<QString, ItemWorld *> World::getItems() const
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
void World::unPause() {
|
||||
time = QDateTime::currentMSecsSinceEpoch();
|
||||
snake.unPause();
|
||||
}
|
||||
|
||||
void World::clearItems() {
|
||||
for (auto i : items) {
|
||||
delete i;
|
||||
}
|
||||
oldRules.clear();
|
||||
items.clear();
|
||||
spead = 0;
|
||||
d_spead = 0;
|
||||
}
|
||||
|
||||
void World::changeCountObjects(const QString &name, int count) {
|
||||
|
||||
if (count > 0) {
|
||||
|
||||
for ( int i = 0; i < count; ++i ) {
|
||||
auto obj = GuiObjectFactory::generate(name);
|
||||
|
||||
if (!obj) {
|
||||
qWarning() <<"object not created line:" << Q_FUNC_INFO;
|
||||
break;
|
||||
}
|
||||
|
||||
items.insertMulti(name, obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( int i = count; i < 0; ++i ) {
|
||||
auto obj = items.value(name);
|
||||
if (1 != items.remove(name, obj)) {
|
||||
qWarning() << "World::changeCountObjects error delete object!";
|
||||
}
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMap<int, GuiObject *> World::init(WorldRules rules) {
|
||||
|
||||
QMap<int, GuiObject*> res;
|
||||
|
||||
// rules["BackGround"] = 1;
|
||||
|
||||
currentLong = -1;
|
||||
for (auto i = rules.begin(); i != rules.end(); ++i) {
|
||||
if (i.key() == "Long") {
|
||||
endLong = rules["Long"];
|
||||
currentLong = 0;
|
||||
}
|
||||
else if (i.key() == "Spead") {
|
||||
d_spead = rules["Spead"];
|
||||
}
|
||||
else {
|
||||
changeCountObjects(i.key(), i.value() - oldRules.value(i.key()));
|
||||
}
|
||||
}
|
||||
|
||||
auto snakeItems = snake.init(20, &spead);
|
||||
|
||||
for (auto i = snakeItems.begin(); i != snakeItems.end(); ++i) {
|
||||
res.insert(i.key(), i.value());
|
||||
}
|
||||
|
||||
for (auto i : items) {
|
||||
res[i->guiId()] = i;
|
||||
}
|
||||
|
||||
|
||||
oldRules = rules;
|
||||
time = QDateTime::currentMSecsSinceEpoch();
|
||||
defiat = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
World::~World() {
|
||||
clearItems();
|
||||
}
|
||||
|
||||
void World::render() {
|
||||
|
||||
qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time;
|
||||
time = QDateTime::currentMSecsSinceEpoch();
|
||||
double dx = spead / 1000 * tempTime;
|
||||
|
||||
spead -= 0.0310 * tempTime;
|
||||
|
||||
if (spead < 0)
|
||||
spead = 0;
|
||||
|
||||
snake.render();
|
||||
auto rig = snake.getItems().first();
|
||||
|
||||
for (auto i = items.begin(); i != items.end(); ++i) {
|
||||
defiat |= (*i)->move(rig, dx);
|
||||
(*i)->render();
|
||||
}
|
||||
|
||||
defiat |= (rig->y()< 0 || rig->y() > 100);
|
||||
|
||||
if (!snake.isDead() && defiat) {
|
||||
snake.kill();
|
||||
}
|
||||
|
||||
currentLong += dx;
|
||||
}
|
||||
|
||||
void World::resetPosition() {
|
||||
for (auto i : items) {
|
||||
i->reset();
|
||||
}
|
||||
spead = 0;
|
||||
|
||||
snake.resetPosotion();
|
||||
}
|
||||
|
||||
bool World::move() {
|
||||
return isEnd();
|
||||
}
|
||||
|
||||
bool World::isEnd() {
|
||||
return currentLong >= endLong;
|
||||
}
|
||||
|
||||
bool World::isDefiat() const {
|
||||
return defiat && !static_cast<bool>(spead);
|
||||
}
|
||||
|
||||
WorldRules World::currentRules() const {
|
||||
return oldRules;
|
||||
}
|
||||
|
||||
void World::reversClick() {
|
||||
if (snake.isDead()) {
|
||||
spead = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
snake.reverse();
|
||||
spead += d_spead;
|
||||
}
|
47
src/ClientLib/SnakeProject/world.h
Normal file
47
src/ClientLib/SnakeProject/world.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef WORLD_H
|
||||
#define WORLD_H
|
||||
|
||||
#define SPEEDWORLD 10
|
||||
|
||||
#include <QVector>
|
||||
#include "itemworld.h"
|
||||
#include "baseclass.h"
|
||||
#include "snakeutils.h"
|
||||
#include "snake.h"
|
||||
|
||||
class World : public BaseClass
|
||||
{
|
||||
private:
|
||||
|
||||
Snake snake;
|
||||
QMultiMap<QString, ItemWorld*> items;
|
||||
double currentLong = 0;
|
||||
int endLong;
|
||||
double spead = 0, d_spead = 0;
|
||||
QString background;
|
||||
qint64 time;
|
||||
bool defiat = false;
|
||||
WorldRules oldRules;
|
||||
|
||||
void clearItems();
|
||||
|
||||
void changeCountObjects(const QString &name, int count);
|
||||
|
||||
public:
|
||||
World();
|
||||
void clear();
|
||||
QMap<int, GuiObject*> init(WorldRules rules);
|
||||
~World() override;
|
||||
void render() override;
|
||||
void resetPosition();
|
||||
bool move();
|
||||
bool isEnd();
|
||||
bool isDefiat() const;
|
||||
WorldRules currentRules() const;
|
||||
void reversClick();
|
||||
double getCurrentLong() const;
|
||||
QMultiMap<QString, ItemWorld *> getItems() const;
|
||||
void unPause();
|
||||
};
|
||||
|
||||
#endif // WORLD_H
|
29
src/ClientLib/SnakeProjectModule/About.qml
Normal file
29
src/ClientLib/SnakeProjectModule/About.qml
Normal file
@ -0,0 +1,29 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Page {
|
||||
|
||||
signal close();
|
||||
|
||||
title: "Page"
|
||||
header: Rectangle {
|
||||
height: parent.height * 0.1
|
||||
color: "#cccccc"
|
||||
Label {
|
||||
id: title
|
||||
text: qsTr("About")
|
||||
font.pointSize: 13
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.fill: parent;
|
||||
anchors.margins: 5
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: AboutPage{
|
||||
}
|
||||
|
||||
}
|
72
src/ClientLib/SnakeProjectModule/AboutPage.qml
Normal file
72
src/ClientLib/SnakeProjectModule/AboutPage.qml
Normal file
@ -0,0 +1,72 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
clip: true
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredHeight: parent.width / 4
|
||||
Layout.preferredWidth: parent.width / 4
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
color: "#00000000"
|
||||
Image {
|
||||
id: aboutLogo
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
source: "qrc:/logo/logo"
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Flickable {
|
||||
id: flickable
|
||||
clip: true
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
|
||||
Layout.preferredHeight: parent.height - parent.height / 2.8
|
||||
|
||||
|
||||
TextArea.flickable: TextArea {
|
||||
id: textArea
|
||||
textFormat: Qt.RichText
|
||||
wrapMode: TextArea.Wrap
|
||||
readOnly: true
|
||||
persistentSelection: true
|
||||
|
||||
leftPadding: 6
|
||||
rightPadding: 6
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
background: null
|
||||
|
||||
text: qsTr("Product of QuasarrApp");
|
||||
font.family: "Verdana"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignTop
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*##^## Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
71
src/ClientLib/SnakeProjectModule/BasePopUp.qml
Normal file
71
src/ClientLib/SnakeProjectModule/BasePopUp.qml
Normal file
@ -0,0 +1,71 @@
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Dialog {
|
||||
id : basePopup
|
||||
width: 200
|
||||
height: 100
|
||||
x: 0
|
||||
y: 0
|
||||
|
||||
transformOrigin: Item.Center
|
||||
|
||||
property bool autoClose: true
|
||||
property bool clickClose: true
|
||||
|
||||
property int closeInterval: 15000;
|
||||
property int margin : 0
|
||||
property color backgroundColor: Material.background
|
||||
|
||||
background: Item {
|
||||
id: bacground
|
||||
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
id: backCorner
|
||||
color: backgroundColor
|
||||
radius: metrix.mm
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: parent
|
||||
source: backCorner
|
||||
color: "#80000000"
|
||||
verticalOffset: 10
|
||||
samples: 30
|
||||
}
|
||||
}
|
||||
|
||||
function _show() {
|
||||
|
||||
if (autoClose) {
|
||||
timerAutoClose.start();
|
||||
}
|
||||
|
||||
open();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timerAutoClose;
|
||||
running: false;
|
||||
repeat: false;
|
||||
interval: closeInterval;
|
||||
|
||||
onTriggered: {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
if (autoClose)
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
closePolicy: (!clickClose || autoClose)? Popup.NoAutoClose: Popup.CloseOnReleaseOutside
|
||||
|
||||
onRejected: close()
|
||||
|
||||
}
|
32
src/ClientLib/SnakeProjectModule/FrameView.qml
Normal file
32
src/ClientLib/SnakeProjectModule/FrameView.qml
Normal file
@ -0,0 +1,32 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Frame {
|
||||
id: frameVew
|
||||
property bool translucent: true
|
||||
property bool showBorder: true
|
||||
|
||||
function _backGroundColor() {
|
||||
if (translucent) {
|
||||
if (Material.theme == Material.Dark) {
|
||||
return "#50000000";
|
||||
}
|
||||
|
||||
return "#50ffffff";
|
||||
}
|
||||
|
||||
return Material.background;
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: _backGroundColor()
|
||||
border.color: (Material.theme == Material.Dark)? "#000000": "#cfcfcf"
|
||||
border.width: (showBorder)? 1 : 0
|
||||
radius: metrix.mm
|
||||
}
|
||||
|
||||
padding: 3 * metrix.mm
|
||||
}
|
38
src/ClientLib/SnakeProjectModule/GraphicItem.qml
Normal file
38
src/ClientLib/SnakeProjectModule/GraphicItem.qml
Normal file
@ -0,0 +1,38 @@
|
||||
import QtQuick 2.9
|
||||
|
||||
Rectangle {
|
||||
id: graphicItem
|
||||
property var model: null
|
||||
property real angle: (model) ? model.angle : 0;
|
||||
property string texture: (model) ? model.texture : "";
|
||||
property int guiId: (model) ? model.guiId : -1;
|
||||
|
||||
z:-1
|
||||
property double devX: width / 2
|
||||
property double devY: height / 2
|
||||
|
||||
Image {
|
||||
id: name
|
||||
visible: texture.length
|
||||
source: texture
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
color: (model) ? model.color : "#11ff32";
|
||||
|
||||
width: (model) ? model.w * metrix.gamePt: 0;
|
||||
height: (model) ? model.h * metrix.gamePt: 0;
|
||||
|
||||
x: (model) ? model.x * metrix.gamePt - devX: 0;
|
||||
y: (model) ? model.y * metrix.gamePt - devY: 0;
|
||||
|
||||
radius: (model) ? model.radius * metrix.gamePt : 0;
|
||||
|
||||
transform: Rotation {
|
||||
origin.x: devX;
|
||||
origin.y: devY;
|
||||
angle: graphicItem.angle;
|
||||
}
|
||||
|
||||
}
|
83
src/ClientLib/SnakeProjectModule/ImageView.qml
Normal file
83
src/ClientLib/SnakeProjectModule/ImageView.qml
Normal file
@ -0,0 +1,83 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Item {
|
||||
id: imageView
|
||||
property int size: 50
|
||||
property double ratio: 1
|
||||
property string drawItem: ""
|
||||
property bool hovered: false
|
||||
property bool hold: false
|
||||
|
||||
signal clicked();
|
||||
|
||||
width: size * ratio
|
||||
height: size
|
||||
|
||||
Image {
|
||||
id: img
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: drawItem
|
||||
sourceSize: Qt.size(width, height)
|
||||
smooth: true
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: img
|
||||
horizontalOffset: (hold)? 20: (hovered)? 10: 5
|
||||
verticalOffset: (hold)? 20: (hovered)? 10: 5
|
||||
radius: 8.0
|
||||
samples: 17
|
||||
Behavior on horizontalOffset {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on verticalOffset {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Behavior on color {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
color: (hold)? "#80000000": (hovered)? "#60000000": "#40000000"
|
||||
source: img
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: {
|
||||
parent.hovered = true;
|
||||
}
|
||||
|
||||
onExited: {
|
||||
parent.hovered = false;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
parent.hold = false;
|
||||
imageView.clicked();
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
parent.hold = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
13
src/ClientLib/SnakeProjectModule/LeftBoxSideBar.qml
Normal file
13
src/ClientLib/SnakeProjectModule/LeftBoxSideBar.qml
Normal file
@ -0,0 +1,13 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
LeftSideBar {
|
||||
resizeHeight: true;
|
||||
closedHeight: closedWidth;
|
||||
openHeight: 10 * metrix.pt;
|
||||
openWidth: 10 * metrix.pt;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: undefined;
|
||||
anchors.bottom: undefined;
|
||||
|
||||
}
|
||||
|
35
src/ClientLib/SnakeProjectModule/LeftSideBar.qml
Normal file
35
src/ClientLib/SnakeProjectModule/LeftSideBar.qml
Normal file
@ -0,0 +1,35 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
SideBar {
|
||||
id: leftSideBar
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
closedWidth: closeButton.width + padding * 2;
|
||||
openWidth: 10 * metrix.pt;
|
||||
resizeHeight: false;
|
||||
|
||||
header:
|
||||
RowLayout {
|
||||
|
||||
Button {
|
||||
id: closeButton
|
||||
text: leftSideBar.isOpened? "<" : ">"
|
||||
|
||||
Layout.preferredHeight: metrix.controlPtMaterial;
|
||||
Layout.preferredWidth: metrix.controlPtMaterial;
|
||||
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||
onClicked: {
|
||||
if (leftSideBar.isOpened)
|
||||
leftSideBar.hide();
|
||||
else
|
||||
leftSideBar.show();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
301
src/ClientLib/SnakeProjectModule/LoginView.qml
Normal file
301
src/ClientLib/SnakeProjectModule/LoginView.qml
Normal file
@ -0,0 +1,301 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Item {
|
||||
id: element
|
||||
|
||||
property int loginStatus : 0
|
||||
|
||||
readonly property int currentView: tabBar.currentIndex
|
||||
readonly property var resultEnum: [
|
||||
qsTr("Success"), // 0
|
||||
qsTr("Password must be at least 8 characters"), // 1
|
||||
qsTr("Name must be at least 1 characters"), // 2
|
||||
qsTr("Passwords must match"), // 3
|
||||
|
||||
qsTr("The letter must match the pattern 'X@xxxx.xxx'") // 4
|
||||
|
||||
]
|
||||
|
||||
signal sigNewUser(var gmail, var password);
|
||||
signal sigLogin(var gmail, var password);
|
||||
signal toOffline();
|
||||
|
||||
|
||||
function _checkLogin() {
|
||||
const pass = loginPass.text;
|
||||
const email = loginEmail.text;
|
||||
|
||||
if (pass.length < 8) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (email.search(/[a-z\-A-Z0-9_]+@[a-z\-A-Z0-9_]+\.[a-z\-A-Z0-9_]+/) < 0) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
function _checkRegister () {
|
||||
const pass = registerPassword.text;
|
||||
const pass2 = registerPassword2.text;
|
||||
|
||||
const email = registerEmail.text;
|
||||
|
||||
if (pass.length < 8) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pass !== pass2) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (email.search(/[a-z\-A-Z0-9_]+@[a-z\-A-Z0-9_]+\.[a-z\-A-Z0-9_]+/) < 0) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function checkData(isregisterForm) {
|
||||
if (isregisterForm) {
|
||||
return _checkRegister();
|
||||
}
|
||||
|
||||
return _checkLogin();
|
||||
}
|
||||
|
||||
SwipeView {
|
||||
id: swipeView
|
||||
anchors.bottom: bottons.top
|
||||
anchors.top: tabBar.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
clip: true
|
||||
|
||||
currentIndex: tabBar.currentIndex
|
||||
|
||||
Item {
|
||||
id: loginPage
|
||||
|
||||
GridLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
rows: 2
|
||||
Label {
|
||||
text: qsTr("Email")
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: loginEmail
|
||||
placeholderText: "Enter Your Email"
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
text: qsTr("Passsword")
|
||||
}
|
||||
TextField {
|
||||
id: loginPass
|
||||
placeholderText: qsTr("Enter Your passsword")
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
echoMode: TextInput.Password
|
||||
cursorVisible: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: rigisterPage
|
||||
GridLayout {
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
columns: 2
|
||||
rows: 3
|
||||
|
||||
Label {
|
||||
text: qsTr("Email")
|
||||
}
|
||||
TextField {
|
||||
id: registerEmail;
|
||||
placeholderText: qsTr("Enter Your Email")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Password")
|
||||
}
|
||||
TextField {
|
||||
id: registerPassword;
|
||||
|
||||
placeholderText: qsTr("Enter Your passsword")
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
echoMode: TextInput.Password
|
||||
cursorVisible: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Repeat password")
|
||||
}
|
||||
TextField {
|
||||
id: registerPassword2;
|
||||
|
||||
placeholderText: qsTr("Enter Your passsword again")
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
echoMode: TextInput.Password
|
||||
cursorVisible: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: tabBar
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
|
||||
TabButton {
|
||||
id: login
|
||||
text: qsTr("Sign in")
|
||||
checkable: false
|
||||
}
|
||||
|
||||
TabButton {
|
||||
id: register
|
||||
text: qsTr("Sign Up")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id : bottons
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: {
|
||||
Qt.quit()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
text: tabBar.currentItem.text
|
||||
|
||||
onClicked: {
|
||||
|
||||
const messageIndex = checkData(tabBar.currentIndex);
|
||||
if (messageIndex === 0) {
|
||||
|
||||
if (tabBar.currentIndex) {
|
||||
// register request
|
||||
sigNewUser(registerEmail.text, registerPassword);
|
||||
} else {
|
||||
//login request
|
||||
sigLogin(loginEmail.text, loginPass.text);
|
||||
}
|
||||
} else {
|
||||
|
||||
notificationService.setNotify(qsTr("Error"),
|
||||
resultEnum[messageIndex],
|
||||
"",
|
||||
2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
onLoginStatusChanged: {
|
||||
if (loginStatus === 2)
|
||||
busy._show();
|
||||
else {
|
||||
busy.close();
|
||||
}
|
||||
}
|
||||
|
||||
PagePopUp {
|
||||
id: busy
|
||||
modal: true
|
||||
autoClose: false;
|
||||
clickClose: false;
|
||||
BusyIndicator {
|
||||
running: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
height: 2 * metrix.controlPtMaterial
|
||||
width: height
|
||||
|
||||
}
|
||||
|
||||
|
||||
FrameView {
|
||||
visible: loginStatus === 4
|
||||
anchors.fill: parent
|
||||
translucent: false
|
||||
showBorder: false
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
text: qsTr("You need connect to server");
|
||||
font.pixelSize: metrix.controlPtMaterial;
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Use OfflineMode");
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
onClicked: {
|
||||
toOffline();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*##^## Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}D{i:3;anchors_height:100;anchors_width:100;anchors_x:228;anchors_y:63}
|
||||
D{i:1;anchors_height:200;anchors_width:200;anchors_x:205;anchors_y:53}D{i:11;anchors_width:240;anchors_x:226;anchors_y:21}
|
||||
}
|
||||
##^##*/
|
196
src/ClientLib/SnakeProjectModule/MainMenu.qml
Normal file
196
src/ClientLib/SnakeProjectModule/MainMenu.qml
Normal file
@ -0,0 +1,196 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: item1
|
||||
property var model: null
|
||||
readonly property int onlineStatus: (model)? model.onlineStatus: false
|
||||
|
||||
visible: true
|
||||
z: 1
|
||||
|
||||
signal playGame();
|
||||
|
||||
onOnlineStatusChanged: {
|
||||
if (onlineStatus && onlineStatus !== 5) {
|
||||
loginPopUp._show();
|
||||
} else {
|
||||
loginPopUp.close();
|
||||
}
|
||||
}
|
||||
|
||||
LeftSideBar {
|
||||
id: userViewSideBar
|
||||
openWidth: 7 * metrix.pt;
|
||||
|
||||
openHeight: columnLayout.height
|
||||
source: UserView {
|
||||
|
||||
anchors.fill: parent;
|
||||
model: (item1.model)? item1.model.userViewModel: null
|
||||
visible: userViewSideBar.openFinished
|
||||
onTryConnect: {
|
||||
if (item1.model)
|
||||
item1.model.tryConnect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
GridLayout {
|
||||
id: columnLayout
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: userViewSideBar.right
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
anchors.bottomMargin: 0
|
||||
anchors.topMargin: 0
|
||||
|
||||
columns: 3
|
||||
rows: 2
|
||||
|
||||
|
||||
transformOrigin: Item.Center
|
||||
|
||||
|
||||
MainMenuButton {
|
||||
id: play
|
||||
text: qsTr("Play game")
|
||||
|
||||
onClicked: {
|
||||
playGame();
|
||||
if (model)
|
||||
model.newGame();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MainMenuButton {
|
||||
id: store
|
||||
text: qsTr("Store")
|
||||
|
||||
}
|
||||
|
||||
MainMenuButton {
|
||||
id: invitar
|
||||
text: qsTr("My Items")
|
||||
}
|
||||
|
||||
MainMenuButton {
|
||||
id: freands
|
||||
text: qsTr("My friends")
|
||||
|
||||
}
|
||||
|
||||
MainMenuButton {
|
||||
id: settings
|
||||
text: qsTr("My Settings")
|
||||
|
||||
onClicked: {
|
||||
settingsPopUp._show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MainMenuButton {
|
||||
id: exit
|
||||
text: qsTr("Exit")
|
||||
|
||||
onClicked: {
|
||||
Qt.quit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PagePopUp {
|
||||
id: about;
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2;
|
||||
|
||||
source: About {}
|
||||
}
|
||||
|
||||
PagePopUp {
|
||||
id: settingsPopUp
|
||||
source: SettingsView {
|
||||
id: settingsView
|
||||
model: item1.model ? item1.model.userSettingsModel: null
|
||||
}
|
||||
|
||||
standardButtons: Dialog.Save | Dialog.Cancel | Dialog.RestoreDefaults
|
||||
modal: false;
|
||||
autoClose: false
|
||||
clickClose: true
|
||||
width: 12 * metrix.controlPtMaterial
|
||||
height: 8 * metrix.controlPtMaterial;
|
||||
|
||||
onAccepted: {
|
||||
settingsView.save();
|
||||
}
|
||||
|
||||
onReset: {
|
||||
settingsView.reset();
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
settingsView.update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
PagePopUp {
|
||||
id: loginPopUp
|
||||
source: LoginView {
|
||||
id: loginView
|
||||
loginStatus: onlineStatus
|
||||
|
||||
onSigLogin: {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.login(gmail, password);
|
||||
}
|
||||
onSigNewUser: {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.registerNewUser(gmail, password);
|
||||
|
||||
}
|
||||
|
||||
onToOffline: {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.playOffline();
|
||||
}
|
||||
}
|
||||
|
||||
visible: true;
|
||||
modal: true;
|
||||
autoClose: false
|
||||
clickClose: false
|
||||
width: 12 * metrix.controlPtMaterial
|
||||
height: ((loginView.currentView)? 9 : 7) * metrix.controlPtMaterial;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*##^## Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
17
src/ClientLib/SnakeProjectModule/MainMenuButton.qml
Normal file
17
src/ClientLib/SnakeProjectModule/MainMenuButton.qml
Normal file
@ -0,0 +1,17 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Button {
|
||||
id: exit
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.pixelSize: height * 0.1
|
||||
display: AbstractButton.TextBesideIcon
|
||||
spacing: 4
|
||||
focusPolicy: Qt.StrongFocus
|
||||
|
||||
Layout.preferredHeight: parent.height / (parent.rows + 1)
|
||||
Layout.preferredWidth: parent.width / (parent.columns + 1)
|
||||
|
||||
}
|
27
src/ClientLib/SnakeProjectModule/Metrix.qml
Normal file
27
src/ClientLib/SnakeProjectModule/Metrix.qml
Normal file
@ -0,0 +1,27 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
Item {
|
||||
readonly property int pointCount: 100;
|
||||
readonly property real mm: Screen.pixelDensity
|
||||
readonly property real sm: 10 * mm
|
||||
readonly property real dsm: Math.sqrt(Math.pow(Screen.desktopAvailableWidth, 2) + Math.pow(Screen.desktopAvailableHeight, 2)) / sm
|
||||
readonly property real pt: getfactor(dsm) * sm
|
||||
readonly property real controlPtMaterial: Material.buttonHeight
|
||||
readonly property real gamePt: (width < height) ? width / pointCount : height / pointCount;
|
||||
|
||||
function getfactor(dsm) {
|
||||
if (dsm < 30) {
|
||||
return 0.5
|
||||
} else if ( dsm < 70) {
|
||||
return 1
|
||||
} else if (dsm < 140) {
|
||||
return 2;
|
||||
} else
|
||||
return 4;
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
84
src/ClientLib/SnakeProjectModule/NotificationForm.qml
Normal file
84
src/ClientLib/SnakeProjectModule/NotificationForm.qml
Normal file
@ -0,0 +1,84 @@
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
BasePopUp {
|
||||
id : popup
|
||||
|
||||
property string text: qsTr("Message")
|
||||
property string img: ""
|
||||
property string titleText: qsTr("Message")
|
||||
property int type: 0
|
||||
|
||||
function _getBackGraundColor(type) {
|
||||
switch(type) {
|
||||
|
||||
case 1: return "#FFC107"
|
||||
case 2: return "#FF5722"
|
||||
|
||||
}
|
||||
|
||||
return Material.background
|
||||
}
|
||||
|
||||
autoClose: true;
|
||||
closeInterval: 5000
|
||||
|
||||
margins: 0
|
||||
margin: 0
|
||||
spacing: 0
|
||||
|
||||
|
||||
backgroundColor: _getBackGraundColor(type);
|
||||
|
||||
Page {
|
||||
id: page
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
background: Rectangle {
|
||||
color: "#00000000"
|
||||
}
|
||||
|
||||
header: Label {
|
||||
text: titleText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
contentItem:
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
spacing: 5
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
color: "#00000000"
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||
Layout.preferredWidth: rowLayout.height;
|
||||
Layout.preferredHeight: rowLayout.height;
|
||||
|
||||
Image {
|
||||
id: image
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
clip: true
|
||||
anchors.fill: parent;
|
||||
source: img
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
id: message
|
||||
text: popup.text
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Layout.fillHeight: true;
|
||||
Layout.fillWidth: true;
|
||||
clip: true
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
src/ClientLib/SnakeProjectModule/NotificationServiceView.qml
Normal file
30
src/ClientLib/SnakeProjectModule/NotificationServiceView.qml
Normal file
@ -0,0 +1,30 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Item {
|
||||
readonly property var model: notificationService;
|
||||
readonly property var msg: model.notify
|
||||
readonly property var history: model.history
|
||||
|
||||
|
||||
NotificationForm {
|
||||
id: notyfyView
|
||||
titleText : msg.title;
|
||||
text: (msg)? msg.text: "";
|
||||
img: (msg)? msg.img: "";
|
||||
type: (msg)? msg.type: 0;
|
||||
|
||||
x: parent.width - width - margin;
|
||||
y: margin;
|
||||
|
||||
width: 6 * metrix.controlPtMaterial;
|
||||
height: width * 0.5
|
||||
}
|
||||
|
||||
onMsgChanged: {
|
||||
notyfyView._show();
|
||||
}
|
||||
}
|
26
src/ClientLib/SnakeProjectModule/PagePopUp.qml
Normal file
26
src/ClientLib/SnakeProjectModule/PagePopUp.qml
Normal file
@ -0,0 +1,26 @@
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
BasePopUp {
|
||||
id: pagePopUp
|
||||
property var source: null
|
||||
autoClose: false
|
||||
|
||||
Item {
|
||||
id: sourceVal
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
onSourceChanged: {
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
source.parent = sourceVal;
|
||||
source.anchors.fill = sourceVal;
|
||||
}
|
||||
|
||||
x: parent.width / 2 - width / 2
|
||||
y: parent.height / 2 - height / 2
|
||||
}
|
124
src/ClientLib/SnakeProjectModule/PropertyView.qml
Normal file
124
src/ClientLib/SnakeProjectModule/PropertyView.qml
Normal file
@ -0,0 +1,124 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
Item {
|
||||
id: properyView
|
||||
|
||||
height: 1 * metrix.pt
|
||||
|
||||
property string keyImage: "";
|
||||
property string keyText: "";
|
||||
|
||||
property string valueImage: "";
|
||||
property string valueText: "";
|
||||
|
||||
property int lineWidth : 0.5 * metrix.mm
|
||||
|
||||
property bool hovered: false
|
||||
property bool hold: false
|
||||
|
||||
Rectangle {
|
||||
id:background
|
||||
anchors.fill: parent
|
||||
color: "#00000000"
|
||||
|
||||
Rectangle {
|
||||
height: lineWidth
|
||||
color: (hold)? Material.accent: (hovered)? Material.foreground:"#aaa"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Behavior on color {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: background
|
||||
horizontalOffset: 2
|
||||
verticalOffset: 2
|
||||
radius: 8.0
|
||||
samples: 17
|
||||
|
||||
color: "#80000000";
|
||||
source: background
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: {
|
||||
parent.hovered = true;
|
||||
}
|
||||
|
||||
onExited: {
|
||||
parent.hovered = false;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
parent.hold = false;
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
parent.hold = true;
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
||||
Label {
|
||||
text: keyText
|
||||
visible: keyText
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
|
||||
}
|
||||
|
||||
ImageView {
|
||||
visible: keyImage
|
||||
drawItem: keyImage
|
||||
size: parent.height * 0.75
|
||||
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
text: valueText
|
||||
visible: valueText
|
||||
horizontalAlignment: Text.AlignRight
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
}
|
||||
|
||||
ImageView {
|
||||
drawItem: valueImage
|
||||
size: parent.height * 0.75
|
||||
visible: valueImage
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
|
||||
}
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*##^## Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
228
src/ClientLib/SnakeProjectModule/Scene.qml
Normal file
228
src/ClientLib/SnakeProjectModule/Scene.qml
Normal file
@ -0,0 +1,228 @@
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: scene;
|
||||
z: -2
|
||||
|
||||
Rectangle {
|
||||
id: background;
|
||||
color: "#ffffff"
|
||||
anchors.fill: parent;
|
||||
|
||||
Behavior on color {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 5000
|
||||
}
|
||||
}
|
||||
|
||||
z: -3
|
||||
|
||||
}
|
||||
|
||||
property var model: null;
|
||||
property var arrayObjects: []
|
||||
readonly property bool showMenu: (model)? model.showMenu: false
|
||||
property bool isPause: false
|
||||
|
||||
function add (cppObjId) {
|
||||
if (!model) {
|
||||
console.log("create object fail")
|
||||
return;
|
||||
}
|
||||
var objModel = model.getGameObject(cppObjId);
|
||||
|
||||
if (!objModel) {
|
||||
console.log("object model not found");
|
||||
return;
|
||||
}
|
||||
|
||||
var viewTemplate = objModel.viewTemplate;
|
||||
|
||||
var temp = Qt.createComponent( viewTemplate + ".qml")
|
||||
if (temp.status === Component.Ready) {
|
||||
var obj = temp.createObject(parent) // parent - это обьект на который будет помещен соззданный элемент
|
||||
obj.model = model.getGameObject(cppObjId);
|
||||
obj.z = -2;
|
||||
arrayObjects.push(obj)
|
||||
} else {
|
||||
console.log("wrong viewTemplate in model");
|
||||
}
|
||||
}
|
||||
|
||||
function remove(id) {
|
||||
if (typeof id !== "number" || id < 0) {
|
||||
console.log("id not found");
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < arrayObjects.length; ++i) {
|
||||
if (id === arrayObjects[i].guiId) {
|
||||
arrayObjects.splice(i,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateBackgroundColor(lvl) {
|
||||
switch(lvl % 7) {
|
||||
case 0: background.color = "#d6eaf8"; break;
|
||||
case 1: background.color = "#d0ece7"; break;
|
||||
case 2: background.color = "#d4efdf"; break;
|
||||
case 3: background.color = "#fcf3cf"; break;
|
||||
case 4: background.color = "#f6ddcc"; break;
|
||||
case 5: background.color = "#f2d7d5"; break;
|
||||
case 6: background.color = "#ebdef0"; break;
|
||||
case 7: background.color = "#fbfcfc"; break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: autoTimer;
|
||||
repeat: true;
|
||||
running: showMenu;
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
interval = Math.random() * 600
|
||||
scene.model.buttonPress();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: model;
|
||||
onGameObjectsChanged: {
|
||||
if (!dif) {
|
||||
console.log("dif not found");
|
||||
return;
|
||||
}
|
||||
|
||||
var tempDifRem = [];
|
||||
tempDifRem = dif.getRemoveIds();
|
||||
var tempDifAdd = [];
|
||||
tempDifAdd = dif.getAddedIds();
|
||||
|
||||
for (var i = 0; i < tempDifAdd.length; ++i) {
|
||||
add(tempDifAdd[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < tempDifRem.length; ++i) {
|
||||
remove(tempDifRem[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateBackgroundColor(0);
|
||||
model.handleNewGame();
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
||||
onClicked: {
|
||||
if (!model || showMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.buttonPress();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: returnToMenu;
|
||||
|
||||
text: "<<"
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: metrix.gamePt
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: metrix.gamePt
|
||||
z: 1
|
||||
|
||||
onClicked: {
|
||||
if (model)
|
||||
model.showMenu = true;
|
||||
}
|
||||
|
||||
visible: !showMenu
|
||||
}
|
||||
|
||||
Button {
|
||||
id: pause
|
||||
|
||||
text: (isPause)? "▶" :"||"
|
||||
|
||||
anchors.left: returnToMenu.right
|
||||
anchors.leftMargin: metrix.gamePt
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: metrix.gamePt
|
||||
z: returnToMenu.z
|
||||
|
||||
onClicked: {
|
||||
isPause = !isPause;
|
||||
if (model) model.setPause(isPause);
|
||||
}
|
||||
|
||||
visible: !showMenu
|
||||
|
||||
}
|
||||
|
||||
Button {
|
||||
id: long_
|
||||
Label {
|
||||
anchors.fill: parent;
|
||||
|
||||
textFormat: Text.AutoText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: qsTr("lvl long: ") + ((model)? model.long_: "0")
|
||||
}
|
||||
|
||||
width: 35 * metrix.gamePt;
|
||||
height: pause.height;
|
||||
|
||||
anchors.left: pause.right
|
||||
anchors.leftMargin: metrix.gamePt
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: metrix.gamePt
|
||||
z: returnToMenu.z
|
||||
|
||||
visible: !showMenu
|
||||
|
||||
}
|
||||
|
||||
Button {
|
||||
Label {
|
||||
anchors.fill: parent;
|
||||
|
||||
textFormat: Text.AutoText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: qsTr("general long: ") + ((model)? model.generalLong: "0")
|
||||
}
|
||||
|
||||
width: 35 * metrix.gamePt;
|
||||
height: long_.height;
|
||||
|
||||
anchors.left: long_.right
|
||||
anchors.leftMargin: metrix.gamePt
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: metrix.gamePt
|
||||
z: returnToMenu.z
|
||||
|
||||
visible: !showMenu
|
||||
|
||||
}
|
||||
}
|
217
src/ClientLib/SnakeProjectModule/SelectLevelScene.qml
Normal file
217
src/ClientLib/SnakeProjectModule/SelectLevelScene.qml
Normal file
@ -0,0 +1,217 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: item1
|
||||
|
||||
GridLayout {
|
||||
id: gridLayout
|
||||
rows: 8
|
||||
columnSpacing: 5
|
||||
rowSpacing: 5
|
||||
anchors.rightMargin: 200
|
||||
anchors.leftMargin: 200
|
||||
anchors.bottomMargin: 100
|
||||
anchors.topMargin: 50
|
||||
anchors.fill: parent
|
||||
columns: 8
|
||||
|
||||
RoundButton {
|
||||
id: roundButton
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "1"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton1
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "2"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton2
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "3"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton3
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "4"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton4
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "5"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton5
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "6"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton6
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "7"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton7
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "8"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton8
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "9"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton9
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "10"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton10
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "11"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton11
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "12"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton12
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "13"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton13
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "14"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton14
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "15"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton15
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "16"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton16
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "17"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton17
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "18"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton18
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "19"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton19
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "20"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton20
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "21"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton21
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "22"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton22
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "23"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton23
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "24"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton24
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "25"
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: roundButton25
|
||||
width: 10*mainWindow.point
|
||||
height: 10*mainWindow.point
|
||||
text: "26"
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: label
|
||||
x: 187
|
||||
color: "#795548"
|
||||
text: qsTr("Select Level")
|
||||
font.bold: true
|
||||
font.pixelSize: 30
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
}
|
||||
|
||||
}
|
||||
|
122
src/ClientLib/SnakeProjectModule/SettingsView.qml
Normal file
122
src/ClientLib/SnakeProjectModule/SettingsView.qml
Normal file
@ -0,0 +1,122 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: settingsView
|
||||
|
||||
property var model: null
|
||||
|
||||
function save() {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.setPort(port.value);
|
||||
model.setHost(host.text);
|
||||
model.setTheme(themeBox.currentIndex);
|
||||
|
||||
}
|
||||
|
||||
function reset() {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.toDefault();
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
model.forceUpdate();
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
|
||||
id: columnLayout
|
||||
rows: 4
|
||||
columns: 2
|
||||
anchors.fill: parent
|
||||
|
||||
|
||||
Label {
|
||||
text: qsTr("Game Host")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: host;
|
||||
text: (model)? model.host: "localhost"
|
||||
Layout.fillHeight: false
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Game Port")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: port;
|
||||
Layout.fillWidth: true
|
||||
to: 10000
|
||||
from: 7000
|
||||
antialiasing: false
|
||||
scale: 1
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
value: (model)? model.port: 7777
|
||||
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Use Them")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: themeBox;
|
||||
Layout.fillWidth: true
|
||||
focusPolicy: Qt.NoFocus
|
||||
|
||||
model: [qsTr("Light"), qsTr("Dark")];
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
currentIndex: (settingsView.model)? settingsView.model.theme: 0
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (((settingsView.model)? settingsView.model.theme: 0)
|
||||
!== currentIndex) {
|
||||
themeWarning.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
Label {
|
||||
id: themeWarning
|
||||
text: qsTr("In order for the new theme to take effect, you need to reload the game.");
|
||||
|
||||
color: "#FF0000"
|
||||
|
||||
wrapMode: Label.WordWrap
|
||||
|
||||
Layout.maximumWidth: themeBox.width
|
||||
|
||||
visible: false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
103
src/ClientLib/SnakeProjectModule/SideBar.qml
Normal file
103
src/ClientLib/SnakeProjectModule/SideBar.qml
Normal file
@ -0,0 +1,103 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
FrameView {
|
||||
id: sideBar
|
||||
property int openHeight: 10 * metrix.pt
|
||||
property int closedHeight: 1 * metrix.pt
|
||||
property int openWidth: 10 * metrix.pt
|
||||
property int closedWidth: 1 * metrix.pt
|
||||
property int headerHeight : 1 * metrix.controlPtMaterial
|
||||
|
||||
clip: true;
|
||||
|
||||
property bool resizeWidth: true
|
||||
property bool resizeHeight: true
|
||||
|
||||
property bool isOpened: true
|
||||
property bool chainAnimation: true
|
||||
property var source: null
|
||||
property var header: null
|
||||
|
||||
readonly property bool openFinished: openHeight === height && openWidth == width;
|
||||
readonly property bool closeFinished: closedHeight === height && closedWidth == width;
|
||||
|
||||
function show() {
|
||||
if (resizeWidth && !(chainAnimation && resizeHeight))
|
||||
width = openWidth;
|
||||
if (resizeHeight )
|
||||
height = openHeight;
|
||||
|
||||
isOpened = true;
|
||||
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (resizeWidth && !(chainAnimation && resizeHeight))
|
||||
width = closedWidth;
|
||||
if (resizeHeight )
|
||||
height = closedHeight;
|
||||
|
||||
isOpened = false;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
show();
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
if (isOpened) {
|
||||
if (height === openHeight) {
|
||||
sideBar.width = openWidth
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (height === closedHeight) {
|
||||
sideBar.width = closedWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on width {
|
||||
PropertyAnimation {
|
||||
duration: 1000
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on height {
|
||||
PropertyAnimation {
|
||||
duration: 1000
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: headerVal
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: headerHeight
|
||||
}
|
||||
|
||||
Item {
|
||||
id: sourceVal
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: headerVal.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
}
|
||||
|
||||
onSourceChanged: {
|
||||
source.parent = sourceVal;
|
||||
source.anchors.fill = sourceVal;
|
||||
}
|
||||
|
||||
onHeaderChanged: {
|
||||
header.parent = headerVal;
|
||||
header.anchors.fill = headerVal;
|
||||
}
|
||||
}
|
17
src/ClientLib/SnakeProjectModule/SnakeItem.qml
Normal file
17
src/ClientLib/SnakeProjectModule/SnakeItem.qml
Normal file
@ -0,0 +1,17 @@
|
||||
import QtQuick 2.9
|
||||
|
||||
GraphicItem {
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 2000
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on radius {
|
||||
NumberAnimation {
|
||||
duration: 2000
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,40 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2021 QuasarApp.
|
||||
//# Distributed under the lgplv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import QtQuick 2.15
|
||||
ApplicationWindow {
|
||||
id: mainWindow;
|
||||
visible: true;
|
||||
width: 640;
|
||||
height: 480;
|
||||
title: qsTr("SnakeOnTheRoad");
|
||||
|
||||
Item {
|
||||
// Component.onCompleted: {
|
||||
// mainWindow.showFullScreen();
|
||||
// }
|
||||
|
||||
|
||||
Metrix {id: metrix}
|
||||
|
||||
Scene {
|
||||
id: scane;
|
||||
model: contr;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
MainMenu {
|
||||
|
||||
model: (contr)? contr.mainMenuModel: null;
|
||||
anchors.fill: parent;
|
||||
visible: scane.showMenu;
|
||||
|
||||
onPlayGame: {
|
||||
contr.showMenu = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NotificationServiceView {
|
||||
anchors.fill: parent;
|
||||
}
|
||||
}
|
||||
|
47
src/ClientLib/SnakeProjectModule/TextInput.qml
Normal file
47
src/ClientLib/SnakeProjectModule/TextInput.qml
Normal file
@ -0,0 +1,47 @@
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
signal close();
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
|
||||
Label {
|
||||
text: qsTr("Write you name ");
|
||||
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
||||
id: input;
|
||||
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
}
|
||||
|
||||
Button {
|
||||
|
||||
id: ok
|
||||
text: qsTr("Ok")
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
onClicked: {
|
||||
if (contr) {
|
||||
var rec = contr.getRecords()
|
||||
rec.append(input.text, contr.generalLong);
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
112
src/ClientLib/SnakeProjectModule/UserView.qml
Normal file
112
src/ClientLib/SnakeProjectModule/UserView.qml
Normal file
@ -0,0 +1,112 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
|
||||
Flickable {
|
||||
id: userVewFlic
|
||||
|
||||
contentWidth: userVew.width
|
||||
contentHeight: userVew.height
|
||||
flickableDirection: Flickable.VerticalFlick;
|
||||
property var model: null
|
||||
signal tryConnect();
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
width: metrix.pt
|
||||
}
|
||||
|
||||
Item {
|
||||
id: userVew
|
||||
|
||||
width: userVewFlic.width
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
|
||||
visible: (model)? !model.offline: false;
|
||||
|
||||
ImageView {
|
||||
drawItem: "image://userItems/player/" + ((model)? model.id: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
Layout.fillWidth: true
|
||||
keyText: qsTr("You ");
|
||||
valueText : (model)? model.name: -1
|
||||
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
valueText : ((model)? model.gmail: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
keyText: qsTr("You gmail");
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
keyText: qsTr("Money ");
|
||||
|
||||
valueText : ((model)? model.money: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
keyText: qsTr("Record ");
|
||||
|
||||
valueText : ((model)? model.record: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
keyText: qsTr("AvgRecord ");
|
||||
|
||||
valueText : ((model)? model.avgRecord: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
PropertyView {
|
||||
keyText: qsTr("Snake ");
|
||||
|
||||
valueImage : "image://userItems/item/" + ((model)? model.cureentSnake: -1).toString()
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: (model)? model.offline: false;
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Offline mode. Your statistics will be frozen until you login your profile.");
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("try conect to server ");
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
onClicked: {
|
||||
tryConnect();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
79
src/ClientLib/android/AndroidManifest.xml
Normal file
79
src/ClientLib/android/AndroidManifest.xml
Normal file
@ -0,0 +1,79 @@
|
||||
<?xml version="1.0"?>
|
||||
<manifest package="quasar.app.snake" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
|
||||
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:icon="@drawable/icon">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="landscape" android:launchMode="singleTop" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- Application arguments -->
|
||||
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
|
||||
<!-- Application arguments -->
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
|
||||
<!-- Deploy Qt libs as part of package -->
|
||||
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||
<!-- Run with local libs -->
|
||||
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
|
||||
<!-- Used to specify custom system library path to run with local system libs -->
|
||||
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
|
||||
<!-- Messages maps -->
|
||||
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
|
||||
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
|
||||
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
||||
<!-- Messages maps -->
|
||||
|
||||
<!-- Splash screen -->
|
||||
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
|
||||
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
|
||||
<!-- Splash screen -->
|
||||
|
||||
<!-- Background running -->
|
||||
<!-- Warning: changing this value to true may cause unexpected crashes if the
|
||||
application still try to draw after
|
||||
"applicationStateChanged(Qt::ApplicationSuspended)"
|
||||
signal is sent! -->
|
||||
<meta-data android:name="android.app.background_running" android:value="false"/>
|
||||
<!-- Background running -->
|
||||
|
||||
<!-- auto screen scale factor -->
|
||||
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
|
||||
<!-- auto screen scale factor -->
|
||||
|
||||
<!-- extract android style -->
|
||||
<!-- available android:values :
|
||||
* full - useful QWidget & Quick Controls 1 apps
|
||||
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
|
||||
* none - useful for apps that don't use any of the above Qt modules
|
||||
-->
|
||||
<meta-data android:name="android.app.extract_android_style" android:value="full"/>
|
||||
<!-- extract android style -->
|
||||
</activity>
|
||||
|
||||
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
||||
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default permissions. -->
|
||||
<!-- %%INSERT_PERMISSIONS -->
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default features. -->
|
||||
<!-- %%INSERT_FEATURES -->
|
||||
|
||||
</manifest>
|
57
src/ClientLib/android/build.gradle
Normal file
57
src/ClientLib/android/build.gradle
Normal file
@ -0,0 +1,57 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
}
|
||||
|
||||
android {
|
||||
/*******************************************************
|
||||
* The following variables:
|
||||
* - androidBuildToolsVersion,
|
||||
* - androidCompileSdkVersion
|
||||
* - qt5AndroidDir - holds the path to qt android files
|
||||
* needed to build any Qt application
|
||||
* on Android.
|
||||
*
|
||||
* are defined in gradle.properties file. This file is
|
||||
* updated by QtCreator and androiddeployqt tools.
|
||||
* Changing them manually might break the compilation!
|
||||
*******************************************************/
|
||||
|
||||
compileSdkVersion androidCompileSdkVersion.toInteger()
|
||||
|
||||
buildToolsVersion androidBuildToolsVersion
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
|
||||
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
|
||||
res.srcDirs = [qt5AndroidDir + '/res', 'res']
|
||||
resources.srcDirs = ['src']
|
||||
renderscript.srcDirs = ['src']
|
||||
assets.srcDirs = ['assets']
|
||||
jniLibs.srcDirs = ['libs']
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
BIN
src/ClientLib/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
src/ClientLib/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
src/ClientLib/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
src/ClientLib/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
172
src/ClientLib/android/gradlew
vendored
Executable file
172
src/ClientLib/android/gradlew
vendored
Executable file
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
84
src/ClientLib/android/gradlew.bat
vendored
Normal file
84
src/ClientLib/android/gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
BIN
src/ClientLib/android/res/drawable-hdpi/icon.png
Normal file
BIN
src/ClientLib/android/res/drawable-hdpi/icon.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.4 KiB |
BIN
src/ClientLib/android/res/drawable-ldpi/icon.png
Normal file
BIN
src/ClientLib/android/res/drawable-ldpi/icon.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.4 KiB |
BIN
src/ClientLib/android/res/drawable-mdpi/icon.png
Normal file
BIN
src/ClientLib/android/res/drawable-mdpi/icon.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.4 KiB |
25
src/ClientLib/android/res/values/libs.xml
Normal file
25
src/ClientLib/android/res/values/libs.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<array name="qt_sources">
|
||||
<item>https://download.qt.io/ministro/android/qt5/qt-5.9</item>
|
||||
</array>
|
||||
|
||||
<!-- The following is handled automatically by the deployment tool. It should
|
||||
not be edited manually. -->
|
||||
|
||||
<array name="bundled_libs">
|
||||
<!-- %%INSERT_EXTRA_LIBS%% -->
|
||||
</array>
|
||||
|
||||
<array name="qt_libs">
|
||||
<!-- %%INSERT_QT_LIBS%% -->
|
||||
</array>
|
||||
|
||||
<array name="bundled_in_lib">
|
||||
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
|
||||
</array>
|
||||
<array name="bundled_in_assets">
|
||||
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
|
||||
</array>
|
||||
|
||||
</resources>
|
@ -1,4 +1,287 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>About</name>
|
||||
<message>
|
||||
<source>About</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AboutPage</name>
|
||||
<message>
|
||||
<source>Product of QuasarrApp</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Controller</name>
|
||||
<message>
|
||||
<source> Next Lvl!!!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source> You anblock next lvl (%0)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginView</name>
|
||||
<message>
|
||||
<source>Success</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password must be at least 8 characters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name must be at least 1 characters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords must match</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The letter must match the pattern 'X@xxxx.xxx'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Email</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passsword</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter Your passsword</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter Your Email</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repeat password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter Your passsword again</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign in</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign Up</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You need connect to server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use OfflineMode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainClient</name>
|
||||
<message>
|
||||
<source>Login status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Success</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authorization Required</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wait for answer</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Login result</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authorization fail</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Client is offline</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Offline Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bad Request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainMenu</name>
|
||||
<message>
|
||||
<source>Play game</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Store</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>My Items</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>My friends</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>My Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NotificationForm</name>
|
||||
<message>
|
||||
<source>Message</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Scene</name>
|
||||
<message>
|
||||
<source>lvl long: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>general long: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SelectLevelScene</name>
|
||||
<message>
|
||||
<source>Select Level</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsView</name>
|
||||
<message>
|
||||
<source>Game Host</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game Port</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Them</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Light</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>In order for the new theme to take effect, you need to reload the game.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SnakeProject</name>
|
||||
<message>
|
||||
<source>SnakeOnTheRoad</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TextInput</name>
|
||||
<message>
|
||||
<source>Write you name </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ok</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UserView</name>
|
||||
<message>
|
||||
<source>You </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You gmail</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Money </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>AvgRecord </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Snake </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Offline mode. Your statistics will be frozen until you login your profile.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>try conect to server </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Undefined name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Undefined gmail</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
BIN
src/ClientLib/res/Settings-icon.png
Normal file
BIN
src/ClientLib/res/Settings-icon.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 28 KiB |
BIN
src/ClientLib/res/asphalt.jpg
Normal file
BIN
src/ClientLib/res/asphalt.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 186 KiB |
BIN
src/ClientLib/res/box-texture.png
Normal file
BIN
src/ClientLib/res/box-texture.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 79 KiB |
1
src/ClientLib/res/cogs-solid.svg
Normal file
1
src/ClientLib/res/cogs-solid.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" data-prefix="fas" data-icon="cogs" class="svg-inline--fa fa-cogs fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"></path></svg>
|
After (image error) Size: 2.5 KiB |
BIN
src/ClientLib/res/defaultSnake.png
Normal file
BIN
src/ClientLib/res/defaultSnake.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 18 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user