mirror of
https://github.com/QuasarApp/Snake.git
synced 2025-04-27 10:14:39 +00:00
added bas snake class
This commit is contained in:
parent
831fb4b620
commit
d5afbd889b
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
// }
|
||||
// ]
|
||||
//}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user