added bas snake class

This commit is contained in:
Andrei Yankovich 2021-06-28 18:16:27 +03:00
parent 831fb4b620
commit d5afbd889b
14 changed files with 222 additions and 63 deletions

View File

@ -14,6 +14,7 @@ GuiObject::GuiObject(const QString &name, const QString &viewTempalte, QObject *
_viewTemplate = viewTempalte;
_className = name;
generateId();
setRatation({1,1,0,0});
}
QString GuiObject::color() const {

View File

@ -31,6 +31,11 @@ public:
*/
virtual void render(unsigned int tbfMsec) = 0;
/**
* @brief init This method should be invoked after create object.
*/
virtual void init() = 0;
/**
* @brief checkminimumRequariedType This method check
* @return This object casted to Requared type this objct.

View File

@ -24,9 +24,11 @@ IWorld::IWorld() {
}
IWorld::~IWorld() {
deinit();
reset();
}
void IWorld::init() {prepare();}
IControl *IWorld::initUserInterface() const {
return new DefaultControl;
}
@ -97,7 +99,7 @@ void IWorld::setPlayer(QObject *newPlayer) {
}
_player = newPlayerObject;
addAtomicItem(_player);
addItem(_player);
emit playerChanged();
}
@ -129,7 +131,7 @@ IWorldItem *IWorld::getItem(int id) const {
return _items.value(id, nullptr);
}
bool IWorld::init() {
bool IWorld::prepare() {
if (isInit())
return true;
@ -144,12 +146,12 @@ bool IWorld::init() {
if (!isInit()) {
QuasarAppUtils::Params::log("Failed to init world implementation.");
deinit();
reset();
return false;
}
if (!_worldRules->size()) {
deinit();
reset();
return false;
}
@ -173,6 +175,8 @@ void IWorld::addItem(IWorldItem *obj, QList<int> *addedObjectsList) {
if (!obj)
return;
obj->init();
// Work wih claster
if (auto claster = dynamic_cast<Claster*>(obj)) {
for (auto item : claster->objects()) {
@ -218,7 +222,7 @@ void IWorld::removeItem(int id, QList<int> *removedObjectsList) {
}
void IWorld::deinit() {
void IWorld::reset() {
if (_player) {
delete _player;
_player = nullptr;

View File

@ -51,7 +51,9 @@ class CRAWL_EXPORT IWorld : public QObject, public IRender
public:
IWorld();
virtual ~IWorld();
~IWorld() override;
void init() override;
/**
* @brief initPlayer The implementation of This interface must be return playerObject.
@ -354,12 +356,12 @@ private slots:
private:
/**
* @brief init This method initialize world object.
* @brief prepare This method initialize world object.
* @note If object alredy initalize then this method do nothing.
* @return
* @return true if world initialized successful
*/
bool init();
void deinit();
bool prepare();
void reset();
void worldChanged(const WorldObjects& objects);
void clearItems();

View File

@ -42,6 +42,8 @@ void IWorldItem::render(unsigned int) {
}
}
void IWorldItem::init() {}
void IWorldItem::initOnWorld(const IWorld *world, const IWorldItem * player) {
_world = world;
_playerObject = player;

View File

@ -31,6 +31,7 @@ public:
* @note new position = playerPosition + scaneSize;
*/
void render(unsigned int tbfMsec) override;
void init() override;
protected:
@ -60,7 +61,6 @@ private:
const IWorld* _world = nullptr;
const IWorldItem *_playerObject = nullptr;
friend class IWorld;
};
#endif // IWORLDITEM_H

View File

