mirror of
https://github.com/QuasarApp/Snake.git
synced 2025-04-26 09:44:40 +00:00
Merge pull request #60 from QuasarApp/render
Add support render function
This commit is contained in:
commit
dbab1e081a
@ -31,7 +31,6 @@ QByteArray ClientApp::initTheme() {
|
||||
case 1: return "Dark";
|
||||
default: return "Light";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ClientApp::ClientApp() {
|
||||
@ -85,7 +84,6 @@ void ClientApp::initLvls() {
|
||||
}
|
||||
|
||||
_menu->setAvailableLvls(_availableWorlds);
|
||||
|
||||
}
|
||||
|
||||
IWorld *ClientApp::getLastWorld() {
|
||||
|
@ -30,7 +30,7 @@ void GuiObject::setColor(QString color) {
|
||||
|
||||
void GuiObject::generateId() {
|
||||
static int id = 0;
|
||||
_guiId = id++;
|
||||
setGuiId(id++);
|
||||
}
|
||||
|
||||
const QString &GuiObject::className() const {
|
||||
|
@ -5,12 +5,13 @@
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#include "defaultcontrol.h"
|
||||
#include "iplayer.h"
|
||||
|
||||
IPlayer::IPlayer(const QString &name,
|
||||
const QString &viewTempalte,
|
||||
QObject *ptr):
|
||||
IWorldItem(name, viewTempalte, ptr) {
|
||||
MovableObject(name, viewTempalte, ptr) {
|
||||
|
||||
}
|
||||
|
||||
@ -52,6 +53,21 @@ void IPlayer::setSpeed(float newSpead) {
|
||||
}
|
||||
}
|
||||
|
||||
void IPlayer::setControl(const IControl *control) {
|
||||
|
||||
|
||||
if (auto oldControl = dynamic_cast<const DefaultControl*>(_currentControl)) {
|
||||
disconnect(oldControl, &DefaultControl::userTap, this, &IPlayer::onTap);
|
||||
}
|
||||
|
||||
auto defaultControl = dynamic_cast<const DefaultControl*>(control);
|
||||
_currentControl = defaultControl;
|
||||
|
||||
if (_currentControl) {
|
||||
connect(defaultControl, &DefaultControl::userTap, this, &IPlayer::onTap);
|
||||
}
|
||||
}
|
||||
|
||||
void IPlayer::kill() {
|
||||
_fDead = true;
|
||||
}
|
||||
|
@ -9,15 +9,15 @@
|
||||
#define IPLAYER_H
|
||||
|
||||
#include "gameresult.h"
|
||||
#include "iworlditem.h"
|
||||
#include "global.h"
|
||||
#include "movableobject.h"
|
||||
|
||||
class IControl;
|
||||
|
||||
/**
|
||||
* @brief The IPlayer class This is base class of the player functions.
|
||||
*/
|
||||
class CRAWL_EXPORT IPlayer: public IWorldItem {
|
||||
class CRAWL_EXPORT IPlayer: public MovableObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
IPlayer(const QString& name,
|
||||
@ -53,7 +53,7 @@ public:
|
||||
* @param control This is control object.
|
||||
* @note This method can invoked two or more times, for example connect with AI control object and player control object. So your implementation should be contains disconnect methods.
|
||||
*/
|
||||
virtual void setControl(const IControl* control) = 0;
|
||||
virtual void setControl(const IControl* control);
|
||||
|
||||
protected:
|
||||
|
||||
@ -92,6 +92,7 @@ protected:
|
||||
*/
|
||||
void fine(int value);
|
||||
|
||||
protected slots:
|
||||
/**
|
||||
* @brief onTap This method invoked when user tap on screen.
|
||||
* @note method connected in the IPlayer::setControl function. So if you overrid the IPlayer::setControl method then please invoke method of a parent class.
|
||||
@ -102,6 +103,7 @@ private:
|
||||
bool _fDead = false;
|
||||
int _currentPoints = 0;
|
||||
float _speed = 0;
|
||||
const IControl * _currentControl = nullptr;
|
||||
};
|
||||
|
||||
#endif // IPLAYER_H
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "worldstatus.h"
|
||||
#include "iai.h"
|
||||
#include "clasteritem.h"
|
||||
#include "thread"
|
||||
#include "chrono"
|
||||
|
||||
IWorld::IWorld() {
|
||||
|
||||
@ -31,6 +33,8 @@ IControl *IWorld::initUserInterface() const {
|
||||
|
||||
void IWorld::render(unsigned int tbfMsec) {
|
||||
|
||||
_ItemsMutex.lock();
|
||||
|
||||
for (auto i = _items.begin(); i != _items.end(); ++i) {
|
||||
(*i)->render(tbfMsec);
|
||||
|
||||
@ -43,6 +47,12 @@ void IWorld::render(unsigned int tbfMsec) {
|
||||
if (_player->isDead()) {
|
||||
emit sigGameFinished(_player->getCurrentStatus());
|
||||
}
|
||||
|
||||
_ItemsMutex.unlock();
|
||||
|
||||
int waitTime = 1000 / _targetFps - tbfMsec;
|
||||
if (waitTime > 0)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
|
||||
}
|
||||
|
||||
void IWorld::initPlayerControl(IControl *control) {
|
||||
@ -63,6 +73,7 @@ bool IWorld::start() {
|
||||
|
||||
|
||||
worldChanged(*_worldRules->begin());
|
||||
setTargetFps(60);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -103,6 +114,8 @@ bool IWorld::stop() {
|
||||
|
||||
_backgroundAI->startAI();
|
||||
|
||||
setTargetFps(30);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -111,6 +124,8 @@ IAI *IWorld::initBackGroundAI() const {
|
||||
}
|
||||
|
||||
IWorldItem *IWorld::getItem(int id) const {
|
||||
QMutexLocker lock(&_ItemsMutex);
|
||||
|
||||
return _items.value(id, nullptr);
|
||||
}
|
||||
|
||||
@ -145,6 +160,8 @@ bool IWorld::init() {
|
||||
}
|
||||
|
||||
void IWorld::clearItems() {
|
||||
QMutexLocker lock(&_ItemsMutex);
|
||||
|
||||
for (const auto& item : qAsConst(_items)) {
|
||||
delete item;
|
||||
}
|
||||
@ -232,11 +249,17 @@ void IWorld::addAtomicItem(IWorldItem* obj) {
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
QMutexLocker lock(&_ItemsMutex);
|
||||
|
||||
_items.insert(obj->guiId(), obj);
|
||||
_itemsGroup.insert(obj->className(), obj->guiId());
|
||||
|
||||
obj->initOnWorld(this, _player);
|
||||
}
|
||||
|
||||
bool IWorld::removeIAtomicItem(int id) {
|
||||
QMutexLocker lock(&_ItemsMutex);
|
||||
|
||||
auto obj = _items.value(id);
|
||||
|
||||
if (!obj) {
|
||||
@ -256,6 +279,8 @@ bool IWorld::removeIAtomicItem(IWorldItem *obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QMutexLocker lock(&_ItemsMutex);
|
||||
|
||||
_itemsGroup.remove(obj->className(), obj->guiId());
|
||||
_items.remove(obj->guiId());
|
||||
|
||||
@ -270,6 +295,14 @@ void IWorld::removeAnyItemFromGroup(const QString &group,
|
||||
removeItem(anyObjectId, removedObjectsList);
|
||||
}
|
||||
|
||||
int IWorld::targetFps() const {
|
||||
return _targetFps;
|
||||
}
|
||||
|
||||
void IWorld::setTargetFps(int newTargetFps) {
|
||||
_targetFps = newTargetFps;
|
||||
}
|
||||
|
||||
const QQuaternion &IWorld::cameraRatation() const {
|
||||
return _cameraRatation;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "irender.h"
|
||||
#include "diff.h"
|
||||
#include "global.h"
|
||||
#include <QMutex>
|
||||
|
||||
class IWorldItem;
|
||||
class IPlayer;
|
||||
@ -298,6 +299,18 @@ protected:
|
||||
*/
|
||||
void setCameraRatation(const QQuaternion &newCameraRatation);
|
||||
|
||||
/**
|
||||
* @brief targetFps This method return current targetFps;
|
||||
* @return current target FPS.
|
||||
*/
|
||||
int targetFps() const;
|
||||
|
||||
/**
|
||||
* @brief setTargetFps This method sets new targetFps.
|
||||
* @param newTargetFps This is new value of target Fps;
|
||||
*/
|
||||
void setTargetFps(int newTargetFps);
|
||||
|
||||
template<class Type>
|
||||
|
||||
/**
|
||||
@ -398,6 +411,9 @@ private:
|
||||
|
||||
QHash<int, IWorldItem*> _items;
|
||||
QMultiHash<QString, int> _itemsGroup;
|
||||
|
||||
mutable QMutex _ItemsMutex;
|
||||
|
||||
QVector3D _cameraReleativePosition;
|
||||
QQuaternion _cameraRatation;
|
||||
|
||||
@ -409,6 +425,8 @@ private:
|
||||
int _worldStatus = 0;
|
||||
QHash<QString, std::function<IWorldItem*()>> _registeredTypes;
|
||||
|
||||
int _targetFps = 60;
|
||||
|
||||
// engine
|
||||
friend class Engine;
|
||||
|
||||
|
61
src/Core/Crawl/movableobject.cpp
Normal file
61
src/Core/Crawl/movableobject.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "movableobject.h"
|
||||
#include <QDebug>
|
||||
|
||||
MovableObject::MovableObject(const QString &name,
|
||||
const QString &viewTempalte,
|
||||
QObject *ptr):
|
||||
IWorldItem(name, viewTempalte, ptr) {
|
||||
|
||||
}
|
||||
|
||||
void MovableObject::render(unsigned int tbfMsec) {
|
||||
|
||||
// get object center position
|
||||
QVector3D currentPosition = position();
|
||||
|
||||
// move object to vector
|
||||
currentPosition += (_currentMovableVector * (tbfMsec / 1000.0));
|
||||
setposition(currentPosition);
|
||||
|
||||
// calc temp vector betvin user moveble vector and real moveble vector
|
||||
QVector3D tempVector = _movableVector - _currentMovableVector ;
|
||||
|
||||
// calc change on this iteration for new moveble vector
|
||||
float delta = std::min(_angularVelocity * (tbfMsec / 1000.0), static_cast<double>(tempVector.length()));
|
||||
|
||||
// resize temp vector for calc changes of the movableVector
|
||||
tempVector = tempVector.normalized() * delta;
|
||||
|
||||
// recalc new currentMovable vector (applay changes)
|
||||
_currentMovableVector += tempVector;
|
||||
|
||||
float newMovableVectorLength = std::max(_movableVector.length() - (_breakingForce * (tbfMsec / 1000.0)), 0.0);
|
||||
|
||||
// update movable vector
|
||||
_movableVector = _movableVector.normalized() * newMovableVectorLength;
|
||||
|
||||
}
|
||||
|
||||
const QVector3D &MovableObject::movableVector() const {
|
||||
return _movableVector;
|
||||
}
|
||||
|
||||
void MovableObject::setMovableVector(const QVector3D &newMovableVector) {
|
||||
_movableVector = newMovableVector;
|
||||
}
|
||||
|
||||
float MovableObject::angularVelocity() const {
|
||||
return _angularVelocity;
|
||||
}
|
||||
|
||||
void MovableObject::setAngularVelocity(float newAngularVelocity) {
|
||||
_angularVelocity = newAngularVelocity;
|
||||
}
|
||||
|
||||
float MovableObject::breakingForce() const {
|
||||
return _breakingForce;
|
||||
}
|
||||
|
||||
void MovableObject::setBreakingForce(float newBreakingForce) {
|
||||
_breakingForce = newBreakingForce;
|
||||
}
|
78
src/Core/Crawl/movableobject.h
Normal file
78
src/Core/Crawl/movableobject.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef MOVABLEOBJECT_H
|
||||
#define MOVABLEOBJECT_H
|
||||
|
||||
#include "iworlditem.h"
|
||||
|
||||
/**
|
||||
* @brief The MovableObject class contains functions for moving object on the world.
|
||||
* All moving separate to next properties:
|
||||
*
|
||||
* * **Movable vector** This property sets direction of move
|
||||
* * **Movable vector force** This is force of the movable vector.
|
||||
* * **Angular velocity** This property sets spead of the angle moving.
|
||||
* * **Braking force** This property are delta decriment the Power of the movable vector on time.
|
||||
*/
|
||||
class CRAWL_EXPORT MovableObject: public IWorldItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MovableObject(const QString& name,
|
||||
const QString& viewTempalte = DEFAULT_VIEW_TEMPLATE,
|
||||
QObject *ptr = nullptr);
|
||||
|
||||
/**
|
||||
* @brief render This impplementation of the render method add simulation of the physics in the vacuum space.
|
||||
* @param tbfMsec This is time betwin frames argument.
|
||||
*/
|
||||
void render(unsigned int tbfMsec) override;
|
||||
|
||||
/**
|
||||
* @brief movableVector This method return current mvable vector.
|
||||
* The movable vector it is second point of line betwin object center and movableVector point.
|
||||
* The movableVector base on own releative asix system wher the object center is vector {0 0 0}
|
||||
* @note So movableVector are 3d angle of the moving of this object.
|
||||
* @return movable vector of object
|
||||
*/
|
||||
const QVector3D &movableVector() const;
|
||||
|
||||
/**
|
||||
* @brief setMovableVector This method sets new value of the mvable vector.
|
||||
* @param newMovableVector - this is a new value ofthe movable vector
|
||||
*/
|
||||
void setMovableVector(const QVector3D &newMovableVector);
|
||||
|
||||
/**
|
||||
* @brief angularVelocity This method return current angular veloscity.
|
||||
* @return angular velosity
|
||||
* @note This property contains speed on angle per second (a/s)
|
||||
*/
|
||||
float angularVelocity() const;
|
||||
|
||||
/**
|
||||
* @brief setAngularVelocity This method sets new value of the angular velacity in angele per second
|
||||
* @param newAngularVelocity This is new value of the angular velacity
|
||||
*/
|
||||
void setAngularVelocity(float newAngularVelocity);
|
||||
|
||||
/**
|
||||
* @brief breakingForce This method return current value of the breaking force.
|
||||
* @return urrent value of the breaking force
|
||||
*/
|
||||
float breakingForce() const;
|
||||
|
||||
/**
|
||||
* @brief setBreakingForce This method sets new value of the breaking force.
|
||||
* @param newBreakingForce This is new value of the breaking force
|
||||
*/
|
||||
void setBreakingForce(float newBreakingForce);
|
||||
|
||||
private:
|
||||
QVector3D _movableVector;
|
||||
QVector3D _currentMovableVector;
|
||||
|
||||
float _angularVelocity = 0;
|
||||
float _breakingForce = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // MOVABLEOBJECT_H
|
@ -103,6 +103,8 @@ Item {
|
||||
return;
|
||||
|
||||
item1.model.newGame(view.selectedLvl)
|
||||
|
||||
selectLvl.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,9 @@ View3D {
|
||||
|
||||
PointLight {
|
||||
position: camera.position
|
||||
brightness: 1500
|
||||
rotation: camera.rotation
|
||||
|
||||
brightness: 250
|
||||
}
|
||||
|
||||
environment: SceneEnvironment {
|
||||
@ -64,6 +66,7 @@ View3D {
|
||||
console.log("create object fail")
|
||||
return;
|
||||
}
|
||||
|
||||
const objModel = model.getGameObject(cppObjId);
|
||||
|
||||
if (!objModel) {
|
||||
|
@ -10,13 +10,20 @@
|
||||
#include <QQmlComponent>
|
||||
#include <Crawl/guiobject.h>
|
||||
#include "Crawl/iworld.h"
|
||||
#include <QThread>
|
||||
#include <quasarapp.h>
|
||||
#include "Crawl/icontrol.h"
|
||||
#include "QDateTime"
|
||||
#include "QtConcurrent"
|
||||
|
||||
Engine::Engine(QObject *parent): QObject(parent) {
|
||||
|
||||
}
|
||||
|
||||
Engine::~Engine() {
|
||||
stopRenderLoop();
|
||||
}
|
||||
|
||||
QObject *Engine::scane() {
|
||||
return _scane;
|
||||
}
|
||||
@ -54,6 +61,7 @@ void Engine::setWorld(IWorld *world) {
|
||||
|
||||
emit worldChanged();
|
||||
|
||||
startRenderLoop();
|
||||
}
|
||||
|
||||
QString Engine::hdr() const {
|
||||
@ -116,6 +124,23 @@ QObject *Engine::getGameObject(int id) const {
|
||||
return _currentWorld->getItem(id);
|
||||
}
|
||||
|
||||
void Engine::startRenderLoop() {
|
||||
if (isRendering())
|
||||
return;
|
||||
|
||||
_renderLoop = true;
|
||||
_renderLoopFuture = QtConcurrent::run(this, &Engine::renderLoop);
|
||||
}
|
||||
|
||||
void Engine::stopRenderLoop() {
|
||||
_renderLoop = false;
|
||||
_renderLoopFuture.waitForFinished();
|
||||
}
|
||||
|
||||
bool Engine::isRendering() const {
|
||||
return _renderLoopFuture.isRunning();
|
||||
}
|
||||
|
||||
void Engine::setPrepareLvlProgress(int newPrepareLvlProgress) {
|
||||
if (_prepareLvlProgress == newPrepareLvlProgress) {
|
||||
return;
|
||||
@ -123,3 +148,24 @@ void Engine::setPrepareLvlProgress(int newPrepareLvlProgress) {
|
||||
_prepareLvlProgress = newPrepareLvlProgress;
|
||||
emit prepareLvlProgressChanged();
|
||||
}
|
||||
|
||||
void Engine::renderLoop() {
|
||||
|
||||
if (!_currentWorld)
|
||||
return;
|
||||
|
||||
while (_renderLoop) {
|
||||
|
||||
quint64 currentTime = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
if (!_oldTimeRender) {
|
||||
_oldTimeRender = currentTime;
|
||||
continue;
|
||||
}
|
||||
|
||||
_currentWorld->render(currentTime - _oldTimeRender);
|
||||
_oldTimeRender = currentTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include <QFuture>
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
#include <Crawl/diff.h>
|
||||
@ -30,6 +31,7 @@ class Engine : public QObject {
|
||||
|
||||
public:
|
||||
Engine(QObject * parent = nullptr);
|
||||
~Engine();
|
||||
|
||||
/**
|
||||
* @brief scane This method return main scane of the game.
|
||||
@ -111,6 +113,21 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE QObject *getGameObject(int id) const;
|
||||
|
||||
/**
|
||||
* @brief startRenderLoop This method start render loop in engine.
|
||||
*/
|
||||
void startRenderLoop();
|
||||
|
||||
/**
|
||||
* @brief stopRenderLoop This method stop render loop in engine.
|
||||
*/
|
||||
void stopRenderLoop();
|
||||
|
||||
/**
|
||||
* @brief isRendering This method erturn true if the render loop is working else false.
|
||||
* @return true if the render loop is working else false.
|
||||
*/
|
||||
bool isRendering() const;
|
||||
|
||||
signals:
|
||||
void scaneChanged();
|
||||
@ -123,12 +140,19 @@ signals:
|
||||
private:
|
||||
void setPrepareLvlProgress(int newPrepareLvlProgress);
|
||||
|
||||
void renderLoop();
|
||||
|
||||
|
||||
QObject *_scane = nullptr;
|
||||
QQmlEngine *_engine = nullptr;
|
||||
IWorld* _currentWorld = nullptr;
|
||||
QObject *_menu = nullptr;
|
||||
int _prepareLvlProgress;
|
||||
|
||||
quint64 _oldTimeRender = 0;
|
||||
|
||||
QFuture<void> _renderLoopFuture;
|
||||
bool _renderLoop = false;
|
||||
};
|
||||
|
||||
#endif // ENGINE_H
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 3f8198a0767f860fa17fed86f6772f09462077fa
|
||||
Subproject commit 46878c18cae14eed67a2b105dc993ff2d670a3bc
|
Loading…
x
Reference in New Issue
Block a user