201 lines
3.9 KiB
C++
Raw Normal View History

2018-09-11 20:10:37 +03:00
#include "snake.h"
2018-10-11 00:04:52 +03:00
#include "guiobject.h"
2018-09-11 20:10:37 +03:00
2018-11-28 22:17:30 +03:00
#include <QDateTime>
2018-10-11 00:04:52 +03:00
#include <QMap>
#include <QRectF>
2018-11-25 03:24:41 +03:00
#include <cmath>
2018-09-11 22:15:30 +03:00
2018-11-25 03:24:41 +03:00
Snake::Snake() {
2018-09-11 22:15:30 +03:00
}
2018-09-11 22:08:08 +03:00
const QVector<Head *> &Snake::getItems() const {
2018-09-14 22:06:34 +03:00
return items;
2018-09-11 20:10:37 +03:00
}
2018-09-11 22:15:30 +03:00
void Snake::render() {
2018-11-28 22:17:30 +03:00
2018-12-01 22:39:03 +03:00
auto centerX = [](const Head* head) {
return head->x()/* + (head->w() / 2)*/;
};
auto centerY = [](const Head* head) {
return head->y() /*+ (head->h() / 2)*/;
};
2018-11-14 23:15:36 +03:00
for (int i = items.length() - 1; i >= 0; --i) {
2018-11-25 03:24:41 +03:00
2018-11-28 22:17:30 +03:00
if (dead) {
items[i]->render();
continue;
}
2019-02-11 16:42:52 +03:00
if (i == 0) {
if (isClick) {
if (countClick & 1){
2018-09-14 22:13:47 +03:00
items[i]->setAngle(45);
2019-02-11 16:42:52 +03:00
} else {
2018-09-14 22:13:47 +03:00
items[i]->setAngle(315);
2018-09-14 22:06:34 +03:00
}
2018-11-16 02:08:35 +03:00
isClick = false;
2018-09-14 22:06:34 +03:00
}
2018-12-01 22:39:03 +03:00
} else {
double _atan2 = atan2(centerY(items[i - 1]) - centerY(items[i]),
2019-02-11 16:42:52 +03:00
centerX(items[i - 1]) - centerX(items[i])) * 90;
2018-11-25 03:24:41 +03:00
items[i]->setAngle(_atan2);
2018-09-14 22:06:34 +03:00
}
2018-11-25 03:24:41 +03:00
2018-11-16 02:08:35 +03:00
items[i]->render();
2018-09-14 22:06:34 +03:00
}
2018-09-11 20:10:37 +03:00
}
2018-11-25 03:24:41 +03:00
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;
}
2018-12-01 22:39:03 +03:00
void Snake::unPause() {
for ( int i = 0; i < items.size(); ++i ) {
items[i]->unPause();
}
}
2018-12-01 21:06:40 +03:00
double Snake::sizeByLvl(double lvl , int count) const {
double maxSize = 9;
double minSize = 5;
double pos = (1 - (lvl / count));
QList<QPair<double, double>> snakeGradientSize {
2018-12-06 22:49:35 +03:00
{1, 4},
{0.99, 7},
{0.8, 5},
{0.6, 6},
2018-12-01 21:06:40 +03:00
{0.0, 3}
};
2018-12-01 22:39:03 +03:00
double local = 0;
2018-12-01 21:06:40 +03:00
int index = 0;
while (index + 1 < snakeGradientSize.size()
&& pos <= snakeGradientSize[index].first) {
2018-12-01 22:39:03 +03:00
maxSize = snakeGradientSize[index].second;
minSize = snakeGradientSize[index + 1].second;
2018-12-01 21:06:40 +03:00
2018-12-01 22:39:03 +03:00
auto range = snakeGradientSize[index].first -
snakeGradientSize[index + 1].first;
2018-12-01 21:06:40 +03:00
2018-12-01 22:39:03 +03:00
local = ( range - (snakeGradientSize[index].first - pos)) /
2018-12-01 21:06:40 +03:00
range;
index++;
}
2018-12-01 22:39:03 +03:00
return local * (maxSize - minSize) + minSize;
2018-12-01 21:06:40 +03:00
}
void Snake::changeCountObjects(int count) {
if (count > 0) {
2018-11-25 03:24:41 +03:00
double margin = 60.0 / count;
for ( int i = 0; i < count; ++i ) {
2018-12-01 21:06:40 +03:00
auto size = sizeByLvl(i, count);
2018-11-25 03:24:41 +03:00
auto obj = new Head(margin * (count - i),
2018-12-02 14:06:48 +03:00
50, size , size,
2018-12-01 21:06:40 +03:00
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;
}
}
}
2018-11-25 03:24:41 +03:00
QMap<int, GuiObject*> Snake::init(int size, double *speed) {
2018-10-11 00:04:52 +03:00
QMap<int, GuiObject*> res;
2018-09-11 22:08:08 +03:00
2018-11-25 03:24:41 +03:00
if (size <= 0) {
2018-10-11 00:04:52 +03:00
return res;
2018-09-11 20:10:37 +03:00
}
2018-09-14 22:06:34 +03:00
this->speed = speed;
2018-09-11 22:08:08 +03:00
2018-11-25 18:10:08 +03:00
changeCountObjects(size - items.size());
2018-10-11 18:09:35 +03:00
for (auto i : items) {
res[i->guiId()] = i;
2018-09-11 22:08:08 +03:00
}
2018-11-28 22:17:30 +03:00
dead = false;
2018-10-11 00:04:52 +03:00
return res;
2018-09-11 20:10:37 +03:00
}
2018-09-11 22:15:30 +03:00
bool Snake::isInited() const {
return items.size();
}
2018-11-25 03:24:41 +03:00
void Snake::clearItems() {
2018-09-14 22:06:34 +03:00
for (auto i : items) {
2018-09-11 22:15:30 +03:00
delete i;
}
2018-09-14 22:06:34 +03:00
items.clear();
2018-11-25 03:24:41 +03:00
}
2018-09-11 22:15:30 +03:00
2018-11-25 18:10:08 +03:00
void Snake::resetPosotion() {
double margin = 60.0 / items.size();
for ( int i = 0; i < items.size(); ++i ) {
items[i]->setX(margin * (items.size() - i));
2018-12-01 21:06:40 +03:00
items[i]->setY(50 + items[i]->h() / 2);
2018-11-25 18:10:08 +03:00
items[i]->setAngle(0);
}
}
2018-11-28 22:17:30 +03:00
void Snake::kill() {
dead = true;
}
bool Snake::isDead() const {
return dead;
}
2018-11-25 03:24:41 +03:00
Snake::~Snake() {
clearItems();
}
void Snake::clear() {
clearItems();
2018-09-11 22:15:30 +03:00
}
2018-10-11 00:04:52 +03:00
2018-11-16 02:08:35 +03:00
void Snake::reverse() {
if (isClick) {
return;
}
isClick = true;
countClick++;
}