@ -14,6 +14,14 @@
Snake::Snake(const QString &name, const QString &viewTempalte, QObject *ptr):
IPlayer (name, viewTempalte, ptr) {
_vectors = new QVector3D[2];
_vectors[0] = QVector3D(50,50,0); // left tap
_vectors[1] = QVector3D(50,-50,0); // right tap
}
Snake::~Snake( ){
delete [] _vectors;
}
void Snake::render(unsigned int tbfMsec) {
@ -22,7 +30,13 @@ void Snake::render(unsigned int tbfMsec) {
void Snake::add(ClasterItem *object) {
if (auto snakeItem = dynamic_cast<SnakeItem*>(object)) {
snakeItem->setPrev(_lastSnakeItem->guiId());
if (_lastSnakeItem) {
snakeItem->setPrev(_lastSnakeItem->guiId());
} else {
snakeItem->setPrev(guiId());
}
_lastSnakeItem = static_cast<IWorldItem*>(snakeItem);
Claster::add(object);
@ -51,8 +65,70 @@ void Snake::remove(int id) {
return Claster::remove(id);
}
void Snake::onTap() {
void Snake::init() {
generateBody();
}
void Snake::onTap() {
setMovableVector(_vectors[_clickIndex++ % 2]);
}
void Snake::generateBody() {
auto scaleIt = _scales.begin();
for(int i = 0; i < _bodyCount; ++i) {
if (!_factory) {
QuasarAppUtils::Params::log("Please use the registerBodyitem method"
" before invoke parent constructor.",
QuasarAppUtils::Error);
return;
}
auto item = _factory();
float scale = 1;
if (scaleIt != _scales.end()) {
float position = static_cast<float>(i) / _bodyCount;
float from = 0, fromKey = 0;
float to = 0, toKey = 0;
while (position > scaleIt.value() && scaleIt != _scales.end()) {
scaleIt++;
if (scaleIt != _scales.end()) {
from = (scaleIt - 1).value();
to = scaleIt.value();
fromKey = (scaleIt - 1).key();
toKey = scaleIt.key();
}
}
scale = ((position - fromKey) * toKey / (to - from)) + from;
scaleIt.value();
}
item->setSize(item->size() * scale);
add(item);
}
}
int Snake::bodyCount() const {
return _bodyCount;
}
void Snake::setBodyCount(int newBodyCount) {
_bodyCount = newBodyCount;
}
const QMap<float, float> &Snake::scales() const {
return _scales;
}
void Snake::setScales(const QMap<float, float> &newScales) {
_scales = newScales;
}
float Snake::lengthBetwinItems() const{

View File

@ -21,12 +21,15 @@ public:
Snake(const QString& name,
const QString& viewTempalte = DEFAULT_VIEW_TEMPLATE,
QObject *ptr = nullptr);
~Snake() override;
void render(unsigned int tbfMsec) override;
void add(ClasterItem *object) override;
void remove(ClasterItem *object) override;
void remove(int id) override;
void init() override;
// IPlayer interface
/**
@ -41,12 +44,62 @@ public:
*/
void setLengthBetwinItems(float newLengthBetwinItems);
template<class Type>
/**
* @brief registerBodyitem This method register snake body item type. The body items will be generated in the generateBody method. The size of body companents calc from the Snake::scales property.
*/
void registerBodyitem() {
_factory = [](){
return new Type;
};
}
/**
* @brief scales This method return the map of the snake body scales.
* The key of map are position of snake Body and the value are scale factor of current body item.
* The default scales map of snake are:
* ```
* 0.1 - 0.7
* 0.6 - 1
* 1 - 0.1
* ```
* @return scales map of snake body.
*/
const QMap<float, float> &scales() const;
/**
* @brief setScales This method sets new scales map for snake body.
* @param newScales This is new value of the scales map.
*/
void setScales(const QMap<float, float> &newScales);
/**
* @brief bodyCount This method return count of the body items of this snake.
* @return count of body items of the snake.
*/
int bodyCount() const;
/**
* @brief setBodyCount This method sets new size of snake.
* @param newBodyCount this is new value of the body count.
* @note Use This method in the constructor of your child snake class.
*/
void setBodyCount(int newBodyCount);
protected slots:
void onTap() override;
private:
float _lengthBetwinItems = 0;
void generateBody();
QMap<float, float> _scales;
std::function<ClasterItem*()> _factory = nullptr;
float _lengthBetwinItems = 10;
int _bodyCount = 10;
const IWorldItem* _lastSnakeItem = nullptr;
unsigned int _clickIndex = 0;
QVector3D* _vectors;
};

View File

@ -13,7 +13,10 @@ Model {
property var model: null
property int guiId: (model) ? model.guiId : -1;
property bool fMapColor: model && (model.baseColorMap.length || model.emissiveMap.length || model.roughnessMap.length || model.normalMap.length)
property bool fMapColor: model && (model.baseColorMap.length ||
model.emissiveMap.length ||
model.roughnessMap.length ||
model.normalMap.length)
DefaultMaterial {
id: defaultMaterial
@ -38,15 +41,3 @@ Model {
position: (model) ? model.position: Qt.vector3d(0,0,0);
}
//Model {
// source: "#Cube";
// property var model: null
// property int guiId: (model) ? model.guiId : -1;
// materials: [
// DefaultMaterial {
// id: defaultMaterial
// diffuseColor: "#ff1111"
// }
// ]
//}

View File

@ -23,10 +23,6 @@ View3D {
:
Qt.vector3d(0,0,100)
onPositionChanged: {
console.log(position)
}
rotation: (privateRoot.world)? privateRoot.world.cameraRatation: Qt.quaternion(0,0,0,0)
}
@ -82,7 +78,7 @@ View3D {
obj.model = model.getGameObject(cppObjId);
arrayObjects.push(obj)
} else {
console.log("wrong viewTemplate in model");
console.log("wrong viewTemplate in model " + temp.errorString());
}
}

View File

@ -7,7 +7,7 @@
#include "movableobject.h"
#include <math.h>
#include <Crawl/guiobject.h>
MovableObject::MovableObject() {
@ -16,31 +16,9 @@ MovableObject::MovableObject() {
void MovableObject::render(unsigned int tbfMsec) {
if (auto _this = checkminimumRequariedType<GuiObject>()) {
// get object center position
QVector3D currentPosition = _this->position();
// move object to vector
currentPosition += (_currentMovableVector * (tbfMsec / 1000.0));
_this->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;
renderPosition(_this, tbfMsec);
renderRatation(_this, tbfMsec);
}
}
@ -67,3 +45,36 @@ float MovableObject::breakingForce() const {
void MovableObject::setBreakingForce(float newBreakingForce) {
_breakingForce = newBreakingForce;
}
void MovableObject::renderRatation(GuiObject *object, unsigned int) {
if (_currentMovableVector.length() > 0) {
object->setRatation(QQuaternion::rotationTo({1.0f, 0.0, 0.0}, _currentMovableVector));
}
}
void MovableObject::renderPosition(GuiObject *object, unsigned int tbfMsec) {
// get object center position
QVector3D currentPosition = object->position();
// move object to vector
currentPosition += (_currentMovableVector * (tbfMsec / 1000.0));
object->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;
}

View File

@ -10,9 +10,10 @@
#define MOVABLEOBJECT_H
#include "Crawl/irender.h"
#include <QVector3D>
class GuiObject;
/**
* @brief The MovableObject class contains functions for moving object on the world.
* All moving separate to next properties:
@ -45,7 +46,8 @@ public:
/**
* @brief setMovableVector This method sets new value of the mvable vector.
* @param newMovableVector - this is a new value ofthe movable vector
* @param newMovableVector this is a new value ofthe movable vector
* @note The movable vector will be changed in time if you set the MovableObject::breakingForce propertye to non 0 value.
*/
void setMovableVector(const QVector3D &newMovableVector);
@ -74,6 +76,22 @@ public:
*/
void setBreakingForce(float newBreakingForce);
protected:
/**
* @brief renderRatation This method recalc raration for an @a object. The Default implementation converts movableVector to ratation of an @a object.
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
virtual void renderRatation(GuiObject* object, unsigned int tbfMsec);
/**
* @brief renderRatation This method recalc position for an @a object. The Default implementation move the current movable vector to setts movable vector. For example if you invoke the MovableObject::setMovableVector method then object change current movable vector with spead MovableObject::angularVelocity. If you sets
* @param object This is provessing object. Usually @a an object is casted pointer of this to GuiObject type.
* @param tbfMsec This is time betwin frames argument. soame as in the IRender::render function.
*/
virtual void renderPosition(GuiObject* object, unsigned int tbfMsec);
private:
QVector3D _movableVector;
QVector3D _currentMovableVector;

View File

@ -40,12 +40,12 @@ void Engine::setWorld(IWorld *world) {
return ;
if (_currentWorld) {
_currentWorld->deinit();
_currentWorld->reset();
}
_currentWorld = world;
if (!_currentWorld->init()) {
if (!_currentWorld->prepare()) {
QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentWorld->name(),
QuasarAppUtils::Error);

@ -1 +1 @@
Subproject commit 931c937cb076766714e74a8241db8ebb78d6633d
Subproject commit b0804c7c9c6ef2214e37d26869179923faa3ac41