fix animation

This commit is contained in:
Andrei Yankovich 2018-11-25 03:24:41 +03:00
parent 03490583c1
commit 3dbb3776cc
19 changed files with 257 additions and 106 deletions

View File

@ -17,7 +17,7 @@ bool Controller::nextLvl() {
}
generateDiff(world.init(lvls.value(++lvl)));
startTimer();
return false;
}
@ -50,10 +50,19 @@ void Controller::update() {
world.render();
if(world.isDefiat()) {
stopTimer();
emit finished(false, lvl, world.getCurrentLong());
}
if (world.isEnd()) {
stopTimer();
emit finished(true, lvl, world.getCurrentLong());
}
}
void Controller::newGame() {
world.clear();
WorldRules newGameRules = lvls.first();
lvl = 0;
generateDiff(world.init(newGameRules));

View File

@ -18,12 +18,6 @@ private:
int lvl = 0;
QMap<int, GuiObject *> objectsContainer;
/**
* @brief nextLvl - switch to next lvl from array lvels
* @return true if all levels are passed
*/
bool nextLvl();
void generateDiff(const QMap<int, GuiObject *> &);
public:
@ -35,6 +29,12 @@ public slots:
void buttonPress();
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
*/
@ -54,7 +54,7 @@ signals:
* @param lvl - game over lvl
* @param distance - game over distance
*/
void finished(bool victory, int lvl, int distance);
void finished(bool victory, int lvl, double distance);
/**
* @brief gameObjectsChanged

View File

@ -15,15 +15,10 @@ QString GuiObject::texture() const {
}
void GuiObject::render() {
}
QRectF GuiObject::rect() const {
return m_rect;
}
QRectF& GuiObject::getRect() {
return m_rect;
return QRectF(m_x, m_y, m_w, m_h);
}
void GuiObject::setAngle(double angle) {
@ -47,12 +42,20 @@ void GuiObject::setColor(QString color) {
emit colorChanged(m_color);
}
void GuiObject::setRect(QRectF rect) {
if (m_rect == rect)
return;
double GuiObject::x() const {
return m_x;
}
m_rect = rect;
emit rectChanged(m_rect);
double GuiObject::y() const {
return m_y;
}
double GuiObject::w() const {
return m_w;
}
double GuiObject::h() const {
return m_h;
}
void GuiObject::generateId() {
@ -60,6 +63,29 @@ void GuiObject::generateId() {
m_guiId = id++;
}
void GuiObject::setH(double h) {
m_h = h;
emit hChanged(m_h);
}
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);

View File

@ -13,23 +13,28 @@ class GuiObject:public QObject, public BaseClass
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(QRectF rect READ rect WRITE setRect NOTIFY rectChanged)
Q_PROPERTY(int guiId READ guiId NOTIFY guiIdChanged)
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();
protected:
int m_guiId;
double m_angle;
QString m_texture;
QString m_color;
QRectF m_rect;
double m_x;
double m_y;
double m_w;
double m_h;
void setTexture(const QString &texture);
void setRect(QRectF rect);
public:
@ -41,7 +46,6 @@ public:
void render();
QRectF rect() const;
QRectF &getRect();
virtual void setAngle(double angle);
int guiId() const;
@ -49,12 +53,25 @@ public:
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);
signals:
void angleChanged(double angle);
void textureChanged(QString texture);
void rectChanged(QRectF rect);
void guiIdChanged(int guiId);
void colorChanged(QString color);
void xChanged(double x);
void yChanged(double y);
void wChanged(double w);
void hChanged(double h);
};
#endif // GUIOBJECT_H

View File

@ -8,7 +8,7 @@ GuiObjectFactory::GuiObjectFactory() {}
ItemWorld *GuiObjectFactory::generate(const QString &name) {
ItemWorld *obj = nullptr;
if (name == "Box") {
obj = new Box(rand() % 100, 0);
obj = new Box(rand() % 400, 0);
}
return obj;

View File

@ -2,23 +2,29 @@
#include <cmath>
#include <QDateTime>
void Head::render(){
void Head::render() {
qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time;
double my = m_rect.y() + *speed * sin(m_angle * TO_RADIAN);
auto dy = (my - m_rect.y()) / 1000 * tempTime;
m_rect.moveTop(m_rect.y() + dy);
time = QDateTime::currentMSecsSinceEpoch();
emit rectChanged(m_rect);
double my = (m_y + (*speed * 0.75) * sin(m_angle * TO_RADIAN));
m_y += (my - m_y) / 1000 * tempTime;
emit yChanged(m_y);
}
Head::Head(const QRectF &rect, double *spead):
Head::Head(double x, double y, double h, double w, double *spead):
GuiObject () {
setRect(rect);
setX(x);
setY(y);
setW(w);
setH(h);
this->speed = spead;
}
void Head::setAngle(double angle) {
m_angle = angle/2;
m_angle = angle;
emit angleChanged(m_angle);
}

View File

@ -12,7 +12,7 @@ private:
qint64 time;
double *speed;
public:
Head(const QRectF &rect , double *speed);
Head(double x , double y, double h, double w, double *speed);
void setAngle(double angle) override;
void render() override;

View File

@ -7,34 +7,37 @@
#define POINT 100
ItemWorld::ItemWorld(double x, double y) {
setSize(x, y);
setLoc(x, y);
}
void ItemWorld::setBeckGroundObject(bool value) {
beckGroundObject = value;
}
void ItemWorld::setSize(double x, double y) {
QRectF rect;
rect.setX(x);
rect.setY(y);
setRect(rect);
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_rect.x() < 0) {
m_rect.setX(rand() % 200);
m_rect.setY(rand() % 100);
emit rectChanged(m_rect);
if (m_x < 0) {
m_x = (rand() % 400) + 200;
m_y = rand() % 100;
emit xChanged(m_x);
emit yChanged(m_y);
}
}
bool ItemWorld::move(const QRectF &snakeRiger, double dx) {
m_rect.setX( m_rect.x() - dx);
emit rectChanged(m_rect);
bool ItemWorld::move(const GuiObject *snakeRiger, double dx) {
m_x -= dx;
emit xChanged(m_x);
return snakeRiger.intersects(m_rect) && !beckGroundObject;
return snakeRiger->rect().intersects(rect()) && !beckGroundObject;
}
bool ItemWorld::isBeckGroundObject() {

View File

@ -9,14 +9,15 @@ class ItemWorld : public GuiObject
private:
bool beckGroundObject = false;
protected:
virtual void setSize(double x, double y);
virtual void setSize(double h, double w);
virtual void setLoc(double x, double y);
void setBeckGroundObject(bool value);
public:
ItemWorld(double x, double y);
void render();
bool move(const QRectF& snakeRiger, double dx);
bool move(const GuiObject* snakeRiger, double dx);
bool isBeckGroundObject();
~ItemWorld();

View File

@ -1,9 +1,9 @@
#include "lvls.h"
QList<WorldRules> lvls {
WorldRules{{"Long", 500}, {"Box", 1}, {"Spead", 10}},
WorldRules{{"Long", 1000}, {"Box", 2}, {"Spead", 10}},
WorldRules{{"Long", 2000}, {"Box", 4}, {"Spead", 10}},
WorldRules{{"Long", 4000}, {"Box", 8}, {"Spead", 10}},
WorldRules{{"Long", 8000}, {"Box", 8}, {"Spead", 10}}
WorldRules{{"Lvl", 1}, {"Long", 500}, {"Box", 2}, {"Spead", 10}},
WorldRules{{"Lvl", 2}, {"Long", 1000}, {"Box", 4}, {"Spead", 12}},
WorldRules{{"Lvl", 3}, {"Long", 2000}, {"Box", 8}, {"Spead", 14}},
WorldRules{{"Lvl", 4}, {"Long", 4000}, {"Box", 16}, {"Spead", 18}},
WorldRules{{"Lvl", 5}, {"Long", 8000}, {"Box", 32}, {"Spead", 26}}
};

View File

@ -16,17 +16,16 @@ int main(int argc, char *argv[])
qmlRegisterType <GuiObject> ();
qmlRegisterType <Diff> ();
engine.load(QUrl(QStringLiteral("qrc:/front-end/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
auto root = engine.rootContext();
if (!root)
return -1;
Controller contr;
root->setContextProperty("contr", &contr);
contr.newGame();
engine.load(QUrl(QStringLiteral("qrc:/front-end/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}

View File

@ -3,9 +3,9 @@
#include <QMap>
#include <QRectF>
#include <cmath>
Snake::Snake() :
speed(SPEEDSNAKE) {
Snake::Snake() {
}
const QVector<Head *> &Snake::getItems() const {
@ -14,7 +14,8 @@ const QVector<Head *> &Snake::getItems() const {
void Snake::render() {
for (int i = items.length() - 1; i >= 0; --i) {
if(i == 0){
if(i == 0) {
if(isClick){
if(countClick & 1){
items[i]->setAngle(45);
@ -23,19 +24,40 @@ void Snake::render() {
}
isClick = false;
}
}else{
items[i]->setAngle(items[i-1]->angle());
}else {
double _atan2 = atan2(items[i - 1]->rect().center().y() - items[i]->rect().center().y(),
items[i - 1]->rect().center().x() - items[i]->rect().center().x()) * 180;
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::changeCountObjects(int count) {
if (count > 0) {
double margin = 40.0 / count;
double margin = 60.0 / count;
for ( int i = 0; i < count; ++i ) {
QRectF rect(margin * (count - i), 50, 10, 10);
auto obj = new Head(rect, &this->speed);
auto obj = new Head(margin * (count - i),
50, 7, 7, this->speed);
items.push_back(obj);
}
@ -49,11 +71,11 @@ void Snake::changeCountObjects(int count) {
}
}
QMap<int, GuiObject*> Snake::init(int size, double speed) {
QMap<int, GuiObject*> Snake::init(int size, double *speed) {
QMap<int, GuiObject*> res;
if (size <= 0 || speed <= 0) {
if (size <= 0) {
return res;
}
@ -72,12 +94,19 @@ bool Snake::isInited() const {
return items.size();
}
Snake::~Snake() {
void Snake::clearItems() {
for (auto i : items) {
delete i;
}
items.clear();
}
Snake::~Snake() {
clearItems();
}
void Snake::clear() {
clearItems();
}
void Snake::reverse() {
@ -87,7 +116,3 @@ void Snake::reverse() {
isClick = true;
countClick++;
}
const QRectF& Snake::getRiger() const {
return items.first()->getRect();
}

View File

@ -12,23 +12,29 @@ class GuiObject;
class Snake : public BaseClass
{
private:
double rataticonDistance = 1;
QVector<Head*> items;
double speed = 0;
double *speed = nullptr;
bool isClick = false;
int countClick = 0;
void changeCountObjects(int count);
double checDistance(int i);
void clearItems();
public:
Snake();
~Snake() override;
void clear();
void reverse();
const QRectF &getRiger() const;
void render() override;
QMap<int, GuiObject *> init(int size, double speed);
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);
};
#endif // SNAKE_H

View File

@ -12,6 +12,15 @@ World::World() {
background = "";
}
void World::clear() {
clearItems();
snake.clear();
}
double World::getCurrentLong() const {
return currentLong;
}
void World::clearItems() {
for (auto i : items) {
delete i;
@ -47,12 +56,6 @@ QMap<int, GuiObject *> World::init(const WorldRules &rules) {
QMap<int, GuiObject*> res;
auto snakeItems = snake.init(10, 15);
for (auto i = snakeItems.begin(); i != snakeItems.end(); ++i) {
res.insert(i.key(), i.value());
}
currentLong = -1;
for (auto i = rules.begin(); i != rules.end(); ++i) {
if (i.key() == "Long") {
@ -60,19 +63,27 @@ QMap<int, GuiObject *> World::init(const WorldRules &rules) {
currentLong = 0;
}
else if (i.key() == "Spead") {
spead = rules["Spead"];
d_spead = rules["Spead"];
}
else {
changeCountObjects(i.key(), i.value() - oldRules.value(i.key()));
}
}
auto snakeItems = snake.init(10, &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();
return res;
}
@ -84,16 +95,22 @@ void World::render() {
qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time;
time = QDateTime::currentMSecsSinceEpoch();
auto dx = speed / 1000 * tempTime;
double dx = spead / 1000 * tempTime;
spead -= 0.0310 * tempTime;
if (spead < 0)
spead = 0;
snake.render();
const QRectF &rig = snake.getRiger();
auto rig = snake.getItems().first();
for (int i = items.length() - 1; i >= 0; --i) {
defiat |= items[i]->move(rig, dx);
items[i]->render();
}
currentLong += dx;
}
@ -115,6 +132,7 @@ WorldRules World::currentRules() const {
void World::reversClick() {
snake.reverse();
spead += d_spead;
}
const QVector<ItemWorld *> &World::getItems() const {

View File

@ -15,11 +15,10 @@ private:
Snake snake;
QVector<ItemWorld*> items;
double currentLong;
double currentLong = 0;
int endLong;
double spead;
double spead = 0, d_spead = 0;
QString background;
double speed;
qint64 time;
bool defiat = false;
WorldRules oldRules;
@ -30,6 +29,7 @@ private:
public:
World();
void clear();
QMap<int, GuiObject*> init(const WorldRules &rules);
~World() override;
void render() override;
@ -39,6 +39,7 @@ public:
bool isDefiat() const;
WorldRules currentRules() const;
void reversClick();
double getCurrentLong() const;
};
#endif // WORLD_H

View File

@ -5,23 +5,23 @@ Rectangle {
property var model: null
property real angle: (model) ? model.angle : 0;
property string texture: (model) ? model.texture : "";
property rect rec: (model) ? model.rect : Qt.rect(0, 0, 0, 0);
property int guiId: (model) ? model.color : -1;
property double devX: width / 2
property double devY: height / 2
color: (model) ? model.color : "#11ff32";
width: rec.width * mainWindow.point;
height: rec.height * mainWindow.point;
width: (model) ? model.w * mainWindow.point: 0;
height: (model) ? model.h * mainWindow.point: 0;
x: rec.x * mainWindow.point;
y: rec.y * mainWindow.point;
x: (model) ? model.x * mainWindow.point - devX: 0;
y: (model) ? model.y * mainWindow.point - devY: 0;
transform: Rotation {
origin.x: rec.x / 2;
origin.y: rec.y / 2;
origin.x: devX;
origin.y: devY;
angle: graphicItem.angle;
}

View File

@ -28,7 +28,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
contr.newGame();
}
}

View File

@ -2,9 +2,9 @@ import QtQuick 2.9
Item {
id: scene;
property var model: contr;
property var model: (contr)? contr: null;
property var arrayObjects: []
signal showMenu();
function add (cppObjId) {
if (!model) {
console.log("create object fail")
@ -36,6 +36,25 @@ Item {
}
}
function setAuto (auto) {
if (auto && model) {
model.newGame();
}
autoTimer.running = auto && model;
}
Timer {
id :autoTimer;
repeat: true;
running: false;
interval: 1000
onTriggered: {
interval = Math.random() * 600
scene.model.buttonPress();
}
}
Connections {
target: model;
onGameObjectsChanged: {
@ -57,6 +76,20 @@ Item {
remove(tempDifRem[i]);
}
}
onFinished: {
var isVictory = victory;
var gameLvl = lvl;
var dist = distance;
if (isVictory ) {
model.nextLvl();
} else if (autoTimer.running) {
model.newGame();
} else {
showMenu();
}
}
}
MouseArea {

View File

@ -13,10 +13,17 @@ ApplicationWindow {
property real point: (width < height) ? width/pointCount : height/pointCount;
Component.onCompleted: {
scane.setAuto(true);
}
Scene {
id: scane;
anchors.fill: parent;
}
// MainMenu {
// anchors.fill: parent;
// }
}